[攻防世界]新手区guess_num
运行了一下发现是个猜数的游戏,还是先看文件属性及保护措施
64位文件用64IDA打开,先看字符串窗口,找可利用的字符串

看main的伪代码,可以看出这个猜数游戏会进行十个回合,如果十个回合都能猜对数的话,就可以调用sub_C3E函数,而这个sub_C3E函数中就有system(“cat flag”)
“rand() % 6 + 1”的含义就是获取1~6的伪随机数。
由于开启了栈保护,所以没法直接覆盖返回地址来进入sub_C3E,但是输入name时,用了gets,利用gets栈溢出,尝试覆盖掉seed,使种子值已知,这样就能得到rand的值,之后只要循环输入十次就能拿到flag。
srand()是用来初始化rand()的C语言函数,而rand()函数用于产生随机数,但并不是真的随机数,只要种子已知,就能得到rand()生成的所有随机数(这个函数产生的随机数和平台有关系,同样的seed,Windows下和Linux下产生的值不同,由于这题文件elf,是基于Linux的,所以脚本在Linux上运行才行)。
思路:
- 输入name时,通过gets溢出,覆盖掉seed的值,使seed已知
- 写脚本,或者手动输入rand()函数产生的前10个值
- 到达sub_C3E拿到flag
EXP:
1 | from pwn import * |
payload解释:
- ‘a’*32:看栈算v7和seed的距离,这里var_30就是v7

地址0x00000030和0x00000010之间距离为32,所以填充32个’a’ - p64(1):将seed的值覆盖为1
关于ctypes:
官方文档,左上角选择 语言 版本
ctypes是Python的外部函数库。它提供C兼容的数据类型,并允许在DLL或共享库中调用函数。它可以用于将这些库包装在纯Python中。
payload中的第四行,就是加载dll,这样就可以调用C里的srand和rand函数,比如调用srand函数,就用libc.srand()