適合讀者:漏洞分析員、程序員、***愛好者
前置知識:端口複用技術,C語言基本語法 腳本小子:如何在溢出後獲得安全的、隱蔽的Shell是你們一直都在討論的問題,由於如今的防火牆和各類安全軟件漫天飛,想不被它們發現還真是很難,幸虧有不少牛人們用本身的實力探 |
適合讀者:漏洞分析員、程序員、***愛好者
前置知識:端口複用技術,C語言基本語法
腳本小子:如何在溢出後獲得安全的、隱蔽的Shell是你們一直都在討論的問題,由於如今的防火牆和各類安全軟件漫天飛,想不被它們發現還真是很難,幸虧有不少牛人們用本身的實力探索出了一條這樣的道路,讓咱們這些人能順着前輩的步伐一點點進步。本文給出了兩種目前比較先進的端口複用技術,用在溢出後的端口綁定和Shell的獲取,目前防火牆和各類安全工具對這樣的技術仍是陌生的,能夠預見又一波新的技術浪潮即將在網絡這片海洋上咆哮!
絕對突破防火牆
文/圖 dangguai27
其實很早就想寫點東西了,可總是以爲本身對於事物的研究不深刻,寫了會讓人笑話。這一次坐臥不安,把最近關於溢出技術中端口利用的體會寫出來,還但願你們給予指點。
溢出後端口利用的缺陷
以 前學習網絡課程的時候,只是瞭解了端口和應用層服務之間的對應關係。後來對安全方面逐漸有了興趣,再經過學習些系統底層的東西,進一步瞭解端口和進程是怎 樣映射的。再後來,接觸了緩衝區溢出,步步深刻,同時也更多地涉及到了端口的使用……呵呵,以爲我在說本身的成長史吧?
回 到正題,在溢出技術(這裏暫時都指堆棧溢出)中,傳統的端口利用方式大體有兩種:一種是普通***所採用的,***成功之後,在對方機器上駐留一段服務程序, 而***者做爲客戶端,服務端經過一個端口打開鏈接資源,等待客戶端鏈接。另外一種方式是反彈***所採用的,在本方機器打開一個端口,做爲服務端,而對方機器 做爲客戶端,***成功後,客戶端會主動鏈接服務端。
對於前一種方式,防火牆對進入本機的數據包進行相應的策略設置,就能輕易的截獲掉***數據包,從而避免本機信息本***者獲取。
後一種方式,通常的我的防火牆的默認策略設置忽略了對於本機向外界發送的數據包的檢測,所以即使是安裝了防火牆,也可以進行鏈接。但這種方式也並不是無懈可擊,只要讓防火牆對本機向外界的端口範圍進行限制,這類***一樣也能夠被避免。例如,***成功之後,***者在本機開了777端口等待對方來鏈接,可是若是對方爲了不反彈***的***,對防火牆對本機訪問網絡的端口作了限制,如圖1所示:
圖1 天網我的防火牆對於本機外連的設置
當只容許訪問本機訪問外界的80如下端口時,咱們讓對方鏈接咱們開放的777端口的但願就會化爲泡影。而且在反彈鏈接時對方防火牆會給出以下告警(如圖2所示):
圖2 防火牆給出的訪問非法端口的告警信息
儘管通常用戶對於我的放火牆這樣設置的狀況很少,但一旦遇到,***就不會成功。
基於上述端口利用方式的缺陷,如今出現了另外一種新的利用方式,即San在xcon2004(2004焦點峯會)中提到的複用當前鏈接的端口利用方式。這裏的端口利用方式分爲端口的重複綁定和從新綁定兩類。本文中我不打算討論ShellCode的具體編寫,由於這方面的資料網上實在太多,我主要從實現方法這個角度來討論。
突破防火牆限制一:複用當前端口
這種方式相對後面介紹的從新綁定端口而言要容易實現一些。在Winsock的實現中,對於服務器開放端口大可能是能夠重複綁定的。
這裏舉一個例子,某機器上開放了WWW服務,端口爲80。若是該主機存在IIS溢出漏洞,則***者發送***代碼到該主機並使其溢出後,採起的利用方式是在ShellCode中重複綁定對方80端口,而且使用函數Setsockopt()對套接字的屬性進行設置,這裏將第3個參數設置爲SO_REUSEADDR而非SO_EXCLUSIVEADDRUSE。緣由是這樣的,SO_REUSEADDR表示若是80端口沒有被獨佔的話,則能夠重複綁定;而SO_EXCLUSIVEADDRUSE則表示只容許80端口綁定一次,可是對方www服務並無掛掉,仍然佔用着80端口,咱們再次綁定確定失敗。
綁定成功之後,對方機器上打開CMD輸入netstat –an命令能夠看到有兩個IP綁定着80端口,如圖3所示:
圖3 重複綁定80端口
這樣綁定以後,若是外界鏈接該主機的80端口,則使用ShellCode中綁定的那個套接字。剩下的事情就只是利用該鏈接來爲***者作哪一種服務而已了,能夠綁定到Cmd,也能夠上傳、下載文件。在附帶的代碼中,我寫了一個用高級語言實現的重複綁定80端口,而後傳輸上傳並執行文件Sample.exe的C/S示例。
因而可知,重複幫定端口的方式的特色是,溢出成功後,直接在原來的進程中重複綁定當前服務開放的端口。
這裏也有一些問題,好比135、139端口是不能重複綁定的,這是因爲對應的服務可能設置了SO_EXCLUSIVEADDRUSE。此外,***者應該注意將咱們的功能和原來的服務區別開來。實現起來,只需先判斷接收到的數據包是不是咱們想要的數據,若是是則按照咱們預約的方式處理。若是不是咱們想要的,則經過127.0.0.1傳送給真正的應用,這也在附帶的代碼中有所實現。
突破防火牆限制二:從新綁定當前端口
這種方式與第一種有所不一樣,實現起來也更爲複雜。因爲135、139端口是不能重複綁定的,所以,要想從新利用當前端口,可行的方法就是先將當前進程結束,再綁定原端口。基本思路是這樣,但問題是,怎樣實如今系統進程中既要本身結束當前進程又要成功地從新綁定原端口呢?實現的方法以下:
1.溢出成功之後,在ShellCode中調用CreateProcess()爲當前進程建立一個Suspend模式的子進程,這裏第6個參數設置爲CREATE_SUSPENDED。
2.調用函數GetThreadContext()來得到子進程中主線程的上下文結構和寄存器信息。
3.調用VirtualAllocEx()在子進程裏分配內存。
4.把ShellCode指令用WriteProcessMemory()來寫入子進程剛纔分配的空間。這裏的ShellCode指令指ShellCode中在從新綁定端口之後將要用到的部分,它的功能能夠是綁定Cmd,也能夠是傳輸文件。
5.調用SetThreadContext()把GetThreadContext()得到的EIP修改指向VirtualAllocEx()分配的內存地址,這樣作的目的是讓子進程的主線程結束後當即跳到咱們的ShellCode指令中執行。
6.接下來就是調用ResumeThread()恢復Suspend模式的進程並立刻調用TerminateProcess()結束當前進程。
這樣就達到了從新綁定原端口,135、139端口均不例外。然而還有一個問題是,子進程對應的執行程序是什麼呢?答案很簡單,固然是Cmd.exe,由於在Windows 2000之後的各系統版本中都存在Cmd.exe。並且更合適的是,Cmd有一個參數是 /c,表示「運行完指令後終止」,這樣就剛好符合了要求其主線程很快結束的需求。實現起來,只須要將CreateProcess()第2參數設置爲如「cmd.exe /c dir」一類的形式就能夠了。
至此,從新綁定端口的過程結束,***者能夠遠端鏈接,而後執行要要的功能。不管是綁定Cmd,仍是傳輸文件,都是經過原來進程開放的端口進行,防火牆是不會阻截。在附帶的代碼中也有對應的高級語言模擬從新綁定19800端口的示例,測試是隻須要連續兩次telnet ip 19800便可。
後記
上面介紹了溢出技術中端口利用的各類方式,側重點在實現方法上,也敘述了在實現過程當中須要注意的一些問題,但願對感興趣的朋友有所幫助。附帶代碼中的模擬過程都是基於高級語言的,通過屢次測試都是成功的。至於彙編實現以及轉變爲ShellCode的生成這裏沒有談及,可是相信從方法上掌握了之後,實現起來也不會是很困難。端口重複綁定和從新綁定以及Socket查找的ShellCode編寫在之後的討論中進行。
(文中涉及的程序及源代碼已收錄到雜誌配套光盤「雜誌相關」欄目,按文章名查找便可)
|