From ae9808f3434e3c4ca939a714f67b1adc296d54e0 Mon Sep 17 00:00:00 2001 From: Florian Obser Date: Fri, 2 Dec 2022 17:11:25 +0100 Subject: [PATCH] Provide links to C file and diff for download. --- fuzzing-ping.org | 6 +- fuzzing-ping/ping_output_hack.diff | 129 +++++++++++++++++++++++++++++ fuzzing-ping/test.c | 34 ++++++++ fuzzing-ping/test.txt | 1 + 4 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 fuzzing-ping/ping_output_hack.diff create mode 100644 fuzzing-ping/test.c create mode 100644 fuzzing-ping/test.txt diff --git a/fuzzing-ping.org b/fuzzing-ping.org index 512f181..2ae7f7c 100644 --- a/fuzzing-ping.org +++ b/fuzzing-ping.org @@ -45,7 +45,7 @@ I installed =afl++= from packages and glanced at + Compile the program with =afl-clang-fast=. + Run =afl-fuzz=. -=test.c:= +[[file:fuzzing-ping/test.c][=test.c=]]: #+begin_src C /* Written by Florian Obser, Public Domain */ #include @@ -98,7 +98,7 @@ Here is a file where the length byte and file size agree. Create folders =in= and =out= and place =test.txt= into =in/test.txt=. Don't forget the newline. -=test.txt=: +[[file:fuzzing-ping/test.txt][=test.txt=]]: #+begin_example ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB #+end_example @@ -132,6 +132,8 @@ parsing is handled by =pr_pack()=, so that's what we should fuzz. We need some sample data. An ICMP package is binary data on-wire. Crafting it by hand is annoying. So let's just hack =ping(8)= to dump the packet to disk. + +[[file:fuzzing-ping/ping_output_hack.diff][=ping_output_hack.diff=]]: #+begin_src diff diff --git sbin/ping/ping.c sbin/ping/ping.c index a3b3d650eb5..78b571b95b4 100644 diff --git a/fuzzing-ping/ping_output_hack.diff b/fuzzing-ping/ping_output_hack.diff new file mode 100644 index 0000000..342f76b --- /dev/null +++ b/fuzzing-ping/ping_output_hack.diff @@ -0,0 +1,129 @@ +diff --git sbin/ping/ping.c sbin/ping/ping.c +index a3b3d650eb5..78b571b95b4 100644 +--- sbin/ping/ping.c ++++ sbin/ping/ping.c +@@ -79,6 +79,7 @@ + + #include + #include ++#include + #include + #include + +@@ -95,6 +96,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -217,6 +219,8 @@ const char *pr_addr(struct sockaddr *, socklen_t); + void pr_pack(u_char *, int, struct msghdr *); + __dead void usage(void); + ++void output(char *, u_char *, int); ++ + /* IPv4 specific functions */ + void pr_ipopt(int, u_char *); + int in_cksum(u_short *, int); +@@ -255,7 +259,7 @@ main(int argc, char *argv[]) + int df = 0, tos = 0, bufspace = IP_MAXPACKET, hoplimit = -1, mflag = 0; + u_char *datap, *packet; + u_char ttl = MAXTTL; +- char *e, *target, hbuf[NI_MAXHOST], *source = NULL; ++ char *e, *target, hbuf[NI_MAXHOST], *source = NULL, *output_path = NULL; + char rspace[3 + 4 * NROUTES + 1]; /* record route space */ + const char *errstr; + double fraction, integral, seconds; +@@ -264,11 +268,13 @@ main(int argc, char *argv[]) + u_int rtableid = 0; + extern char *__progname; + ++#if 0 + /* Cannot pledge due to special setsockopt()s below */ + if (unveil("/", "r") == -1) + err(1, "unveil /"); + if (unveil(NULL, NULL) == -1) + err(1, "unveil"); ++#endif + + if (strcmp("ping6", __progname) == 0) { + v6flag = 1; +@@ -297,8 +303,8 @@ main(int argc, char *argv[]) + preload = 0; + datap = &outpack[ECHOLEN + ECHOTMLEN]; + while ((ch = getopt(argc, argv, v6flag ? +- "c:DdEefgHh:I:i:Ll:mNnp:qS:s:T:V:vw:" : +- "DEI:LRS:c:defgHi:l:np:qs:T:t:V:vw:")) != -1) { ++ "c:DdEefgHh:I:i:Ll:mNno:p:qS:s:T:V:vw:" : ++ "DEI:LRS:c:defgHi:l:no:p:qs:T:t:V:vw:")) != -1) { + switch(ch) { + case 'c': + npackets = strtonum(optarg, 0, INT64_MAX, &errstr); +@@ -375,6 +381,9 @@ main(int argc, char *argv[]) + case 'n': + options &= ~F_HOSTNAME; + break; ++ case 'o': ++ output_path = optarg; ++ break; + case 'p': /* fill buffer with user pattern */ + options |= F_PINGFILLED; + fill((char *)datap, optarg); +@@ -768,10 +777,10 @@ main(int argc, char *argv[]) + } + + if (options & F_HOSTNAME) { +- if (pledge("stdio inet dns", NULL) == -1) ++ if (pledge("stdio inet dns wpath cpath", NULL) == -1) + err(1, "pledge"); + } else { +- if (pledge("stdio inet", NULL) == -1) ++ if (pledge("stdio inet wpath cpath", NULL) == -1) + err(1, "pledge"); + } + +@@ -960,8 +969,11 @@ main(int argc, char *argv[]) + } + } + continue; +- } else ++ } else { ++ if (output_path != NULL) ++ output(output_path, packet, cc); + pr_pack(packet, cc, &m); ++ } + + if (npackets && nreceived >= npackets) + break; +@@ -2274,3 +2286,29 @@ usage(void) + } + exit(1); + } ++ ++void ++output(char *path, u_char *pack, int len) ++{ ++ size_t bsz, off; ++ ssize_t nw; ++ int fd; ++ char *fname; ++ ++ bsz = len; ++ if (asprintf(&fname, "%s/ping_%lld_%d.out", path, time(NULL), ++ getpid()) == -1) ++ err(1, NULL); ++ ++ fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | ++ S_IROTH); ++ free(fname); ++ ++ if (fd == -1) ++ err(1, "open"); ++ ++ for (off = 0; off < bsz; off += nw) ++ if ((nw = write(fd, pack + off, bsz - off)) == 0 || nw == -1) ++ err(1, "write"); ++ close(fd); ++} diff --git a/fuzzing-ping/test.c b/fuzzing-ping/test.c new file mode 100644 index 0000000..c02b4cf --- /dev/null +++ b/fuzzing-ping/test.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + FILE *f; + size_t fsize; + uint8_t *buf, len, *dbuf; + + f = fopen(argv[1], "rb"); + fseek(f, 0, SEEK_END); + fsize = ftell(f); + rewind(f); + + buf = malloc(fsize + 1); + if (buf == NULL) + err(1, NULL); + fread(buf, fsize, 1, f); + fclose(f); + + buf[fsize] = 0; + + len = buf[0]; + + dbuf = malloc(len); + if (dbuf == NULL) + err(1, NULL); + memcpy(buf +1, dbuf, fsize -1); + warnx("len: %d", len); + return 0; +} diff --git a/fuzzing-ping/test.txt b/fuzzing-ping/test.txt new file mode 100644 index 0000000..c864665 --- /dev/null +++ b/fuzzing-ping/test.txt @@ -0,0 +1 @@ +ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB