pwnlib.shellcraft.aarch64
— Shellcode for AArch64¶
pwnlib.shellcraft.aarch64
¶
-
pwnlib.shellcraft.aarch64.
breakpoint
()[source]¶ Inserts a debugger breakpoint (raises SIGTRAP).
Example
>>> run_assembly(shellcraft.breakpoint()).poll(True) -5
-
pwnlib.shellcraft.aarch64.
crash
()[source]¶ Crashes the process.
Example
>>> run_assembly(shellcraft.crash()).poll(True) -11
-
pwnlib.shellcraft.aarch64.
infloop
()[source]¶ An infinite loop.
Example
>>> io = run_assembly(shellcraft.infloop()) >>> io.recvall(timeout=1) '' >>> io.close()
-
pwnlib.shellcraft.aarch64.
mov
(dst, src)[source]¶ Move src into dest.
Support for automatically avoiding newline and null bytes has to be done.
If src is a string that is not a register, then it will locally set context.arch to ‘arm’ 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.Examples
>>> print shellcraft.mov('x0','x1').rstrip() mov x0, x1 >>> print shellcraft.mov('x0','0').rstrip() mov x0, xzr >>> print shellcraft.mov('x0', 5).rstrip() mov x0, #5 >>> print shellcraft.mov('x0', 0x34532).rstrip() /* Set x0 = 214322 = 0x34532 */ mov x0, #17714 movk x0, #3, lsl #16
Parameters:
-
pwnlib.shellcraft.aarch64.
push
(value, register1='x14', register2='x15')[source]¶ Pushes a value onto the stack without using null bytes or newline characters.
If src is a string, then we try to evaluate 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.
Note
AArch64 requires that the stack remain 16-byte aligned at all times, so this alignment is preserved.
Parameters: Example
>>> print pwnlib.shellcraft.push(0).rstrip() /* push 0 */ mov x14, xzr str x14, [sp, #-16]! >>> print pwnlib.shellcraft.push(1).rstrip() /* push 1 */ mov x14, #1 str x14, [sp, #-16]! >>> print pwnlib.shellcraft.push(256).rstrip() /* push 0x100 */ mov x14, #256 str x14, [sp, #-16]! >>> print pwnlib.shellcraft.push('SYS_execve').rstrip() /* push SYS_execve (0xdd) */ mov x14, #221 str x14, [sp, #-16]! >>> print pwnlib.shellcraft.push('SYS_sendfile').rstrip() /* push SYS_sendfile (0x47) */ mov x14, #71 str x14, [sp, #-16]! >>> with context.local(os = 'freebsd'): ... print pwnlib.shellcraft.push('SYS_execve').rstrip() ... /* push SYS_execve (0x3b) */ mov x14, #59 str x14, [sp, #-16]!
-
pwnlib.shellcraft.aarch64.
pushstr
(string, append_null=True, register1='x14', register2='x15', pretty=None)[source]¶ Pushes a string onto the stack.
r12 is defined as the inter-procedural scratch register ($ip), so this should not interfere with most usage.
Parameters: Examples
>>> print shellcraft.pushstr("Hello!").rstrip() /* push 'Hello!\x00' */ /* Set x14 = 36762444129608 = 0x216f6c6c6548 */ mov x14, #25928 movk x14, #27756, lsl #16 movk x14, #8559, lsl #0x20 str x14, [sp, #-16]! >>> print shellcraft.pushstr("Hello, world!").rstrip() /* push 'Hello, world!\x00' */ /* Set x14 = 8583909746840200520 = 0x77202c6f6c6c6548 */ mov x14, #25928 movk x14, #27756, lsl #16 movk x14, #11375, lsl #0x20 movk x14, #30496, lsl #0x30 /* Set x15 = 143418749551 = 0x21646c726f */ mov x15, #29295 movk x15, #25708, lsl #16 movk x15, #33, lsl #0x20 stp x14, x15, [sp, #-16]! >>> print shellcraft.pushstr("Hello, world, bienvenue").rstrip() /* push 'Hello, world, bienvenue\x00' */ /* Set x14 = 8583909746840200520 = 0x77202c6f6c6c6548 */ mov x14, #25928 movk x14, #27756, lsl #16 movk x14, #11375, lsl #0x20 movk x14, #30496, lsl #0x30 /* Set x15 = 7593667296735556207 = 0x6962202c646c726f */ mov x15, #29295 movk x15, #25708, lsl #16 movk x15, #8236, lsl #0x20 movk x15, #26978, lsl #0x30 stp x14, x15, [sp, #-16]! /* Set x14 = 28558089656888933 = 0x65756e65766e65 */ mov x14, #28261 movk x14, #25974, lsl #16 movk x14, #30062, lsl #0x20 movk x14, #101, lsl #0x30 str x14, [sp, #-16]! >>> print shellcraft.pushstr("Hello, world, bienvenue!").rstrip() /* push 'Hello, world, bienvenue!\x00' */ /* Set x14 = 8583909746840200520 = 0x77202c6f6c6c6548 */ mov x14, #25928 movk x14, #27756, lsl #16 movk x14, #11375, lsl #0x20 movk x14, #30496, lsl #0x30 /* Set x15 = 7593667296735556207 = 0x6962202c646c726f */ mov x15, #29295 movk x15, #25708, lsl #16 movk x15, #8236, lsl #0x20 movk x15, #26978, lsl #0x30 stp x14, x15, [sp, #-16]! /* Set x14 = 2406458692908510821 = 0x2165756e65766e65 */ mov x14, #28261 movk x14, #25974, lsl #16 movk x14, #30062, lsl #0x20 movk x14, #8549, lsl #0x30 mov x15, xzr stp x14, x15, [sp, #-16]!
-
pwnlib.shellcraft.aarch64.
setregs
(reg_context, stack_allowed=True)[source]¶ Sets multiple registers, taking any register dependencies into account (i.e., given eax=1,ebx=eax, set ebx first).
Parameters: Example
>>> print shellcraft.setregs({'x0':1, 'x2':'x3'}).rstrip() mov x0, #1 mov x2, x3 >>> print shellcraft.setregs({'x0':'x1', 'x1':'x0', 'x2':'x3'}).rstrip() mov x2, x3 eor x0, x0, x1 /* xchg x0, x1 */ eor x1, x0, x1 eor x0, x0, x1
-
pwnlib.shellcraft.aarch64.
trap
()[source]¶ Inserts a debugger breakpoint (raises SIGTRAP).
Example
>>> run_assembly(shellcraft.breakpoint()).poll(True) -5
-
pwnlib.shellcraft.aarch64.
xor
(key, address, count)[source]¶ XORs data a constant value.
Parameters: Example
>>> sc = shellcraft.read(0, 'sp', 32) >>> sc += shellcraft.xor(0xdeadbeef, 'sp', 32) >>> sc += shellcraft.write(1, 'sp', 32) >>> io = run_assembly(sc) >>> io.send(cyclic(32)) >>> result = io.recvn(32) >>> expected = xor(cyclic(32), p32(0xdeadbeef)) >>> result == expected True
pwnlib.shellcraft.aarch64.linux
¶
-
pwnlib.shellcraft.aarch64.linux.
cat
(filename, fd=1)[source]¶ Opens a file and writes its contents to the specified file descriptor.
Example
>>> write('flag', 'This is the flag\n') >>> shellcode = shellcraft.cat('flag') + shellcraft.exit(0) >>> print disasm(asm(shellcode)) 0: d28d8cce mov x14, #0x6c66 // #27750 4: f2acec2e movk x14, #0x6761, lsl #16 8: f81f0fee str x14, [sp, #-16]! c: d29ff380 mov x0, #0xff9c // #65436 10: f2bfffe0 movk x0, #0xffff, lsl #16 14: f2dfffe0 movk x0, #0xffff, lsl #32 18: f2ffffe0 movk x0, #0xffff, lsl #48 1c: 910003e1 mov x1, sp 20: aa1f03e2 mov x2, xzr 24: aa1f03e3 mov x3, xzr 28: d2800708 mov x8, #0x38 // #56 2c: d4000001 svc #0x0 30: aa0003e1 mov x1, x0 34: d2800020 mov x0, #0x1 // #1 38: aa1f03e2 mov x2, xzr 3c: d29fffe3 mov x3, #0xffff // #65535 40: f2afffe3 movk x3, #0x7fff, lsl #16 44: d28008e8 mov x8, #0x47 // #71 48: d4000001 svc #0x0 4c: aa1f03e0 mov x0, xzr 50: d2800ba8 mov x8, #0x5d // #93 54: d4000001 svc #0x0 >>> run_assembly(shellcode).recvline() 'This is the flag\n'
-
pwnlib.shellcraft.aarch64.linux.
connect
(host, port, network='ipv4')[source]¶ Connects to the host on the specified port. Network is either ‘ipv4’ or ‘ipv6’. Leaves the connected socket in x12.
-
pwnlib.shellcraft.aarch64.linux.
echo
(string, sock='1')[source]¶ Writes a string to a file descriptor
Example
>>> run_assembly(shellcraft.echo('hello\n', 1)).recvline() 'hello\n'
-
pwnlib.shellcraft.aarch64.linux.
forkexit
()[source]¶ Attempts to fork. If the fork is successful, the parent exits.
-
pwnlib.shellcraft.aarch64.linux.
loader
(address)[source]¶ Loads a statically-linked ELF into memory and transfers control.
Parameters: address (int) – Address of the ELF as a register or integer.
-
pwnlib.shellcraft.aarch64.linux.
loader_append
(data=None)[source]¶ Loads a statically-linked ELF into memory and transfers control.
Similar to loader.asm but loads an appended ELF.
Parameters: 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:
The following doctest is commented out because it doesn’t work on Travis for reasons I cannot diagnose. However, it should work just fine :-)
# >>> gcc = process([‘aarch64-linux-gnu-gcc’,’-xc’,’-static’,’-Wl,-Ttext-segment=0x20000000’,’-‘]) # >>> gcc.write(‘’’ # … int main() { # … printf(“Hello, %s!\n”, “world”); # … } # … ‘’‘) # >>> gcc.shutdown(‘send’) # >>> gcc.poll(True) # 0 # >>> sc = shellcraft.loader_append(‘a.out’) # >>> run_assembly(sc).recvline() # ‘Hello, world!n’
-
pwnlib.shellcraft.aarch64.linux.
readn
(fd, buf, nbytes)[source]¶ Reads exactly nbytes bytes from file descriptor fd into the buffer buf.
Parameters: - fd (int) – fd
- buf (void) – buf
- nbytes (size_t) – nbytes
-
pwnlib.shellcraft.aarch64.linux.
sh
()[source]¶ Execute a different process.
>>> p = run_assembly(shellcraft.aarch64.linux.sh()) >>> p.sendline('echo Hello') >>> p.recv() 'Hello\n'
-
pwnlib.shellcraft.aarch64.linux.
stage
(fd=0, length=None)[source]¶ Migrates shellcode to a new buffer.
Parameters: 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.aarch64.linux.
syscall
(syscall=None, arg0=None, arg1=None, arg2=None, arg3=None, arg4=None, arg5=None, arg6=None)[source]¶ - Args: [syscall_number, *args]
- Does a syscall
Any of the arguments can be expressions to be evaluated by
pwnlib.constants.eval()
.Example
>>> print shellcraft.aarch64.linux.syscall(11, 1, 'sp', 2, 0).rstrip() /* call syscall(11, 1, 'sp', 2, 0) */ mov x0, #1 mov x1, sp mov x2, #2 mov x3, xzr mov x8, #11 svc 0 >>> print shellcraft.aarch64.linux.syscall('SYS_exit', 0).rstrip() /* call exit(0) */ mov x0, xzr mov x8, #SYS_exit svc 0 >>> print pwnlib.shellcraft.openat(-2, '/home/pwn/flag').rstrip() /* openat(fd=-2, file='/home/pwn/flag', oflag=0) */ /* push '/home/pwn/flag\x00' */ /* Set x14 = 8606431000579237935 = 0x77702f656d6f682f */ mov x14, #26671 movk x14, #28015, lsl #16 movk x14, #12133, lsl #0x20 movk x14, #30576, lsl #0x30 /* Set x15 = 113668128124782 = 0x67616c662f6e */ mov x15, #12142 movk x15, #27750, lsl #16 movk x15, #26465, lsl #0x20 stp x14, x15, [sp, #-16]! mov x1, sp /* Set x0 = -2 = -2 */ mov x0, #65534 movk x0, #65535, lsl #16 movk x0, #65535, lsl #0x20 movk x0, #65535, lsl #0x30 mov x2, xzr /* call openat() */ mov x8, #SYS_openat svc 0