Stalking a reporter – behind the scenes!

Introduction
Around mid-October we got a call from a reporter working on an article covering online privacy and social media. Rather than writing about others, the reporter wanted to have his own story. So, he asked NVISO to research him on-line, and find out as much as possible about him! Of-course, after agreeing on some “ground rules” with the journalist, we were 100% up for it!

The ground rules that were put in place:

  • We would focus on mining only publicly available information, not make him a target of an attack.
  • We were not allowed to use social engineering tricks on him or his friends and family to get additional information.
  • In other words: we could use any information already available online, without actively asking for more.

The article that was recently published by the journalist can be found online (Dutch only, sorry!): http://www.nieuwsblad.be/cnt/dmf20171107_03174488. For anyone interested in the “behind the scenes” on how we approached this – keep on reading!

Let’s hunt!

The team that stalks together…

We assembled a small group of volunteers and got to the task. We created a repository to collectively track our findings, as all bits of information would help the other researchers to move further on their own search, or validate information pieces gathered from different sources. The starting point was obvious: We had the journalists’ name, the email address he used to propose the experiment and a phone number on his signature. Plenty of information to start from!

The first step was to find his Facebook profile. We quickly found out that the reporter does not use the combination name + last name as the profile name, making it more difficult to track down the profile (assuming that he actually has a Facebook profile 😊). But as it often happens, some friends had mentioned his full name on publicly tagged Facebook pictures. We knew his face now! After that, identifying his own profile was possible by looking at metadata in the pictures, including the tagged friends. From there on we started building our file. The privacy settings for the profile were (unfortunately for us) quite restrictive… luckily for us that was not the case for all his friends!

Screen Shot 2017-11-14 at 14.57.36

Facebook showing profile picture after you’ve entered a wrong password

We found his personal email account by guessing and trying to login with the email account to Facebook. Facebook shows you your profile picture when you say that you forgot your password. That is how we could link his personal email with Facebook. We correctly guessed that he also used this email for other social media and apps, and used the same method to see of he had an account. From there onwards, figuring which other services he was using was easy. From there we could gather additional interests, routines, professional activities, social relations…

Of course, this kind of research leads to many false positives. In our case, someone with the same name happens to live close by to our reporter, and some of our data actually referred to that person. That is where crossing data from different sources comes in handy. It allows to discard some of the bits that don’t really match the puzzle.

During our investigations, we also discovered details on the ex-girlfriend of the journalist – her online activity proved to be an excellent source of information! Prolific Instagrammer, her account gave us a lot of info about travels they did together, pictures, friends… Why do we know she was his ex? They are not friends on Facebook anymore! We got no juicy stuff about the breakup, though.

With the parents name (which we found in a cached document on Google), we could find their house, pets, and social media accounts with additional clues… We could assemble a fairly decent family tree. We were also able to find his home address.

With these results we got back to our reporter. He was quite surprised by the things we found out without directly approaching him or his friends! He found particularly scary what we found out about his family and his ex-girlfriend.  He was surprised, though, not seeing his birthdate on our data list.

One step further … go phishing
After our initial investigations, we mutually agreed to take it one step further. 

So what did we do ? We created a fake Facebook profile to trick him or his friends into sharing additional information, contacting his parent or just some good, old phishing to get his credentials and access his email account. We opted for the last option.

We crafted an email based on his interests (which we already identified during the first part of the research). We sent him a link that sounded very relevant for him, so he would definitely try to check it it. And it worked, even though he knew he was going to be targeted by us in this time window. He clicked, and he was directed to a google authentication page. Google? Well, actually NVISO-owned, Google-looking. That is how we got his password.

Once we gain access to his account, we stopped the game. We called him and showed him we were in by sending a mail via his own private inbox to his work email. The challenge was completed. We left nicely, whiteout reading his emails.

Untitled

Emailing from within the inbox of the reporter to the reporter (yes, this is a dummy screenshot!)

In a meeting afterwards, we explained him how he was phished. Up till then he had no clue how he had given us his credential! But we have to confess: still, we didn’t get his birthdate.

Conclusion
Most people aren’t too surprised anymore about the wealth of information available on each of us online. What is interesting, though, is how often we believe we are fine, just because we have our privacy settings nicely set and reviewed for all our accounts (as was the case with the journalists’ Facebook profile for example). That old account you forgot you had, the friends that tagged you, the university bulletin, a legal document or a nice note in memoriam of a loved one can give most valuable information to anyone who is interested.

Entering the active reconnaissance part, phishing once again proved a very reliable method to get additional details from a target – in our case, it even gave us full access to the journalists’ mailbox.

We are all on-line. Most of our life is these days, and that is not necessarily a bad thing. But it is important to remember that, despite all privacy and security rules we want to enforce, humans are still the weakest link. Understanding how we share information online and the impact it has on us and others is key in an increasingly digitalised world – we are happy to have contributed to the article & hope to have raised some awareness with the readers!

 

KRACKing WPA2

A new vulnerability in the WPA2 protocol was discovered by Mathy Vanhoef (researcher at KU Leuven) and published yesterday. The vulnerability – dubbed  “KRACK” – enables an attacker to intercept WPA2 encrypted network traffic between a client device (e.g. mobile or laptop) and a router. Depending on the network configuration it is even possible for an attacker to alter or inject data. Since the vulnerability lies in the WPA2 protocol, most platforms are susceptible to the attack. However, the impact is even higher on Android 6.0+ and Linux devices due to their specific implementation of WPA2.

The original publication can be found at https://www.krackattacks.com, with full details, a demonstration of the attack, and recommendations.

How does it work?

The KRACK vulnerability can be exploited by using Key Reinstallation AttaCKs. When a device wants to connect to a wireless access point, the WPA2 protocol will use a 4-way handshake. Part of this handshake consists of an acknowledgment that is sent from the client device to the wireless access point to ensure the client has successfully received the signed key. However, until the wireless access point has received the acknowledgment, it will continuously retransmit the signed key. If the attacker is able to block the acknowledgement from being sent to the wireless access point, the attacker is able to record and replay the signed key, which ensures the reinstallation of an already used key on the client’s device. As soon as the key is installed, it will be used to encrypt the network traffic between the client and the wireless access point. Since the attacker knows the keystream, he is able to decrypt the network traffic.

Since this attack exploits a vulnerability in the four-way handshake, all WPA versions are vulnerable.

Are all devices vulnerable?

Since this vulnerability is found in the WPA2 protocol, all platforms, such as Windows, Linux, MacOs, iOs, OpenBSD and Android can be targeted. Linux and Android 6.0+ devices are especially vulnerable, because the WiFi client will clear the encryption key from memory after installation. If the Android device is told to reinstall they key, the cleared out key will be installed, which is actually an all-zero key. This makes it trivial for an attacker to intercept and inject or alter data sent by these devices.

Does this mean that we need to stop using WPA2?

Although an attacker is able to intercept traffic and in some cases traffic can be altered or injected, this attack can only be performed when the attacker is in close proximity of the client’s device and wireless access point.

If the attacker has successfully exploited this vulnerability, traffic over TLS, such as HTTPS or VPN traffic, will not be accessible to the attacker.

What should we do? 

When this vulnerability was discovered, it was first disclosed to various vendors. Many vendors (e.g. Microsoft, Cisco) have already released patches for this issue. Install the available patches on all your devices or contact your vendors to see if a patch is available. A list with all patches per vendor can be found on https://www.kb.cert.org/vuls/byvendor?searchview&Query=FIELD+Reference=228519.

Furthermore, it is strongly advised to only use encrypted connections, such as HTTPS or a VPN connection, when sensitive content is transmitted over WiFi networks.

Additionally, watch out for rogue access point in your surroundings, office buildings.

More information? 

NVISO analysts are still working on additional research and will update this blogpost with any results.

Should you require additional support, please don’t hesitate to contact our 24/7 hotline on +32 (0) 588 43 80 or csirt@nviso.be.

If you are interested in receiving our advisories via our mailing list, you can subscribe by sending us an e-mail at csirt@nviso.be.

YARA DDE rules: DDE Command Execution observed in-the-wild

The MS Office DDE YARA rules that we published yesterday detected several malicious documents samples since 10/10/2017.

Remark: the malicious samples we mention were detected with our DDEAUTO rule (Office_DDEAUTO_field); as we feared, the second rule (Office_DDE_field) is generating some false positives and we will update it.

The first sample uses PowerShell to download an executable and run it. With zipdump.py and our YARA rules we can extract the command, and with sed command “s/<[^>]*>//g” we can remove the XML tags to reveal the command:

The second sample is using PowerShell with a second stage DLL (we were not able to recover the DLL):

As could be expected, we also observed many samples that are not truly malicious, but just the samples of persons experimenting with DDE code execution starting 10/10/2017. This could also be the case for the “DLL sample”.

Finally, we observed a malicious campaign spoofing emails from the U.S. Securities and Exchange Commission (SEC)’s EDGAR filing system with .docx attachments abusing DDE code execution.

This campaign used compromised government servers to serve a PowerShell second stage script:

Leveraging compromised government servers increases the success of such campaigns, because of the implied trust associated with government servers.

Talos published an extensive analysis for this campaign. We observed the same samples, and also a sample (email attachment) from the same campaign that uses pastebin to host the second stage:

Should you have to analyze the next stages, know that they are PowerShell scripts that have been compressed and BASE64 encoded. Here is one method to extract these scripts:

New IOCs:

  • bf38288956449bb120bae525b6632f0294d25593da8938bbe79849d6defed5cb
  • 316f0552684bd09310fc8a004991c9b7ac200fb2a9a0d34e59b8bbd30b6dc8ea

Detecting DDE in MS Office documents

Dynamic Data Exchange is an old Microsoft technology that can be (ab)used to execute code from within MS Office documents. Etienne Stalmans and Saif El-Sherei from Sensepost published a blog post in which they describe how to weaponize MS Office documents.

We wrote 2 YARA rules to detect this in Office Open XML files (like .docx):

Update 1: our YARA rules detected several malicious documents in-the-wild.

Update 2: we added rules for OLE files (like .doc) and updated our OOXML rules based on your feedback.

// YARA rules Office DDE
// NVISO 2017/10/10 - 2017/10/12
// https://sensepost.com/blog/2017/macro-less-code-exec-in-msword/
 
rule Office_DDEAUTO_field {
  strings:
    $a = /<w:fldChar\s+?w:fldCharType="begin"\/>.+?\b[Dd][Dd][Ee][Aa][Uu][Tt][Oo]\b.+?<w:fldChar\s+?w:fldCharType="end"\/>/
  condition:
    $a
}
 
rule Office_DDE_field {
  strings:
    $a = /<w:fldChar\s+?w:fldCharType="begin"\/>.+?\b[Dd][Dd][Ee]\b.+?<w:fldChar\s+?w:fldCharType="end"\/>/
  condition:
    $a
}

rule Office_OLE_DDEAUTO {
  strings:
    $a = /\x13\s*DDEAUTO\b[^\x14]+/ nocase
  condition:
    uint32be(0) == 0xD0CF11E0 and $a
}

rule Office_OLE_DDE {
  strings:
    $a = /\x13\s*DDE\b[^\x14]+/ nocase
  condition:
    uint32be(0) == 0xD0CF11E0 and $a
}

These rules can be used in combination with a tool like zipdump.py to scan XML files inside the ZIP container with the YARA engine:

The detection is based on regular expressions designed to detect fields containing the word DDEAUTO or DDE. By dumping the detected YARA strings with option –yarastringsraw, one can view the actual command:

Here is an example of the DDE rule firing:

You can also look for MS Office files containing DDE using this YARA rule in combination with ClamAV as described in this blog post.

YARA rules for CCleaner 5.33

First reported by Talos and Morphisec, the compromise of CCleaner version 5.33 is still making news.

At NVISO Labs, we created YARA detection rules as soon as the news broke, and distributed these rules to our clients subscribed to our NVISO Security Advisories. In a later blog post, we will explain in detail how to create such YARA rules, so that you can do the same for your organization.

Here are the YARA rules we created:

// YARA rules compromised CCleaner
// NVISO 2017/09/18
// http://blog.talosintelligence.com/2017/09/avast-distributes-malware.html

import "hash"

rule ccleaner_compromised_installer {
	condition:
		filesize == 9791816 and hash.sha256(0, filesize) == "1a4a5123d7b2c534cb3e3168f7032cf9ebf38b9a2a97226d0fdb7933cf6030ff"
}

rule ccleaner_compromised_application {
	condition:
		filesize == 7781592 and hash.sha256(0, filesize) == "36b36ee9515e0a60629d2c722b006b33e543dce1c8c2611053e0651a0bfdb2e9" or
		filesize == 7680216 and hash.sha256(0, filesize) == "6f7840c77f99049d788155c1351e1560b62b8ad18ad0e9adda8218b9f432f0a9"
}

rule ccleaner_compromised_pdb {
	strings:
		$a = "s:\\workspace\\ccleaner\\branches\\v5.33\\bin\\CCleaner\\Release\\CCleaner.pdb" 
		$b = "s:\\workspace\\ccleaner\\branches\\v5.33\\bin\\CCleaner\\ReleaseTV\\CCleaner.pdb" 
	condition:
		uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and ($a or $b)
}

You can scan the C: drive of a computer with YARA like this:

yara64.exe -r ccleaner.yara C:\

And there are also many other scanning tools that include the YARA engine, like ClamAV.

Hunting

The first 2 rules we created are hash based, but the third rule (ccleaner_compromised_pdb) is based on a particular string found in CCleaner’s 32-bit executables. This string is the full path of the Program Database (PDB) file, a debug file created by default by Visual Studio and referenced in compiled executables.

With this rule, we were able to identify 235 files on VirusTotal. Most of these are actually container files (like ZIP files): CCleaner is a popular application, and is distributed through various channels other than Piriform’s website. We saw examples of portable application packages distributing this compromised version of CCleaner (like LiberKey) and also RAR files with pirated versions of CCleaner.

23 files were actual executables, and were all compromised versions of the 32-bit executable of CCleaner version 5.33, except one. Most of these files did not have a (valid) signature: they were modified versions, e.g. cracked and infected with other malware.

Only one executable detected by our ccleaner_compromised_pdb rule was not infected: an executable with SHA256 hash c48b9db429e5f0284481b4611bb5b69fb6d5f9ce0d23dcc4e4bf63d97b883fb2. It turns out to be a 32-bit executable of CCleaner version 5.33, digitally signed on 14/09/2017, e.g. after Talos informed Avast/Piriform. The build number was increased with one (6163 instead of 6162). This executable was signed with the same certificate that was used for the compromised version 5.33 (thumbprint f4bda9efa31ef4a8fa3b6bb0be13862d7b8ed9b0), and also for follow-up version 5.34. Yesterday (20/9/2017), Piriform finally released a new version (5.35) signed with a new digital certificate obtained yesterday.

At this moment, we are uncertain about the origins and purpose of this particular executable (c48b9db429e5f0284481b4611bb5b69fb6d5f9ce0d23dcc4e4bf63d97b883fb2).

Are you infected?

Our rules allow you to detect compromised CCleaner executables in your environment, but this does not imply that the machines identified by these rules were infected.

Our analysis shows that the compromised CCleaner installer (version 5.33) will install 32-bit and 64-bit versions of the CCleaner executables on a Windows 64-bit machine, and only the 32-bit version on a Windows 32-bit machine.

The shortcuts (like Start and Desktop shortcuts) deployed during the install on Windows 64-bit machines will point to the 64-bit executable, hence normal usage on a Windows 64-bit machine will execute 64-bit CCleaner.

Only the 32-bit executable of CCleaner is compromised.

It is therefore perfectly possible that compromised 32-bit executables of CCleaner are detected on Windows 64-bit machines with the YARA rules we provided, but that this compromised version was never executed.

If the compromised 32-bit executable runs successfully, it will create the following registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Piriform\Agomo

Two values will be found for this key: MUID and TCID

Conclusion

We recommend that you check for the presence of this registry key, should our YARA rules detect compromised CCleaner installations on your machines.

Compromised machines should be reinstalled after a DFIR investigation.

Active exploitation of Struts vulnerability S2-052 CVE-2017-9805

Yesterday night (06 September 2017 UTC) we observed active exploitation of Struts vulnerability S2-052 CVE-2017-9805 (announced a day earlier).

Here is the request we observed:

The POST request to /struts2-rest-showcase/orders/3 allowed us initially to detect this attempt.

The packet capture shows that this is a full exploit attempt for reconnaissance purposes: the payload is a /bin/sh command to execute a silent wget command to a compromised Russian website (it includes the name of the scanned site as query). The downloaded content is discarded.

The XML data used in this exploit attempt is slightly different from the Metasploit module for CVE-2017-9805: XML element ibuffer is represented as <ibuffer/> in this exploit attempt, while it is represented as <ibuffer></ibuffer> in the proposed Metasploit module. Both forms are functionally equivalent.

We did find an older version of this script that is used in this attack here. This shows how fast attackers attempt to abuse newly discovered vulnerabilities using (potentially unverified) exploits.

The source of this request is the same compromised Russian website, it is the first time we observe exploit attempts for CVE-2017-9805. We saw no other requests from this source since this attempt.

