summaryrefslogtreecommitdiff
path: root/socketfuzzer
diff options
context:
space:
mode:
Diffstat (limited to 'socketfuzzer')
-rw-r--r--socketfuzzer/Makefile2
-rw-r--r--socketfuzzer/README.md62
-rwxr-xr-xsocketfuzzer/honggfuzz_socketclient.py93
-rw-r--r--socketfuzzer/unittest.sh3
-rw-r--r--socketfuzzer/vulnserver_cov.c57
5 files changed, 158 insertions, 59 deletions
diff --git a/socketfuzzer/Makefile b/socketfuzzer/Makefile
index 8cb8c7d8..14096678 100644
--- a/socketfuzzer/Makefile
+++ b/socketfuzzer/Makefile
@@ -1,5 +1,5 @@
all: vulnserver_cov
-vulnserver_cov:
+vulnserver_cov: vulnserver_cov.c
unset HFUZZ_CC_ASAN
../hfuzz_cc/hfuzz-cc vulnserver_cov.c -o vulnserver_cov
diff --git a/socketfuzzer/README.md b/socketfuzzer/README.md
index eaa06c00..80062fe1 100644
--- a/socketfuzzer/README.md
+++ b/socketfuzzer/README.md
@@ -1,8 +1,10 @@
# Honggfuzz - SocketClient
-Implement an external fuzzer to fuzz network servers or similar.
+Use Honggfuzz as Code-Coverage tool, and implement an external fuzzer which
+interacts with the target (usually a network server). The actual fuzzer and
+honggfuzz communicate via a local socket.
-Tested on Ubuntu 17.04.
+Tested on Ubuntu 17.04, 18.04.
## Protocol
@@ -16,6 +18,8 @@ HonggFuzz <-> FFW
"New!" -->
"Cras" -->
<-- "bad!"
+...
+ <-- "halt"
```
* "Fuzz": HongFuzz tells FFW to send its network messages to the target server
@@ -23,6 +27,7 @@ HonggFuzz <-> FFW
* "New!": HonggFuzz tells FFW that new basic blocks have been reached
* "Cras": HonggFuzz tells FFW that the target has crashed
* "bad!": FFW tells Honggfuzz that the server is crashed
+* "halt": Fuzzing finished, shutdown HonggFuzz in an orderly manner.
## Overview
@@ -89,38 +94,73 @@ Send to target: 5
Automatic test, successful run:
```
$ ./unittest.sh
-Auto
-connecting to /tmp/honggfuzz_socket
+Auto Test
+connecting to /tmp/honggfuzz_socket.24916
Test: 0 - initial
+A SocketFuzzer client connected. Continuing.
ok: Fuzz
-Test: 1 - first new BB
+Test: 1 - expecting first new BB
+# vulnserver_cov: Listening on port: 5001
+# vulnserver_cov: New client connected
+# vulnserver_cov: Received data with len: 6 on state: 0
+# vulnserver_cov: Auth success
+# vulnserver_cov: Closing...
ok: New!
ok: Fuzz
-Test: 2 - second new BB
+Test: 2 - expecting second new BB
+# vulnserver_cov: New client connected
+# vulnserver_cov: Received data with len: 6 on state: 0
+# vulnserver_cov: Handledata1: BBBBBB
+# vulnserver_cov: Closing...
ok: New!
ok: Fuzz
-Test: 3 - repeat second msg, no new BB
+Test: 3 - repeat second msg, expecting no new BB
+# vulnserver_cov: New client connected
+# vulnserver_cov: Received data with len: 6 on state: 0
+# vulnserver_cov: Handledata1: BBBBBB
+# vulnserver_cov: Closing...
ok: Fuzz
-Test: 4 - crash stack
+Test: 4 - crash stack, expect new BB, then crash notification
+# vulnserver_cov: New client connected
+# vulnserver_cov: Received data with len: 128 on state: 0
+# vulnserver_cov: Handledata1: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB�
+ ok: New!
ok: Cras
ok: Fuzz
-Test: 5 - resend second, no new BB
+Test: 5 - resend second, expecting no new BB
+# vulnserver_cov: Listening on port: 5001
ok: Fuzz
-Test: 6 - send three, new BB
+Test: 6 - send three, expecting new BB
+# vulnserver_cov: New client connected
+# vulnserver_cov: Received data with len: 6 on state: 0
+# vulnserver_cov: Handledata2: CCCCCC
+# vulnserver_cov: Closing...
ok: New!
ok: Fuzz
Test: 7 - send four, new BB
+# vulnserver_cov: New client connected
+# vulnserver_cov: Received data with len: 6 on state: 0
+# vulnserver_cov: Handledata3: 6
+# vulnserver_cov: Closing...
ok: New!
ok: Fuzz
-Test: 8 - send four again, no new BB
+Test: 8 - fake unresponsive server
+ ok: Fuzz
+
+Test: 9 - send four again, no new BB
+# vulnserver_cov: New client connected
+# vulnserver_cov: Received data with len: 6 on state: 0
+# vulnserver_cov: Handledata3: 6
+# vulnserver_cov: Closing...
+# vulnserver_cov: Listening on port: 5001
ok: Fuzz
```
diff --git a/socketfuzzer/honggfuzz_socketclient.py b/socketfuzzer/honggfuzz_socketclient.py
index b129d6a6..29a90c76 100755
--- a/socketfuzzer/honggfuzz_socketclient.py
+++ b/socketfuzzer/honggfuzz_socketclient.py
@@ -107,12 +107,14 @@ class TargetSocket:
if n == 7:
# heap buffer overflow
data = "C" * 128
+ if n == 8:
+ # heap buffer overflow
+ data = "FFFFFF"
#print " Send: " + str(data)
return self.sendToSocket(data)
-
def sendResp(targetSocketRes, hfSocket):
if not targetSocketRes:
print " ! Server down. Send: bad!"
@@ -121,16 +123,12 @@ def sendResp(targetSocketRes, hfSocket):
hfSocket.send("okay")
-
def auto(pid):
- print "Auto"
-
+ print "Auto Test"
hfSocket = HonggfuzzSocket(pid)
targetSocket = TargetSocket()
-
hfSocket.connect()
-
print ""
print "Test: 0 - initial"
ret = hfSocket.recv()
@@ -140,9 +138,8 @@ def auto(pid):
print " nok: " + ret
return
-
print ""
- print "Test: 1 - first new BB"
+ print "Test: 1 - expecting first new BB"
ret = targetSocket.sendFuzz(1)
sendResp(ret, hfSocket)
ret = hfSocket.recv()
@@ -158,9 +155,8 @@ def auto(pid):
print " nok: " + ret
return
-
print ""
- print "Test: 2 - second new BB"
+ print "Test: 2 - expecting second new BB"
targetSocket.sendFuzz(2)
sendResp(ret, hfSocket)
ret = hfSocket.recv()
@@ -176,9 +172,8 @@ def auto(pid):
print " nok: " + ret
return
-
print ""
- print "Test: 3 - repeat second msg, no new BB"
+ print "Test: 3 - repeat second msg, expecting no new BB"
targetSocket.sendFuzz(2)
sendResp(ret, hfSocket)
ret = hfSocket.recv()
@@ -189,15 +184,25 @@ def auto(pid):
return
print ""
- print "Test: 4 - crash stack"
+ print "Test: 4 - crash stack, expect new BB, then crash notification"
targetSocket.sendFuzz(6)
sendResp(ret, hfSocket)
+ # first, a new BB is detected
+ ret = hfSocket.recv()
+ if ret == "New!":
+ print " ok: " + ret
+ else:
+ print " nok: " + ret
+ return
+ # this leads to a crash
ret = hfSocket.recv()
if ret == "Cras":
print " ok: " + ret
else:
print " nok: " + ret
return
+ # after the crash, the target should have been restarted, and
+ # we are ready to fuzz again
ret = hfSocket.recv()
if ret == "Fuzz":
print " ok: " + ret
@@ -206,7 +211,7 @@ def auto(pid):
return
print ""
- print "Test: 5 - resend second, no new BB"
+ print "Test: 5 - resend second, expecting no new BB"
targetSocket.sendFuzz(2)
sendResp(ret, hfSocket)
ret = hfSocket.recv()
@@ -217,22 +222,25 @@ def auto(pid):
return
print ""
- print "Test: 6 - send three, new BB"
+ print "Test: 6 - send three, expecting new BB"
targetSocket.sendFuzz(3)
sendResp(ret, hfSocket)
ret = hfSocket.recv()
if ret == "New!":
print " ok: " + ret
- else:
- print " nok: " + ret
- return
- ret = hfSocket.recv()
- if ret == "Fuzz":
- print " ok: " + ret
+ elif ret == "Fuzz":
+ print " okish: Should have been New!, but lets continue anyway"
else:
print " nok: " + ret
return
+ if ret == "New!":
+ ret = hfSocket.recv()
+ if ret == "Fuzz":
+ print " ok: " + ret
+ else:
+ print " nok: " + ret
+ return
print ""
print "Test: 7 - send four, new BB"
@@ -251,9 +259,20 @@ def auto(pid):
print " nok: " + ret
return
+ # lets simulate that the server has become unresponsive for some reason.
+ # as described in #253
+ print ""
+ print "Test: 8 - fake unresponsive server"
+ hfSocket.send("bad!")
+ ret = hfSocket.recv()
+ if ret == "Fuzz":
+ print " ok: " + ret
+ else:
+ print " nok: " + ret
+ return
print ""
- print "Test: 8 - send four again, no new BB"
+ print "Test: 9 - send four again, no new BB"
targetSocket.sendFuzz(4)
sendResp(ret, hfSocket)
ret = hfSocket.recv()
@@ -263,6 +282,35 @@ def auto(pid):
print " nok: " + ret
return
+ # shut honggfuzz down
+ hfSocket.send("halt")
+
+ # this does not really work yet in honggfuzz.
+ if (False):
+ # lets make the server unresponsive
+ print ""
+ print "Test: 10 - real unresponsive server"
+ targetSocket.sendFuzz(8)
+ sendResp(ret, hfSocket)
+ # we first have a new BB
+ ret = hfSocket.recv()
+ if ret == "New!":
+ print " ok: " + ret
+ else:
+ print " nok: " + ret
+ return
+
+ print ""
+ print "Test: 11 - send four again, no new BB"
+ targetSocket.sendFuzz(4)
+ sendResp(ret, hfSocket)
+ ret = hfSocket.recv()
+ if ret == "Fuzz":
+ print " ok: " + ret
+ else:
+ print " nok: " + ret
+ return
+
def interactive(pid):
hfSocket = HonggfuzzSocket(pid)
@@ -306,7 +354,6 @@ def interactive(pid):
print("Exception: " + str(e))
-
def main():
mode = None
pid = None
diff --git a/socketfuzzer/unittest.sh b/socketfuzzer/unittest.sh
index e1c3781e..e119c160 100644
--- a/socketfuzzer/unittest.sh
+++ b/socketfuzzer/unittest.sh
@@ -1,7 +1,6 @@
#!/bin/bash
-rm -rf HONGGFUZZ.REPORT.TXT SIGABR* HF.san*
+rm HONGGFUZZ.REPORT.TXT SIGABR* HF.san* SIGSEGV.*.fuzz
../honggfuzz --keep_output --debug --sanitizers --stdin_input --threads 1 --verbose --logfile log.txt --socket_fuzzer -- ./vulnserver_cov &
-
python ./honggfuzz_socketclient.py auto $!
diff --git a/socketfuzzer/vulnserver_cov.c b/socketfuzzer/vulnserver_cov.c
index d0926e33..a9d29cb1 100644
--- a/socketfuzzer/vulnserver_cov.c
+++ b/socketfuzzer/vulnserver_cov.c
@@ -10,7 +10,7 @@
/* Do nothing with first message */
void handleData0(char *data, int len) {
- printf("Auth success\n");
+ printf("# vulnserver_cov: Auth success\n");
}
/* Second message is stack based buffer overflow */
@@ -18,30 +18,37 @@ void handleData1(char *data, int len) {
char buff[8];
bzero(buff, 8);
memcpy(buff, data, len);
- printf("Handledata1: %s\n", buff);
+ printf("# vulnserver_cov: Handledata1: %s\n", buff);
}
/* Third message is heap overflow */
void handleData2(char *data, int len) {
char *buff = malloc(8);
+ if (!buff) {
+ abort();
+ }
bzero(buff, 8);
memcpy(buff, data, len);
- printf("Handledata2: %s\n", buff);
+ printf("# vulnserver_cov: Handledata2: %s\n", buff);
free(buff);
}
void handleData3(char *data, int len) {
- printf("Meh: %i\n", len);
+ printf("# vulnserver_cov: Handledata3: %i\n", len);
}
void handleData4(char *data, int len) {
- printf("Blah: %i\n", len);
+ printf("# vulnserver_cov: Handledata4: %i\n", len);
+}
+
+void handleData5(char *data, int len) {
+ printf("# vulnserver_cov: Handledata5: %i\n", len);
}
-void doprocessing(int sock) {
+void doprocessing(int sock, int serversock) {
char data[1024];
- int n = 0;
- int len = 0;
+ int n = 0;
+ int len = 0;
while (1) {
bzero(data, sizeof(data));
@@ -51,7 +58,7 @@ void doprocessing(int sock) {
return;
}
- printf("Received data with len: %i on state: %i\n", len, n);
+ printf("# vulnserver_cov: Received data with len: %i on state: %i\n", len, n);
switch (data[0]) {
case 'A':
handleData0(data, len);
@@ -73,6 +80,12 @@ void doprocessing(int sock) {
handleData4(data, len);
write(sock, "ok", 2);
break;
+ case 'F':
+ handleData5(data, len);
+ write(sock, "ok", 2);
+ // close the main server socket whoooops
+ close(serversock);
+ break;
default:
return;
}
@@ -82,10 +95,10 @@ void doprocessing(int sock) {
}
int main(int argc, char *argv[]) {
- int sockfd, newsockfd, portno, clilen;
- char buffer[256];
+ int sockfd, newsockfd, portno, clilen;
+ char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
- int n, pid;
+ int n, pid;
if (argc == 2) {
portno = atoi(argv[1]);
@@ -95,24 +108,24 @@ int main(int argc, char *argv[]) {
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
- perror("ERROR opening socket");
+ perror("# vulnserver_cov: ERROR opening socket");
exit(1);
}
int reuse = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (const char *)&reuse, sizeof(reuse)) < 0)
- perror("setsockopt(SO_REUSEPORT) failed");
+ perror("# vulnserver_cov: setsockopt(SO_REUSEPORT) failed");
bzero((char *)&serv_addr, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
+ serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
- serv_addr.sin_port = htons(portno);
+ serv_addr.sin_port = htons(portno);
- printf("Listening on port: %i\n", portno);
+ printf("# vulnserver_cov: Listening on port: %i\n", portno);
/* Now bind the host address using bind() call.*/
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
- perror("ERROR on binding");
+ perror("# vulnserver_cov: ERROR on binding");
exit(1);
}
@@ -122,12 +135,12 @@ int main(int argc, char *argv[]) {
while (1) {
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
if (newsockfd < 0) {
- perror("ERROR on accept");
+ perror("# vulnserver_cov: ERROR on accept");
exit(1);
}
- printf("New client connected\n");
- doprocessing(newsockfd);
- printf("Closing...\n");
+ printf("# vulnserver_cov: New client connected\n");
+ doprocessing(newsockfd, sockfd);
+ printf("# vulnserver_cov: Closing...\n");
shutdown(newsockfd, 2);
close(newsockfd);
}