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

Telnet服务器

开发平台:

Unix_Linux

  1. /* Nessuslib -- the Nessus Library
  2.  * Copyright (C) 1998 - 2002 Renaud Deraison
  3.  *
  4.  * $Id: ids_send.c,v 1.27.2.1 2005/07/06 20:48:11 renaud Exp $
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Library General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Library General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Library General Public
  17.  * License along with this library; if not, write to the Free
  18.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  *
  21.  *
  22.  *
  23.  *
  24.  *
  25.  * IDS stressing functions. 
  26.  *
  27.  * ids_send() sends data spliced into several packets, with bad packets
  28.  * between them, thus making bad NIDSes reassemble the tcp stream awkwardly;
  29.  * 
  30.  * 
  31.  * ids_open_sock_tcp() opens a tcp socket and immediately sends a badly
  32.  * formed RST packet to the remote host, thus making bad NIDSes think
  33.  * the connection was immediately dropped on our end.
  34.  * 
  35.  *
  36.  */ 
  37.  
  38.  
  39. #define EXPORTING
  40. #include <includes.h>
  41. #include <stdarg.h>
  42. #include "network.h"
  43. #include "resolve.h"
  44. #include "ids_send.h"
  45. /*
  46.  * We define our own packet structs (they'll be defined in libnasl later
  47.  * on, and I feel lazy today)
  48.  */
  49. struct ip_packet {
  50. #if !WORDS_BIGENDIAN
  51. u_char ip_hl:4, /* header length */
  52. ip_v:4; /* version */
  53. #else
  54.  u_char ip_v:4, /* version */
  55. ip_hl:4; /* header length */
  56. #endif
  57. u_char ip_tos; /* type of service */
  58. u_short ip_len; /* total length */
  59. u_short ip_id; /* identification */
  60. u_short ip_off; /* fragment offset field */
  61. u_char ip_ttl; /* time to live */
  62. u_char ip_p; /* protocol */
  63. u_short ip_sum; /* checksum */
  64. struct in_addr ip_src,ip_dst; /* source and dest address */
  65. };
  66. struct tcp_packet {
  67. u_short th_sport; /* source port */
  68. u_short th_dport; /* destination port */
  69. u_long th_seq; /* sequence number */
  70. u_long th_ack; /* acknowledgement number */
  71. #if !WORDS_BIGENDIAN
  72. u_int th_x2:4, /* (unused) */
  73. th_off:4; /* data offset */
  74. #endif
  75. #if WORDS_BIGENDIAN
  76. u_int th_off:4, /* data offset */
  77. th_x2:4; /* (unused) */
  78. #endif
  79. u_char th_flags;
  80. u_short th_win; /* window */
  81. u_short th_sum; /* checksum */
  82. u_short th_urp; /* urgent pointer */
  83. };
  84. /*
  85.  * our own definition of the tcp flags
  86.  */
  87. #define TCP_FLAG_RST  0x0004
  88. #define TCP_FLAG_ACK  0x0010
  89. #define TCP_FLAG_PUSH 0x0008
  90. struct pseudohdr
  91. {
  92.         struct in_addr saddr;
  93.         struct in_addr daddr;
  94.         u_char zero;
  95.         u_char protocol;
  96.         u_short length;
  97.         struct tcp_packet tcpheader;
  98. };
  99. /*
  100.  * This function returns the TTL we should use when forging our own
  101.  * IP packets. If <method & NESSUS_CNX_IDS_EVASION_SHORT_TTL>, then
  102.  * it returns an estimation of the number of hops between us and the
  103.  * remote host (see comment), minus 1. 
  104.  * 
  105.  * By default, it returns the TTL our OS usually returns (to be improved)
  106.  *
  107.  */
  108. static 
  109. int which_ttl(method, old_ttl)
  110.  int method, old_ttl;
  111. {
  112.  int ttl;
  113.  
  114.  if(method & NESSUS_CNX_IDS_EVASION_SHORT_TTL)
  115.  {
  116.   /*
  117.    * XXXX
  118.    * To find out the number of hops to the remote host,
  119.    * we assume that the TTL set remotely is one of {32,64,128,255}.
  120.    * (by default, I know of no OS which uses a different value)
  121.    * 
  122.    * We could fine grain that by reading Host/OS or even by
  123.    * computing the traceroute by ourselves (especially since we're
  124.    * not sure that our packets will go through the same path as those
  125.    * we receive) however this will do for now.
  126.    */
  127.   int num_hops = old_ttl;
  128.   if(num_hops < 32)
  129.   {
  130.    ttl = 32 - num_hops;
  131.   }
  132.   else if(num_hops < 64)
  133.   {
  134.    ttl = 64 - num_hops;
  135.   }
  136.   else if(num_hops < 128)
  137.   {
  138.    ttl = 128 - num_hops;
  139.   }
  140.   else ttl = 255 - num_hops;
  141.  }
  142.  /*
  143.   * We try to set up a 'normal' TTL
  144.   */
  145.  else /* if(method & NESSUS_CNX_IDS_EVASION_INJECT) */
  146.  {
  147. #ifdef LINUX
  148.  int f;
  149.  f = open("/proc/sys/net/ipv4/ip_default_ttl", O_RDONLY);
  150.  if(f >= 0)
  151.  {
  152.   char rd[20];
  153.   
  154.   read(f, rd, sizeof(rd) - 1);
  155.   close(f);
  156.   ttl = atoi(rd);
  157.  }
  158. #else
  159.  /*
  160.   * TODO :
  161.   * XXX sysctl support (BSD)
  162.   * XXX Solaris support...
  163.   */
  164.  ttl = 64;
  165. #endif
  166.  }
  167.  
  168.  return ttl;
  169. }
  170. static
  171. int in_cksum(p,n)
  172. u_short *p; int n;
  173. {
  174.   register u_short answer;
  175.   register long sum = 0;
  176.   u_short odd_byte = 0;
  177.   while( n > 1 )  { sum += *p++; n -= 2; }
  178.   /* mop up an odd byte, if necessary */
  179.   if( n == 1 ) {
  180.       *(u_char *)(&odd_byte) = *(u_char *)p;
  181.       sum += odd_byte;
  182.   }
  183.   sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  184.   sum += (sum >> 16); /* add carry */
  185.   answer = (int)~sum; /* ones-complement, truncate*/
  186.   return (answer);
  187. }
  188. static 
  189. int tcp_cksum(packet, len)
  190.  char* packet;
  191.  int len;
  192. {
  193.  struct pseudohdr pseudoheader;
  194.  char * tcpsumdata = (char *)emalloc(sizeof( struct pseudohdr ) + 
  195.       ( len % 2 ? len + 1 : 0 ) );
  196.  struct in_addr source, dest;
  197.  struct ip_packet * ip = (struct ip_packet*)packet;
  198.  struct tcp_packet * tcp = (struct tcp_packet*)(packet + ip->ip_hl*4); 
  199.  char * data = (char*)(packet + ip->ip_hl*4 + tcp->th_off*4);
  200.      
  201.   source.s_addr = ip->ip_src.s_addr;
  202.   dest.s_addr = ip->ip_dst.s_addr;
  203.   
  204.   bzero(&pseudoheader, 12+sizeof(struct tcp_packet));
  205.   pseudoheader.saddr.s_addr=source.s_addr;
  206.   pseudoheader.daddr.s_addr=dest.s_addr;
  207.  
  208.   pseudoheader.protocol=IPPROTO_TCP;
  209.   pseudoheader.length=htons(sizeof(struct tcp_packet)+len);
  210.   bcopy((char *) tcp,(char *) &pseudoheader.tcpheader,sizeof(struct tcp_packet));
  211.   /* fill tcpsumdata with data to checksum */
  212.   bcopy((char *) &pseudoheader, tcpsumdata ,sizeof(struct pseudohdr));
  213.   bcopy((char *) data, tcpsumdata + sizeof(struct pseudohdr), len);
  214.   tcp->th_sum = in_cksum((unsigned short *)tcpsumdata,12+sizeof(struct tcp_packet) + len );
  215.   efree(&tcpsumdata);
  216.   return 0;
  217. }
  218. /*
  219.  * This function injects a tcp packet in a stream. If
  220.  * method & NESSUS_CNX_IDS_EVASION_SHORT_TTL != 0, then 
  221.  * the injected tcp packet will be completely valid but will
  222.  * have a short TTL (so that it does not reach the remote host).
  223.  *
  224.  * If method & NESSUS_CNX_IDS_EVASION_INJECT != 0, then 
  225.  * the injected tcp packet will have a normal TTL but will
  226.  * have a bad checksum.
  227.  *
  228.  * <orig_packet> is the capture of the last packet sent by the
  229.  * remote host (hopefully a ACK). We use it to obtain the th_seq
  230.  * and th_ack elements that are being waited for by the remote
  231.  * host.
  232.  *
  233.  * <packet_len> is the size of the captured packet
  234.  *
  235.  *
  236.  * We also use the ttl of the packet to determine the number
  237.  * of hops between us and the remote host (see the function
  238.  * which_ttl()).
  239.  *
  240.  * <flags> are the flags of the tcp packet we should send (RST, ...)
  241.  *
  242.  * <data> is the data we should append to our tcp packet. This can
  243.  * be NULL
  244.  * <data_len> is the length of the data. 
  245.  *
  246.  *
  247.  * Note that this function opens a raw socket each time it's called, which
  248.  * is highly inefficient.
  249.  */
  250. static int 
  251. inject(orig_packet, packet_len, method, flags, data, data_len)
  252.  char * orig_packet;
  253.  int packet_len;
  254.  int method;
  255.  int flags;
  256.  char * data;
  257.  int data_len;
  258. {
  259.  int soc;
  260.  char * packet;
  261.  struct ip_packet * ip, * old_ip;
  262.  struct tcp_packet * tcp, * old_tcp;
  263.  int tot_len = sizeof(struct ip_packet) + sizeof(struct tcp_packet) + data_len;
  264.  int i;
  265.  int one = 1;
  266.  struct sockaddr_in sockaddr; 
  267.  
  268.  if(packet_len < sizeof(struct ip_packet) + sizeof(struct tcp_packet))
  269.   return -1;
  270.  
  271.  
  272.  
  273.  old_ip = (struct ip_packet*)orig_packet;
  274.  
  275.  if((old_ip->ip_hl * 4)+sizeof(struct tcp_packet) > packet_len)
  276.   return -1;
  277.  old_tcp = (struct tcp_packet*)(orig_packet + (old_ip->ip_hl * 4));
  278.  
  279.  
  280.  soc = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  281.  if(soc < 0)
  282.    return -1;
  283. #ifdef IP_HDRINCL
  284.  setsockopt(soc, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one));
  285. #endif
  286.  packet =  emalloc(tot_len);
  287.  /*
  288.   * Copy data, if any
  289.   */
  290.  for(i=0;i<data_len;i++)packet[i+sizeof(struct ip_packet)] = data[i];
  291.  
  292.  ip = (struct ip_packet*)packet;
  293.  tcp = (struct tcp_packet*)(packet + sizeof(struct ip_packet));
  294.  
  295.  /* 
  296.   * for the sake of code shortness, we copy the header of the
  297.   * received packet into the packet we forge, and we'll change
  298.   * some stuff in it.
  299.   */
  300.  memcpy(ip, old_ip, sizeof(struct ip_packet));
  301.  
  302.  ip->ip_len = FIX(tot_len);
  303.  ip->ip_hl = 5;
  304.  ip->ip_off = 0;
  305.  ip->ip_src.s_addr = old_ip->ip_dst.s_addr;
  306.  ip->ip_dst.s_addr = old_ip->ip_src.s_addr;
  307.  ip->ip_id = rand();
  308.  ip->ip_ttl = which_ttl(method, old_ip->ip_ttl);
  309.  ip->ip_sum = in_cksum((u_short *)packet, sizeof(struct ip_packet));
  310.  
  311.  memcpy(tcp, old_tcp, sizeof(struct tcp_packet));
  312.  tcp->th_flags = flags;
  313.  if((flags & TCP_FLAG_RST) && (method & NESSUS_CNX_IDS_EVASION_FAKE_RST))
  314.   tcp->th_ack = htonl(ntohl(old_tcp->th_seq) + 1);
  315.  else
  316.   tcp->th_ack = old_tcp->th_seq;
  317.  tcp->th_seq = old_tcp->th_ack;
  318.  tcp->th_sport = old_tcp->th_dport;
  319.  tcp->th_dport = old_tcp->th_sport;
  320.  tcp->th_off = 5;
  321.  tcp->th_sum = 0;
  322.  if(method & NESSUS_CNX_IDS_EVASION_SHORT_TTL)
  323.   tcp_cksum(packet, data_len);
  324.  else 
  325.   tcp->th_sum = rand(); /* bad checksum - packet will be dropped */
  326.   
  327.  /*
  328.   * Sending the packet now
  329.   */
  330.  bzero(&sockaddr, sizeof(sockaddr));
  331.  sockaddr.sin_family = AF_INET;
  332.  sockaddr.sin_addr.s_addr = ip->ip_dst.s_addr;
  333.  
  334.  
  335.  if(sendto(soc, packet, tot_len, 0, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0)
  336.  {
  337.   perror("nessus-libraries : libnessus : ids_send.c : inject() : sendto() ");
  338.  }
  339.  efree(&packet);
  340.  close(soc);
  341.  return 0;
  342. }
  343. ExtFunc int
  344. ids_send(fd, buf0, n, method)
  345.  int fd;
  346.  void * buf0;
  347.  int n;
  348.  int method;
  349. {
  350.  struct in_addr dst, src;
  351.  struct sockaddr_in sockaddr;
  352.  char * iface;
  353.  char filter[255];
  354.  char * src_host, * dst_host;
  355.  int port;
  356.  int ret = 0;
  357.  int len;
  358.  char * buf = (char*)buf0;
  359.  unsigned int sz  = sizeof(sockaddr);
  360.  int e;
  361.  unsigned char * packet;
  362.  int bpf;
  363.  
  364.  bzero(&sockaddr, sizeof(sockaddr));
  365.  if(getpeername(fd, (struct sockaddr*)&sockaddr, &sz) < 0)
  366.  {
  367.   perror("getpeername() ");
  368.  }
  369.  port = ntohs(sockaddr.sin_port);
  370.  dst.s_addr = sockaddr.sin_addr.s_addr;
  371.  bzero(&src, sizeof(src));
  372.  iface = routethrough(&dst, &src);
  373.  
  374.  
  375.  src_host = estrdup(inet_ntoa(src));
  376.  dst_host = estrdup(inet_ntoa(dst));
  377.  
  378.  snprintf(filter, sizeof(filter), "tcp and (src host %s and dst host %s and src port %d)",
  379. dst_host,
  380. src_host,
  381. port);
  382.   efree(&src_host);
  383.   efree(&dst_host);
  384.   
  385.   bpf = bpf_open_live(iface, filter);
  386.   if(bpf >= 0)
  387.   {
  388.   e = send(fd, buf+ret, 1, 0);
  389.   packet = bpf_next(bpf, &len);
  390.   if(e < 0)
  391.    return -1;
  392.   else
  393.    ret+=e;
  394.   /*
  395.    * We can start to send stuff now
  396.    */
  397.   while(ret < n)
  398.  {
  399.    if(packet)
  400.    {
  401.    char *pkt_ip;
  402.    int num_before = (rand() / 1000) % 3;
  403.    int num_after = (rand() / 1000) % 3;
  404.    int i;
  405.    
  406.    if(!num_before && !num_after)
  407.    {
  408.      if(rand() % 2)num_before = 1;
  409.      else num_after = 1;
  410.    }
  411.    pkt_ip = (char*)(packet + get_datalink_size(bpf_datalink(bpf)));
  412.    
  413.    /*
  414.     * send bogus data before
  415.     */
  416.    for(i=0;i<num_before;i++)
  417.     {
  418.     int j;
  419. char data[10];
  420. for(j=0;j<10;j++)data[j]=rand();
  421.     inject(pkt_ip, len - get_datalink_size(bpf_datalink(bpf)), method, TCP_FLAG_ACK|TCP_FLAG_PUSH, data, (rand()%9)+1);
  422. }
  423.    e = send(fd, buf+ret, 1, 0);
  424.    packet = bpf_next(bpf, &len);
  425.    /*
  426.     * send bogus data after
  427.     */
  428.    for(i=0;i<num_after;i++)
  429.     {
  430. int j;
  431. char data[10];
  432. for(j=0;j<10;j++)data[j]=rand();
  433.     inject(pkt_ip, len - get_datalink_size(bpf_datalink(bpf)), method, TCP_FLAG_ACK|TCP_FLAG_PUSH, data, (rand()%9)+1);
  434. }
  435.    }
  436.    else
  437.    {
  438.     e = send(fd, buf+ret, 1, 0);
  439. packet = bpf_next(bpf, &len);
  440.    }
  441.    if(e < 0)
  442.     return -1;
  443.    else
  444.     ret+=e;
  445.  } 
  446.   bpf_close(bpf);
  447.   return ret;
  448.  }
  449.   else return send(fd, buf, n, 0);
  450. }
  451. int ids_open_sock_tcp(args, port, method, timeout)
  452.  struct arglist * args;
  453.  int port;
  454.  int method;
  455.  int timeout;
  456. {
  457.  int bpf;
  458.  struct in_addr *dst, src;
  459.  char * iface;
  460.  char filter[255];
  461.  char * src_host, * dst_host;
  462.  int ret = 0;
  463.  int len;
  464.  dst = plug_get_host_ip(args);
  465.  if(!dst)
  466.  {
  467.   fprintf(stderr, "Error - no address associated with namen");
  468.   return -1;
  469.  }
  470.  iface = routethrough(dst, &src);
  471.  src_host = estrdup(inet_ntoa(src));
  472.  dst_host = estrdup(inet_ntoa(*dst));
  473.  snprintf(filter, sizeof(filter), "tcp and (src host %s and dst host %s and src port %d)",
  474.    dst_host, src_host, port);
  475.   
  476.  efree(&src_host);
  477.  efree(&dst_host);
  478.  
  479.  bpf = bpf_open_live(iface, filter);
  480.  if(bpf >= 0)
  481.  { 
  482.   ret = open_sock_tcp(args, port, timeout);
  483.   if(ret >= 0)
  484.   {
  485.    unsigned char * packet = bpf_next(bpf, &len);
  486.    if(packet)
  487.    {
  488.    char *pkt_ip;
  489.    pkt_ip = (char*)(packet + get_datalink_size(bpf_datalink(bpf)));
  490.   
  491.    inject(pkt_ip, len - get_datalink_size(bpf_datalink(bpf)), method, TCP_FLAG_RST, NULL, 0);
  492.    }
  493.   }
  494.   bpf_close(bpf);
  495.   return ret;
  496.  }
  497.  else
  498.   return open_sock_tcp(args, port, timeout);
  499. }