pwnlib.shellcraft.mips — Shellcode for MIPS

pwnlib.shellcraft.mips

Shellcraft module containing generic MIPS shellcodes.

pwnlib.shellcraft.mips.mov(dst, src)[source]

Move src into dst without newlines and null bytes.

Registers $t8 and $t9 are not guaranteed to be preserved.

If src is a string that is not a register, then it will locally set context.arch to ‘mips’ 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.

Parameters
  • dst (str) – The destination register.

  • src (str) – Either the input register, or an immediate value.

Example

>>> print(shellcraft.mips.mov('$t0', 0).rstrip())
    slti $t0, $zero, 0xFFFF /* $t0 = 0 */
>>> print(shellcraft.mips.mov('$t2', 0).rstrip())
    xor $t2, $t2, $t2  /* $t2 = 0 */
>>> print(shellcraft.mips.mov('$t0', 0xcafebabe).rstrip())
    li $t0, 0xcafebabe
>>> print(shellcraft.mips.mov('$t2', 0xcafebabe).rstrip())
    li $t9, 0xcafebabe
    add $t2, $t9, $zero
>>> print(shellcraft.mips.mov('$s0', 0xca0000be).rstrip())
    li $t9, ~0xca0000be
    not $s0, $t9
>>> print(shellcraft.mips.mov('$s0', 0xca0000ff).rstrip())
    li $t9, 0x1010101 ^ 0xca0000ff
    li $s0, 0x1010101
    xor $s0, $t9, $s0
>>> print(shellcraft.mips.mov('$t9', 0xca0000be).rstrip())
    li $t9, ~0xca0000be
    not $t9, $t9
>>> print(shellcraft.mips.mov('$t2', 0xca0000be).rstrip())
    li $t9, ~0xca0000be
    not $t9, $t9
    add $t2, $t9, $0 /* mov $t2, $t9 */
>>> print(shellcraft.mips.mov('$t2', 0xca0000ff).rstrip())
    li $t8, 0x1010101 ^ 0xca0000ff
    li $t9, 0x1010101
    xor $t9, $t8, $t9
    add $t2, $t9, $0 /* mov $t2, $t9 */
>>> print(shellcraft.mips.mov('$a0', '$t2').rstrip())
    add $a0, $t2, $0 /* mov $a0, $t2 */
>>> print(shellcraft.mips.mov('$a0', '$t8').rstrip())
    sw $t8, -4($sp) /* mov $a0, $t8 */
    lw $a0, -4($sp)
pwnlib.shellcraft.mips.nop()[source]

MIPS nop instruction.

pwnlib.shellcraft.mips.push(value)[source]

Pushes a value onto the stack.

pwnlib.shellcraft.mips.pushstr(string, append_null=True)[source]

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

Example

>>> print(shellcraft.mips.pushstr('').rstrip())
    /* push b'\x00' */
    sw $zero, -4($sp)
    addiu $sp, $sp, -4
>>> print(shellcraft.mips.pushstr('a').rstrip())
    /* push b'a\x00' */
    li $t9, ~0x61
    not $t1, $t9
    sw $t1, -4($sp)
    addiu $sp, $sp, -4
>>> print(shellcraft.mips.pushstr('aa').rstrip())
    /* push b'aa\x00' */
    ori $t1, $zero, 24929
    sw $t1, -4($sp)
    addiu $sp, $sp, -4
>>> print(shellcraft.mips.pushstr('aaa').rstrip())
    /* push b'aaa\x00' */
    li $t9, ~0x616161
    not $t1, $t9
    sw $t1, -4($sp)
    addiu $sp, $sp, -4
>>> print(shellcraft.mips.pushstr('aaaa').rstrip())
    /* push b'aaaa\x00' */
    li $t1, 0x61616161
    sw $t1, -8($sp)
    sw $zero, -4($sp)
    addiu $sp, $sp, -8
>>> print(shellcraft.mips.pushstr('aaaaa').rstrip())
    /* push b'aaaaa\x00' */
    li $t1, 0x61616161
    sw $t1, -8($sp)
    li $t9, ~0x61
    not $t1, $t9
    sw $t1, -4($sp)
    addiu $sp, $sp, -8
>>> print(shellcraft.mips.pushstr('aaaa', append_null = False).rstrip())
    /* push b'aaaa' */
    li $t1, 0x61616161
    sw $t1, -4($sp)
    addiu $sp, $sp, -4
>>> print(shellcraft.mips.pushstr(b'\xc3').rstrip())
    /* push b'\xc3\x00' */
    li $t9, ~0xc3
    not $t1, $t9
    sw $t1, -4($sp)
    addiu $sp, $sp, -4
