New ICS Attack Framework “TRITON” targeting Critical Infrastructure

 In APT, Backdoor, Breach, Business, Exploits, Malware, News, SCADA, Threat Intelligence

Mandiant recently responded to an incident at a critical infrastructure organization where an attacker deployed malware designed to manipulate industrial safety systems. The targeted systems provided emergency shutdown capability for industrial processes. We assess with moderate confidence that the attacker was developing the capability to cause physical damage and inadvertently shutdown operations. This malware, which we call TRITON, is an attack framework built to interact with Triconex Safety Instrumented System (SIS) controllers. We have not attributed the incident to a threat actor, though we believe the activity is consistent with a nation state preparing for an attack.

TRITON is one of a limited number of publicly identified malicious software families targeted at industrial control systems (ICS). It follows Stuxnet which was used against Iran in 2010 and Industroyer which we believe was deployed by Sandworm Team against Ukraine in 2016. TRITON is consistent with these attacks, in that it could prevent safety mechanisms from executing their intended function, resulting in a physical consequence.

Malware Family Main Modules Description
TRITON trilog.exe Main executable leveraging libraries.zip
library.zip Custom communication library for interaction with Triconex controllers.

Table 1: Description of TRITON Malware

Incident Summary

The attacker gained remote access to an SIS engineering workstation and deployed the TRITON attack framework to reprogram the SIS controllers. During the incident, some SIS controllers entered a failed safe state, which automatically shutdown the industrial process and prompted the asset owner to initiate an investigation. The investigation found that the SIS controllers initiated a safe shutdown when application code between redundant processing units failed a validation check — resulting in an MP diagnostic failure message.

We assess with moderate confidence that the attacker inadvertently shutdown operations while developing the ability to cause physical damage for the following reasons:

  • Modifying the SIS could prevent it from functioning correctly, increasing the likelihood of a failure that would result in physical consequences.
  • TRITON was used to modify application memory on SIS controllers in the environment, which could have led to a failed validation check.
  • The failure occurred during the time period when TRITON was used.
  • It is not likely that existing or external conditions, in isolation, caused a fault during the time of the incident.

To know more about Fireeye’s good analysis, follow: https://www.fireeye.com/blog/threat-research/2017/12/attackers-deploy-new-ics-attack-framework-triton.html

If you are just looking for Indicators of Compromise:

First, a YARA rule made by nicholas.carr@itsreallynick:

