<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    原文地址:http://drops.wooyun.org/tips/9650

                    (本文純屬虛構,如有雷同,實屬巧合)

                    大名鼎鼎的AspxSpy,罹患間歇性木馬病而被白道追殺。大權在握的系統管理員,冷笑著把這位老兄打入了十八層地獄。拒絕訪問,組件錯誤……連最寶貴的命令執行都要封殺。是可忍孰不可忍!拿上小饅頭,我閉關數月。

                    國慶悄然而至,滿街地小姐們穿著爆乳裝,齊P小短裙(學名硬得快)擠來擠去,中國首位本土科學家獲得了諾貝爾獎,我靜靜地呆在家中,把這漫長的歷練一一道來,以饗讀者。

                    0x00 詞匯約定


                    非專業術語,僅供娛樂:

                    Shell:這里指類似于命令提示符的,一個用于運行可執行文件的C#頁面。

                    本機代碼:與托管代碼對應。

                    0x01 *外殺馬


                    和* 外真是有緣,這不,最近又偶遇* 外的服務器,規模約莫二十上下。向來服務器的安全檢測,也有不少無法獲得最高權限的情形,但這次最令人困惑的,是無論如何也無法在Shell中執行命令。管理員,你在挑逗我么?不想讓我知道其中的奧妙,為何又留下了一個漏洞?給管理員戴好可愛的綠帽后,我搜遍系統,終于發現裝神弄鬼的,是一個小小驅動——*外殺馬。

                    圖1 *外殺馬

                    圖2 IDA中的*外殺馬

                    一個名為NotifyRoutine的函數引起了我的興趣。這是一個回調函數,它的偽代碼如下:

                    void __stdcall NotifyRoutine(HANDLE ParentId, HANDLE ProcessId, BOOLEAN Create)
                    {
                    // …
                      ProcessHandle = ProcessId;
                      v66 = ProcessId;
                      if ( Create && PsLookupProcessByProcessId(ParentId, &Object) >= 0 )
                      {
                        v3 = (const char *)PsGetProcessImageFileName(Object);
                        if ( !stricmp(v3, "w3wp.exe") || (v4 = (const char *)PsGetProcessImageFileName(Object), !stricmp(v4, "php-cgi.exe")) )
                        {
                          v5 = 1;
                          PsLookupProcessByProcessId(ProcessId, &TokenHandle);
                    // …
                    

                    圖3 NotifyRoutine

                    DriverEntry注冊NotifyRoutine的偽代碼如下:

                    int __stdcall sub_407000(int a1, int a2)
                    {
                    // …
                      DbgPrint("加載*外驅動.\n");
                      PsSetCreateProcessNotifyRoutine(NotifyRoutine, 0);
                    // …
                      return dword_405248(dword_4056BC, a1, a2, &v3, &v7, 0); 
                    }
                    

                    圖4 PsSetCreateProcessNotifyRoutine

                    NotifyRoutine的流程很簡單,最重要的分支如下:

                    (1) 判斷是否創建了進程

                    (2) 是,則判斷是否由w3wp.exe所創建

                    (3) 是,則與白名單比較。

                    (4) 中止所有不在白名單上的進程

                    (5) 給用戶返回“拒絕訪問”的提示

                    白名單為硬編碼,主要放行了.Net編譯器的命令,否則源代碼就無法在線編譯執行了。它允許的命令:

                    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe
                    C:\\WINDOWS\\Microsoft.NET\\Framework\\v4.0.30319\\csc.exe”
                    ……
                    

                    它還允許System用戶(SID為S-1-5-18)執行C:\WINDOWS\system32\cmd.exe等命令。

                    所有命令都帶有完整路徑,如果擁有足夠的權限(如提權成功后),可將存在于白名單且系統中一般不存在的命令替換為你的工具,如:

                    C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc.exe
                    C:\\WINDOWS\\Microsoft.NET\\Framework\\v3.5\\csc.ex
                    …
                    

                    替換后的命令在Shell中可正常執行,僅會在C盤根目錄下的日志中留下一條NotKill記錄。

                    判斷系統中是否存在*外殺馬,一看C盤根目錄是否存在 7i24_com_FreeHostKill_vxxx.txt的日志文件,二看system32\drivers下是否存在FreeHostKill.sys,三看注冊表。

                    總之,*外殺馬不僅僅殺馬,它是什么人都殺。它只是一個極其原始的防火墻,通過監控所有進程的創建,在白名單的控制之下,哪怕位高權重的Administrators組用戶也無法在Shell中執行命令。

                    0x02 光明而曲折的破解之路


                    道高一尺,魔高一丈,既然明白了原理,就來嘗試如何破解吧。

                    我不知道是否有人在低權限的腳本環境中有辦法躲過驅動的監控,如果有,那真要頂禮膜拜了。

                    我不是圣人,還是按照通常的思路來完成我的Shell:

                    (1) 不創建進程

                    (2) 不創建線程

                    (3) 直接使用Shell代碼將用戶提升至最高權限

                    前途是光明的,道路是曲折的。只要有人嘗試了這條路,很快就會出現更多的探索者,期待更多的奇思妙想的出現。

                    許多漏洞Exploit都采用了vc++編寫,因此最初的做法是弄清漏洞的原理后,使用C#語法逐行重寫這些源代碼。十多天磨練下來,唯一的感受就是——痛苦,九九八十一重的煉獄也不過如此。

                    重寫內容 對人的摧殘度 說明
                    API DllImport API、結構、常數,PInvoke站點提供查詢
                    C++指針 IntPtr
                    托管內存與非托管內存的數據交換 Marshal類支持
                    內嵌匯編 ShellCode,召喚請叫我雷鋒的人

                    好想開個遵義會議,讓人指出一條明路。日夜google中,終于一個家伙說,使用dll封裝你的代碼吧。神啊,如此有創意的點子,為何不是我想出來的呢?

                    醍醐灌頂之后,本人的血壓暫時飆升到160,刷刷刷地把main函數改名導出,兩分鐘內dll封裝完畢,真是無本生意的典范。看導演的安排,接下的劇情無非就是千里狙敵,褲襠藏雷,開著21世紀的R2概念車去欺負剛擺脫叢林文化的小膏藥旗了。

                    可惜天亮了,美夢成空,為了讓大伙不再走我的老路,我把那些令人欲仙欲死的問題總結如下:

                    (1) Wow64麻煩

                    省略幾千字,我把它放到了本系列篇(三)中加以詳述。

                    (2) LoadLibrary加載DLL提示無法找到模塊

                    在本機上正常加載的DLL,天殺的虛擬機卻提示無法找到模塊。這是因為操作系統缺少DLL所依賴的運行庫文件。若不想把自己的寶貝工具弄得像超生游擊隊,只有想辦法把庫代碼直接封裝進DLL中。我使用兩種方式來解決:

                    (1)右鍵打開項目的屬性,C/C++ - 代碼生成 – 運行庫 – 將/MD選項改為/MT(或/MTd)選項。再次編譯,立刻發現生成的dll臃腫了不少,問題解決。

                    (2)把源代碼放到vc6下編譯。我首先嘗試利用vs2015環境來輔助vc6的編譯。不曾想捅了一個危險的馬蜂窩,彈出了一大串與頭文件有關的警告和錯誤,想來微軟也懶得保持那代價高昂的兼容性了。前后折騰了半小時,乖乖放棄。接著切換到vs2010環境,無須任何的修改,vc6順利完成編譯,問題解決。

                    在vc6中如何編譯64位程序?山寨某前輩的經驗給懶漢們參考一下:(以vs2010為例)

                    分為3個步驟:

                    創建64位環境

                    在開始菜單下點擊“Visual Studio 2010 – Visual Studio Tools – Visual Studio x64 兼容工具命令提示(2010)”,然后在此命令提示符中運行VC6:

                    D:\vc\vc6common\MSDev98\Bin\MSDEV.EXE /useenv

                    圖5 x64 兼容工具命令提示

                    修改配置

                    復制Release或Debug的配置,起名xx64,激活該配置。(1、Build – Configurations – Add…;2、Build – Set Active Configuration…)

                    圖6 新建Win32 Debug64配置

                    修改項目配置

                    1、在“Project Settings”對話框中, 點擊“General”標簽. 在“Output directories”, 在“Intermediate files” 和“Output files”輸入框中, 鍵入“Debug64”(無引號)

                    圖7 設置輸出路徑

                    2、在“C/C++”標簽上, “Debug info”下拉列表中, 選擇“Program database”(參數選項對應是 /Zi)

                    圖8 設置調試信息

                    3、在“Link”標簽上, “Project options”的輸入框中, 將“/machine:I386”改為“/machine:AMD64”(命令中將出現兩個不同的/machine)

                    圖9 設置編譯指令

                    編譯后成功得到大腹便便的64位dll。

                    (3) w3wp.exe遇到無法處理的異常,網站崩潰

                    我的破壞力還蠻大的。把本機調試通過的程序放到服務器上運行,瞬間弄崩了網站,重啟IIS后再執行幾次,服務器藍屏死機。

                    代碼基本未變,我只是把它封裝在DLL中,由w3wp.exe加載運行,怎么就崩潰了呢。長夜漫漫,無心睡眠,在迷糊中把IIS 7應用程序池從集成模式調整為經典模式后,異常莫明地消失了。比爾,你想玩死人么 ?集成與經典模式到底是怎么一回事?

                    圖10 集成模式處理管道

                    八股文常常引用上圖說明IIS7的集成模式。IIS 7集成了ASP.NET運行庫,使用統一的管道來處理請求。經典模式兼容了IIS 6,如下圖所示,處理ASP.NET動態請求的只是IIS的一個插件——ISAPI模塊。同理,PHP插件只處理PHP請求,它們各司其職,互不干涉。兩種模式的差別涇渭分明。

                    圖11 經典模式處理流程

                    還有一些值得閱讀的入門文檔,如《ASP.NET Application Life Cycle Overview for IIS 7.0》,概述了ASP.NET應用程序在生命周期里發生了什么事情。《IIS Modules Overview》主要說明模式及其配置方式。從IIS 7的模塊界面可以看到,集成模式使用托管代碼模塊來處理.aspx頁面的請求,而經典模式使用本機代碼模塊。

                    圖12 請求處理模塊

                    書讀了不少,按流行俚語,“然而這并沒有什么ruan用”,還缺少某種催化劑,看來我只能再次求助于Windbg了。

                    使用kp命令查看異常發生時的調用棧,前后幾十個調用,秘密就隱藏在它們中間。仔細觀察兩種模式,為了運行我的代碼,最后都從托管環境轉入了非托管環境,非托管環境下的調用完全相同。完蛋了,究竟要從哪里下手哇。咬咬牙,開始跟吧,十多天下來,人比黃花瘦。

                    今天是個好日子,我升級了。我察覺自己又犯了老毛病,沒有認真檢查關鍵語句的運行結果。

                    if (x)
                    {
                        // y
                    }
                    

                    經典模式下x為真,這符合預期,然而在操蛋的集成模式下為假,稍不留神就忽略了。再追溯x的來源,終于發現集成模式似乎由于緩存的影響,對本機DLL的變化不能做出實時的更新。

                    解決起來簡單而粗暴,加個else直接返回錯誤提示。我并不介意多運行三兩次,誰讓它們不是我的機子呢,等集成模式睡醒了,更新了它的緩存,權限也到手了。

                    (4) w3wp.exe已提升為System權限,但Shell權限不變。

                    經過第三階段的苦戰,我的代碼終于可以穩定地運行了,但又出現了一個奇怪的現象。

                    在提升權限之前,查詢應用程序池的用戶:

                    圖13 提權前用戶

                    此時,75804號進程,即w3wp.exe擁有IIS_IUSRS用戶權限。緊接著提升權限,頁面顯示了執行結果:

                    圖14 Shell代碼提權

                    請忽略若干無用的調試信息,我們需要關注的是最后三行。w3wp.exe的進程號仍為75804(也可能會創建新的w3wp.exe),用戶權限已提升為SYSTEM。

                    讓我們再次查看此時應用程序池的用戶:

                    圖15 提權成功后用戶未變

                    怪哉?應用程序池的用戶為何沒有改變呢?

                    晚飯時間到了,補充足夠的能量后,我已經想到了一種可能。IIS啟用了模擬功能后,即使w3wp.exe以SYSTEM權限運行,應用程序池用戶仍保持不變。

                    為了驗證這種可能性,讓我們亮劍,它就是用來中斷模擬的API——RevertToSelf。美女現身,Beautiful!

                    圖16 強制中斷IIS模擬恢復用戶身份

                    0x03 勝利的號角

                    西元201x年,001號大殺器研制成功,為紀念cctv,我把它命名為cv51。

                    圖17 未能進入內核無權讀寫致出錯

                    首次執行出錯,不必理會,再次嘗試執行。

                    圖18 提權成功

                    cv51的兄弟cvbb此時運行在SYSTEM權限下,順利添加用戶tingting。

                    圖19 其他工具共享同一個w3wp.exe的權限

                    登錄服務器。任務管理器中,w3wp.exe(PID:22324)在提升權限后的身份可能顯示為SYSTEM,也可能保持不變。

                    圖20 模擬使任務管理器不能真實顯示Shell的權限

                    查看管理員的密碼,統計是否有使用強密碼的習慣,獲得的密碼僅用于學習與研究,將在24小時內刪除。上傳mimikatz,在命令提示符下執行如下命令,所有登錄用戶盡在日志中:(mimikatz是開源工具,請到官方站點下載,不吃毒蘋果)

                    mimikatz log privilege::debug sekurlsa::logonpasswords

                    圖21 mimikatz破解曾經登錄的用戶信息

                    以上測試在Windows 2003、2008及R2版本中通過。

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频