0x00 UAF principle
As shown in the code above, the pointer P1 request memory, print its address, value
Then release P1.
The pointer p2 applies the same size of memory, prints the address of the P2, P1 the value pointed to by the pointer
GCC compiles and runs the following results:
P1 is the same as the P2 address, after P1 the pointer is released, P2 requests the same size of memory, the operating system assigns the P1 address to P2, modifies the P2 value, and P1 has been modified.
From this we can know:
1. After free a piece of memory, then request the same size of memory, the operating system will be just free of memory allocated again.
The root cause is Dllmalloc:
Reference: http://blog.csdn.net/ycnian/article/details/12971863
When the application calls free () frees memory, if the memory block is less than 256kb,dlmalloc and does not immediately release the memory block back into memory, the memory block is marked as idle. There are two reasons for this: the memory block does not necessarily release the kernel immediately (for example, the memory block is not at the top of the heap), and the second is for the application to request memory usage next time (this is the main reason). When the amount of free memory in dlmalloc reaches a certain value, Dlmalloc frees free memory for the kernel. If the application requests more memory than the 256KB,DLMALLOC call Mmap () requests a piece of memory to the kernel and returns it back to the application for use. If the application frees more memory than 256kb,dlmalloc immediately calls Munmap () to free memory. Dlmalloc does not cache memory blocks larger than 256kb, because such chunks of memory are too large to be used for long periods of memory resources.
2. Through the P2 can operate the P1, if after P1 continue to be used (using after free), you can achieve through the P2 to modify the program function.
0x01 a usage scenario
On the internet to find a UAF loophole of the CTF program, refer to the blog as follows:
http://www.syjzwjj.com/use-after-free-tutorial/
The author has analyzed in detail, through the whole process of debugging, to understand the use of UAF.
1. combine Ida with program operation to briefly understand the function of the program.
Select 1 to leave a message, the information will be stored in 1 linked lists
Select 2 will traverse the linked list to find the corresponding node, print the node information
After printing, you can delete and modify the operation
The linked list node structure is as follows
Tips: Applying data structures in reverse code reference to the 8th chapter of the IDA Pro authoritative guide
2. UAF Vulnerability Code
After the linked list node is deleted, you can continue into the Modify function, and the Modify function can continue to enter the Modify function.
The delete function is as follows:
The delete function has a free operation on the node, and if the delete operation is performed in the loop code, after releasing the node, select 2 to enter the Modify function.
The Modify function is as follows:
The Modify function reads the data from the user and then copies it to the corresponding pointer, but at this point it uses a pointer that has already been disposed. When you enter content, the length of the content is allocated as the size of the memory, and when the allocated memory size equals the MSG structure size (48 bytes, obtained through the previous structure), the memory just freed is allocated to the content pointer.
As shown below
The content points to the MSG structure itself
The content is then copied to the content pointer, i.e. our input is copied to the freed node memory.
In the loop code, you can continue to enter modify after the modify is finished. A copy of the address pointed to by the author,title,content pointer of the MSG structure is then copied. Since the previous step has been able to make arbitrary changes to the MSG structure, it is possible to modify the destination address of several memcpy to the desired address to make any memory (which belongs to the program's legitimate memory).
At this point we have been able to complete the modification of any memory address.
The next thing to consider is the use of some command execution.
3. exploit execution commands
To execute a command, you need to call the system function, but there is no system function in the code, how do you complete the command execution?
You can use the lazy load function of Linux, change the direction of the strlen function, and change the original strlen to execute the system.
Tips: Lazy Loading
When calling a standard function, the standard function needs to be loaded from other so files, not directly calling the address of the function, but rather by jumping to the real address of the function through an intermediate table.
Take the invocation of the strlen function as an example
In program debugging, print 0x804c04c information
The whole process is as follows:
Call strlen jump to strlen function, there is only one sentence jmpds:off_804c04c
When the program is running, the value in 0X804C04C is 0xb7658210, which is the real address of strlen.
That is, 0x804c04c stores the true address of the strlen in the LIBC library.
Change the value of 0x804c04c to the address of system 0xb7614360. Although it looks like strlen is being called, the system function is actually executing.
Before modification:
Call Strlen
Strlen:
JMP 0x804c04c
0x804c04c:0xb7658210 (strlen)
After modification:
Call Strlen
Strlen:
JMP 0x804c04c
0x804c04c:0xb7614360 (System)
Tips: Addressing the real address of the system
The system was not found in the relocation table of the program because the system function was not called by the entire program. So you need to locate the real address of system in this program.
The libc is loaded into the 0xb75d6000-0xb777a000 address space, and the size is 0x1a4000
Write a program to call the system function
Debug run view its libc address space
is loaded into the 0xb7e10000-0xb7fb4000, and the size is 0x1a4000.
Therefore, the address of system in the vulnerability program should be = (System address in the calling program-the calling program libc start address + Vulnerability program LIBC start address)
0xb7e4e360
System address =0xb7e4e360-0xb7e10000+0xb75d6000= 0xb7614360 in the vulnerability program
4. POC operation effect
Execute a mkdir hack command to create a hack directory
POC Fragments
5. Process Review
1) Release the node in the Delete function
2) The Modify function passes in the released pointer
3) The allocated memory size in the Modify function is controllable, by allocating the same size as the node, to gain control over the freed memory
4) Modify the destination address to be copied msg->author pointer to the middle table address of the function strlen to be executed
5) Change the real strlen address that strlen points to the real address of system
6) appears to execute Callstrlen, but actually executes the system function
0x02 Summary
When the pointer is released and then requests the same size of memory, the system allocates the freed address to improve the system's speed, so it can be modified to the freed memory data, which could cause a UAF vulnerability if the released pointer continues to be used.
Through the UAF vulnerability, can cause some arbitrary memory modification, combined with code characteristics, may cause arbitrary memory read or, serious can cause arbitrary command execution, to obtain the shell. Depends on how the released pointer is used.
Relevant knowledge points: GDB debugging (How to debug the fork out of the program), deferred loading (PLT and got), the standard function in memory positioning, UAF modify the content of the release pointer Dllmalloc
UAF Learning--Principle and utilization