pwnlib.shellcraft.amd64 — Shellcode for AMD64

pwnlib.shellcraft.amd64

Shellcraft module containing generic Intel x86_64 shellcodes.

pwnlib.shellcraft.amd64.crash()[源代码]

Crash.

Example

>>> run_assembly(shellcraft.crash()).poll(True)
-11
pwnlib.shellcraft.amd64.infloop()[源代码]

A two-byte infinite loop.

pwnlib.shellcraft.amd64.itoa(v, buffer='rsp', allocate_stack=True)[源代码]

Converts an integer into its string representation, and pushes it onto the stack.

参数:
  • v (str, int) – Integer constant or register that contains the value to convert.
  • alloca

Example

>>> sc = shellcraft.amd64.mov('rax', 0xdeadbeef)
>>> sc += shellcraft.amd64.itoa('rax')
>>> sc += shellcraft.amd64.linux.write(1, 'rsp', 32)
>>> run_assembly(sc).recvuntil('\x00')
'3735928559\x00'
pwnlib.shellcraft.amd64.memcpy(dest, src, n)[源代码]

Copies memory.

参数:
  • dest – Destination address
  • src – Source address
  • n – Number of bytes
pwnlib.shellcraft.amd64.mov(dest, src, stack_allowed=True)[源代码]

Move src into dest without newlines and null bytes.

If the src is a register smaller than the dest, then it will be zero-extended to fit inside the larger register.

If the src is a register larger than the dest, then only some of the bits will be used.

If src is a string that is not a register, then it will locally set context.arch to ‘amd64’ and use pwnlib.constants.eval() to evaluate the string. Note that this means that this shellcode can change behavior depending on the value of context.os.

Example

>>> print shellcraft.amd64.mov('eax','ebx').rstrip()
    mov eax, ebx
>>> print shellcraft.amd64.mov('eax', 0).rstrip()
    xor eax, eax /* 0 */
>>> print shellcraft.amd64.mov('ax', 0).rstrip()
    xor ax, ax /* 0 */
>>> print shellcraft.amd64.mov('rax', 0).rstrip()
    xor eax, eax /* 0 */
>>> print shellcraft.amd64.mov('rdi', 'ax').rstrip()
    movzx edi, ax
>>> print shellcraft.amd64.mov('al', 'ax').rstrip()
    /* moving ax into al, but this is a no-op */
>>> print shellcraft.amd64.mov('ax', 'bl').rstrip()
    movzx ax, bl
>>> print shellcraft.amd64.mov('eax', 1).rstrip()
    push 1
    pop rax
>>> print shellcraft.amd64.mov('rax', 0xc0).rstrip()
    xor eax, eax
    mov al, 0xc0
>>> print shellcraft.amd64.mov('rax', 0xc000).rstrip()
    xor eax, eax
    mov ah, 0xc000 >> 8
>>> print shellcraft.amd64.mov('rax', 0xc0c0).rstrip()
    xor eax, eax
    mov ax, 0xc0c0
>>> print shellcraft.amd64.mov('rdi', 0xff).rstrip()
    mov edi, 0x1010101 /* 255 == 0xff */
    xor edi, 0x10101fe
>>> print shellcraft.amd64.mov('rax', 0xdead00ff).rstrip()
    mov eax, 0x1010101 /* 3735879935 == 0xdead00ff */
    xor eax, 0xdfac01fe
>>> print shellcraft.amd64.mov('rax', 0x11dead00ff).rstrip()
    mov rax, 0x101010101010101 /* 76750323967 == 0x11dead00ff */
    push rax
    mov rax, 0x1010110dfac01fe
    xor [rsp], rax
    pop rax
>>> print shellcraft.amd64.mov('rax', 0xffffffff).rstrip()
    mov eax, 0xffffffff
>>> print shellcraft.amd64.mov('rax', 0x7fffffff).rstrip()
    mov eax, 0x7fffffff
>>> print shellcraft.amd64.mov('rax', 0x80010101).rstrip()
    mov eax, 0x80010101
>>> print shellcraft.amd64.mov('rax', 0x80000000).rstrip()
    mov eax, 0x1010101 /* 2147483648 == 0x80000000 */
    xor eax, 0x81010101
