Download presentation
Presentation is loading. Please wait.
Published byKendal Goodley Modified over 9 years ago
1
Format Strings Lee Eun-Hun
2
Format Parameters
3
Some format parameters ParameterInput TypeOutput Type %dValueDecimal %uValueUnsigned Decimal %xValueHexadecimal %sPointerString %nPointerNumber of bytes written so far
4
fmt_uncommon.c
5
Result 46Bytes
6
What happens in memory? Top of the stack Low addressAddress of format string Value of A (5) Address of A (0xbffff844) Value of B (7) High addressBottom of the Stack
7
Change fmt_uncommon.c
8
Result What is this value?
9
Then what happens in memory? Top of the stack Low addressAddress of format string Value of A (5) Address of A (0xbffff844) High addressBottom of the Stack So this point next memory area. (first value found below stack frame)
10
The Format String Vulnerability
11
fmt_vuln.c
12
Result Why it is working fine?
13
fmt_vuln_alter.c
14
Result Why it isn’t working?
15
What happens in memory? Top of the stack Low addressAddress of format string Address of Argv[1] High addressBottom of the Stack In Right Case
16
What happens in memory? Top of the stack Low addressAddress of Argv[1] High addressBottom of the Stack In Wrong Case So in this case, argv[1] pretends as format string.
17
So lets do some trick Top of the stack Low addressAddress of argv[1] (testing%x) High addressBottom of the Stack (bffff420)
18
Lets do more trick
19
What happens in memory? Top of the stack Low addressAddress of argv[1] some stack values High addressArgv[1] (%08x. %08x. %08x. %08x. % 08x. %08x. … …)
20
Reading from Arbitrary Memory Addresses
21
Let’s reading from arbitrary memory address
22
Getenvaddr.c
23
What happens in memory? Top of the stack Low addressAddress of argv[1] some stack values High addressAddress of PATH
24
Writing to Arbitrary Memory Addresses
25
It’s time to WRITING to arbitrary memory address! 31Bytes
26
Let’s see in memory’s view Top of the stack Low addressAddress of argv[1] Some stack value (bffff420) Some stack value (b7fe75fc) Some stack value (00000000) Agrv[1] (address : test_val + %08x.%08x.%08x.%n) High addressSome stack values 0x08049794test_val 31
27
Another example -> So we can control writing value!
28
Our GOAL Change value at 0x08049794 as ‘aabbccdd’ HOW? Memory94959697 First write to 0x08049794aa00 Second write to 0x08049795bb00 Third write to 0x08049796cc00 Forth write to 0x08049797dd00 Resultaabbccdd00
29
Let’s do first step
30
On memory’s view Top of the stack Low addressAddress of argv[1] Some stack value (bffff420) Some stack value (b7fe75fc) Some stack value (00000000) Agrv[1] (address : 0x08049794) High addressSome stack values (%x%x%150x%n) and so on… 0x08049794 170(aa)
31
Then how about second step? Top of the stack Low addressAddress of argv[1] Some stack value (bffff420) Some stack value (b7fe75fc) Some stack value (00000000) Agrv[1] (address : 0x08049794) Address : 0x08049795 High addressSome stack values (%x%x%150x%n) and so on… 0x08049794 0x08049795 170(aa) 187(bb) Is it work? NO!
32
What is problem? If we put $(printf “\x94\x97\x04\x08\x95\x97\x04\x08”)%x%x%150x%n %n then… CAN WE PUT ‘177(bb)’ TO 0x08049795?? So we NEED some JUNK value. (Junk value must be 4Bytes.)
33
Solution Top of the stack Low addressAddress of argv[1] Some stack value (bffff420) Some stack value (b7fe75fc) Some stack value (00000000) Address : 0x08049794 JUNK Address : 0x08049795 High addressSome stack values (%x%x%150x%n) 0x08049794 0x08049795 170(aa) 187(bb)
34
Now we can do it
35
I just wonder What if we modify 0x08049794’s value in just one step? It dosen’t work WHY?
36
How about two step? It is work!
37
Another writing memory example Make new C program
38
New goal Last example, we modify test_val to “0xddccbbaa” How about modify test_val to “0x0806abcd”? Is there a new problem? Let’s do it!
39
Let’s try Do subtract by using %n is possible?
40
New problem Last example “0xddccbbaa”, ‘dd > cc’ ‘cc > bb’ ‘bb > aa’ so, we only need to add some Bytes. This time “0x0806abcd”, ‘08 > 06’ ‘06 < ab’ ‘ab < cd’ then we need subract some Bytes. We can’t subtract, so we add bytes for calculation. Like ‘1ab > cd’
41
Solution You can see next_val is overwrittened.
42
Keep going on Why it is not ’08’????
43
New problem again %2x option doesn’t print only 2 Byte! Because of ‘%2x’ point at ‘JUNK’, it print 8 Bytes! So solution is same as before!
44
Final result
45
Direct Parameter Access
46
So we can access some parameter directly by using $ option.
47
Test direct reading access So, we can access ‘AAAA’ simply.
48
Test direct writing access Let’s modify test_val as ‘0xbffffd72’ We don’t need ‘JUNK’ value, because we directly access to address.
49
Using Short Writes
50
h option ‘Short’ is two-Byte word. We can define ‘short’ simply put h at parameter. (%hi, %hd, %hn and so on) By using short, we can modify 4 Bytes value in 2 step!
51
Some example
52
Why need short write? At previous side, I show 4 Byte write also can overwrite memory in two step. Then what is benefit?
53
Let’s change order of write With 4 Byte word It doesn’t work, because writing at 0x08049794 overwrites previous job.
54
Benefit of short writes Short take only 2 Bytes, so we can avoid overwrite. So order doesn’t matter.
55
Detours with.dtors
56
Two function Constructor : excute before main function. Destructor : excute before exit system call. Table section ‘.dtors’ and ‘.ctors’ are made for destructor and constructor.
57
Dtors_sample.c Cleanup function is defined with destructor attribute, so cleanup function is automatically call when main call exit system call.
58
Result
59
.dtors table section The.dtors table array always begins with 0xffffffff and ends with the NULL address of 0x00000000. Between these two are the addresses of all functions that have been declared with the destructor attributes..dtors table section is always include in binary even if you don’t use destructor attribute, if you compiled with GNU C compiler.
60
nm command nm command list symbols from object files. It can be used to find the address of function.
61
nm command example As definition, __DTOR_END__ contains 0xffffffff __DTOR_LIST__ contains 0x00000000 And address between __DTOR_END__ and __DTOR_LIST__(0x080495b0) contains address of cleanup function.(0x080483e8)
62
See actual content By using objdump command, we can see actual content of.dtors section. So as we can see.dtors section address is 0x80495ac, and it contains 0xffffffff, 0x080483e8, and 0x00000000.
63
.dtors sction is WRITABLE!
64
./fmt_vuln also contain.dtors section.dtors section is WRITABLE, so by overwrite this section we can do some malicious attack!
65
Let’s do it! We will run shellcode when exit system call by overwrite.dtors section. So we need to get shellcode address. Also we need.dtors section address.
66
Change.dtors section Change __DTOR_END__ value as shellcode address. It change __DTOR_END__ value as shellcode address, so when main call exit system call it suddenly run shellcode.
67
Let’s see in memory view Top of the stack Low addressAddress of argv[1] Some stack value Address of 0x08049696 Address of 0x08049694 High addressSome stack values 0x080496940000 0x08049794-74 Pass 0xbfff Pass 0xf9f1
68
Question?
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.