Posts

栈溢出 技术清单: shellcode:修改返回地址,指向溢出数据中的一段指令 return2libc:修改返回地址,指向内存中已有的某个函数 ROP:修改返回地址,指向内存中已有的一段指令 hijack GOT:修改某个被调用函数的地址,指向另一个函数 Shellcode ​ shellcode的存放位置可以是caller的栈帧(严格意义上不全是caller的栈帧,可以覆盖或超出),也可以是callee的栈帧,一般我们选择caller的栈帧,因为有时callee的栈帧太小了。 Payload构造 padding1 address of shellcode padding2 shellcode Q&A padding1里面数据是什么? padding1的数据可以任意填充,但最好不要包含’\x00’,可能会被检测为字符串末尾的’\0’最后造成截断。 padding1多长? 可以使用反汇编工具查看汇编代码来确定距离(静态) 可以使用调试工具(例如gdb)运行程序时不断增加输入长度的方法来试探(如果返回地址被无效地址例如“AAAA”覆盖,程序会终止并报错) shellcode的起始地址应该是多少? 我们可以在调试工具里查看返回地址的位置(可以查看 ebp 的内容然后再加4(32位机),参见前面关于函数状态的解释),**可是在调试工具里的这个地址和正常运行时并不一致,这是运行时环境变量等因素有所不同造成的。**https://www.mathyvanhoef.com/2012/11/common-pitfalls-when-writing-exploits.html所以这种情况下我们只能得到大致但不确切的 shellcode 起始地址,解决办法是在 padding2 里填充若干长度的 “\x90”。这个机器码对应的指令是 NOP (No Operation),也就是告诉 CPU 什么也不做,然后跳到下一条指令。有了这一段 NOP 的填充,只要返回地址能够命中这一段中的任意位置,都可以无副作用地跳转到 shellcode 的起始处,所以这种方法被称为 NOP Sled(中文含义是“滑雪橇”)。这样我们就可以通过增加 NOP 填充来配合试验 shellcode 起始地址。