pwnable.kr第二遍---lotto blackjack

>>>>>lotto
尽管没有退出程序,用户可以一直玩下去
但是每次要重新打开/dev/random取随机数
这里的随机数是每次更新的
所以......
1.每次的/dev/urandom的数字是变化的
根据linux下的系统熵产生的随机数


2.第二次做,显然不如第一次那样有对题目的敬畏之心,没能好好看代码
>首先从main函数开始读,了解整个函数的逻辑以及攻击点,函数主要包括三个部分:play help exit。其中只有play有意义
>略读之后发现,只要我们令macth=6,就可以拿到flag
>从help中我们可以看到,作者提醒我们如果用数学方法来解题,可能性很小
此外每一次play只能进行一次尝试,也就是说每次随机数都在变


3.精读play代码,找细节方面的漏洞
submit是一个字符数组首地址
从标准输入读取6bytes给submit,submit的内容为字符!
int r是Read()函数返回值
fd是open("",mode)的返回值,文件描述符
lotto是一个字符数组首地址,数组内容为字符
"/dev/urandom"文件中的内容是数字
那么从文件中读入数字值给char类型,此时char字符的ascii为该整型数字!!
然后将lotto[]数组中的字符进行处理:将ascii值对45取余+1
于是lotto[]数组中的字符就被映射到ascii为1~45的范围内
这就提示我们输入的submit的内容应该是ascii值为1~45内的
--------
继续缩小范围:
cat /dev/urandom |head -c 6
很少看到有控制字符???控制字符??继续了解


后边是代码的逻辑错误
双层循环中令match=6的方法有两种
一种是各个位分别相同并且数组中没有相同字符
另一种是submit中为6bytes相同字符,并且该字符在lotto[]中出现且仅出现一次


4.ascii范围
0-31是控制字符;其余都是可见字符


5.于是找到ascii为32-45的可见字符
不断尝试,即可得到flag


6.我觉得是不是也可以将标准输入重定向到一个可执行代码
这段代码的功能是产生6个相同的bytes,并以ascii码的形式
输入给当前./lotto
同样是从程序中产生的,是不是可以建立管道之类的。。。
虽然这样是比尝试麻烦,但是是否可行???????


7.机智机智机智!!!!
这里有一个简单的use after free漏洞!!!
submit[]在每次使用之后都没有清空过???如何清空???
上次赋的值依然保存在submit中
于是第一次输入五个字符,那么最后一位是换行符,第二次输入四个字符,以此推
之后就不用输入了,此时submit[]中保留的一直是\n的ascii
这个控制字符是在1~45之间的
此时再根据上述思路,也是可以碰出答案的!




>>>>>blakjack game
1.由于是上次做过的题目,有点印象
思路的关键点还是在于仔细阅读代码
找到代码的逻辑漏洞
这个题目中的逻辑漏洞在于bet其实是可以大于我们现有的Cash的
所以只要令bet=1000000
然后赢一次就可以capture the flag了


2.在判断bet之后,默认用户会输入正确的内容
但是没有循环判断,这就造成了漏洞


3.机智啊机智机智机智
令bet=-1000000
赢不容易,输还不容易吗........感觉要赶上脑筋急转弯了
!!!!点赞


4.bet函数还存在整型溢出
想办法输入一个超级大的数字使得bet为-1000000
这里输入了一个4293967296
scanf("%d",&bet) int类型数据
那么bet值为多少呢????


5.写脚本玩游戏,赚1000,000
但是因为发牌是随机的,脚本逻辑不易控制

猜你喜欢

转载自blog.csdn.net/lee_ham/article/details/79586356
今日推荐