Last active
August 13, 2024 18:02
-
-
Save n30m1nd/ec19fc17c6293be303b85a998cd05aa9 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