>>> print shellcraft.amd64.mov('rax', 0xffffffffffffffff).rstrip()
    push 0xffffffffffffffff
    pop rax
>>> with context.local(os = 'linux'):
...     print shellcraft.amd64.mov('eax', 'SYS_read').rstrip()
    xor eax, eax /* SYS_read */
>>> with context.local(os = 'freebsd'):
...     print shellcraft.amd64.mov('eax', 'SYS_read').rstrip()
    push SYS_read /* 3 */
    pop rax
>>> with context.local(os = 'linux'):
...     print shellcraft.amd64.mov('eax', 'PROT_READ | PROT_WRITE | PROT_EXEC').rstrip()
    push (PROT_READ | PROT_WRITE | PROT_EXEC) /* 7 */
    pop rax
参数:
  • dest (str) – The destination register.
  • src (str) – Either the input register, or an immediate value.
  • stack_allowed (bool) – Can the stack be used?
pwnlib.shellcraft.amd64.nop()[源代码]

A single-byte nop instruction.

pwnlib.shellcraft.amd64.popad()[源代码]

Pop all of the registers onto the stack which i386 popad does, in the same order.

pwnlib.shellcraft.amd64.push(value)[源代码]

Pushes a value onto the stack without using null bytes or newline characters.

If src is a string, then we try to evaluate with context.arch = ‘amd64’ using pwnlib.constants.eval() before determining how to push it. Note that this means that this shellcode can change behavior depending on the value of context.os.

参数:value (int,str) – The value or register to push

Example

>>> print pwnlib.shellcraft.amd64.push(0).rstrip()
    /* push 0 */
    push 1
    dec byte ptr [rsp]
>>> print pwnlib.shellcraft.amd64.push(1).rstrip()
    /* push 1 */
    push 1
>>> print pwnlib.shellcraft.amd64.push(256).rstrip()
    /* push 256 */
    push 0x1010201 ^ 0x100
    xor dword ptr [rsp], 0x1010201
>>> with context.local(os = 'linux'):
...     print pwnlib.shellcraft.amd64.push('SYS_write').rstrip()
    /* push 'SYS_write' */
    push 1
>>> with context.local(os = 'freebsd'):
...     print pwnlib.shellcraft.amd64.push('SYS_write').rstrip()
    /* push 'SYS_write' */
    push 4
pwnlib.shellcraft.amd64.pushad()[源代码]

Push all of the registers onto the stack which i386 pushad does, in the same order.

pwnlib.shellcraft.amd64.pushstr(string, append_null=True)[源代码]

Pushes a string onto the stack without using null bytes or newline characters.

Example

>>> print shellcraft.amd64.pushstr('').rstrip()
    /* push '\x00' */
    push 1
    dec byte ptr [rsp]
>>> print shellcraft.amd64.pushstr('a').rstrip()
    /* push 'a\x00' */
    push 0x61
>>> print shellcraft.amd64.pushstr('aa').rstrip()
    /* push 'aa\x00' */
    push 0x1010101 ^ 0x6161
    xor dword ptr [rsp], 0x1010101
>>> print shellcraft.amd64.pushstr('aaa').rstrip()
    /* push 'aaa\x00' */
    push 0x1010101 ^ 0x616161
    xor dword ptr [rsp], 0x1010101
>>> print shellcraft.amd64.pushstr('aaaa').rstrip()
    /* push 'aaaa\x00' */
    push 0x61616161
>>> print shellcraft.amd64.pushstr('aaa\xc3').rstrip()
    /* push 'aaa\xc3\x00' */
    mov rax, 0x101010101010101
    push rax
    mov rax, 0x101010101010101 ^ 0xc3616161
    xor [rsp], rax
>>> print shellcraft.amd64.pushstr('aaa\xc3', append_null = False).rstrip()
    /* push 'aaa\xc3' */
    push -0x3c9e9e9f
>>> print shellcraft.amd64.pushstr('\xc3').rstrip()
    /* push '\xc3\x00' */
    push 0x1010101 ^ 0xc3
    xor dword ptr [rsp], 0x1010101
>>> print shellcraft.amd64.pushstr('\xc3', append_null = False).rstrip()
    /* push '\xc3' */
    push -0x3d
>>> with context.local():
...    context.arch = 'amd64'
...    print enhex(asm(shellcraft.pushstr("/bin/sh")))
48b801010101010101015048b82e63686f2e72690148310424
>>> with context.local():
...    context.arch = 'amd64'
...    print enhex(asm(shellcraft.pushstr("")))
6a01fe0c24
>>> with context.local():
...    context.arch = 'amd64'
...    print enhex(asm(shellcraft.pushstr("\x00", False)))
6a01fe0c24
参数:
  • string (str) – The string to push.
  • append_null (bool) – Whether to append a single NULL-byte before pushing.
pwnlib.shellcraft.amd64.pushstr_array(reg, array)[源代码]

Pushes an array/envp-style array of pointers onto the stack.

参数:
  • reg (str) – Destination register to hold the pointer.
  • array (str,list) – Single argument or list of arguments to push. NULL termination is normalized so that each argument ends with exactly one NULL byte.
pwnlib.shellcraft.amd64.ret(return_value=None)[源代码]

A single-byte RET instruction.

参数:return_value – Value to return
pwnlib.shellcraft.amd64.setregs(reg_context, stack_allowed=True)[源代码]

Sets multiple registers, taking any register dependencies into account (i.e., given eax=1,ebx=eax, set ebx first).

参数:
  • reg_context (dict) – Desired register context
  • stack_allowed (bool) – Can the stack be used?

Example

>>> print shellcraft.setregs({'rax':1, 'rbx':'rax'}).rstrip()
    mov rbx, rax
    push 1
    pop rax
>>> print shellcraft.setregs({'rax': 'SYS_write', 'rbx':'rax'}).rstrip()
    mov rbx, rax
    push SYS_write /* 1 */
    pop rax
>>> print shellcraft.setregs({'rax':'rbx', 'rbx':'rax', 'rcx':'rbx'}).rstrip()
    mov rcx, rbx
    xchg rax, rbx
>>> print shellcraft.setregs({'rax':1, 'rdx':0}).rstrip()
    push 1
    pop rax
    cdq /* rdx=0 */
pwnlib.shellcraft.amd64.strcpy(dst, src)[源代码]

Copies a string

Example

>>> sc  = 'jmp get_str\n'
>>> sc += 'pop_str: pop rax\n'
>>> sc += shellcraft.amd64.strcpy('rsp', 'rax')
>>> sc += shellcraft.amd64.linux.write(1, 'rsp', 32)
>>> sc += shellcraft.amd64.linux.exit(0)
>>> sc += 'get_str: call pop_str\n'
>>> sc += '.asciz "Hello, world\\n"'
>>> run_assembly(sc).recvline()
'Hello, world\n'
pwnlib.shellcraft.amd64.strlen(string, reg='rcx')[源代码]

Calculate the length of the specified string.

参数:
  • string (str) – Register or address with the string
  • reg (str) – Named register to return the value in, rcx is the default.

Example

>>> sc  = 'jmp get_str\n'
>>> sc += 'pop_str: pop rdi\n'
>>> sc += shellcraft.amd64.strlen('rdi', 'rax')
>>> sc += 'push rax;'
>>> sc += shellcraft.amd64.linux.write(1, 'rsp', 8)
>>> sc += shellcraft.amd64.linux.exit(0)
>>> sc += 'get_str: call pop_str\n'
>>> sc += '.asciz "Hello, world\\n"'
>>> run_assembly(sc).unpack() == len('Hello, world\n')
True
pwnlib.shellcraft.amd64.trap()[源代码]

A trap instruction.

pwnlib.shellcraft.amd64.xor(key, address, count)[源代码]

XORs data a constant value.

参数:
  • key (int,str) – XOR key either as a 8-byte integer, If a string, length must be a power of two, and not longer than 8 bytes. Alternately, may be a register.
  • address (int) – Address of the data (e.g. 0xdead0000, ‘esp’)
  • count (int) – Number of bytes to XOR, or a register containing the number of bytes to XOR.