>>> print(shellcraft.mips.pushstr(b'\xc3', append_null = False).rstrip())
    /* push b'\xc3' */
    li $t9, ~0xc3
    not $t1, $t9
    sw $t1, -4($sp)
    addiu $sp, $sp, -4
>>> print(enhex(asm(shellcraft.mips.pushstr("/bin/sh"))))
696e093c2f622935f8ffa9af97ff193cd08c393727482003fcffa9aff8ffbd27
>>> print(enhex(asm(shellcraft.mips.pushstr(""))))
fcffa0affcffbd27
>>> print(enhex(asm(shellcraft.mips.pushstr("\x00", False))))
fcffa0affcffbd27
Parameters
  • string (str) – The string to push.

  • append_null (bool) – Whether to append a single NULL-byte before pushing.

pwnlib.shellcraft.mips.pushstr_array(reg, array)[source]

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

Parameters
  • 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.mips.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
  • reg_context (dict) – Desired register context

  • stack_allowed (bool) – Can the stack be used?

Example

>>> print(shellcraft.setregs({'$t0':1, '$a3':'0'}).rstrip())
    slti $a3, $zero, 0xFFFF /* $a3 = 0 */
    li $t9, ~1
    not $t0, $t9
>>> print(shellcraft.setregs({'$a0':'$a1', '$a1':'$a0', '$a2':'$a1'}).rstrip())
    sw $a1, -4($sp) /* mov $a2, $a1 */
    lw $a2, -4($sp)
    xor $a1, $a1, $a0 /* xchg $a1, $a0 */
    xor $a0, $a1, $a0
    xor $a1, $a1, $a0
pwnlib.shellcraft.mips.trap()[source]

A trap instruction.

pwnlib.shellcraft.mips.linux

Shellcraft module containing MIPS shellcodes for Linux.

pwnlib.shellcraft.mips.linux.bindsh(port, network)[source]

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.mips.linux.cat(filename, fd=1)[source]

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

Example

>>> f = tempfile.mktemp()
>>> write(f, 'FLAG')
>>> sc = shellcraft.mips.linux.cat(f)
>>> sc += shellcraft.mips.linux.exit(0)
>>> run_assembly(sc).recvall()
b'FLAG'
pwnlib.shellcraft.mips.linux.cat2(filename, fd=1, length=16384)[source]

Opens a file and writes its contents to the specified file descriptor. Uses an extra stack buffer and must know the length.

Example

>>> f = tempfile.mktemp()
>>> write(f, 'FLAG')
>>> sc = shellcraft.mips.linux.cat2(f)
>>> sc += shellcraft.mips.linux.exit(0)
>>> run_assembly(sc).recvall()
b'FLAG'
pwnlib.shellcraft.mips.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 $s0.

pwnlib.shellcraft.mips.linux.dupio(sock='$s0')[source]

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

pwnlib.shellcraft.mips.linux.dupsh(sock='$s0')[source]

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

pwnlib.shellcraft.mips.linux.echo(string, sock=1)[source]

Writes a string to a file descriptor

pwnlib.shellcraft.mips.linux.findpeer(port)[source]

Finds a connected socket. If port is specified it is checked against the peer port. Resulting socket is left in $s0.

pwnlib.shellcraft.mips.linux.findpeersh(port)[source]

Finds a connected socket. If port is specified it is checked against the peer port. A dup2 shell is spawned on it.

pwnlib.shellcraft.mips.linux.forkbomb()[source]

Performs a forkbomb attack.

pwnlib.shellcraft.mips.linux.forkexit()[source]

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

pwnlib.shellcraft.mips.linux.kill(pid, sig) str[source]

Invokes the syscall kill.

See ‘man 2 kill’ for more information.

Parameters
  • pid (pid_t) – pid

  • sig (int) – sig

Returns

int

pwnlib.shellcraft.mips.linux.killparent()[source]

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

pwnlib.shellcraft.mips.linux.listen(port, network)[source]

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

pwnlib.shellcraft.mips.linux.readfile(path, dst='$s0')[source]

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

pwnlib.shellcraft.mips.linux.setresuid(ruid=None, euid=None, suid=None)[source]

Args: [ruid = geteuid(), euid = ruid, suid = ruid] Sets real, effective and saved user ids to given values

pwnlib.shellcraft.mips.linux.sh()[source]

Execute /bin/sh

Example

