Forked from n30m1nd/apatching_for_AFL_Persistent_fuzzing.diff
Created
January 4, 2020 08:03
-
-
Save richinseattle/1cb6cab27d9ce465cd428afd41f8be0d to your computer and use it in GitHub Desktop.
Patch for Apache httpd to make it fuzzable through afl-clang-fast
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: server/main.c | |
=================================================================== | |
--- server/main.c (revision 1794475) | |
+++ server/main.c (working copy) | |
@@ -434,11 +434,157 @@ | |
ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, | |
" -X : debug mode (only one worker, do not detach)"); | |
- destroy_and_exit_process(process, 1); | |
+ destroy_and_exit_process(process, 0); | |
} | |
-int main(int argc, const char * const argv[]) | |
+#include <sched.h> | |
+#include <linux/sched.h> | |
+#include <arpa/inet.h> | |
+#include <errno.h> | |
+#include <net/if.h> | |
+#include <net/route.h> | |
+#include <netinet/ip6.h> | |
+#include <netinet/tcp.h> | |
+#include <sched.h> | |
+#include <stdio.h> | |
+#include <stdint.h> | |
+#include <stdlib.h> | |
+#include <string.h> | |
+#include <strings.h> | |
+#include <sys/ioctl.h> | |
+#include <sys/resource.h> | |
+#include <sys/socket.h> | |
+#include <sys/time.h> | |
+#include <sys/types.h> | |
+#include <sys/wait.h> | |
+#include <unistd.h> | |
+ | |
+static void netIfaceUp(const char *ifacename) | |
{ | |
+ int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); | |
+ if (sock == -1) { | |
+ perror("socket(AF_INET, SOCK_STREAM, IPPROTO_IP)"); | |
+ _exit(1); | |
+ } | |
+ | |
+ struct ifreq ifr; | |
+ memset(&ifr, '\0', sizeof(ifr)); | |
+ snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", ifacename); | |
+ | |
+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { | |
+ perror("ioctl(iface='lo', SIOCGIFFLAGS, IFF_UP)"); | |
+ _exit(1); | |
+ } | |
+ | |
+ ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); | |
+ | |
+ if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { | |
+ perror("ioctl(iface='lo', SIOCSIFFLAGS, IFF_UP)"); | |
+ _exit(1); | |
+ } | |
+ | |
+ close(sock); | |
+} | |
+ | |
+void unsh(void) | |
+{ | |
+ unshare(CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWNS); | |
+ | |
+ if (mount("tmpfs", "/tmp", "tmpfs", 0, "") == -1) { | |
+ perror("tmpfs"); | |
+ _exit(1); | |
+ } | |
+ netIfaceUp("lo"); | |
+} | |
+ | |
+static void GETDATA(process_rec *process) | |
+{ | |
+ int BUFSIZE=1024*1024; | |
+ usleep(10000); | |
+ char buf[BUFSIZE+1]; | |
+ while ( __AFL_LOOP(10000)){ | |
+ printf("[+] Looping\n"); | |
+ memset(buf, 0, BUFSIZE); | |
+ size_t read_bytes = read(0, buf, BUFSIZE); | |
+ buf[BUFSIZE-2] = '\r'; | |
+ buf[BUFSIZE-1] = '\n'; | |
+ buf[BUFSIZE] = '\0'; | |
+ | |
+ int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); | |
+ if (sockfd == -1) { | |
+ perror("socket"); | |
+ _exit(1); | |
+ } | |
+ | |
+ int sz = (1024 * 1024); | |
+ if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof(sz)) == -1) { | |
+ perror("setsockopt"); | |
+ exit(1); | |
+ } | |
+ | |
+ printf("[+] Connecting\n", buf); | |
+ | |
+ struct sockaddr_in saddr; | |
+ saddr.sin_family = AF_INET; | |
+ saddr.sin_port = htons(80); | |
+ saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | |
+ if (connect(sockfd, &saddr, sizeof(saddr)) == -1) { | |
+ printf("[-] Connect failed\n"); | |
+ perror("connect"); | |
+ continue; | |
+ } | |
+ | |
+ printf("[+] Sending buf %s\n", buf); | |
+ | |
+ if (send(sockfd, buf, read_bytes, MSG_NOSIGNAL) != read_bytes) { | |
+ perror("send() failed 1"); | |
+ exit(1); | |
+ } | |
+ | |
+ printf("[+] Buf sent %s\n", &buf); | |
+ | |
+ if (shutdown(sockfd, SHUT_WR) == -1) { | |
+ perror("shutdown"); | |
+ exit(1); | |
+ } | |
+ | |
+ char b[1024 * 1024]; | |
+ while (recv(sockfd, b, sizeof(b), MSG_WAITALL) > 0) ; | |
+ | |
+ printf("[+] Received %s\n", b); | |
+ | |
+ close(sockfd); | |
+ printf("[+] Nice run\n"); | |
+ } | |
+ printf("[+] Whew lad!\n"); | |
+ usleep(100000); | |
+ _exit(0); | |
+ exit(0); | |
+} | |
+ | |
+static void LAUNCHTHR(process_rec *process) | |
+{ | |
+ pthread_t t; | |
+ pthread_attr_t attr; | |
+ | |
+ pthread_attr_init(&attr); | |
+ pthread_attr_setstacksize(&attr, 1024 * 1024 * 8); | |
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
+ | |
+ pthread_create(&t, &attr, GETDATA, process); | |
+} | |
+ | |
+int main(int argc, const char *const argv[]) | |
+{ | |
+ | |
+ process_rec *process; // Needed to finish apache | |
+ if (getenv("NO_FUZZ") == NULL) { | |
+ unsh(); | |
+ LAUNCHTHR(process); | |
+ printf("[+] Launched loop\n"); | |
+ } | |
+ printf("[+] I did follow\n"); | |
+ | |
char c; | |
int showcompile = 0, showdirectives = 0; | |
const char *confname = SERVER_CONFIG_FILE; | |
@@ -445,7 +591,6 @@ | |
const char *def_server_root = HTTPD_ROOT; | |
const char *temp_error_log = NULL; | |
const char *error; | |
- process_rec *process; | |
apr_pool_t *pconf; | |
apr_pool_t *plog; /* Pool of log streams, reset _after_ each read of conf */ | |
apr_pool_t *ptemp; /* Pool for temporary config stuff, reset often */ | |
@@ -688,7 +833,8 @@ | |
/* If our config failed, deal with that here. */ | |
if (rv != OK) { | |
- destroy_and_exit_process(process, 1); | |
+ printf("[-] Config failed...\n"); | |
+ destroy_and_exit_process(process, 0); | |
} | |
signal_server = APR_RETRIEVE_OPTIONAL_FN(ap_signal_server); | |
@@ -696,6 +842,7 @@ | |
int exit_status; | |
if (signal_server(&exit_status, pconf) != 0) { | |
+ printf("[-] Server signaled out\n"); | |
destroy_and_exit_process(process, exit_status); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment