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_ */