Showing blog posts from April 2022

rss

Industroyer2 IEC-104 Analysis

The Industroyer2 malware was hardwired to attack a specific set of electric utility substations in Ukraine. It seems to have been custom built to open circuit breakers, which would effectively cut the power from the substation.

Industroyer2

After connecting to an RTU in a substation the malware would immediately start changing the outputs at specific addresses without first having to enumerate which IOAs that were available on the targeted device. This custom-built malware seems to know what IOAs to use at each station, as well as what type of output each specific IOA controls.

UPDATE 2022-04-26

Upon popular demand we've decided to release three PCAP files with IEC-104 traffic from our own sandbox execution of the Industroyer2 malware. Please feel free to use these capture files to verify our findings using any tool of your choice. The capture files can be downloaded from here:
https://www.netresec.com/files/Industroyer2-Netresec.zip

These PCAP files are shared under a CC BY 4.0 license, which allows you to redistribute them as long as you give appropriate credit.

UPDATE 2022-04-29

A PNG image in the original CERT-UA security alert #4435 turned out to actually include the IOAs targeted by the non-public 108_100.exe Industroyer2 version. The IOAs disclosed in CERT-UAs alert have now been included in this blog post as well.

Backstory

I was looking at a public sandbox execution of a presumed Industroyer2 malware sample two weeks ago. At first glance the malware sample, which was named “40_115.exe”, didn't do much. It just printed the text below to the console and then terminated the process.

19:46:06:0106> T281 00006800
19:46:06:0247> RNM 0015
19:46:06:0294> 10.82.40.105: 2404: 3
19:46:06:0294> T65 00006800
19:46:06:0341> 10.82.40.105 M68B0 SGCNT 44
19:46:06:0497> RNM 0015
19:46:06:0544> T113 00006800
19:46:06:0544> 192.168.122.2: 2404: 2
19:46:06:0544> 192.168.122.2 M68B0 SGCNT 8
19:46:06:0591> RNM 0015
19:46:06:0653> 192.168.121.2: 2404: 1
19:46:06:0700> 192.168.121.2 M68B0 SGCNT 16
19:46:21:0747> 192.168.122.2 M6812
19:46:21:0747> 10.82.40.105 M6812
19:46:21:0794> 192.168.121.2 M6812

I later noticed that it also sent TCP SYN packets to three different RFC1918 addresses, but never received a response.

Industroyer2 trying to connect to TCP port 2404 on 10.82.40.105, 192.168.122.2 and 192.168.121.2 in Wireshark

Image: Wireshark showing Industroyer2 trying to reach TCP port 2404

TCP port 2404 is used by the SCADA protocol IEC 60870-5-104, also known as IEC-104, which is primarily used to monitor and control electricity transmission and distribution systems. IEC-104 is also the only Industrial Control System (ICS) protocol implemented in Industroyer2 according to ESET. The previous version of Industroyer, which was used to cut the power in Ukraine in 2016, additionally supported the IEC 61850 and OPC DA protocols according to the CRASHOVERRIDE report from Dragos.

Industroyer2's IEC-104 client didn't receive any SYN+ACK response in the sandbox execution I was looking at, so I couldn't tell what it was trying to do. I therefore decided to set up my own sandbox with a built-in IEC-104 server (also known as a slave, RTU or IED). My sandbox execution confirmed that Industroyer2 was indeed trying to communicate with these three IP addresses using IEC-104. I also noticed that it was very specific about which outputs (or IOAs) it wanted to access on those servers in order to turn these outputs either ON or OFF.

Station Address 1 at 192.168.121.2

The Industroyer2 malware spawned three separate threads when started, one thread for each IEC-104 server to contact. The malware would communicate with all three servers in parallel if all of them were available. However, in order to simplify my analysis I decided to only respond to one of the IPs at a time, starting with IP address 192.168.121.2.

