Skip to content

Instantly share code, notes, and snippets.

@n30m1nd
Last active October 10, 2021 15:12
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save n30m1nd/ec19fc17c6293be303b85a998cd05aa9 to your computer and use it in GitHub Desktop.
Save n30m1nd/ec19fc17c6293be303b85a998cd05aa9 to your computer and use it in GitHub Desktop.
Patch for Apache httpd to make it fuzzable through afl-clang-fast
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