bitreich-httpd.c - bitreich-httpd - Bitreich HTTPD service
 (HTM) git clone git://bitreich.org/bitreich-httpd git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/bitreich-httpd
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
 (DIR) README
 (DIR) LICENSE
       ---
       bitreich-httpd.c (9340B)
       ---
            1 /*
            2  * Copy me if you can.
            3  * by 20h
            4  */
            5 
            6 #include <unistd.h>
            7 #include <stdio.h>
            8 #include <stdlib.h>
            9 #include <time.h>
           10 #include <sys/types.h>
           11 #include <sys/stat.h>
           12 #include <fcntl.h>
           13 #include <string.h>
           14 #include <strings.h>
           15 #include <sys/socket.h>
           16 #include <sys/wait.h>
           17 #include <netdb.h>
           18 #include <time.h>
           19 
           20 void *
           21 xmalloc(size_t size)
           22 {
           23         void *p;
           24 
           25         if (!(p = malloc(size))) {
           26                 perror("malloc");
           27                 exit(1);
           28         }
           29 
           30         return p;
           31 }
           32 
           33 void
           34 print404(void)
           35 {
           36         printf("HTTP/1.1 404 Google Broke The Web\r\n");
           37         printf("\r\n");
           38 }
           39 
           40 void
           41 printheaders(char *ctype)
           42 {
           43         time_t t;
           44         char fortunecookie[512];
           45         FILE *fcstdout;
           46         int fclen = 0;
           47 
           48         bzero(fortunecookie, sizeof(fortunecookie));
           49         fcstdout = popen("/home/annna/bin/fortune-cookie", "r");
           50         if (fcstdout != NULL) {
           51                 fread(fortunecookie, sizeof(fortunecookie)-1, 1, fcstdout);
           52                 pclose(fcstdout);
           53                 fclen = strlen(fortunecookie);
           54                 if (fclen > 0) {
           55                         if (fortunecookie[fclen-1] == '\n')
           56                                 fortunecookie[fclen-1] = '\0';
           57                 }
           58         }
           59 
           60         t = time(NULL);
           61         if (t > 0)
           62                 printf("Date: %s", asctime(gmtime(&t)));
           63         printf("X-Future: Gopher ftw!\r\n");
           64         if (fclen > 0)
           65                 printf("X-Fortune-Cookie: %s\r\n", fortunecookie);
           66         printf("Content-Type: %s\r\n", ctype);
           67         printf("X-Irritate: Be irritated.\r\n");
           68         printf("X-Use-Gopher: gophers://bitreich.org\r\n");
           69         printf("If-By-Whiskey: Terrorist\r\n");
           70         printf("X-Powered-By: love\r\n");
           71         printf("Permission-Policy: interest-cohort=()\r\n");
           72         printf("Fuck-Off: Google\r\n");
           73         printf("Server: bitreich-httpd/2.0\r\n");
           74         printf("X-Alarm: <script>window.alert(\"Turn off Javascript, it hurts me.\");</script>\r\n");
           75         printf("X-Goat-0: (_(\r\n");
           76         printf("X-Goat-1: /_/'_____/)\r\n");
           77         printf("X-Goat-2: \"  |      |\r\n");
           78         printf("X-Goat-3:    |\"\"\"\"\"\"| \r\n");
           79         printf("Host: bitreich.org\r\n");
           80         printf("Connection: close\r\n");
           81         /* Have some fun with the websters. */
           82         printf("X-Fun-Begins: Yes!\r\n");
           83         printf("Content-Security: secure\r\n");
           84         printf("X-Cachwall-Reason: no reason\r\n");
           85         printf("X-Powered-By: binarysec\r\n");
           86         printf("X-Here-We-Match: squid\r\n");
           87         printf("aessecure-code: Kot\r\n");
           88         printf("X-CDN: jup\r\n");
           89         printf("X-Backside-Trans: ok\r\n");
           90         printf("X-dotDefender-denied: 1\r\n");
           91         printf("X-ASPNET-Version: got me\r\n");
           92         printf("X-Powered-By-360wzb: Of course!\r\n");
           93         printf("asp-id: here I am\r\n");
           94         printf("X-Not-Here: cloudfront\r\n");
           95         printf("WZWS-RAY: anyu yuuuuu\r\n");
           96         printf("Strict-Transport: Prussian\r\n");
           97         printf("X-Sucuri-Block: We are sucur!\r\n");
           98         printf("gladius_blockchain_driven_cyber_protection_network_session: oi!\r\n");
           99         printf("GW-Server: grey.wizard\r\n");
          100         printf("X-Cache: wt696969696969cdn\r\n");
          101         printf("X-Cache: YUNDUN\r\n");
          102         printf("X-Arrested: dosarrest\r\n");
          103         printf("X-Instart-Request-ID: dadadadada\r\n");
          104         printf("Complain-About: government\r\n");
          105         printf("Via: 1.1 varnish\r\n");
          106         printf("X-Cachwall-Action: ACTION! SET!\r\n");
          107         printf("X-st8id33133: yeah\r\n");
          108         printf("X-Sucuri-ID: Curry is tasty.\r\n");
          109         printf("X-Varnish: 37337\r\n");
          110         printf("X-Powered-By: waf1337\r\n");
          111         printf("X-Instart-CacheKeyMod: ahahahahaha\r\n");
          112 }
          113 
          114 int
          115 servefile(char *path, char *ctype, int sock)
          116 {
          117         struct stat st;
          118         char *sendb, *sendi;
          119         size_t bufsiz = BUFSIZ;
          120         int len, sent, fd;
          121 
          122         fd = open(path, O_RDONLY);
          123         if (fd < 0) {
          124                 print404();
          125                 return 1;
          126         }
          127 
          128         printf("HTTP/1.1 200 OK\r\n");
          129         printheaders(ctype);
          130 
          131         if (fstat(fd, &st) >= 0)
          132                 if ((bufsiz = st.st_blksize) < BUFSIZ)
          133                         bufsiz = BUFSIZ;
          134 
          135         printf("Content-Length: %ld\r\n", st.st_size);
          136         printf("\r\n");
          137         fflush(stdout);
          138 
          139         sendb = xmalloc(bufsiz);
          140         while ((len = read(fd, sendb, bufsiz)) > 0) {
          141                 sendi = sendb;
          142                 while (len > 0) {
          143                         if ((sent = write(sock, sendi, len)) < 0) {
          144                                 free(sendb);
          145                                 return 1;
          146                         }
          147                         len -= sent;
          148                         sendi += sent;
          149                 }
          150         }
          151         free(sendb);
          152 
          153         return 0;
          154 }
          155 
          156 char *
          157 read_line(int fd, int *len, int maxread)
          158 {
          159         char *buf;
          160         int r, rbytes;
          161 
          162         buf = xmalloc(maxread+1);
          163         memset(buf, 0, maxread+1);
          164 
          165         rbytes = 0;
          166         while (rbytes < maxread) {
          167                 r = read(fd, &buf[rbytes], 1);
          168                 if (r < 0) {
          169                         free(buf);
          170                         return NULL;
          171                 }
          172                 if (r == 0)
          173                         break;
          174                 if (buf[rbytes] == '\n') {
          175                         buf[rbytes] = '\0';
          176                         break;
          177                 }
          178                 rbytes += r;
          179         }
          180 
          181         *len = rbytes;
          182         return buf;
          183 }
          184 
          185 int
          186 main(int argc, char *argv[])
          187 {
          188         char *wwwbase, *wwwindex, *request, *ctype, *path, *le_file,
          189                 *le_base, clienth[NI_MAXHOST], clientp[NI_MAXSERV], *zuccbase,
          190                 *requested, *header, *headerval, *hosthdr;
          191         int rlen, i, user_agent_script_pid, isxfirefoxai, flags;
          192         struct sockaddr_storage clt;
          193         socklen_t cltlen = sizeof(clt);
          194         time_t tim;
          195 
          196         hosthdr = NULL;
          197         user_agent_script_pid = -1;
          198 
          199         wwwbase = "/bitreich/www";
          200         wwwindex = "index.html";
          201 
          202         le_base = "/br/www/uacme";
          203         zuccbase = "/br/www/zuccless";
          204 
          205         /*
          206          * Try to set keepalive in case we have some socket on stdin.
          207          */
          208         flags = 1;
          209         setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));
          210 
          211         if (!getpeername(0, (struct sockaddr *)&clt, &cltlen)) {
          212                 if (getnameinfo((struct sockaddr *)&clt, cltlen, clienth,
          213                                         sizeof(clienth), clientp, sizeof(clientp),
          214                                         NI_NUMERICHOST|NI_NUMERICSERV)) {
          215                         clienth[0] = clientp[0] = '\0';
          216                 }
          217                 if (!strncmp(clienth, "::ffff:", 7))
          218                         memmove(clienth, clienth+7, strlen(clienth)-6);
          219         } else {
          220                         clienth[0] = clientp[0] = '\0';
          221         }
          222 
          223         request = read_line(0, &rlen, 512);
          224         if (request == NULL)
          225                 return 1;
          226         if (request[rlen-1] == '\r')
          227                 request[rlen-1] = '\0';
          228 
          229         /* Header parsing. */
          230         /* At max read 16 headers. Do not allow DDoS. */
          231         isxfirefoxai = 0;
          232         for (i = 0; i < 16; i++) {
          233                 header = read_line(0, &rlen, 512);
          234                 if (header == NULL || rlen == 0)
          235                         break;
          236                 if (header[rlen-1] == '\r') {
          237                         header[rlen-1] = '\0';
          238                         if (rlen == 1) {
          239                                 free(header);
          240                                 break;
          241                         }
          242                 }
          243                 headerval = strchr(header, ':');
          244                 if (headerval == NULL) {
          245                         free(header);
          246                         continue;
          247                 }
          248                 *headerval = '\0';
          249                 headerval += 2;
          250                 if (headerval > (header + rlen)) {
          251                         free(header);
          252                         continue;
          253                 }
          254                 if (!strcasecmp(header, "user-agent")) {
          255                         user_agent_script_pid = fork();
          256                         switch (user_agent_script_pid) {
          257                         case -1:
          258                                 perror("fork");
          259                                 return 1;
          260                         case 0:
          261                                 return execl("add-user-agent.sh",
          262                                         "/home/annna/bin/modules/http-user-agent/add-user-agent.sh",
          263                                         headerval, 0);
          264                         }
          265                 }
          266                 if (!strcasecmp(header, "host")) {
          267                         rlen = strlen(headerval);
          268                         hosthdr = xmalloc(rlen+1);
          269                         memset(hosthdr, 0, rlen+1);
          270                         strncpy(hosthdr, headerval, rlen);
          271                 }
          272                 if (!strcasecmp(header, "x-firefox-ai")) {
          273                         isxfirefoxai = 1;
          274                         ctype = "video/webm";
          275                         asprintf(&path, "%s/s/aiaiaiai.webm", wwwbase);
          276                 }
          277                 free(header);
          278         }
          279 
          280         if (strncmp(request, "GET ", 4))
          281                 return 1;
          282 
          283         if (isxfirefoxai) {
          284         } else if (strstr(request, "s/bitreich.sh")) {
          285                 asprintf(&path, "%s/s/bitreich.sh", wwwbase);
          286                 ctype = "text/plain";
          287         } else if (strstr(request, "favicon.gif")) {
          288                 asprintf(&path, "%s/s/favicon.gif", wwwbase);
          289                 ctype = "image/gif";
          290         } else if (strstr(request, "deep-thinker.gif")) {
          291                 asprintf(&path, "%s/s/deep-thinker.gif", wwwbase);
          292                 ctype = "image/gif";
          293         } else if (strstr(request, "startup.mp3")) {
          294                 asprintf(&path, "%s/s/startup.mp3", wwwbase);
          295                 ctype = "audio/mpeg";
          296         } else if (strstr(request, "padme-hum.mp3")) {
          297                 asprintf(&path, "%s/s/padme-hum.mp3", wwwbase);
          298                 ctype = "audio/mpeg";
          299         } else if (strstr(request, "dickbutt")) {
          300                 asprintf(&path,
          301                         "/home/annna/bin/locate-cake-hater \"%s\" \"%s\"",
          302                         clienth, clientp);
          303                 system(path);
          304                 free(path);
          305                 asprintf(&path, "%s/s/dickbutt.jpg", wwwbase);
          306                 ctype = "image/jpeg";
          307         } else if (strstr(request, "bitreich.css")) {
          308                 asprintf(&path, "%s/s/bitreich.css", wwwbase);
          309                 ctype = "text/css";
          310         } else if (strstr(request, "neko.png")) {
          311                 asprintf(&path, "%s/s/neko.png", wwwbase);
          312                 ctype = "image/png";
          313         } else if (strstr(request, "snow.js")) {
          314                 asprintf(&path, "%s/s/snow.js", wwwbase);
          315                 ctype = "text/javascript";
          316         } else if (strstr(request, "fluid.js")) {
          317                 asprintf(&path, "%s/s/fluid.js", wwwbase);
          318                 ctype = "text/javascript";
          319         } else if (strstr(request, "ads-prebid-wp-ads-banner.js")) {
          320                 asprintf(&path, "%s/s/ads-prebid-wp-ads-banner.js", wwwbase);
          321                 ctype = "text/javascript";
          322         } else if (strstr(request, "yolo-css-")) {
          323                 /* We hate CSS in here. */
          324                 sleep(1);
          325                 asprintf(&path, "%s/s/yolo-css.css", wwwbase);
          326                 ctype = "text/css";
          327         } else if ((le_file = strstr(request, ".well-known/acme-challenge/"))) {
          328                 /* Setup for Letsencrypt */
          329                 le_file += strlen(".well-known/acme-challenge/");
          330                 requested = strtok(le_file, " ");
          331                 if (strchr(requested, '/') != NULL) {
          332                         /* Get Zucced, no path exploitation. */
          333                         asprintf(&path, "%s/zucc-job.webm", zuccbase);
          334                         ctype = "video/webm";
          335                 } else {
          336                         /* Seems legit. */
          337                         asprintf(&path, "%s/%s", le_base, requested);
          338                         ctype = "text/plain";
          339                 }
          340         } else {
          341                 if (hosthdr != NULL && strstr(hosthdr, "zuccless.org")) {
          342                         tim = time(NULL);
          343                         srandom(tim);
          344                         wwwbase = zuccbase;
          345                         switch (random() % 3) {
          346                         case 0:
          347                                 asprintf(&path, "%s/zucc-job.webm", zuccbase);
          348                                 break;
          349                         default:
          350                                 asprintf(&path, "%s/zucc-meat.webm", zuccbase);
          351                                 break;
          352                         }
          353                         ctype = "video/webm";
          354                 } else {
          355                         asprintf(&path, "%s/%s", wwwbase, wwwindex);
          356                         ctype = "text/html";
          357                 }
          358         }
          359         if (hosthdr != NULL)
          360                 free(hosthdr);
          361         free(request);
          362 
          363         rlen = servefile(path, ctype, 1);
          364         free(path);
          365 
          366         if (user_agent_script_pid != -1) {
          367                 if (waitpid(user_agent_script_pid, NULL, 0) < 0) {
          368                         perror("waitpid");
          369                         return 1;
          370                 }
          371         }
          372 
          373         return rlen;
          374 }
          375