We would recommend everyone to keep an eye out for this type of behavior in their web server logs. As always, we won’t hesitate to share any additional observations we make. Should you observe suspicious behavior and would like to receive additional support, please don’t hesitate to get in touch with our experts!

 

Decoding malware via simple statistical analysis

Intro

Analyzing malware often requires code reverse engineering which can scare people away from malware analysis.

Executables are often encoded to avoid detection. For example, many malicious Word documents have an embedded executable payload that is base64 encoded (or some other encoding). To understand the encoding, and be able to decode the payload for further analysis, reversing of the macro code is often performed.

But code reversing is not the only possible solution. Here we will describe a statistical analysis method that can be applied to certain malware families, such as the Hancitor malicious documents. We will present this method step by step.

Examples

First we start with a Windows executable (PE file) that is BASE64 encoded. In BASE64 encoding, 64 different characters are used to encode bytes. 64 is 6 bits, hence there is an overhead when encoding in BASE64, as encoding one byte (8 bits) will require 2 BASE64 characters (6 bits + 2 bits).

With byte-stats.py, we can generate statistics for the different byte values found in a file. When we use this to analyze our BASE64 encoded executable, we get this output:

20170818-121549

In the screenshot above see that we have 64 different byte values, and that 100% of the byte values are BASE64 characters. This is a strong indication that the data in file base64.txt is indeed BASE64 encoded.

Using the option -r of byte-stats.py, we are presented with an overview of the ranges of byte values found in the file:

20170818-121603

The identified ranges /0123456789, ABCDEFGHIJKLMNOPQRSTUVWXYZ and abcdefghijklmnopqrstuvwxyz (and single charcter +) confirm that this is indeed BASE64 data. Padded BASE64 data would include one or two padding characters at the end (the padding character is =).

Decoding this file with base64dump.py (a BASE64 decoding tool), confirms that it is a PE file (cfr. MZ header) that is BASE64 encoded.

20170818-121639

Now, sometimes the encoding is a bit more complex than just BASE64 encoding.

Let’s take a look at another sample:

20170818-134020.png

The range of lowercase letters, for example, starts with d (in stead of a) and ends with } (in stead of z). We observer a similar change for the other ranges.

It looks like all BASE64 characters have been shifted 3 positions to the right.

We can test this hypothesis by subtracting 3 from every byte value (that’s shifting 3 positions to the left) and analyzing the result. To subtract 3 from every byte, we use program translate.py. translate.py takes a file as input and an arithmetic operation: operation “byte – 3” will subtract 3 from every byte value.

This is the result we get when we perform a statistical analysis of the byte values shifted 3 positions to the left:

20170818-140557

In the screenshot above we see 64 unique bytes and all bytes are BASE64 characters. When we try to decode this with base64dump, we can indeed recover the executable:

20170818-141640

Let’s move on to another example. Malicious documents that deliver Hancitor malware use an encoding that is a bit more complex:

20170818-141220

This time, we have 68 unique byte values, and the ranges are shifted by 3 positions when we look at the left of a range, but they appear to be shifted by 4 positions when we look at the right of a range.

How can this be explained?

One hypothesis, is that the malware is encoded by shifting some of the bytes with 3 positions, and the other bytes with 4 positions. A simple method is to alternate this shift: the first byte is shifted by 3 positions, the second by 4 positions, the third again by 3 positions, the fourth by 4 positions, and so on …

Let’s try out this hypothesis, by using translate.py to shift by 3 or 4 positions depending on the position:

20170818-142338

Variable position is an integer that gives the position of the byte (starts with 0), and position % 2 is the remainder of dividing position by 2. Expression position % 2 == 0 is True for even positions, and False for uneven positions. IFF is the IF Function: if argument 1 is true, it returns argument 2, otherwise it returns argument 3. This is how we can shift our input alternating with 3 and 4.

But as you can see, the result is certainly not BASE64, so our hypothesis is wrong.

Let’s try with shifting by 4 and 3 (instead of 3 and 4):

20170818-142729

This time we get the ranges for BASE64.

Testing with base64dump.py confirms our hypothesis:

20170818-142903

Conclusion

Malware authors use encoding schemes that can be reverse engineered by statistical analysis and testing simple hypotheses. Sometimes a bit of trial and error is needed, but these encoding schemes can be simple enough to decode without having to perform reverse engineering of code.