The thread that connected to IP address 192.168.121.2 toggled all outputs between 1250 and 1265 to OFF at Station Address 1 (also known as “ASDU address” or “common address”). Judging from the command type used (ID 46 with short pulse duration) these outputs likely control circuit breakers, which are used to disconnect the power from an electric utility substation.

IEC-104 traffic to 192.168.121.2 in NetworkMiner

Image: PCAP file with IEC-104 traffic to 192.168.121.2 in NetworkMiner

Station Address 2 at 192.168.122.2

On 192.168.122.2 the malware targeted station address 2, where it toggled outputs between 1101 and 1108 to OFF.

IEC-104 traffic to 192.168.122.2 in NetworkMiner

Image: PCAP file with IEC-104 traffic to 192.168.122.2 in NetworkMiner

Station Address 3 at 10.82.40.105

The malware toggled a great deal of outputs on 10.82.40.105, which had station address 3. But in contrast to the other stations, many of these outputs were toggled to the “ON” state rather than “OFF”.

IEC-104 traffic to 10.82.40.105 in NetworkMiner

Image: PCAP file with IEC-104 traffic to 10.82.40.105 in NetworkMiner

Yet, after setting those outputs to “ON” it proceeded with setting outputs to “OFF” for several other IOAs on station address 3.

IEC-104 traffic to 10.82.40.105 in NetworkMiner

Image: PCAP file with IEC-104 traffic to 10.82.40.105 in NetworkMiner

In each thread Industroyer2 paused for approximately 3 seconds between each accessed IOA. This delay seems to have been hard coded since the malware didn't seem to care whether or not the IEC-104 server responded with an OK message, such as ACT or ACTTERM, or an error message, like “unknown common address of ASDU”. Each thread would simply proceed with setting an IOA every 3 seconds no matter what the server responded.

The specific order in which the IOAs were accessed was also very deterministic, the exact same sequence of IOAs was used every time. I verified this behavior by running the malware multiple times as well as by comparing my results to an execution of the same sample on a different sandbox (thanks for the PCAP Joe and Dan).

What Did the Attackers Know?

The fact that the malware toggled these specific outputs, rather than just randomly turning outputs ON or OFF, indicates that the threat actors had technical knowledge about the specific substation(s) they were attacking. Not only did the attackers know the IP addresses, station addresses and IOAs of each targeted output. They also knew what ASDU Type ID to use for each respective output. For IOA 1101 to 1404 the Type ID 46 was used (also known as "double command" or C_DC_NA_1) while for IOAs from 130202 and above it used Type ID 45 (also known as “single command” or C_SC_NA_1).

As you can see in the previous screenshots, NetworkMiner nicely parses and presents the IEC-104 commands issued by Industroyer2. But I noticed that the malware also printed all sent and received commands to the console when executed. For example, the following output was printed to the console by the Industroyer2 thread communicating with station address 2 on 192.168.122.2:

11:51:56:0163> T65 00006800
11:51:56:0201> RNM 0003
11:51:56:0241> 192.168.122.2: 2404: 2
11:51:56:0267> 192.168.122.2 M68B0 SGCNT 8
11:51:56:0297> 192.168.122.2 M6813

The string “192.168.122.2: 2404: 2” above reveals that “2404” is the target port and “2” is the station address. The “SGCNT 8” string additionally tells us that there were 8 outputs to be toggled on that station. The other two stations had SGCNT 16 and 44.

The malware also printed very detailed information about each sent and received IEC-104 command, such as in the example below where the output at IOA 1104 was successfully turned off at station address 2 (here referred to as “ASDU:2”).

MSTR ->> SLV 192.168.122.2:2404
  x68 x0E x02 x00 x08 x00 x2E x01 x06 x00 x02 x00 x50 x04 x00 x05

  I |Length:16 bytes | Sent=x1 | Received=x4
  ASDU:2 | OA:0 | IOA:1104 |
  Cause: (x6) | Telegram type: (x2E)

