#include <stdio.h> #include <math.h> void hijack_cinit() { printf("first running,hijack __cinit function\n"); } int g_a; int main(int argc, char* argv[]) { g_a = 100; //double f = sin(g_a); printf("Hello World! %f\n",g_a); hijack_cinit(); getchar(); return 0; }
void __cdecl initterm(void (__cdecl **pfbegin)(), void (__cdecl **pfend)()) { while ( pfbegin < pfend ) { if ( *pfbegin ) (*pfbegin)(); // 传入一个边界,传入保存地址的指针 然后每次+4 去调用 ++pfbegin; } }
char globalArrayA[5] = { 'A', 'A', 'A', 'A', 'A'}; char globalArrayB[5] = { 'B', 'B', 'B', 'B', 'B'}; //模拟信息泄露 void InfoLeak_Address() { printf("I'm Calling to InfoLeak Functions\n"); char *pointer = (char *)globalArrayA; CExploit *exp = new CExploit; printf("string:%s len is %d\n",pointer,strlen(pointer)); //模拟任意地址写漏洞,修改终止符,可以越界访问数组后面的数据 *(pointer + 5) = 0x1; *(pointer + 6) = 0x1; *(pointer + 7) = 0x1; printf("string:%s len is %d\n",pointer,strlen(pointer)); //构造对象,放置在数组globalArrayA的后方 memcpy(pointer + 5 + 1, (void *)exp, sizeof(CExploit)); //越界读取 DWORD dwModuleoffset = *(DWORD *)&globalArrayA[6]; /* .textbss:00401000 ; Input MD5 : 1626AC6E19A9D1D153E3980CE98838F2 .textbss:00401000 ; Input CRC32 : 7237D060 .textbss:00401000 .textbss:00401000 ; File Name : F:\work\code\TestCode\Exploit-study\Debug\Exploit-study.exe .textbss:00401000 ; Format : Portable executable for 80386 (PE) .textbss:00401000 ; Imagebase : 400000 .textbss:00401000 ; Section 1. (virtual address 00001000) .textbss:00401000 ; Virtual size : 00010000 ( 65536.) .textbss:00401000 ; Section size in file : 00000000 ( 0.) .textbss:00401000 ; Offset to raw data for section: 00000000 .textbss:00401000 ; Flags E00000A0: Text Bss Executable Readable Writable .textbss:00401000 ; Alignment : default .textbss:00401000 ; PDB File Name : F:\work\code\TestCode\Exploit-study\Debug\Exploit-study.pdb 相对模块起始地址的偏移 rdata:00423B1C ; const CExploit::`vftable' .rdata:00423B1C ??_7CExploit@@6B@ dd offset j_CExploit__GetPointer .rdata:00423B1C ; DATA XREF: CExploit__CExploit+2Eo .rdata:00423B1C ; CExploit___CExploit+26o .rdata:00423B20 dd offset j_CInterface__SetPointer .rdata:00423B24 dd offset j_CExploit__SetPointer .rdata:00423B28 db 0 .rdata:00423B29 db 0 .rdata:00423B2A db 0 .rdata:00423B2B db 0 */ //比较magic number ,如果一直说明是我们放置的对象,读取虚函数表,计算出模块的具体偏移 if (0x99978456 == *(DWORD *)&globalArrayA[6 + 4]) { //每个编译器编译出来的偏移可能都不一样,所以需要自己选择一个偏移 // VS2012 V120 + WIN7 X86 => 0x23b1c // VS2012 V110 + WIN7 X64 => 0x1d98c dwModuleoffset -= 0x1d98c; // ===> (const CExploit::`vftable')00423B1C - 400000 = 0x23b1c printf("info leak of address is 0x%x\n", dwModuleoffset); printf("GetModuleHandle:Getting address as current module is 0x%x\n\n", (DWORD)GetModuleHandle(NULL)); } delete exp; }
CWinApp theApp; using namespace std;
class CInterface { public: int m_flag; CInterface::CInterface(){ m_flag = 0x99978456;/*it's my magic number*/ } virtual int GetPointer(){ return m_flag; }; virtual int SetPointer(){ return m_flag; }; int TellMe(){ printf("Tell me ,What is flag ? %d\n", m_flag); return m_flag; } }; class CExploit : public CInterface { public: int m_pointer; int m_calc; char *pszArray; CExploit::CExploit() :m_pointer(0x7fffffff),pszArray(0){} CExploit::~CExploit() { if (pszArray) delete pszArray; } virtual int GetPointer() { return m_pointer; } virtual int SetPointer(int pointer){ m_pointer = pointer; return m_pointer; } int Calc(int x) { m_pointer = x * 0x79865 + 0x10111 - 0x7d63d; return m_pointer; } int CExpAllocBuff(int x){ m_pointer = Calc(x); pszArray = (char *)malloc(m_pointer); } };