>>> b'\0' in pwnlib.asm.asm(shellcraft.mips.linux.sh())
False
>>> p = run_assembly(shellcraft.mips.linux.sh())
>>> p.sendline(b'echo Hello')
>>> p.recv()
b'Hello\n'
pwnlib.shellcraft.mips.linux.sleep(seconds)[source]

Sleeps for the specified amount of seconds.

Uses SYS_nanosleep under the hood. Doesn’t check for interrupts and doesn’t retry with the remaining time.

Parameters

seconds (int,float) – The time to sleep in seconds.

pwnlib.shellcraft.mips.linux.stager(sock, size)[source]

Read ‘size’ bytes from ‘sock’ and place them in an executable buffer and jump to it. The socket will be left in $s0.

pwnlib.shellcraft.mips.linux.syscall(syscall=None, arg0=None, arg1=None, arg2=None, arg3=None, arg4=None, arg5=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(pwnlib.shellcraft.mips.linux.syscall('SYS_execve', 1, '$sp', 2, 0).rstrip())
    /* call execve(1, '$sp', 2, 0) */
    li $t9, ~1
    not $a0, $t9
    add $a1, $sp, $0 /* mov $a1, $sp */
    li $t9, ~2
    not $a2, $t9
    slti $a3, $zero, 0xFFFF /* $a3 = 0 */
    ori $v0, $zero, SYS_execve
    syscall 0x40404
>>> print(pwnlib.shellcraft.mips.linux.syscall('SYS_execve', 2, 1, 0, 20).rstrip())
    /* call execve(2, 1, 0, 0x14) */
    li $t9, ~2
    not $a0, $t9
    li $t9, ~1
    not $a1, $t9
    slti $a2, $zero, 0xFFFF /* $a2 = 0 */
    li $t9, ~0x14
    not $a3, $t9
    ori $v0, $zero, SYS_execve
    syscall 0x40404
>>> print(pwnlib.shellcraft.mips.linux.syscall().rstrip())
    /* call syscall() */
    syscall 0x40404
>>> print(pwnlib.shellcraft.mips.linux.syscall('$v0', '$a0', '$a1').rstrip())
    /* call syscall('$v0', '$a0', '$a1') */
    /* setregs noop */
    syscall 0x40404
>>> print(pwnlib.shellcraft.mips.linux.syscall('$a3', None, None, 1).rstrip())
    /* call syscall('$a3', ?, ?, 1) */
    li $t9, ~1
    not $a2, $t9
    sw $a3, -4($sp) /* mov $v0, $a3 */
    lw $v0, -4($sp)
    syscall 0x40404
>>> print(pwnlib.shellcraft.mips.linux.syscall(
...               'SYS_mmap2', 0, 0x1000,
...               'PROT_READ | PROT_WRITE | PROT_EXEC',
...               'MAP_PRIVATE | MAP_ANONYMOUS',
...               -1, 0).rstrip())
    /* call mmap2(0, 0x1000, 'PROT_READ | PROT_WRITE | PROT_EXEC', 'MAP_PRIVATE | MAP_ANONYMOUS', -1, 0) */
    li $t0, -1
    sw $t0, -4($sp)
    addi $sp, $sp, -4
    slti $t0, $zero, 0xFFFF /* $t0 = 0 */
    sw $t0, -4($sp)
    addi $sp, $sp, -4
    slti $a0, $zero, 0xFFFF /* $a0 = 0 */
    li $t9, ~0x1000
    not $a1, $t9
    li $t9, ~(PROT_READ | PROT_WRITE | PROT_EXEC) /* 7 */
    not $a2, $t9
    ori $a3, $zero, (MAP_PRIVATE | MAP_ANONYMOUS)
    ori $v0, $zero, SYS_mmap2
    syscall 0x40404
>>> print(pwnlib.shellcraft.open('/home/pwn/flag').rstrip())
    /* open(file='/home/pwn/flag', oflag=0, mode=0) */
    /* push b'/home/pwn/flag\x00' */
    li $t1, 0x6d6f682f
    sw $t1, -16($sp)
    li $t1, 0x77702f65
    sw $t1, -12($sp)
    li $t1, 0x6c662f6e
    sw $t1, -8($sp)
    ori $t1, $zero, 26465
    sw $t1, -4($sp)
    addiu $sp, $sp, -16
    add $a0, $sp, $0 /* mov $a0, $sp */
    slti $a1, $zero, 0xFFFF /* $a1 = 0 */
    slti $a2, $zero, 0xFFFF /* $a2 = 0 */
    /* call open() */
    ori $v0, $zero, SYS_open
    syscall 0x40404