Example

>>> sc  = shellcraft.read(0, 'rsp', 32)
>>> sc += shellcraft.xor(0xdeadbeef, 'rsp', 32)
>>> sc += shellcraft.write(1, 'rsp', 32)
>>> io = run_assembly(sc)
>>> io.send(cyclic(32))
>>> result = io.recvn(32)
>>> expected = xor(cyclic(32), p32(0xdeadbeef))
>>> result == expected
True

pwnlib.shellcraft.amd64.linux

Shellcraft module containing Intel x86_64 shellcodes for Linux.

pwnlib.shellcraft.amd64.linux.bindsh(port, network)[源代码]

Listens on a TCP port and spawns a shell for the first to connect. Port is the TCP port to listen on, network is either ‘ipv4’ or ‘ipv6’.

pwnlib.shellcraft.amd64.linux.cat(filename, fd=1)[源代码]

Opens a file and writes its contents to the specified file descriptor.

pwnlib.shellcraft.amd64.linux.connect(host, port, network='ipv4')[源代码]

Connects to the host on the specified port. Network is either ‘ipv4’ or ‘ipv6’. Leaves the connected socket in rbp.

pwnlib.shellcraft.amd64.linux.connectstager(host, port, network='ipv4')[源代码]

connect recvsize stager :param host, where to connect to: :param port, which port to connect to: :param network, ipv4 or ipv6? (default: ipv4)

pwnlib.shellcraft.amd64.linux.dup(sock='rbp')[源代码]

Args: [sock (imm/reg) = rbp] Duplicates sock to stdin, stdout and stderr

pwnlib.shellcraft.amd64.linux.dupsh(sock='rbp')[源代码]

Args: [sock (imm/reg) = rbp] Duplicates sock to stdin, stdout and stderr and spawns a shell.

pwnlib.shellcraft.amd64.linux.echo(string, sock='1')[源代码]

Writes a string to a file descriptor

pwnlib.shellcraft.amd64.linux.egghunter(egg, start_address = 0)[源代码]

Searches memory for the byte sequence ‘egg’.

Return value is the address immediately following the match, stored in RDI.

参数:
  • egg (str, int) – String of bytes, or word-size integer to search for
  • start_address (int) – Where to start the search
pwnlib.shellcraft.amd64.linux.findpeer(port=None)[源代码]

Args: port (defaults to any port) Finds a socket, which is connected to the specified port. Leaves socket in RDI.

pwnlib.shellcraft.amd64.linux.findpeersh(port=None)[源代码]

Args: port (defaults to any) Finds an open socket which connects to a specified port, and then opens a dup2 shell on it.

pwnlib.shellcraft.amd64.linux.findpeerstager(port=None)[源代码]

Findpeer recvsize stager :param port, the port given to findpeer: :type port, the port given to findpeer: defaults to any

pwnlib.shellcraft.amd64.linux.forkbomb()[源代码]

Performs a forkbomb attack.

pwnlib.shellcraft.amd64.linux.forkexit()[源代码]

Attempts to fork. If the fork is successful, the parent exits.

pwnlib.shellcraft.amd64.linux.getpid()[源代码]

Retrieve the current PID

pwnlib.shellcraft.amd64.linux.kill(pid, signal='SIGKILL')[源代码]

Writes a string to a file descriptor

pwnlib.shellcraft.amd64.linux.killparent()[源代码]

Kills its parent process until whatever the parent is (probably init) cannot be killed any longer.

pwnlib.shellcraft.amd64.linux.listen(port, network)[源代码]

Listens on a TCP port, accept a client and leave his socket in RAX. Port is the TCP port to listen on, network is either ‘ipv4’ or ‘ipv6’.

pwnlib.shellcraft.amd64.linux.loader(address)[源代码]

Loads a statically-linked ELF into memory and transfers control.

参数:address (int) – Address of the ELF as a register or integer.
pwnlib.shellcraft.amd64.linux.loader_append(data=None)[源代码]

Loads a statically-linked ELF into memory and transfers control.

Similar to loader.asm but loads an appended ELF.

参数:data (str) – If a valid filename, the data is loaded from the named file. Otherwise, this is treated as raw ELF data to append. If None, it is ignored.

Example

>>> gcc = process(['gcc','-m64','-xc','-static','-Wl,-Ttext-segment=0x20000000','-'])
>>> gcc.write('''
... int main() {
...     printf("Hello, %s!\\n", "amd64");
... }
... ''')
>>> gcc.shutdown('send')
>>> gcc.poll(True)
0
>>> sc = shellcraft.loader_append('a.out')

The following doctest is commented out because it doesn’t work on Travis for reasons I cannot diagnose. However, it should work just fine :-)

# >>> run_assembly(sc).recvline() == ‘Hello, amd64!n’ # True
pwnlib.shellcraft.amd64.linux.membot(readsock=0, writesock=1)[源代码]

Read-write access to a remote process’ memory.

Provide a single pointer-width value to determine the operation to perform:

  • 0: Exit the loop
  • 1: Read data
  • 2: Write data
pwnlib.shellcraft.amd64.linux.migrate_stack(size=1048576, fd=0)[源代码]

Migrates to a new stack.

pwnlib.shellcraft.amd64.linux.mmap_rwx(size=4096, protection=7, address=None)[源代码]

Maps some memory

pwnlib.shellcraft.amd64.linux.read(fd=0, buffer='rsp', count=8)[源代码]

Reads data from the file descriptor into the provided buffer. This is a one-shot and does not fill the request.

pwnlib.shellcraft.amd64.linux.read_upto(fd=0, buffer='rsp', sizereg='rdx')[源代码]

Reads up to N bytes 8 bytes into the specified register

pwnlib.shellcraft.amd64.linux.readfile(path, dst='rdi')[源代码]

Args: [path, dst (imm/reg) = rdi ] Opens the specified file path and sends its content to the specified file descriptor.

pwnlib.shellcraft.amd64.linux.readinto(sock=0)[源代码]

Reads into a buffer of a size and location determined at runtime. When the shellcode is executing, it should send a pointer and pointer-width size to determine the location and size of buffer.

pwnlib.shellcraft.amd64.linux.readloop(sock=0)[源代码]

Reads into a buffer of a size and location determined at runtime. When the shellcode is executing, it should send a pointer and pointer-width size to determine the location and size of buffer.

pwnlib.shellcraft.amd64.linux.readn(fd, buf, nbytes)[源代码]

Reads exactly nbytes bytes from file descriptor fd into the buffer buf.

参数:
  • fd (int) – fd
  • buf (void) – buf
  • nbytes (size_t) – nbytes
pwnlib.shellcraft.amd64.linux.readptr(fd=0, target_reg='rdx')[源代码]

Reads 8 bytes into the specified register

pwnlib.shellcraft.amd64.linux.recvsize(sock, reg='rcx')[源代码]

Recives 4 bytes size field Useful in conjuncion with findpeer and stager :param sock, the socket to read the payload from.: :param reg, the place to put the size: :type reg, the place to put the size: default ecx

Leaves socket in ebx

pwnlib.shellcraft.amd64.linux.setregid(gid='egid')[源代码]

Args: [gid (imm/reg) = egid] Sets the real and effective group id.

pwnlib.shellcraft.amd64.linux.setreuid(uid='euid')[源代码]

Args: [uid (imm/reg) = euid] Sets the real and effective user id.

pwnlib.shellcraft.amd64.linux.sh()[源代码]

Execute a different process.

>>> p = run_assembly(shellcraft.amd64.linux.sh())
>>> p.sendline('echo Hello')
>>> p.recv()
'Hello\n'
pwnlib.shellcraft.amd64.linux.socket(network='ipv4', proto='tcp')[源代码]

Creates a new socket

pwnlib.shellcraft.amd64.linux.stage(fd=0, length=None)[源代码]

Migrates shellcode to a new buffer.

参数:
  • fd (int) – Integer file descriptor to recv data from. Default is stdin (0).
  • length (int) – Optional buffer length. If None, the first pointer-width of data received is the length.

Example

