type
status
date
slug
summary
tags
category
icon
password
这两天在做西电的那个moectf的时候遇到一题,比较有意思,那道题是个栈题,并且其中有后门函数这些,整体来时就是一个简单的ret2text,但是其中对输入的检查和手法还是比较有意思的。故写这篇文章记录一下。
开始之前有点想喷一喷这个moectf,这个比赛的质量确实高,这个没话说,虽然说是新生但其中还是能学到很多有用的知识。but这个比赛给的ip和端口要用wsrx去解析一遍才能用,这个有点难受,甚至pwn的网址用windows上的wsrx解析后还不能用,要在liunx上解析后才能nc。而这个软件在我的liunx上一运行,就让我的乌班图不能复制粘贴了,然后重新整了又出这个问题,后面甚至一度把虚拟机整崩了。唉,希望下次能有用一个好一点的解析软件吧。
回到题目,这个题目的一开始就是要输入数据,并且会对这个数据进行检查,具体的过程就放在下面,
简单来说就是先生成一个v8的随机数,然后由我们输入v6的值,之后如果v6的值和v8的值相同或者我们在输入数据后能使scanf函数返回值为-1,就可以满足条件,从而打印
[Info] Cage opened.\n
不然就要进入循环直达满足条件为止。而这两个条件很明显第2个条件使scanf函数返回值为-1,这是不可能的。故重点来看第一个条件让v6的值和v8的值相同。
首先我们知道v8的值一个随机数,由这个生成
这里使用arc4random这个函数,这个函数是一个比较智能的C语言函数,不需要种子这些就能生成随机数,故这里不能用模拟的方法得到。
这里当时困扰了我许久,后来突然发现这个在arc4random函数之后还有一个
% 0x2345
这里结合前面的arc4random函数,其实整体的v8的指就可以简单预测一个了,这里v8的值的范围就是[0+16678186]~[0x2345+16768186]这个其中的一个值,再结合之前我们知道在输入v6的值时,如果我们没有满足条件,那就会一直循环知道满足v6等于v8,才会去到下一步,于是这里我们就可以使用爆破的手法,向程序从[0+16678186]开始输入,不满足条件就把输入的数加一再输入直到输入的数与v8的值相同停止输入。
就这样通过依次输入数据的方法暴力满足v6和v8的值相同,从而满足这里的条件,进入下面的程序。
详细分析一下后面的程序通过scanf函数向从v9[0]的地方开始读入数据,读3次数据,然后对v9[0],v9[1],v10这3个地方的数据进行检测,要满足的条件为v10为195874819,而v9的位置不能被改变,因此这里我们要的便是在使用scanf函数的前两次都不能有任何的读数进去,在第3次读数的地方输入195874819,从而把v10的值修改为满足要求的那种。
这里我们最大的问题就是如何让scanf函数在前两个读数的地方,不读入进去,但依然能往下进行。
简单来时就是如何跳过前两次读数。
关于scanf函数这个函数只用来读入数的,如果读入的非数的会因为不可读取从而报错,但是两有个符号除外,这两个是‘-’和‘+’,这两个符号在程序中有表示正负的含义,故当你在scanf函数中输入这两个符号时,程序会把它当做正负的判断从而不报错。
于是这里我们便可以对其进行利用这里的3次输入,前两次输入‘+’,从而实现跳过,在第3次的时候便输入,要满足的数,这样v9[0]和v9[1]的值都没有改变,但我们就能修改v10的值。
这里可以看出,此时的scanf函数要向
0x7fffffffdde0
这个读入数据,这里就是我们的v[0]的地址,这里已经有原本的数据0x1000027786fec
,这个我们不能改变他,我们要改的是这个v10的数据于是我们3次输入,前两次都输入’+‘
在第3次的时候便可以看到此时的scanf函数要输入的地方不是之前的
0x7fffffffdde0
而是0x7fffffffddf0
这里就是v10的地址,我们就可见直接输入我们要的数据从而达到我们要的目的。同时还可以看到,v9[0]和v9[1]的被没有改变,程序直接跳过这两个地方了。绕过这两个检查,这到题就没什么难度了,就是简单的泄露canary,然后ret2text。
这道题又是一个对程序理解深度的考察,其中对第一个随机数的爆破和scanf函数输入‘—’和‘+’跳过这两个点之后都没遇到过,值得好好学习一下
- 作者:wgiegie
- 链接:https://tangly1024.com/article/1083ecc9-5160-8010-9433-f34b5f90084a
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。