虽然我们可以利用pwntools自动生成shellcode,也可以利用alpha生成纯字符的shellcode绕过某些限制,但是当程序对输入限制较为严苛时,就不得不和这些自动化工具说再见了。由于之前完全没有手写shellcode的经验,所以本文主要是理解分析其他师傅的shellcode,尝试从中获得技巧和方法(说得明白点就先从照葫芦画瓢开始。。。)
首先直接来看题,这是2020 NUAA CTF的一道题,主要考点是ascii shellcode,难点在于限制只能用0x1f-0x7f的字符,并且buf长度只有0x40。
虽然程序中if语句的判断是小于31(0x1f),但由于类型为char(长度为8位)当其大于127(0x7f)时,值会变成负数,因此可输入字符范围是0x1f-0x7f。
要构造shellcode最主要的是两个问题,一是构造/bin/sh字符串,二是构造syscall指令(0x050f)。这里/bin/sh比较简单,由于是buf是在在栈上,所以直接push进栈就好了,而且字符范围也符合要求。问题在于syscall指令(0x050f)不符合字符范围要求,根据TaQini师傅的方法是利用异或来绕过限制。直接来看师傅的exp逐步分析吧。
from pwn import *
local_file = './pwn6'
local_libc = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = local_libc # '../libc.so.6'
is_local = False
is_remote = False
if len(sys.argv) == 1:
is_local = True
p = process(local_file)
libc = ELF(local_libc)
elif len(sys.argv) > 1:</