首页
社区
课程
招聘
[原创]ciscn_2019_es_2栈转移
发表于: 2021-9-1 19:30 26482

[原创]ciscn_2019_es_2栈转移

2021-9-1 19:30
26482

栈转移非常的亏贼啊!是因为栈溢出造成的漏洞,而溢出的又不多,通常刚好溢出到ebp和返回地址,无法构造参数,所以有时候不能直接利用,所以我们通过改变esp和ebp在我们可以改写的地方构造一个新的栈

我们直接上题ciscn_2019_es_2

很明显的栈溢出啊,s只有40byte,但是read能读0x30byte,简单分析下啊,read读入的数据刚好将返回地址覆盖掉
再翻翻IDA,欸我们可以看到啊,有个hack函数,这名就不是什么正经名,打开一看,果然,看到了systeam("echo flag")

说到这块,我不得不说自己基本知识不扎实(出题人太狗),这里"echo flag"很明显的输出flag,我当时就直接起飞,hack地址覆盖返回地址,好家伙,果然没让我失望,终端直接输出flag四个大大的字母,我当时还纳闷了好久,后来才想明白,echo就是用来输出字符串的,你要写个echo Steal Wang Xishun's tribute ,他就能输出Steal Wang Xishun's tribute,人都麻了。

咳咳,让我们回到正题systeam有了,题中没有/bin/sh字符串,我们可以自己写入一个,然后将其地址作为systeam()的参数。
假设这里栈溢出长度没有限制,那么我们构造的栈应该是这样的

但是只能写入0x30字节的payload,所以我们通过leave命令将栈转移到别的地方,我们将栈中ebp的内容改为s的地址,return改为leave的地址
这是执行了两次leave之后的栈的样子 注意,一般leave命令后面都会跟着ret命令,也是必须要有的。此处如果继续执行ret命令就会返回到esp所指向内容填写的地址,那么接下来就很好办了,我们构造栈的内容

亏贼啊!
当然此处我们还有一个问题就是'/bin/sh'的地址我们不知道。
这个啊,我们可以通过泄露原来ebp的值来确定(就是上图中蓝色ebp的值),我们将此地址叫做addr,以免和ebp寄存器混淆
具体怎么来啊,听我慢慢讲,我们再次回到IDA中
printf函数会打印s字符串,且遇到0就会停止打印,所以如果我们将addr之前的内容全部填充不为0的字符,就能将addr打印出来(亏贼啊,这个printf函数可真是个好东西),我们通过地址再计算出addr到s的距离,我们就可以通过addr来表示'/bin/sh'所在的地址了。

很明显啊,我们先通过第一个read传入payload,然后通过printf打印出addr的值(栈中蓝色ebp的值,为了不和寄存器ebp混淆,我们将其称之为addr),然后通过第二个read函数构造栈转移,执行systeam('/bin/sh')



我们通过pwndbg调试一下发现s的地址为0xffbc5270,addr为0xffbc52a8,相距0x38,所以s的地址为addr-0x38,则上面'/bin/sh'的地址为addr-0x38+0x10(每次调试addr和s的地址都不同,但是它们之间的间距相同都是0x38)

接下来我们构造第二个payload


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2021-9-1 19:35 被凡人_编辑 ,原因:
上传的附件:
收藏
免费 5
支持
分享
最新回复 (4)
雪    币: 224
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
老哥当年退出文坛我是万万不同意的
2021-12-4 23:07
0
雪    币: 871
活跃值: (1730)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
老哥当年退出文坛我是万万不同意的。另外所有的systeam其实都是system
2022-8-12 16:45
0
雪    币: 871
活跃值: (1730)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
忘了加狗头
2022-8-12 16:45
0
雪    币: 237
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
学习了
2024-6-30 21:38
0
游客
登录 | 注册 方可回帖
返回
//