ps:本题思路由youlin师傅指引
checksec一下,查看一下保护机制
保护全开 64位?有点被吓到了
不过这种题估计都是flag已经准备好了或者自带shellcode
拖进ida看看
int __cdecl main(int argc, const char **argv, const char **envp) |
用时间做了种子,循环一百次,每次都随机一个数,我们需要输对这个数,算是经典的猜数字吧
一开始看到我们可以自定义赋值的v4和随机数v6是相邻的字节,所以想通过溢出来覆盖v6,使得if判断成立,不过貌似不行
所以还是正常做法吧
随机数,我目前知道的两种做法,一种是溢出数据覆盖seed,这样我们在知晓种子的值的情况下,因为c语言的rand是伪随机(下面就要降到了,我知道你很急,但你先别急),所以就可以知道随机数的值
还有一种办法是本题将要使用到的,这道题我们可以发现他是用当前时间作为种子,来生成随机数,所以我们只要在exp中也是用当前时间作为种子,就可以得到一样的随机数(这里看不懂的话,是伪随机的概念不清楚)
from pwn import * |
几个疑点
1.cdll.LoadLibrary的用法:
看了很多篇猜数字的题解啊,竟然没有一个人对这个函数用法有解释,那没办法了,只能自己wiki了
这个函数就是在python中重新加载文件库
还是有限制的:在64位的windows系统中,一个64位进程不能加载一个32位dll,同理一个32位进程也不能加载一个64位dll。
查资料的时候还看到这个限制的特殊情况,不过看不明白,估计了解的价值也不大,先丢在这,有空来填这个坑,感兴趣的可以自己先看(3条消息) python 调用 C++ dll 32位 64位 问题 ctypes.cdll.LoadLibrary_wowocpp的博客-CSDN博客_python调用32位dll
还有一种更深的用法是这个代码库将允许原生Linux程序从一个WindowsDLL文件中加载或调用功能函数
(3条消息) linux运行dll文件命令,LoadLibrary:一款能够允许Linux程序从DLL文件中加载或调用函数的工具…_七分醉玲珑的博客-CSDN博客
因为涉及到linux和windows的进程间通信和内核相关知识,我自己也还没有搞懂,留个坑吧,看以后有没有时间填上
2.伪随机
这里介绍一下c语言中的伪随机
一些基础的c语言知识这里就不多解释了,比如说srand用法和种子的概念
先看看一段代码吧
int main() |
输出10个随机数,我们两次运行试试
生成的随机数都一样?
我们不妨这么理解,所谓的rand函数就是根据每个种子分配一张表格,所谓的随机数是从这个表格调用的,所以当我们第二次运行时,由于种子没改变,那么这张表格的数据也不会改变
那么我们如何获得真正意义上的随机数?想一下有什么东西的数据是一直在变化的
我们把目光瞄向时间,函数srand( (unsigned)time( NULL ) ) 中time返回的是1970年1月1日0点到现在时间流失的秒数值
因此,我们这下没法得知种子是多少,也就无法知道这个种子对应的随机数表是什么
但是我们重加载了libc库,同步获取了time返回的种子值,由于time是以秒作为单位的,我们每次for循环得出的随机数和题目的随机数几乎没有差距,所以这道题的随机数就呼之欲出了