MSTR <<- SLV 192.168.122.2:2404
  x68 x0E x08 x00 x04 x00 x2E x01 x47 x00 x02 x00 x50 x04 x00 x05

  I |Length:16 bytes | Sent=x4 | Received=x2
  ASDU:2 | OA:0 | IOA:1104 |
  Cause: (x47) | Telegram type: (x2E)

Note that the Type ID values were also logged to the console by Industroyer2, but it used the term “Telegram type” instead of “Type ID”.

Static Analysis

The following three Unicode strings can be found in the 40_115.exe binary:

10.82.40.105 2404 3 0 1 1 PService_PPD.exe 1 "D:\OIK\DevCounter" 0 1 0 0 1 0 0 44 130202 1 0 1 1 1 160921 1 0 1 1 2 160923 1 0 1 1 3 160924 1 0 1 1 4 160925 1 0 1 1 5 160927 1 0 1 1 6 160928 1 0 1 1 7 190202 1 0 1 1 8 260202 1 0 1 1 9 260901 1 0 1 1 10 260902 1 0 1 1 11 260903 1 0 1 1 12 260904 1 0 1 1 13 260905 1 0 1 1 14 260906 1 0 1 1 15 260907 1 0 1 1 16 260908 1 0 1 1 17 260909 1 0 1 1 18 260910 1 0 1 1 19 260911 1 0 1 1 20 260912 1 0 1 1 21 260914 1 0 1 1 22 260915 1 0 1 1 23 260916 1 0 1 1 24 260918 1 0 1 1 25 260920 1 0 1 1 26 290202 1 0 1 1 27 338501 1 0 1 1 28 1401 0 0 0 1 29 1402 0 0 0 1 30 1403 0 0 0 1 31 1404 0 0 0 1 32 1301 0 0 0 1 33 1302 0 0 0 1 34 1303 0 0 0 1 35 1304 0 0 0 1 36 1201 0 0 0 1 37 1202 0 0 0 1 38 1203 0 0 0 1 39 1204 0 0 0 1 40 1101 0 0 0 1 41 1102 0 0 0 1 42 1103 0 0 0 1 43 1104 0 0 0 1 44
192.168.122.2 2404 2 0 1 1 PService_PPD.exe 1 "D:\OIK\DevCounter" 0 1 0 0 1 0 0 8 1104 0 0 0 1 1 1105 0 0 0 1 2 1106 0 0 0 1 3 1107 0 0 0 1 4 1108 0 0 0 1 5 1101 0 0 0 1 6 1102 0 0 0 1 7 1103 0 0 0 1 8
192.168.121.2 2404 1 0 1 1 PService_PPD.exe 1 "D:\OIK\DevCounter" 0 1 0 0 1 0 0 16 1258 0 0 0 1 1 1259 0 0 0 1 2 1260 0 0 0 1 3 1261 0 0 0 1 4 1262 0 0 0 1 5 1265 0 0 0 1 6 1252 0 0 0 1 7 1253 0 0 0 1 8 1254 0 0 0 1 9 1255 0 0 0 1 10 1256 0 0 0 1 11 1257 0 0 0 1 12 1263 0 0 0 1 13 1264 0 0 0 1 14 1250 0 0 0 1 15 1251 0 0 0 1 16

After having analyzed the IEC-104 traffic from the binary it's obvious that this is the IEC-104 configuration that has been hard-coded into the binary. For example, the substring “10.82.40.105 2404 3” in the first Unicode string refers to the IP, port and station number of the first target.

The “16 1258 [...]” section in the third Unicode string above tells us that there are 16 outputs configured for station address 1, where the first one to be set is at IOA 1258. Thus, we can easily verify that all accessed IOAs on all three stations were hard-coded into the binary.

Additional Substations Targeted

The malware sample I've analyzed has the following properties:

  • Filename: 40_115.exe
  • MD5: 7c05da2e4612fca213430b6c93e76b06
  • SHA1: fdeb96bc3d4ab32ef826e7e53f4fe1c72e580379
  • SHA256: d69665f56ddef7ad4e71971f06432e59f1510a7194386e5f0e8926aea7b88e00
  • Compiled: 2022-03-23 10:07:29 UTC

But there is an additional Industroyer2 sample called “108_100.exe” (MD5 3229e8c4150b5e43f836643ec9428865), which has been mentioned by ESET as well as CERT-UA. I haven't been able to access that binary though, so I don't yet know which IP addresses it was designed to target. However, a few screenshots [1] [2] [3] published by ESET reveal that the 108_100.exe malware sample was hard coded to access 8 different station addresses, 5 of which were on the 10.0.0.0/8 network and 3 on the 192.168.0.0/16 net. An image in CERT-UA's alert #4435 from April 12 reveals the targeted IOAs for these 8 stations.

Targets hard-coded in 108_100.exe ordered by station address:

  • SA#1, 192.x.x.x, 12 IOAs (1101-1104, 1201-1204, 1301-1304)
  • SA#2, 10.x.x.x, 12 IOAs (1101-1104, 1201-1204, 1301-1304)
  • SA#3, 192.x.x.x, 18 IOAs (1103-1104, 1201-1204, 1301-?, 38601-38607)
  • SA#4, 10.x.x.x, 34 IOAs (16501, 16603, 26502, 38507-38513, 38519-38524 and more...)
  • SA#5, 192.x.x.x, 10 IOAs (1101-1103, 1201-1204, 1301-1303)
  • SA#6, 10.x.x.x, 8 IOAs (1101-1104, 1201-1204)
  • SA#7, 10.x.x.x, 8 IOAs (1101-1104, 1201-1204)
  • SA#8, 10.x.x.x, 8 IOAs (1101-1104, 1201-1204)

We can compare those station addresses, IP addresses and IOAs to the ones targeted by the 40_115.exe sample, which was analyzed in this blog post.

  • SA#1, 192.168.121.2, 16 IOAs (1250-1265)
  • SA#2, 192.168.122.2, 8 IOAs (1101-1108)
  • SA#3, 10.82.40.105, 44 IOAs (1101-1104, 1201-1204, 1301-1304, 1401-1404, 130202, 160921-160928, 190202, 260202, 260901-260920, 290202, 338501)

There doesn't seem to be any overlap across the two sets (except for possibly station address 1 which is on the 192.x.x.x network in both configs but has different IOAs). This indicates that the 108_100.exe Industroyer2 version was hard coded to attack a different set of targets than the 40_115.exe sample that I've analyzed.

More ICS blog posts from Netresec

If you'd like to find our earlier work in the field of ICS/SCADA security, then check out these (slightly older but still very relevant) blog posts:

Posted by Erik Hjelmvik on Monday, 25 April 2022 10:35:00 (UTC/GMT)

Tags: #IEC-104#60870-5-104#ICS#ICS#SCADA#PCAP#RFC1918

Short URL: https://netresec.com/?b=224e357


NetworkMiner 2.7.3 Released

NetworkMiner 2.7.3

NetworkMiner now extracts meterpreter payloads from reverse shells and performs offline lookups of JA3 hashes and TLS certificates. Our commercial tool, NetworkMiner Professional, additionally comes with a packet carver that extracts network packets from memory dumps.

Extraction of Meterpreter Payloads

NetworkMiner 2.7.3 supports extraction of meterpreter DLL payloads from reverse shell TCP sessions deployed with Metasploit. The free version of NetworkMiner will try to extract the meterpreter DLL from TCP sessions going to "poker-hand ports" commonly used for meterpreter sessions, such as 3333, 4444, 5555, etc. The port-independent protocol detection feature available in NetworkMiner Professional additionally enables extraction of meterpreter DLLs regardless which LPORT the attacker specifies when deploying the reverse shell.

Meterpreter DLL extracted from PCAP file in NetworkMiner Professional

Image: Meterpreter DLL extracted from DFIR Madness' case001.pcap

Packet Carving in NetworkMiner Professional

If you try to open anything other than a PCAP, PcapNG or ETL file in NetworkMiner Professional, then you'll be presented with an option to carve packets from the opened file as of this release.

NetworkMiner Unknown Capture File Format

The packet carver can extract packets from any structured or unstructured data, such as memory dumps and proprietary packet capture formats. NetworkMiner Pro's carver is a simplified version of the packet carving feature in CapLoader.

Loading the 1GB "memdump.mem" from Ali Hadi's Challenge #1 - Web Server Case into NetworkMiner Professional takes roughly five seconds, during which 612 packets get extracted.

NetworkMiner Professional with packets extracted from memory dump

Image: Information about network hosts carved from memory dump

In this scenario the memory was dumped on the 192.168.56.101 host, which NetworkMiner identifies as "WIN-L0ZZQ76PMUF". The carved packets also indicate that this computer had an outgoing TCP connection to 192.168.56.102, which appears to be a Linux machine called "kali". As you can see in the screenshot, the packets carved from the memory dump also reveal a great deal about other hosts on the network, such as the 192.168.56.1 host, which seems to be a Windows 7 machine called "IT104-00".

Offline Matching of JA3 and X.509 hashes

NetworkMiner 2.7.3 comes with a local copy of the SSL Certificate and JA3 Fingerprint Blacklists from the awesome abuse.ch project. JA3 hashes and extracted X.509 certificates are matched against these lists in order to see if they are associated with any piece of malware or botnet.

Here's one example showing the default Cobalt Strike certificate being identified as "AKBuilder C&C", since that's how it is listed in abuse.ch's SSL certificate database.

CobaltStrike default X.509 certificate

Image: Cobalt Strike's default certificate identified as "AKBuilder C&C"
PCAP: Cobalt Strike PCAP from malware-traffic-analysis.net

The port-independent protocol detection feature in NetworkMiner Professional additionally enables X.509 certificates to be extracted even from non-standard TLS ports, such as this certificate, which is identified as "BitRAT" with help of the abuse.ch certificate block-list.

NetworkMiner Professional with BitRAT TLS traffic

Image: Both X.509 certificate and JA3 hash identified as BitRAT
PCAP: BitRAT PCAP from Joe Sandbox

The client's JA3 hash 8515076cbbca9dce33151b798f782456 is also associated with BitRAT according to abuse.ch.

DBSBL Lookup Detection

DNSBL services are used by servers handling incoming email to verify that the sender's IP address isn't a known SPAM sender and that it isn't from a network that shouldn't be sending emails.

But DNSBL services can also be used by malware and botnets, such as TrickBot and Emotet, to verify that the public IP of a victim is allowed to send emails and that it hasn't already been blacklisted for sending SPAM. We have therefore decided to add DNSBL lookups to the Host Details section in NetworkMiner 2.7.3.

DNSBL lookups in NetworkMiner

Image: TrickBot victim checks if its public IP is blocked by DNSBL services
PCAP: TrickBot PCAP from malware-traffic-analysis.net

DNSBL lookups are also logged to the "Parameters" tab of NetworkMiner.

NetworkMiner with DNSBL parameters

Image: NetworkMiner's Parameters tab with "DNSBL" filter
PCAP: TrickBot PCAP from malware-traffic-analysis.net

Additional Features and Updates

We'd also like to mention some additional new features, bug fixes and improvements that have been included in this new release.

  • Support for HTTP CONNECT request method to extract artifacts like X.509 certificates and JA3 hashes from HTTPS traffic passing through a web proxy.
  • Traffic to TCP ports 3000 and 8000 are now configured to be parsed as HTTP by default in order to handle WEBrick traffic.
  • Improved extraction of SMTP credentials.
  • JA3 hashes were previously incorrect for clients that supported more than one EC point format (RFC 8422). This has now been fixed.
  • Support for SLL2 (Linux cooked capture v2) frames.
  • Improved handling of concurrent GUI events, for example when poking around in the "Hosts" tab while loading a PCAP file or doing live sniffing.
  • NetworkMiner's GUI no longer reloads between each PCAP file when multiple files are loaded at once.

