diff --git a/ArtyImplementation/debug.sh b/ArtyImplementation/debug.sh new file mode 100755 index 0000000000000000000000000000000000000000..91e8f1e5e15b28f15f2ad560c0c1cd6707e3a4f6 --- /dev/null +++ b/ArtyImplementation/debug.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +make && make load + +if [ -n $OPENOCD ]; then + $OPENOCD/bin/openocd -c "gdb_port 3333" -c "telnet_port 4444" -c "tcl_port 6666" -c "set protocol cjtag"\ + -c "set connection probe" -f bsp/X300/openocd.cfg -d3 > openocd-debug.log 2>&1 & +else + echo "OPENOCD not set" + exit +fi + +echo "$(ps -A | grep openocd)" +#wait for openocd +sleep 1 + +if [ -n $RISCV ]; then + $RISCV/bin/riscv64-unknown-elf-gdb zone1/zone1.elf -ex "target extended-remote localhost:3333" +else + echo "RISCV not set" + exit +fi diff --git a/ArtyImplementation/zone1/http_helpers.c b/ArtyImplementation/zone1/http_helpers.c new file mode 100644 index 0000000000000000000000000000000000000000..7d3675a8652f08aad2f34faa27ad0d04e018dedb --- /dev/null +++ b/ArtyImplementation/zone1/http_helpers.c @@ -0,0 +1,114 @@ +#include <stddef.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include "http_helpers.h" + +char *http_status_code_str(uint16_t status_code) { + switch(status_code) { + case 100: return "Continue"; + case 101: return "Switching Protocols"; + case 102: return "Processing"; + case 200: return "OK"; + case 201: return "Created"; + case 202: return "Accepted"; + case 203: return "Non-authoritative Information"; + case 204: return "No Content"; + case 205: return "Reset Content"; + case 206: return "Partial Content"; + case 207: return "Multi-Status"; + case 208: return "Already Reported"; + case 226: return "IM Used"; + case 300: return "Multiple Choices"; + case 301: return "Moved Permanently"; + case 302: return "Found"; + case 303: return "See Other"; + case 304: return "Not Modified"; + case 305: return "Use Proxy"; + case 307: return "Temporary Redirect"; + case 308: return "Permanent Redirect"; + case 400: return "Bad Request"; + case 401: return "Unauthorized"; + case 402: return "Payment Required"; + case 403: return "Forbidden"; + case 404: return "Not Found"; + case 405: return "Method Not Allowed"; + case 406: return "Not Acceptable"; + case 407: return "Proxy Authentication Required"; + case 408: return "Request Timeout"; + case 409: return "Conflict"; + case 410: return "Gone"; + case 411: return "Length Required"; + case 412: return "Precondition Failed"; + case 413: return "Payload Too Large"; + case 414: return "Request-URI Too Long"; + case 415: return "Unsupported Media Type"; + case 416: return "Requested Range Not Satisfiable"; + case 417: return "Expectation Failed"; + case 418: return "I'm a teapot"; + case 421: return "Misdirected Request"; + case 422: return "Unprocessable Entity"; + case 423: return "Locked"; + case 424: return "Failed Dependency"; + case 426: return "Upgrade Required"; + case 428: return "Precondition Required"; + case 429: return "Too Many Requests"; + case 431: return "Request Header Fields Too Large"; + case 444: return "Connection Closed Without Response"; + case 451: return "Unavailable For Legal Reasons"; + case 499: return "Client Closed Request"; + case 500: return "Internal Server Error"; + case 501: return "Not Implemented"; + case 502: return "Bad Gateway"; + case 503: return "Service Unavailable"; + case 504: return "Gateway Timeout"; + case 505: return "HTTP Version Not Supported"; + case 506: return "Variant Also Negotiates"; + case 507: return "Insufficient Storage"; + case 508: return "Loop Detected"; + case 510: return "Not Extended"; + case 511: return "Network Authentication Required"; + case 599: return "Network Connect Timeout Error"; + default: return NULL; + } +} + +char *http_prepare_response(char *content, uint32_t content_len, uint16_t status_code, uint32_t *out_len) { + char *status_code_str = http_status_code_str(status_code); + + if(status_code_str == NULL) { + content = "Internal server error."; + content_len = strlen(content); + status_code = 500; + status_code_str = http_status_code_str(status_code); + } + + uint32_t status_code_len = strlen(status_code_str); + // 70 bytes for the protocol version, response code, two headers and newlines should be enough. + uint32_t buf_len = content_len + status_code_len + 70; + char *buf = malloc(buf_len); + + int written_len = snprintf( + buf, + buf_len, + "HTTP/1.1 %u %s\r\n" + "Content-Length: %u\r\n" + "Connection: Close\r\n" + "\r\n", + status_code, + status_code_str, + content_len + ); + + if(written_len + content_len >= buf_len) { + printf("buffer for server reply is not big enough\r\n"); + free(buf); + return NULL; + } + + memcpy(buf + written_len, content, content_len); + + *out_len = written_len + content_len; + + return buf; +} diff --git a/ArtyImplementation/zone1/http_helpers.h b/ArtyImplementation/zone1/http_helpers.h new file mode 100644 index 0000000000000000000000000000000000000000..0d3205af113c8dcd56ca43857ea7c33c3faa4cbf --- /dev/null +++ b/ArtyImplementation/zone1/http_helpers.h @@ -0,0 +1,10 @@ +#ifndef HTTP_HELPERS_H_ +#define HTTP_HELPERS_H_ + +#include <stdint.h> + +// prepares an http response with the given content and status code +// the returned buffer should be freed by the caller +char *http_prepare_response(char *content, uint32_t content_len, uint16_t status_code, uint32_t *out_len); + +#endif /* HTTP_HELPERS_H_ */ diff --git a/ArtyImplementation/zone1/server_utility.h b/ArtyImplementation/zone1/server_utility.h new file mode 100644 index 0000000000000000000000000000000000000000..0bb35f166e149569c2116116df51b36416125192 --- /dev/null +++ b/ArtyImplementation/zone1/server_utility.h @@ -0,0 +1,97 @@ +/* + * server_utility.h + * + * Created on: Feb 19, 2021 + * Author: riscv + */ + +#ifndef SERVER_UTILITY_H_ +#define SERVER_UTILITY_H_ + +#include "http_helpers.h" +#include "webserver.h" + +#define INDEX_PAGE \ + "<!DOCTYPE html>\n"\ + "<html>\n"\ + " <body>\n"\ + " <form method=\"POST\">\n"\ + " <div>\n"\ + " <label for=\"name\">Bitte geben Sie Ihren Namen ein:</label> <input type=\"text\" name=\"name\">\n"\ + " </div>\n"\ + " <div>\n"\ + " <input type=\"submit\" value=\"Absenden\">\n"\ + " </div>\n"\ + " </form>\n"\ + " </body>\n"\ + "</html>" +#define RESPONSE_404 \ + "<!DOCTYPE html>\n"\ + "<html>\n"\ + " <body>\n"\ + " <h1>404 Nicht gefunden</h1>\n"\ + " <p>Wir haben leider diese Seite nicht gefunden.</p>\n"\ + " </body>\n"\ + "</html>" + + +char *target = "secret"; +char * get_target() { + return target; +} + +int is_target(char *test) { + return strncmp(test, target, strlen(target)) == 0; +} + +/* + * char message[128]; +printf("Framepointer: 0x%x\n", *(uint32_t *)&message[140]); +printf("Rücksprungadresse: 0x%x\n", *(uint32_t *)&message[140] - 204); + */ +char *attack_me(char *data, uint32_t data_len) { + // nobody could possibly enter a name longer than 20 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!"); + } + else { + memcpy(message + 7, data, data_len); + } + + char *result = malloc(strlen(message) + 1); + memcpy(result, message, strlen(message) + 1); + return result; +} + +char *server_request_handler(char *location, enum request_type type, char *data, uint32_t data_len, uint32_t *out_len, bool *free_result) { + *free_result = true; + if(type == GET_REQUEST && strncmp(location, "/", 2) == 0) { + return http_prepare_response(INDEX_PAGE, strlen(INDEX_PAGE), 200, out_len); + } else if(type == POST_REQUEST && strncmp(location, "/", 2) == 0) { + if(data_len >= 5 && strncmp(data, "name=", 5) == 0) { + uint32_t name_len = data_len - 5; + name_len = webserver_percent_decode(&data[5], name_len); + // nobody could possibly enter a name longer than 20 characters, so this buffer + // is definitely large enough + char *return_string; + return_string = attack_me(data, name_len); + + char* response = http_prepare_response(return_string, strlen(return_string), 200, out_len); + free(return_string); + return response; + } else { + return http_prepare_response(RESPONSE_404, strlen(RESPONSE_404), 404, out_len); + } + } else { + return http_prepare_response(RESPONSE_404, strlen(RESPONSE_404), 404, out_len); + } + return NULL; +} + +#endif /* ZONE1_SERVER_UTILITY_H_ */