Upload
kendal-goodley
View
219
Download
1
Embed Size (px)
Citation preview
Some format parameters
Parameter Input Type Output Type
%d Value Decimal
%u Value Unsigned Decimal
%x Value Hexadecimal
%s Pointer String
%n Pointer Number of bytes written so far
What happens in memory?Top of the stack
Low address Address of format string
Value of A (5)
Address of A (0xbffff844)
Value of B (7)
High address Bottom of the Stack
Then what happens in memory?
Top of the stack
Low address Address of format string
Value of A (5)
Address of A (0xbffff844)
High address Bottom of the Stack
So this point next memory area.(first value found below stack frame)
What happens in memory?
Top of the stack
Low address Address of format string
Address of Argv[1]
High ad-dress
Bottom of the Stack
In Right Case
What happens in memory?
Top of the stack
Low address Address of Argv[1]
High ad-dress
Bottom of the Stack
In Wrong Case
So in this case,argv[1] pretends as format string.
So lets do some trick
Top of the stack
Low address Address of argv[1] (test-ing%x)
High ad-dress
Bottom of the Stack (bffff420)
What happens in memory?Top of the stack
Low address Address of argv[1]
some stack values
High address Argv[1] (%08x. %08x. %08x. %08x. %08x. %08x. … …)
What happens in memory?Top of the stack
Low address Address of argv[1]
some stack values
High address Address of PATH
Let’s see in memory’s viewTop of the stack
Low address Address 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 address Some stack values
0x08049794 test_val
31
Our GOAL• Change value at 0x08049794 as ‘aabbccdd’
• HOW?
Memory 94 95 96 97
First write to 0x08049794 aa 00 00 00
Second write to 0x08049795 bb 00 00 00
Third write to 0x08049796 cc 00 00 00
Forth write to 0x08049797 dd 00 00 00
Result aa bb cc dd 00 00 00
On memory’s viewTop of the stack
Low address Address of argv[1]
Some stack value (bffff420)
Some stack value (b7fe75fc)
Some stack value (00000000)
Agrv[1](address : 0x08049794)
High address Some stack values (%x%x%150x%n) and so on…
0x08049794
170(aa)
Then how about second step?
Top of the stack
Low address Address of argv[1]
Some stack value (bffff420)
Some stack value (b7fe75fc)
Some stack value (00000000)
Agrv[1](address : 0x08049794)
Address : 0x08049795
High address Some stack values (%x%x%150x%n) and so on…
0x08049794
0x08049795
170(aa)
187(bb)
Is it work?
NO!
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.)
SolutionTop of the stack
Low address Address of argv[1]
Some stack value (bffff420)
Some stack value (b7fe75fc)
Some stack value (00000000)
Address : 0x08049794
JUNK
Address : 0x08049795
High address Some stack values (%x%x%150x%n)
0x08049794
0x08049795
170(aa)
187(bb)
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!
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’
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!
Test direct writing access• Let’s modify test_val as ‘0xbffffd72’
We don’t need ‘JUNK’ value, be-cause we directly access to address.
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!
Why need short write?• At previous side, I show 4 Byte write also can over-
write memory in two step.
• Then what is benefit?
Let’s change order of write• With 4 Byte word
• It doesn’t work, because writing at 0x08049794 over-writes previous job.
Benefit of short writes
• Short take only 2 Bytes, so we can avoid overwrite.So order doesn’t matter.
Two function• Constructor : excute before main function.
• Destructor : excute before exit system call.
• Table section ‘.dtors’ and ‘.ctors’ are made for de-structor and constructor.
Dtors_sample.c
• Cleanup function is defined with destructor at-tribute, so cleanup function is automatically call when main call exit system call.
.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 func-tions 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 com-piled with GNU C compiler.
nm command• nm command list symbols from object files.
• It can be used to find the address of function.
nm command example• As definition,
__DTOR_END__ contains 0xffffffff__DTOR_LIST__ contains 0x00000000
• And address between __D-TOR_END__ and __DTOR_LIST__(0x080495b0) contains address of cleanup function.(0x080483e8)
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.
./fmt_vuln also contain .dtors section
.dtors section is WRITABLE, so by overwrite this section we can do some malicious attack!
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.
Change .dtors section• Change __DTOR_END__ value as shellcode address.
• It change __DTOR_END__ value as shellcode ad-dress, so when main call exit system call it sud-denly run shellcode.
Let’s see in memory viewTop of the stack
Low address Address of argv[1]
Some stack value
Some stack value
Some stack value
Address of 0x08049696
Address of 0x08049694
High address Some stack values
0x08049694 0000 0000
0x08049794 -74 Pass 0xbfff
Pass 0xf9f1