www_funcs.c
上传用户:tjescc
上传日期:2021-02-23
资源大小:419k
文件大小:16k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /* Copyright (C) 1998 - 2003 Renaud Deraison
  2.  * Portions (C)  2002 - 2003 Michel Arboi
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License version 2,
  6.  * as published by the Free Software Foundation
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  *
  17.  */
  18. #define EXPORTING
  19. #include <includes.h>
  20. /*
  21.  * This function implements "whisker like" IDS evasion tactics plus a couple
  22.  * of other methods.
  23.  * Read http://www.wiretrip.net/rfp/pages/whitepapers/whiskerids.html
  24.  *
  25.  * Note: RFP is not responsible for the bugs here. I (Michel Arboi) wrote it!
  26.  *
  27.  * 2002-02-26: added Pavel kankovsky's "absolute URI"
  28.  * 2002-03-06: added "CGI.pm parameters" by Noam Rathaus from securiteam.com
  29.  * Partial support: we should changed & to ; in the "posted" data.
  30.  * 2002-05-29: added "protocol string". See Alla Bezroutchko's message on 
  31.  * VULN-DEV (Date: 15 Feb 2002; From: <alla@scanit.be>;
  32.  * Subject: Possible IDS-evasion technique
  33.  * Message-ID: <3C6D434B.4377034A@scanit.be>)
  34.  */
  35. /* TBD
  36.  * Pollute Apache logs with this:
  37. To make a request and to make it seem like it came from NO IP ADDRESS at
  38. all, the request should be made as this :
  39. GET / HTTP/1.0 rrn
  40. In this case APACHE will print in the log file the carriage return
  41. character. So when we try to tail the access_log file it will be shown in
  42. the screen as :
  43. " 414 3461.251 - - [24/Oct/2001:18:58:18 +0100] "GET / HTTP/1.0
  44. A normal line would be :
  45. 127.0.0.1 - - [24/Oct/2001:19:00:32 +0100] "GET / HTTP/1.0" 200 164
  46. The normal line output will help us to understand that what happens is cat
  47. made a carriage return after the HTTP/1.0 and printed the rest of the log
  48. over the Ip Address field.
  49. We can also make it look like the request came from another Ip address, and
  50. this is preferable because like this the SysAdmin will see no apparent
  51. strange behaviour in the logfile. Just be carefull with the timestamp !!
  52. So the request should be :
  53. GET / HTTP/1.0 r10.0.0.1 - - [24/Oct/2001:19:00:32 +0100] "GET /
  54. HTTP/1.0rn
  55. And the logfile will appear like this :
  56. 10.0.0.1 - - [24/Oct/2001:19:00:32 +0100] "GET / HTTP/1.0" 200 164
  57. This is a perfect log entry and nobody can suspect on it :-)
  58. */
  59. char *
  60. build_encode_URL(data, method, path, name, httpver)
  61.  struct arglist * data;
  62.  char *method, *path, *name, *httpver;
  63. {
  64.   int i, l = 0, n_slash = 0, n_backslash = 0, start_with_slash = 0;
  65.   char *ret, *ret2;
  66.   /* NIDS evasion options */
  67.   char *s, *s2;
  68.   int double_slash, reverse_traversal, self_ref_dir;
  69.   int prem_req_end, param_hiding, cgipm_param;
  70.   int dos_win_syntax, null_method, tab_sep, http09;
  71.   char *abs_URI_type, *abs_URI_host;
  72.   char sep_c;
  73. #define URL_CODE_NONE 0
  74. #define URL_CODE_HEX 1
  75. #define URL_CODE_UTF16 2
  76. #define URL_CODE_UTF16MS 3
  77. #define URL_CODE_UTF8BAD 4
  78.   int url_encoding;
  79.   char gizmo[32];
  80.   struct kb_item ** kb = plug_get_kb(data);
  81.   /* 
  82.    * basically, we need to store the path, a slash, and the name 
  83.    * Encoding will expand this
  84.    * We'll add the method in front of all this and the HTTP version 
  85.    * at the end when all is done. That's not optimized, but that's simpler
  86.    */
  87.   l = path !=  NULL ? strlen(path) : 0;
  88.   l += strlen(name) + (path != NULL);
  89.   ret = emalloc(l+ 1);
  90.   if (path == NULL)
  91.     strcpy(ret, name);
  92.   else
  93.     sprintf(ret, "%s/%s", path, name);
  94. #ifdef URL_DEBUG
  95.   fprintf(stderr, "Request => %sn", ret);
  96. #endif
  97.   for (s = ret; *s != ''; s ++)
  98.     if (*s == '/')
  99.       n_slash ++;
  100.     else if (*s == '\')
  101.       n_backslash ++;
  102.   start_with_slash = (*ret == '/');
  103.   s = kb_item_get_str(kb, "NIDS/HTTP/CGIpm_param");
  104.   cgipm_param = (s != NULL && strcmp(s, "yes") == 0);
  105.   if (cgipm_param)
  106.     {
  107. #ifdef URL_DEBUG
  108.       i = 0;
  109. #endif
  110.       for (s = ret; *s != '' && *s != '?'; s ++)
  111. ;
  112.       if (*s == '?')
  113. for (; *s != ''; s ++)
  114.   if (*s == '&')
  115.     {
  116.       *s = ';';
  117. #ifdef URL_DEBUG
  118.       i ++;
  119. #endif
  120.     }
  121. #ifdef URL_DEBUG
  122.       if (i > 0)
  123. fprintf(stderr, "Request =  %sn", ret);
  124. #endif
  125.     }
  126.   s = kb_item_get_str(kb, "NIDS/HTTP/self_ref_dir");
  127.   self_ref_dir = (s != NULL && strcmp(s, "yes") == 0);
  128.   if (self_ref_dir)
  129.     {
  130.       l += 2 * n_slash;
  131.       ret2 = emalloc(l + 1);
  132.       for (s = ret, s2 = ret2; *s != '' && *s != '?'; s ++)
  133. if (*s != '/')
  134.   *s2++ = *s;
  135. else
  136.   {
  137.     strcpy(s2, "/./");
  138.     s2 += 3;
  139.   }
  140.       while (*s != '')
  141. *s2++ = *s++;
  142.       *s2 = '';
  143.       efree(&ret);
  144.       ret = ret2;
  145.       n_slash *= 2;
  146. #ifdef URL_DEBUG
  147.       fprintf(stderr, "Request =  %sn", ret);
  148. #endif
  149.     }
  150.   s = kb_item_get_str(kb, "NIDS/HTTP/reverse_traversal");
  151.   reverse_traversal = (s == NULL ? 0 : atoi(s));
  152.   if (reverse_traversal > 0)
  153.     {
  154.       l += (reverse_traversal + 4)  * n_slash;
  155.       ret2 = emalloc(l + 1);
  156.       for (s = ret, s2 = ret2; *s != '' && *s != '?'; s ++)
  157. if (*s != '/')
  158.   *s2++ = *s;
  159. else
  160.   {
  161.     *s2++ = '/';
  162.     for (i = reverse_traversal; i > 0; i --) 
  163.       *s2++ = lrand48() % 26 + 'a';
  164.     strcpy(s2, "/../");
  165.     s2 += 4;
  166.   }
  167.       while (*s != '')
  168. *s2++ = *s++;
  169.       *s2 = '';
  170.       efree(&ret);
  171.       ret = ret2;
  172.       n_slash *= 3;
  173. #ifdef URL_DEBUG
  174.       fprintf(stderr, "Request =  %sn", ret);
  175. #endif
  176.     }
  177.   s = kb_item_get_str(kb, "NIDS/HTTP/premature_request_ending");
  178.   prem_req_end = (s != NULL && strcmp(s, "yes") == 0);
  179.   if (prem_req_end)
  180.     {
  181.       l += 36;
  182.       ret2 = emalloc(l + 1);
  183.       n_slash += 4;
  184.       
  185.       s = gizmo;
  186.       *s++ = lrand48() % 26 + 'A';
  187.       for (i = 1; i < 8; i ++)
  188. *s++ = lrand48() % 26 + 'a';
  189.       *s++ = '';
  190.       sprintf(ret2, "/%%20HTTP/1.0%%0d%%0a%s:%%20/../..%s", gizmo, ret);
  191.       efree(&ret);
  192.       ret = ret2;
  193. #ifdef URL_DEBUG
  194.       fprintf(stderr, "Request =  %sn", ret);
  195. #endif
  196.     }
  197.   
  198.   s = kb_item_get_str(kb, "NIDS/HTTP/param_hiding");
  199.   param_hiding = (s != NULL && strcmp(s, "yes") == 0);
  200.   if (param_hiding)
  201.     {
  202.       l += 25;
  203.       ret2 = emalloc(l + 1);
  204.       n_slash += 2;
  205.       
  206.       s = gizmo;
  207.       for (i = 0; i < 8; i ++)
  208. *s++ = lrand48() % 26 + 'a';
  209.       *s++ = '';
  210.       sprintf(ret2, "/index.htm%%3f%s=/..%s", gizmo, ret);
  211.       efree(&ret);
  212.       ret = ret2;
  213. #ifdef URL_DEBUG
  214.       fprintf(stderr, "Request =  %sn", ret);
  215. #endif
  216.     }
  217.   s = kb_item_get_str(kb, "NIDS/HTTP/double_slash");
  218.   double_slash = (s != NULL && strcmp(s, "yes") == 0);
  219.   if (double_slash)
  220.     {
  221.       l += n_slash;
  222.       
  223.       ret2 = emalloc(l + 1);
  224.       for (s = ret, s2 = ret2; *s != '' && *s != '?'; s ++)
  225. if (*s != '/')
  226.   *s2++ = *s;
  227. else
  228.   {
  229.     *s2++ = '/';
  230.     *s2++ = '/';
  231.   }
  232.       while (*s != '')
  233. *s2++ = *s++;
  234.       *s2 = '';
  235.       efree(&ret);
  236.       ret = ret2;
  237.       n_slash *= 2;
  238. #ifdef URL_DEBUG
  239.       fprintf(stderr, "Request =  %sn", ret);
  240. #endif
  241.     }
  242.   s = kb_item_get_str(kb, "NIDS/HTTP/dos_win_syntax");
  243.   dos_win_syntax = (s != NULL && strcmp(s, "yes") == 0);
  244.   if (dos_win_syntax)
  245.     {
  246.       for (s = ret + 1; *s != '' && *s != '?'; s ++)
  247. if (*s == '/')
  248.   {
  249.     *s = '\';
  250.     n_backslash ++;
  251.   }
  252. #ifdef URL_DEBUG
  253.       fprintf(stderr, "Request =  %sn", ret);
  254. #endif
  255.     }
  256.   s = kb_item_get_str(kb, "NIDS/HTTP/URL_encoding");
  257.   url_encoding = URL_CODE_NONE;
  258.   if (s != NULL)
  259.   {
  260.     if (strcmp(s, "Hex") == 0)
  261.       url_encoding = URL_CODE_HEX;
  262.     else if (strcmp(s, "UTF-16 (double byte)") == 0)
  263.       url_encoding = URL_CODE_UTF16;
  264.     else if (strcmp(s, "UTF-16 (MS %u)") == 0)
  265.       url_encoding = URL_CODE_UTF16MS;
  266.     else if (strcmp(s, "Incorrect UTF-8") == 0)
  267.       url_encoding = URL_CODE_UTF8BAD;
  268.   }
  269.   
  270.   
  271.   switch (url_encoding)
  272.     {
  273.     case URL_CODE_UTF16:
  274.     case URL_CODE_UTF16MS:
  275.     case URL_CODE_UTF8BAD:
  276.       /* Let's try first without encoding [back]slashes */
  277.       l = (l - n_slash - n_backslash) * 6 + n_slash + n_backslash;
  278.       break;
  279.     case URL_CODE_HEX:
  280.       /* We do not encode slashes, as this does not work against Apache, 
  281.        * at least apache-1.3.22-2 from redhat */
  282.       l = (l - n_slash) * 3 + n_slash;
  283.       break;
  284.     }
  285.   if (url_encoding != URL_CODE_NONE)
  286.     {  
  287.       ret2 = emalloc(l + 1);
  288.       for (s = ret, s2 = ret2; *s != ''; s ++)
  289. if (*s == '/' ||
  290.     ((url_encoding == URL_CODE_UTF8BAD ||
  291.       url_encoding == URL_CODE_UTF16 ||
  292.       url_encoding == URL_CODE_UTF16MS) && *s == '\'))
  293.   *s2++ = *s;
  294. else if (s[0] == '%' && isxdigit(s[1]) && isxdigit(s[2]))
  295.   {
  296.     /* Already % encoded. Do not change it! */
  297.     *s2++ = *s++;
  298.     *s2++ = *s++;
  299.     *s2++ = *s;
  300.   }
  301. else if (s[0] == '%' && tolower(s[1]) == 'u' &&
  302.  isxdigit(s[2]) && isxdigit(s[3]) &&
  303.  isxdigit(s[4]) && isxdigit(s[5]) )
  304.   {
  305.     /* Already %u encoded. Do not change it! */
  306.     *s2++ = *s++;
  307.     *s2++ = *s++;
  308.     *s2++ = *s++;
  309.     *s2++ = *s++;
  310.     *s2++ = *s;
  311.   }   
  312. else if (url_encoding == URL_CODE_UTF16MS)
  313.   {
  314.     sprintf(s2, "%%u00%02x", *(unsigned char*)s); 
  315.     /* The argument MUST be "unsigned char" */
  316.     s2 += 6;
  317.   }
  318. else if (url_encoding == URL_CODE_UTF16)
  319.   {
  320.     sprintf(s2, "%%00%%%02x", *(unsigned char*)s); 
  321.     /* The argument MUST be "unsigned char" */
  322.     s2 += 6;
  323.   }
  324. else if (url_encoding == URL_CODE_UTF8BAD)
  325.   {
  326.     unsigned char c = *(unsigned char*)s;
  327.     sprintf(s2, "%%%02x%%%02x",
  328.     0xC0 | (c >> 6), 0x80 | (c & 0x3F)); 
  329.     s2 += 6;
  330.     /* Note: we could also use the raw unencoded characters */
  331.   }
  332. else
  333.   {
  334.     sprintf(s2, "%%%02x", *(unsigned char*)s); 
  335.     /* The argument MUST be "unsigned char", so that it stays between
  336.      * 0 and 255. Otherwise, we might get something like %FFFFFF42 */
  337.     s2 += 3;
  338.     if (*s == '\')
  339.       n_backslash --;
  340.   }
  341.       *s2 = '';
  342.       efree(&ret);
  343.       ret = ret2;
  344. #ifdef URL_DEBUG
  345.       fprintf(stderr, "Request =  %sn", ret);
  346. #endif
  347.     }
  348.   abs_URI_type = kb_item_get_str(kb, "NIDS/HTTP/absolute_URI/type");
  349.   if (start_with_slash && 
  350.       abs_URI_type != NULL && strcmp(abs_URI_type, "none") != 0)
  351.     {
  352. #ifndef MAXHOSTNAMELEN
  353. # define MAXHOSTNAMELEN 64
  354. #endif
  355.       char h[MAXHOSTNAMELEN];
  356.       abs_URI_host = kb_item_get_str(kb, "NIDS/HTTP/absolute_URI/host");
  357.       h[0] = '';
  358.       if (abs_URI_host != NULL)
  359.       {
  360. if (strcmp(abs_URI_host, "host name") == 0)
  361.   {
  362.     if ((s = (char*)plug_get_hostname(data)) != NULL)
  363.       strncpy(h, s, sizeof(h));
  364.     h[sizeof(h)-1] = '';
  365.   }
  366. else if (strcmp(abs_URI_host, "host IP") == 0)
  367.   {
  368.     struct in_addr * ptr;
  369.     if ((ptr = plug_get_host_ip(data)) != NULL)
  370.     {
  371.       char * asc = inet_ntoa(*ptr);
  372.       strncpy(h, asc, sizeof(h));
  373.     }
  374.     h[sizeof(h)-1] = '';
  375.   }
  376. else if (strcmp(abs_URI_host, "random name") == 0)
  377.   {
  378.     for (s2 = h, i = 0; i < 16; i ++)
  379.       *s2++ = lrand48() % 26 + 'a';
  380.     *s2++ = '';
  381.   }
  382. else if (strcmp(abs_URI_host, "random IP") == 0)
  383.   sprintf(h, "%d.%d.%d.%d", rand() % 256, rand() % 256, rand() % 256, rand() % 256);
  384. #if 0
  385. else
  386.   fprintf(stderr, "Unhandled value %sn", abs_URI_host);
  387. #endif
  388.      }
  389.  
  390.       l += strlen(h) + strlen(abs_URI_type) + 3;
  391.       n_slash += 2;
  392.       ret2 = emalloc(l + 1);
  393.       sprintf(ret2, "%s://%s%s", abs_URI_type, h, ret);
  394.       efree(&ret);
  395.       ret = ret2;
  396. #ifdef URL_DEBUG
  397.       fprintf(stderr, "Request =  %sn", ret);
  398. #endif
  399.     }
  400.   s = kb_item_get_str(kb, "NIDS/HTTP/null_method");
  401.   null_method = (s != NULL && strcmp(s, "yes") == 0);
  402.   if (null_method)
  403.     {
  404.       l += 3;
  405.       ret2 = emalloc(l + 1);
  406.       strcpy(ret2, "%00");
  407.       strcpy(ret2+3, ret);
  408.       efree(&ret);
  409.       ret = ret2;
  410.     }
  411.   l += strlen(method) + 1;
  412.   s = kb_item_get_str(kb, "NIDS/HTTP/http09");
  413.   http09 = (s != NULL && strcmp(s, "yes") == 0);
  414.   if (! http09)
  415.     {
  416.       s = kb_item_get_str(kb, "NIDS/HTTP/protocol_string");
  417.       if (s != NULL && *s != '')
  418. {
  419.   httpver = s;
  420. #if 0
  421.   fprintf(stderr, "NIDS/HTTP/protocol_string = %sn", s);
  422. #endif
  423. }
  424.       l += strlen(httpver) + 1;
  425.     }
  426.   s = kb_item_get_str(kb, "NIDS/HTTP/tab_separator");
  427.   tab_sep = (s != NULL && strcmp(s, "yes") == 0);
  428.   sep_c = (tab_sep ? 't' : ' ');
  429.   ret2 = emalloc(l + 1);
  430.   if (http09)
  431.     sprintf(ret2, "%s%c%s", method, sep_c, ret);
  432.   else
  433.     sprintf(ret2, "%s%c%s%c%s", method, sep_c, ret, sep_c, httpver);
  434.   efree(&ret);
  435.   ret = ret2;
  436. #ifdef URL_DEBUG
  437.       fprintf(stderr, "Request <= %sn", ret);
  438. #endif
  439.   return ret;
  440. }
  441. static char *
  442. http11_get_head(port, data, path, name, method)
  443.  struct arglist * data;
  444.  int port;
  445.  char *  path;
  446.  char *  name;
  447.  char *  method;
  448. {
  449.  char * hostname = (char*)plug_get_hostname(data);
  450.  char * url = build_encode_URL(data, method, path, name, "HTTP/1.1"); 
  451.  char * ret;
  452.  char * auth_string, tmp[32];
  453.  struct kb_item ** kb = plug_get_kb(data);
  454.  snprintf(tmp, sizeof(tmp), "/tmp/http/auth/%d", port);
  455.  auth_string = kb_item_get_str(kb, tmp);
  456.  if (auth_string == NULL)
  457.    auth_string = kb_item_get_str(kb, "http/auth");
  458.  ret = emalloc(strlen(hostname) + strlen(url) + (auth_string ? strlen(auth_string):0) + 1024);
  459.  sprintf(ret, "%srn
  460. Connection: Closern
  461. Host: %srn
  462. Pragma: no-cachern
  463. User-Agent: Mozilla/4.75 [en] (X11, U; Nessus)rn
  464. Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*rn
  465. Accept-Language: enrn
  466. Accept-Charset: iso-8859-1,*,utf-8rn%s%srn",
  467. url,
  468. hostname,
  469. auth_string ? auth_string:"",
  470. auth_string ? "rn":"");
  471.  efree(&url);
  472.  return ret;
  473. }
  474. static char *
  475. http11_get(port, data, path, name)
  476.  struct arglist * data;
  477.  int port;
  478.  char *  path;
  479.  char *  name;
  480. {
  481.   return http11_get_head(port, data, path, name, "GET");
  482. }
  483. static char *
  484. http11_head(port, data, path, name)
  485.  struct arglist * data;
  486.  int port;
  487.  char *  path;
  488.  char *  name;
  489. {
  490.   return http11_get_head(port, data, path, name, "HEAD");
  491. }
  492. /* ******** */
  493. static char *
  494. http10_get_head(port, data, path, name, method)
  495.  struct arglist * data;
  496.  int port;
  497.  char *  path;
  498.  char *  name;
  499.  char *  method;
  500. {
  501.  char * url = build_encode_URL(data, method, path, name, "HTTP/1.0"); 
  502.  char * ret;
  503.  char * auth_string, tmp[32];
  504.  struct kb_item ** kb = plug_get_kb(data);
  505.  snprintf(tmp, sizeof(tmp), "/tmp/http/auth/%d", port);
  506.  auth_string = kb_item_get_str(kb, tmp);
  507.  if (auth_string == NULL)
  508.    auth_string = kb_item_get_str(kb, "http/auth");
  509.  
  510.  ret = emalloc(strlen(url) + 1024 + (auth_string ? strlen(auth_string) : 0));
  511.  
  512.  sprintf(ret, "%srn%srn%s",
  513. url,
  514. auth_string?auth_string:"",
  515. auth_string?"rn":"");
  516.  efree(&url);
  517.  return ret;
  518. }
  519. static char *
  520. http10_get(port, data, path, name)
  521.  struct arglist * data;
  522.  int port;
  523.  char *  path;
  524.  char *  name;
  525. {
  526.   return http10_get_head(port, data, path, name, "GET");
  527. }
  528. static char *
  529. http10_head(port, data, path, name)
  530.  struct arglist * data;
  531.  int port;
  532.  char *  path;
  533.  char *  name;
  534. {
  535.   return http10_get_head(port, data, path, name, "HEAD");
  536. }
  537. /* ******** */
  538. static char *
  539. http_get(port, data, ver, path, name)
  540.  int port;
  541.  struct arglist * data;
  542.  int ver;
  543.  char *  path;
  544.  char *  name;
  545. {
  546.  if(ver == 10)
  547.   return http10_get(port, data, path, name);
  548.  else
  549.   return http11_get(port, data, path, name);
  550. }
  551. static char *
  552. http_head(port, data, ver, path, name)
  553.  struct arglist * data;
  554.  int port;
  555.  int ver;
  556.  char *  path;
  557.  char *  name;
  558. {
  559.  if(ver == 11)
  560.   return http11_head(port, data, path, name);
  561.  else
  562.   return http10_head(port, data, path, name);
  563. }
  564. static int 
  565. httpver(data, port)
  566.  struct arglist * data;
  567.  int port;
  568. {
  569.  char req[255];
  570.  int value;
  571.  bzero(req, sizeof(req));
  572.  snprintf(req, sizeof(req), "http/%d", port);
  573.  value = kb_item_get_int(plug_get_kb(data), req);
  574.  if ( value <= 0 )
  575.     return 11;
  576.  else
  577.     return value;
  578. }