rule TRITON_ICS_FRAMEWORK
{
meta:
author = “nicholas.carr @itsreallynick”
md5 = “0face841f7b2953e7c29c064d6886523”
description = “TRITON framework recovered during Mandiant ICS incident response”
strings:
$python_compiled = “.pyc” nocase ascii wide
$python_module_01 = “__module__” nocase ascii wide
$python_module_02 = “<module>” nocase ascii wide
$python_script_01 = “import Ts” nocase ascii wide
$python_script_02 = “def ts_” nocase ascii wide

$py_cnames_01 = “TS_cnames.py” nocase ascii wide
$py_cnames_02 = “TRICON” nocase ascii wide
$py_cnames_03 = “TriStation ” nocase ascii wide
$py_cnames_04 = ” chassis ” nocase ascii wide

$py_tslibs_01 = “GetCpStatus” nocase ascii wide
$py_tslibs_02 = “ts_” ascii wide
$py_tslibs_03 = ” sequence” nocase ascii wide
$py_tslibs_04 = /import Ts(Hi|Low|Base)[^:alpha:]/ nocase ascii wide
$py_tslibs_05 = /module\s?version/ nocase ascii wide
$py_tslibs_06 = “bad ” nocase ascii wide
$py_tslibs_07 = “prog_cnt” nocase ascii wide

$py_tsbase_01 = “TsBase.py” nocase ascii wide
$py_tsbase_02 = “.TsBase(” nocase ascii wide

$py_tshi_01 = “TsHi.py” nocase ascii wide
$py_tshi_02 = “keystate” nocase ascii wide
$py_tshi_03 = “GetProjectInfo” nocase ascii wide
$py_tshi_04 = “GetProgramTable” nocase ascii wide
$py_tshi_05 = “SafeAppendProgramMod” nocase ascii wide
$py_tshi_06 = “.TsHi(” ascii nocase wide

$py_tslow_01 = “TsLow.py” nocase ascii wide
$py_tslow_02 = “print_last_error” ascii nocase wide
$py_tslow_03 = “.TsLow(” ascii nocase wide
$py_tslow_04 = “tcm_” ascii wide
$py_tslow_05 = ” TCM found” nocase ascii wide

$py_crc_01 = “crc.pyc” nocase ascii wide
$py_crc_02 = “CRC16_MODBUS” ascii wide
$py_crc_03 = “Kotov Alaxander” nocase ascii wide
$py_crc_04 = “CRC_CCITT_XMODEM” ascii wide
$py_crc_05 = “crc16ret” ascii wide
$py_crc_06 = “CRC16_CCITT_x1D0F” ascii wide
$py_crc_07 = /CRC16_CCITT[^_]/ ascii wide

$py_sh_01 = “sh.pyc” nocase ascii wide

$py_keyword_01 = ” FAILURE” ascii wide
$py_keyword_02 = “symbol table” nocase ascii wide

$py_TRIDENT_01 = “inject.bin” ascii nocase wide
$py_TRIDENT_02 = “imain.bin” ascii nocase wide

condition:
2 of ($python_*) and 7 of ($py_*) and filesize < 3MB
}

Update 28 Dec 2017 – YARA Rule update

/*
* DESCRIPTION: Yara rules to match the known binary components of the HatMan
* malware targeting Triconex safety controllers. Any matching
* components should hit using the “hatman” rule in addition to a
* more specific “hatman_*” rule.
* AUTHOR: DHS/NCCIC/ICS-CERT
*/

/* Globally only look at small files. */

private global rule hatman_filesize : hatman {
condition:
filesize < 100KB
}

/* Private rules that are used at the end in the public rules. */

private rule hatman_setstatus : hatman {
strings:
$preset = { 80 00 40 3c 00 00 62 80 40 00 80 3c 40 20 03 7c
?? ?? 82 40 04 00 62 80 60 00 80 3c 40 20 03 7c
?? ?? 82 40 ?? ?? 42 38 }
condition:
$preset
}
private rule hatman_memcpy : hatman {
strings:
$memcpy_be = { 7c a9 03 a6 38 84 ff ff 38 63 ff ff 8c a4 00 01
9c a3 00 01 42 00 ff f8 4e 80 00 20 }
$memcpy_le = { a6 03 a9 7c ff ff 84 38 ff ff 63 38 01 00 a4 8c
01 00 a3 9c f8 ff 00 42 20 00 80 4e }
condition:
$memcpy_be or $memcpy_le
}
private rule hatman_dividers : hatman {
strings:
$div1 = { 9a 78 56 00 }
$div2 = { 34 12 00 00 }
condition:
$div1 and $div2
}
private rule hatman_nullsub : hatman {
strings:
$nullsub = { ff ff 60 38 02 00 00 44 20 00 80 4e }
condition:
$nullsub
}
private rule hatman_origaddr : hatman {
strings:
$oaddr_be = { 3c 60 00 03 60 63 96 f4 4e 80 00 20 }
$oaddr_le = { 03 00 60 3c f4 96 63 60 20 00 80 4e }
condition:
$oaddr_be or $oaddr_le
}
private rule hatman_origcode : hatman {
strings:
$ocode_be = { 3c 00 00 03 60 00 a0 b0 7c 09 03 a6 4e 80 04 20 }
$ocode_le = { 03 00 00 3c b0 a0 00 60 a6 03 09 7c 20 04 80 4e }
condition:
$ocode_be or $ocode_le
}
private rule hatman_mftmsr : hatman {
strings:
$mfmsr_be = { 7c 63 00 a6 }
$mfmsr_le = { a6 00 63 7c }
$mtmsr_be = { 7c 63 01 24 }
$mtmsr_le = { 24 01 63 7c }
condition:
($mfmsr_be and $mtmsr_be) or ($mfmsr_le and $mtmsr_le)
}
private rule hatman_loadoff : hatman {
strings:
$loadoff_be = { 80 60 00 04 48 00 ?? ?? 70 60 ff ff 28 00 00 00
40 82 ?? ?? 28 03 00 00 41 82 ?? ?? }
$loadoff_le = { 04 00 60 80 ?? ?? 00 48 ff ff 60 70 00 00 00 28
?? ?? 82 40 00 00 03 28 ?? ?? 82 41 }
condition:
$loadoff_be or $loadoff_le
}
private rule hatman_injector_int : hatman {
condition:
hatman_memcpy and hatman_origaddr and hatman_loadoff
}
private rule hatman_payload_int : hatman {
condition:
hatman_memcpy and hatman_origcode and hatman_mftmsr
}

/* Actual public rules to match using the private rules. */

rule hatman_compiled_python : hatman {
condition:
hatman_nullsub and hatman_setstatus and hatman_dividers
}
rule hatman_injector : hatman {
condition:
hatman_injector_int and not hatman_payload_int
}
rule hatman_payload : hatman {
condition:
hatman_payload_int and not hatman_injector_int
}
rule hatman_combined : hatman {
condition:
hatman_injector_int and hatman_payload_int and hatman_dividers
}
rule hatman : hatman {
meta:
author = “DHS/NCCIC/ICS-CERT”
description = “Matches the known samples of the HatMan malware.”
condition:
hatman_compiled_python or hatman_injector or hatman_payload
or hatman_combined
}

Category type value
Payload delivery filename trilog.exe
Payload delivery md5 6c39c3f4a08d3d78f2eb973a94bd7718
Payload delivery filename imain.bin
Payload delivery md5 437f135ba179959a580412e564d3107f
Payload delivery md5 0544d425c7555dc4e9d76b571f31f500
Payload delivery filename inject.bin
Payload delivery md5 0face841f7b2953e7c29c064d6886523
Payload delivery filename library.zip
Payload delivery filename TS_cnames.pyc
Payload delivery md5 e98f4f3505f05bf90e17554fbc97bba9
Payload delivery filename TsBase.pyc
Payload delivery md5 288166952f934146be172f6353e9a1f5
Payload delivery md5 27c69aa39024d21ea109cc9c9d944a04
Payload delivery filename TsHi.pyc
Payload delivery md5 f6b3a73c8c87506acda430671360ce15
Payload delivery filename TsLow.pyc
Payload delivery md5 8b675db417cc8b23f4c43f3de5c83438
Payload delivery filename sh.pyc
External analysis attachment Fig4.png
Payload delivery sha1 dc81f383624955e0c0441734f9f1dabfe03f373c
External analysis link https://www.virustotal.com/file/e8542c07b2af63ee7e72ce5d97d91036c5da56e2b091aa2afe737b224305d230/analysis/1513264635/
Payload delivery md5 6c39c3f4a08d3d78f2eb973a94bd7718
Payload delivery sha256 e8542c07b2af63ee7e72ce5d97d91036c5da56e2b091aa2afe737b224305d230

Here is a Source code repository for TRISIS TRITON HATMAN

https://github.com/ICSrepo/TRISIS-TRITON-HATMAN/
https://github.com/ICSrepo/TRISIS-TRITON-HATMAN/tree/master/decompiled_code

References:

https://www.fireeye.com/blog/threat-research/2017/12/attackers-deploy-new-ics-attack-framework-triton.html

Header image from securityzap.com

Recommended Posts

Start typing and press Enter to search