New Features in NetworkMiner Professional

We have also added a few new features exclusively to NetworkMiner Professional, which is the commercial version of NetworkMiner. Apart from the packet carver feature, mentioned earlier in this blog post, we've also updated the collection of OSINT lookup services available in the GUI. One of the newly added services is Ryan Benson's unfurl, which picks apart URLs to reveal data that might have been encoded into a complex URL. The unfurl lookup can be found by right-clicking an URL in NetworkMiner Professional's "Browsers" tab and selecting the "Lookup URL" sub menu.

Other OSINT services that we've added are FileScan.IO and JoeSandbox lookups of extracted files. These lookups can be performed by right clicking a file in the "Files" tab and opening the sub-menu called "Lookup Hash".

Lookup of file hash on JoeSandbox

Image: OSINT lookup of an EXE file extracted from network traffic

The command-line version of NetworkMiner Professional, NetworkMinerCLI, has also been updated to allow extracted information to be printed directly on standard output instead of logging everything to files. Here is an example showing this feature while running NetworkMinerCLI in Linux (with help of Mono):

mono /opt/NetworkMinerProfessional_2-7-3/NetworkMinerCLI.exe -r 2022-03-14-Qakbot-with-Cobalt-Strike-and-VNC-module.pcap -w /tmp/malware -X FileInfos | cut -d, -f 5,9
"s2Fmok83x.zip.html","ba2ef33c7aef593f95d261b6f4406b39"
"nexus.officeapps.live.com.cer","373ccffe30d3477867642abab723a351"
"Microsoft RSA TLS CA 01.cer","806f1c72f6d67c9c114eff43d3d84100"
"nexusrules.officeapps.live.c.cer","4c08442740cb020d457a5df16be406ff"
"Microsoft RSA TLS CA 02.cer","65d17ecae5798c79db8e840fe98a53b9"
"6537991.dat.exe","124207bc9c64e20e114bcaeabde12a4e"
"6537991.dat.exe","ca7ef367c935182a40a95b9ad8b95f42"
"6537991.dat.exe","a9a8366fa6be54b45ca04192ca217b75"
[...]

The command above extracts files from a PCAP file, which contains traffic from a Windows PC infected with Qbot. The "-w" switch specifies the output directory for the files extracted from network traffic, and the "-X FileInfos" specifies that metadata for these files should be sent to STDOUT instead of being written to log files. The cut utility was used to show only the filename (column 5) and MD5 hash (column 9) of the file info output.

The MD5 hashes of the extracted files confirm that this is indeed a Qbot infection:

  • 124207bc9c64e20e114bcaeabde12a4e (VT)
  • ca7ef367c935182a40a95b9ad8b95f42 (VT)
  • a9a8366fa6be54b45ca04192ca217b75 (VT)

NetworkMinerCLI previously printed some information about the parsing process to STDOUT. That output has now been moved to STDERR in order to provide the "-X [type]" output with exclusive access to STDOUT.

Credits

We'd like to thank Michael Taggart for noticing that NetworkMiner previously failed to parse HTTP traffic to ports 3000 and 8000.

Upgrading to Version 2.7.3

Users who have purchased NetworkMiner Professional can download a free update to version 2.7.3 from our customer portal, or use the “Help > Check for Updates” feature. Those who instead prefer to use the free and open source version can grab the latest version of NetworkMiner from the official NetworkMiner page.

Posted by Erik Hjelmvik on Monday, 04 April 2022 06:52:00 (UTC/GMT)

Tags: #NetworkMiner#carve#JA3#X.509#JoeSandbox#CobaltStrike#Cobalt Strike#DNSBL#TrickBot#Emotet#PIPI#Protocol Detection#OSINT#NetworkMinerCLI

Short URL: https://netresec.com/?b=22479d5