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 "pwn template" command for generating templates #909

Merged
merged 1 commit into from Feb 17, 2017

Conversation

zachriggle
Copy link
Member

@zachriggle zachriggle commented Feb 16, 2017

Super useful for quickly stubbing stuff out, and for introducing people to pwntools for the first time.

Any File

This only happens if we get something not-an-ELF, e.g. perhaps the target is a shell-script wrapper around something else. Note we set context explicitly here.

$ pwn template not-a-valid-elf
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *

# Set up pwntools for the correct architecture
context.update(arch='i386')

gdbscript = '''
continue
'''.format(**locals())

if args.GDB:
    io = gdb.debug('not-a-valid-elf', gdbscript=gdbscript)
else:
    io = process('not-a-valid-elf')

#===========================================================
#                    EXPLOIT GOES HERE
#===========================================================
# shellcode = asm(shellcraft.sh())
# payload = fit({
#     32: 0xdeadbeef,
#     'iaaa': [1, 2, 'Hello', 3]
# }, length=128)
# io.send(payload)
# flag = io.recv(...)
# log.success(flag)

io.interactive()

ELF File

If a valid ELF file is specified, we set the context, and add a breakpoint on either the entry or main.

Additionally, we use gdb.debug() instead of gdb.attach() in case there is a foreign-architecture binary (can't attach to a QEMU-emulated process), and we avoid the question of "How do I debug from the start?".

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *

# Set up pwntools for the correct architecture
exe = context.binary = ELF('vulnerable')


gdbscript = '''
break *0x{exe.entry:x}
continue
'''.format(**locals())


if args.GDB:
    io = gdb.debug(exe, gdbscript=gdbscript)
else:
    io = process(exe)

#===========================================================
#                    EXPLOIT GOES HERE
#===========================================================
...

Remote TCP exploit

Note that we use args and inform the user about their options.

Additionally, note that we use gdb.attach() for the remote process.

Finally, we use connect instead of remote. This makes it so I don't need a better name for remote.

$ pwn template vulnerable --host example.com --port 9999
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *

# Set up pwntools for the correct architecture
exe = context.binary = ELF('vulnerable')

# Change any of these or built-in settings settings when running the exploit
# python exploit.py GDB DEBUG NOASLR HOST=example.com PORT=4141
host = args.HOST or 'example.com'
port = int(args.PORT or 9999)

gdbscript = '''
break *0x{exe.entry:x}
continue
'''.format(**locals())

def local():
    if args.GDB:
        return gdb.debug(exe.path, gdbscript=gdbscript)
    else:
        return process(exe.path)

def remote():
    return connect(host, port)

start = local if args.LOCAL else remote

io = start()

if args.GDB and not args.LOCAL:
    gdb.attach(io, gdbscript=gdbscript)

#===========================================================
#                    EXPLOIT GOES HERE
#===========================================================
...

Secure Shell

Again, we use gdb.debug() in favor of gdb.attach().

$ pwn template vulnerable --host example.com --user username --password secret1234
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *

# Set up pwntools for the correct architecture
exe = context.binary = ELF('vulnerable')

# Change any of these or built-in settings settings when running the exploit
# python exploit.py GDB DEBUG NOASLR HOST=example.com PORT=4141
host = args.HOST or 'example.com'
port = int(args.PORT or 22)
user = args.USER or 'username'
password = args.PASSWORD or 'secret1234'
remote_path = 'vulnerable'

gdbscript = '''
break *0x{exe.entry:x}
continue
'''.format(**locals())

shell = None
if not args.LOCAL:
    shell = ssh(user, host, port, password)
    shell.set_working_directory(symlink=True)

def local():
    if args.GDB:
        return gdb.debug(exe.path, gdbscript=gdbscript)
    else:
        return process(exe.path)

def remote():
    if args.GDB:
        return gdb.debug(remote_path, gdbscript=gdbscript, ssh=shell)
    else:
        return shell.process(remote_path)

start = local if args.LOCAL else remote

io = start()

#===========================================================
#                    EXPLOIT GOES HERE
#===========================================================
...

Closes #680
Closes #830

@EvanCarroll
Copy link

Is pwn template documented anywhere?

@zachriggle
Copy link
Member Author

zachriggle commented Jan 16, 2019

Yes, but there's not any more docs than what is available via pwn template --help. The template generated by the command also has a bunch of comments about how to use it.

It looks like somebody made a cool little video here: https://www.youtube.com/watch?v=NhNbivMVPk0

(Note: I can't speak for the accuracy or up-to-date-ness of the video, but the video looks pretty well done!)

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

Successfully merging this pull request may close these issues.

None yet

3 participants