By James Haughom, Antonis Terefos, Jim Walter, Jeff Cavanaugh, Nick Fox, and Shai Tilias
In a recent IR engagement, our team happened upon a rather interesting packer (aka crypter or obfuscator) that was ultimately utilized to construct and execute shellcode responsible for downloading a Cobalt Strike Beacon. The sample at the end of this chain is not necessarily sophisticated or particularly novel, but it does leverage an interesting obfuscation technique that we have dubbed “IPfuscation”.
In this post, we describe this novel technique as it is used across several variants of malware. Along with the IPfuscation technique, we have identified a number of markers which have allowed us to pivot into additional discoveries around the actor or group behind this campaign.
The samples in question are 64-bit Windows Portable Executables, each containing an obfuscated payload used to deliver an additional implant. The obfuscated payload masquerades itself as an array of ASCII IPv4 addresses. Each one of these IPs is passed to the RtlIpv4StringToAddressA function, which will translate the ASCII IP string to binary. The binary representation of all of these IPs is combined to form a blob of shellcode.
The general flow is:
Using byte sequences, sequences of WinAPI calls, and some hardcoded metadata affiliated with the malware author, we were able to identify a handful of other variants of this loader (hashes provided below with the IOCs), one of which we have dubbed “UUIDfuscation” and was also recently reported on by Jason Reaves. A Golang Cobalt Strike loader was also discovered during the investigation, which had a hardcoded source code path similar to what we have already seen with the ‘IPfuscated’ samples, suggesting that the same author may be responsible for both.
The TTPs uncovered during the incident align with previous reporting of the Hive Ransomware Affiliate Program, with the attackers having a preference for publicly available Penetration Testing frameworks and tooling (see TTPs table). Like many other ransomware groups, pre-deployment Powershell and BAT scripts are used to prepare the environment for distribution of the ransomware, while ADFind, SharpView, and BloodHound are used for Active Directory enumeration. Password spraying was performed with SharpHashSpray and SharpDomainSpray, while Rubeus was used to request TGTs. Cobalt Strike remains their implant of choice, and several different Cobalt Strike loaders were identified including: IPfuscated loader, Golang loader, and a vanilla Beacon DLL. Finally, GPOs and Scheduled Tasks are used to deploy digitally signed ransomware across the victim’s network.
Our team discovered and analyzed a 64-bit PE (4fcc141c13a4a67e74b9f1372cfb8b722426513a) with a hardcoded PDB path matching the project structure of a Visual Studio project.
C:\Users\Administrator\source\repos\ConsoleApplication1\x64\Release\ConsoleApplication1.pdb
This particular sample leverages the IPfuscation technique. Within the binary is what appears to be an array of IP addresses.
Each of these “IP addresses” is passed to RtlIpv4StringToAddressA
and then written to heap memory.
What is interesting is that these “IP addresses” are not used for network communication, but instead represent an encoded payload. The binary representation of these IP-formatted strings produced by RtlIpv4StringToAddressA
is actually a blob of shellcode.
For example, the first hardcoded IP-formatted string is the ASCII string “252.72.131.228”, which has a binary representation of 0xE48348FC (big endian), and the next “IP” to be translated is “240.232.200.0”, which has a binary representation of 0xC8E8F0. Together, they create the below sequence of bytes.
Disassembling these “binary representations” shows the start of shellcode generated by common pentesting frameworks.
Once the shellcode has finished being deobfuscated in this manner, the malware proxies invocation of the shellcode by passing its address to the EnumUILanguagesA
WinAPI function. This is achieved by supplying the shellcode address as the UILanguageEnumProc
, which is a callback routine to be executed.
The shellcode is the common Cobalt Strike stager to download and execute Beacon. Here is a look at the PEB traversal to find one of the modules lists, followed by the ROT13 hash being calculated for target WinAPIs to execute.
A handful of additional samples were found with a similar sequence of functions and static properties, including the same error message. The Hell’s Gate variant (d83df37d263fc9201aa4d98ace9ab57efbb90922) is different from the previous sample in that it uses Hell’s Gate (direct SYSCALLs) rather than EnumUILanguagesA
to execute the deobfuscated shellcode. This sample’s PDB path is:
E:\Users\PC\source\repos\HellsGate+ipv4\x64\Release\HellsGate+ipv4.pdb
In this variant, the IP-formatted strings are procedurally placed in local variables, rather than being looped through as seen previously.
Once all the IP strings have been defined within the scope of this function, memory is allocated with NtAllocateVirtualMemory
via a direct SYSCALL, and the deobfuscation loop commences.
Following the loop, a few SYSCALLs are made to pass control flow to the deobfuscated shellcode.
Among the discovered variants were three additional obfuscation methods using techniques very similar to IPfuscation. Rather than using IPv4 addresses, the following were also found being used to hide the payload:
Here we can see the original IPfuscated sample versus the UUID variant being translated via UuidFromStringA
.
The UUID variant stores the obfuscated payload in the same manner as IPfuscated samples.
The MAC address variant translates the shellcode via RtlEthernetStringToAdressA
and then uses a callback function, a parameter to EnumWindows
, to pass control flow to the shellcode. Again, the MAC addresses forming the payload are stored the same as with previous variants.
The IPv6 variants operate almost identically to the original IPfuscated sample. The only difference is that IPv6-style address are used, and RtlIpv6StringToAddressA
is called to translate the string to binary data.
Among other samples discovered during the incident was a Golang-compiled EXE (3a743e2f63097aa15cec5132ad076b87a9133274) with a reference to a source code Golang file that follows the same syntax as one of the identified IPfuscated samples.
[0x0045d2c0]> iz~go~Users 4542 0x000d62e9 0x004d78e9 27 28 .rdata ascii C:/Users/76383/tmp/JzkFF.go
GetProcAddress
is called repeatedly, with 8 byte stack strings being used to form the WinAPI names to be located in memory.
The shellcode is stored as a cleartext hexadecimal string in the .rdata
section.
This string is read into a buffer and translated into binary, somewhat similar to the IPfuscated flow.
Before translation into binary:
After translation into binary:
Control flow is then passed to the shellcode, which is yet another Cobalt Strike stager attempting to download Beacon.
Our incident response team is constantly intercepting early-use tactics, techniques and artifacts, with IPfuscation just the latest such technique deployed by malware authors. Such techniques prove that oftentimes a creative and ingenious approach can be just as effective as a highly sophisticated and advanced one, particularly when enterprise defense is based on security tools that rely on static signatures rather than on behavioral detection.
If you would like to learn how SentinelOne can help protect your organization regardless of the attack vector, contact us or request a free demo.
SHA1 | Description |
d83df37d263fc9201aa4d98ace9ab57efbb90922 | IPfuscated Cobalt Strike stager (Hell’s Gate variant) |
49fa346b81f5470e730219e9ed8ec9db8dd3a7fa | IPfuscated Cobalt Strike stager |
fa8795e9a9eb5040842f616119c5ab3153ad71c8 | IPfuscated Cobalt Strike stager |
6b5036bd273d9bd4353905107755416e7a37c441 | IPfuscated Cobalt Strike stager |
8a4408e4d78851bd6ee8d0249768c4d75c5c5f48 | IPfuscated Cobalt Strike stager |
49fa346b81f5470e730219e9ed8ec9db8dd3a7fa | IPfuscated Cobalt Strike stager |
6e91cea0ec671cde7316df3d39ba6ea6464e60d9 | IPfuscated Cobalt Strike stager |
24c862dc2f67383719460f692722ac91a4ed5a3b | IPfuscated Cobalt Strike stager |
415dc50927f9cb3dcd9256aef91152bf43b59072 | IPfuscated Cobalt Strike stager |
2ded066d20c6d64bdaf4919d42a9ac27a8e6f174 | IPfuscated Cobalt Strike stager (Hell’s Gate variant) |
27b5d056a789bcc85788dc2e0cc338ff82c57133 | IPfuscated Cobalt Strike stager |
SHA 256 | Description |
065de95947fac84003fd1fb9a74123238fdbe37d81ff4bd2bff6e9594aad6d8b | UUID variant |
0809e0be008cb54964e4e7bda42a845a4c618868a1e09cb0250210125c453e65 | UUID variant |
12d2d3242dab3deca29e5b31e8a8998f2a62cea29592e3d2ab952fcc61b02088 | UUID variant |
130c062e45d3c35ae801eb1140cbf765f350ea91f3d884b8a77ca0059d2a3c54 | UUID variant |
39629dc6dc52135cad1d9d6e70e257aa0e55bd0d12da01338306fbef9a738e6b | UUID variant |
5086cc3e871cf99066421010add9d59d321d76ca5a406860497faedbb4453c28 | UUID variant |
56c5403e2afe4df8e7f98fd89b0099d0e2f869386759f571de9a807538bad027 | UUID variant |
60cfce921a457063569553d9d43c2618f0b1a9ab364deb7e2408a325e3af2f6f | UUID variant |
6240193f7c84723278b9b5e682b0928d4faf22d222a7aa84556c8ee692b954b0 | UUID variant |
6a222453b7b3725dcf5a98e746f809e02af3a1bd42215b8a0d606c7ce34b6b2b | UUID variant |
6bdd253f408a09225dee60cc1d92498dac026793fdf2c5c332163c68d0b44efd | UUID variant |
9c90c72367526c798815a9b8d58520704dc5e9052c41d30992a3eb13b6c3dd94 | UUID variant |
9cd407ea116da2cda99f7f081c9d39de0252ecd8426e6a4c41481d9113aa523e | UUID variant |
a586efbe8c627f9bb618341e5a1e1cb119a6feb7768be076d056abb21cc3db66 | UUID variant |
c384021f8a68462348d89f3f7251e3483a58343577e15907b5146cbd4fa4bd53 | UUID variant |
c76671a06fd6dd386af102cf2563386060f870aa8730df0b51b72e79650e5071 | UUID variant |
e452371750be3b7c88804ea5320bd6a2ac0a7d2c424b53a39a2da3169e2069e9 | UUID variant |
e9bb47f5587b68cd725ab4482ad7538e1a046dd41409661b60acc3e3f177e8c4 | UUID variant |
e9da9b5e8ebf0b5d2ea74480e2cdbd591d82cd0bdccbdbe953a57bb5612379b0 | UUID variant |
efbdb34f208faeaebf62ef11c026ff877fda4ab8ab31e99b29ff877beb4d4d2b | UUID variant |
f248488eedafbeeb91a6cfcc11f022d8c476bd53083ac26180ec5833e719b844 | UUID variant |
e61ecd6f2f8c4ba8c6f135505005cc867e1eea7478a1cbb1b2daf22de25f36ce | MAC Address Variant |
f07a3c6d9ec3aeae5d51638a1067dda23642f702a7ba86fc3df23f0397047f69 | MAC Address Variant |
7667d0e90b583da8c2964ba6ca2d3f44dd46b75a434dc2b467249cd16bf439a0 | IPv6 Variant |
75244059f912d6d35ddda061a704ef3274aaa7fae41fdea2efc149eba2b742b3 | x86 IPv4 Variant |
7e8dd90b84b06fabd9e5290af04c4432da86e631ab6678a8726361fb45bece58 | x86 IPv4 Variant |
C2 | Description |
103.146.179.89 | Cobalt Strike server |
service-5inxpk6g-1304905614.gz.apigw.tencentcs[.]com | Cobalt Strike server |
service-kibkxcw1-1305343709.bj.apigw.tencentcs[.]com:80 | Cobalt Strike server |
103.146.179.89 | Cobalt Strike server |
1.15.80.102 | Cobalt Strike server |
175.178.62.140 | Cobalt Strike server |
84.32.188.238 | Cobalt Strike server |
import "pe" rule IPfuscatedCobaltStrike { meta: description = "IPfuscated Cobalt Strike shellcode" author = "James Haughom @ SentinelLabs" date = "2022-3-24" hash = "49fa346b81f5470e730219e9ed8ec9db8dd3a7fa" reference = "https://s1.ai/ipfuscation" strings: /* This rule will detect IPfuscated Cobalt Strike shellcode in PEs. For example: IPfuscated | binary representation | instruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++ "252.72.131.228" | 0xE48348FC | CLD ... "240.232.200.0" | 0xC8E8F0 | CALL ... */ $ipfuscated_payload_1 = "252.72.131.228" $ipfuscated_payload_2 = "240.232.200.0" $ipfuscated_payload_3 = "0.0.65.81" $ipfuscated_payload_4 = "65.80.82.81" $ipfuscated_payload_5 = "86.72.49.210" $ipfuscated_payload_6 = "101.72.139.82" $ipfuscated_payload_7 = "96.72.139.82" $ipfuscated_payload_8 = "24.72.139.82" $ipfuscated_payload_9 = "32.72.139.114" $ipfuscated_payload_10 = "80.72.15.183" $ipfuscated_payload_11 = "74.74.77.49" $ipfuscated_payload_12 = "201.72.49.192" $ipfuscated_payload_13 = "172.60.97.124" $ipfuscated_payload_14 = "2.44.32.65" $ipfuscated_payload_15 = "193.201.13.65" $ipfuscated_payload_16 = "1.193.226.237" $ipfuscated_payload_17 = "82.65.81.72" $ipfuscated_payload_18 = "139.82.32.139" $ipfuscated_payload_19 = "66.60.72.1" $ipfuscated_payload_20 = "208.102.129.120" condition: // sample is a PE uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and 5 of ($ipfuscated_payload_*) } rule IPfuscationEnumUILanguages { meta: description = "IPfuscation with execution via EnumUILanguagesA" author = "James Haughom @ SentinelLabs" date = "2022-3-24" hash = "49fa346b81f5470e730219e9ed8ec9db8dd3a7fa" reference = "https://s1.ai/ipfuscation" strings: // hardcoded error string in IPfuscated samples $err_msg = "ERROR!" condition: // sample is a PE uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and $err_msg and // IPfuscation deobfuscation pe.imports("ntdll.dll", "RtlIpv4StringToAddressA") and // shellcode execution pe.imports ("kernel32.dll", "EnumUILanguagesA") } rule IPfuscationHellsGate { meta: description = "IPfuscation with execution via Hell's Gate" author = "James Haughom @ SentinelLabs" date = "2022-3-24" hash = "d83df37d263fc9201aa4d98ace9ab57efbb90922" reference = "https://s1.ai/ipfuscation" strings: $err_msg = "ERROR!" /* Hell's Gate / direct SYSCALLs for calling system routines 4C 8B D1 mov r10, rcx 8B 05 36 2F 00 00 mov eax, cs:dword_140005000 0F 05 syscall C3 retn */ $syscall = { 4C 8B D1 8B 05 ?? ?? 00 00 0F 05 C3 } /* SYSCALL codes are stored in global variable C7 05 46 2F 00 00 00 00 00 00 mov cs:dword_140005000, 0 89 0D 40 2F 00 00 mov cs:dword_140005000, ecx C3 retn */ $set_syscall_code = {C7 05 ?? ?? 00 00 00 00 00 00 89 0D ?? ?? 00 00 C3} condition: // sample is a PE uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and all of them and // IPfuscation deobfuscation pe.imports("ntdll.dll", "RtlIpv4StringToAddressA") } rule IPfuscatedVariants { meta: author = "@Tera0017/@SentinelOne" description = "*fuscation variants" date = "2022-3-28" hash = "2ded066d20c6d64bdaf4919d42a9ac27a8e6f174" reference = "https://s1.ai/ipfuscation" strings: // x64 Heap Create/Alloc shellcode $code1 = {33 D2 48 8B [2-3] FF 15 [4] 3D 0D 00 00 C0} // x64 RtlIpv4StringToAddressA to shellcode $code2 = {B9 00 00 04 00 FF [9] 41 B8 00 00 10 00} condition: any of them }
TTP | Description | Mitre ID |
BAT/Powershell scripts | Automate pre-ransomware deployment actions | T1059 |
Scheduled Tasks | Execute the ransomware payload | T1053 |
Cobalt Strike | Primary implant / backdoor | S0154 |
ADFind | Active Directory enumeration | S0552 / T1087 |
SharpHashSpray | Password spraying | T1110.003 |
DomainHashSpray | Password spraying | T1110.003 |
Bloodhound/SharpHound | Active Directory enumeration | S0521 / T1087 |
Signed Ransomware | Ransomware payload is digitally signed | T1587.002 |
Domain Policy GPO | Deploy ransomware via GPO | T1484 |
Net-GPPPassword | Steal cleartext passwords from Group Policy Preferences | T1552.006 |
Rubeus | Request Kerberos Ticket Granting Tickets | T1558 |
Sharpview | Active Directory enumeration | T1087 |
RDP | Lateral movement via RDP | T1021.001 |
SAM Dump | Credential theft | T1003.002 |