>>> p = run_assembly(shellcraft.stage())
>>> sc = asm(shellcraft.echo("Hello\n", constants.STDOUT_FILENO))
>>> p.pack(len(sc))
>>> p.send(sc)
>>> p.recvline()
'Hello\n'
pwnlib.shellcraft.amd64.linux.stager(sock, size, handle_error=False)[源代码]

Recives a fixed sized payload into a mmaped buffer Useful in conjuncion with findpeer. After running the socket will be left in RDI. :param sock, the socket to read the payload from.: :param size, the size of the payload:

pwnlib.shellcraft.amd64.linux.strace_dos()[源代码]

Kills strace

pwnlib.shellcraft.amd64.linux.syscall(syscall=None, arg0=None, arg1=None, arg2=None, arg3=None, arg4=None, arg5=None)[源代码]
Args: [syscall_number, *args]
Does a syscall

Any of the arguments can be expressions to be evaluated by pwnlib.constants.eval().

Example

>>> print pwnlib.shellcraft.amd64.linux.syscall('SYS_execve', 1, 'rsp', 2, 0).rstrip()
    /* call execve(1, 'rsp', 2, 0) */
    xor r10d, r10d /* 0 */
    push SYS_execve /* 0x3b */
    pop rax
    push 1
    pop rdi
    push 2
    pop rdx
    mov rsi, rsp
    syscall
>>> print pwnlib.shellcraft.amd64.linux.syscall('SYS_execve', 2, 1, 0, -1).rstrip()
    /* call execve(2, 1, 0, -1) */
    push -1
    pop r10
    push SYS_execve /* 0x3b */
    pop rax
    push 2
    pop rdi
    push 1
    pop rsi
    cdq /* rdx=0 */
    syscall
>>> print pwnlib.shellcraft.amd64.linux.syscall().rstrip()
    /* call syscall() */
    syscall
>>> print pwnlib.shellcraft.amd64.linux.syscall('rax', 'rdi', 'rsi').rstrip()
    /* call syscall('rax', 'rdi', 'rsi') */
    /* setregs noop */
    syscall
>>> print pwnlib.shellcraft.amd64.linux.syscall('rbp', None, None, 1).rstrip()
    /* call syscall('rbp', ?, ?, 1) */
    mov rax, rbp
    push 1
    pop rdx
    syscall
>>> print pwnlib.shellcraft.amd64.linux.syscall(
...               'SYS_mmap', 0, 0x1000,
...               'PROT_READ | PROT_WRITE | PROT_EXEC',
...               'MAP_PRIVATE | MAP_ANONYMOUS',
...               -1, 0).rstrip()
    /* call mmap(0, 4096, 'PROT_READ | PROT_WRITE | PROT_EXEC', 'MAP_PRIVATE | MAP_ANONYMOUS', -1, 0) */
    push (MAP_PRIVATE | MAP_ANONYMOUS) /* 0x22 */
    pop r10
    push -1
    pop r8
    xor r9d, r9d /* 0 */
    push SYS_mmap /* 9 */
    pop rax
    xor edi, edi /* 0 */
    push (PROT_READ | PROT_WRITE | PROT_EXEC) /* 7 */
    pop rdx
    mov esi, 0x1010101 /* 4096 == 0x1000 */
    xor esi, 0x1011101
    syscall
>>> print pwnlib.shellcraft.open('/home/pwn/flag').rstrip()
    /* open(file='/home/pwn/flag', oflag=0, mode=0) */
    /* push '/home/pwn/flag\x00' */
    mov rax, 0x101010101010101
    push rax
    mov rax, 0x101010101010101 ^ 0x67616c662f6e
    xor [rsp], rax
    mov rax, 0x77702f656d6f682f
    push rax
    mov rdi, rsp
    xor edx, edx /* 0 */
    xor esi, esi /* 0 */
    /* call open() */
    push SYS_open /* 2 */
    pop rax
    syscall
pwnlib.shellcraft.amd64.linux.writeloop(readsock=0, writesock=1)[源代码]

Reads from a buffer of a size and location determined at runtime. When the shellcode is executing, it should send a pointer and pointer-width size to determine the location and size of buffer.