Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dockerized tube for better pwning #1628

Open
ohk990102 opened this issue Jul 4, 2020 · 8 comments
Open

add dockerized tube for better pwning #1628

ohk990102 opened this issue Jul 4, 2020 · 8 comments
Labels

Comments

@ohk990102
Copy link

ohk990102 commented Jul 4, 2020

When pwning(especially heap challenges), I sometimes want to make docker environment, put all challenge files, execute and debug with pwntools enabled.

Maybe this process can be automated by adding process-like tube (I called it dockerized)

from pwn import *

context.log_level = 'debug'

if __name__ == "__main__":
    p = dockerized('./realloc', baseimage='ubuntu:18.04', prefer_dockerfile=False)
    gdb.attach(p)
    p.interactive()

I made similar feature in https://github.com/ohk990102/pwntools-addon-dockerized, and hope this can be added in pwntools too.

@zachriggle
Copy link
Member

zachriggle commented Jul 4, 2020 via email

@ohk990102
Copy link
Author

I thought that by this feature, we do not need to make any new Docker script and just write exploit scripts like we do in normal pwning or in qemu usermode. And also gdb attach can be solved by opening gdbserver and connecting to it.

@zachriggle
Copy link
Member

zachriggle commented Jul 5, 2020 via email

@ohk990102
Copy link
Author

I'll try, but as I don't know much about pwntools codebase, can you give me some advice for adding new tube?

And on second thought, making ssh-like tube will give more flexibility, like this

from pwn import *

r = dockerized(baseimage='ubuntu:18.04', prefer_dockerfile=False)
p = r.process('./sample')
p.interactive()

@zachriggle
Copy link
Member

I think the best way for this to work is to have dockerize just spin up the VM with openssh running, and have e.g. r.process POSSIBLY do some magic to copy the binary to the target VM if it doesn't exist.

Doing it in a more Docker-y way has a few outstanding questions...

  • dockerize does a docker pull and creates an instance
    • How do we create an instance with no running processes?
  • dockerize.process copies the library into the running instance
    • Where do we copy it to?
  • dockerize.process starts the process
    • How do we capture stdio?
    • How do we handle stdin=subprocess.PIPE vs stdin=PTY?
  • How do we handle file copying? Let's say we need to get a file OUT of the container, or multiple files.

I think the best bet for this is to just have dockerize be a wrapper that installs and starts openssh, maps a port to the external interface, and SSHes into the box.

This lets us leverage all of the existing SSH infrastructure.

@ohk990102
Copy link
Author

ohk990102 commented Jul 8, 2020

To be more specific, I'm planning to make tube like this.

  • dockerize: Makes a docker image and run it.
    • If Dockerfile exists in context and baseimage not specified, create image based on the Dockerfile
    • If baseimage specified, makes a temporary Dockerfile and create image.
      • The contents will be somewhat like this
#As given in baseimage arg
FROM ubuntu:18.04
COPY ./ ./
# Install gdbserver when debugging options specified. 
CMD [ '/bin/sh' ]
  • dockerize.process: execute process on the container. (just like ssh.process)
    • will return process-like tube.

For the questions,

  • How do we create an instance with no running processes?
    • Default CMD or ENTRYPOINT can be shell like /bin/sh, just like spawning a base ubuntu image.
    • or maybe we can offer args (e.g. dockerize(cmd='...'))
  • Where do we copy it to?
    • dockerize.process does not copy files, but dockerize does.
  • How do we capture stdio?
  • How do we handle stdin=subprocess.PIPE vs stdin=PTY?
    • I'm not good at PIPEs and PTYs, so I can't understand the question(sorry 😭).
  • How do we handle file copying? Let's say we need to get a file OUT of the container, or multiple files.
    • There is docker api that handles such thing, e.g. get_archive.

I agree with the point that using openssh and wrapping existing ssh tube will solve most of the problem.
However, I want to deal with the case when ctf challenges are given with Dockerfile. When we use existing ssh tube, we should modify on the Dockerfile script to spawn ssh daemon and expose port. But using docker api, this limits will be gone(I guess).

I'll make a pull request when these functions are implemented. Maybe you can merge it when all the functions work correctly and finds it useful.

@heapcrash
Copy link
Collaborator

Any updates on this? I'd love to see your pull request

@ohk990102
Copy link
Author

ohk990102 commented Aug 5, 2020

I'm working on this, but facing some problems.

  • Implementing all features provided in process tube is a little bit difficult, as access to proc system from host is limited. Getting information inside container may solve this.
  • docker api is little bit inconsistent between python2 and python3

The code is on https://github.com/ohk990102/pwntools.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants