Nighthawk 0.3.4 – Sivako

Introduction

At the start of July, we released Nighthawk 0.3.4 to customers. It’s been some time since our last release and there’s good reason for that, which we’ll outline below, but suffice to say the team have been exceptionally busy building new tools and continuing to work on new groundbreaking R&D which customers will start to see the fruits of over the coming releases.

Undressing the Elephant

Before we dive in to this release, let’s first address the elephant in the room. In February this year, some components of an older Nighthawk version (from October 2022) were being publicly shared in various underground forums, Telegram and on other exchanges. This was not a complete build, and could not be used in its existing form. Irrespective, this was clearly not acceptable. To understand how this came to pass and what we did at the time, let’s rewind back further.

In December 2024, roughly 3 months before this release was being publicly shared, we noted a user on both XSS.is and Telegram offering the software for sale. Now, it’s worth mentioning that we pro-actively monitor these and other underground forums/marketplaces using both automated and manual analysis, looking for any references to our software. We consider this part of our pro-active approach to product protection. There have been many individuals claiming to have access to the software and offering it for sale. However, engaging with these users had always historically revealed them to be scams, with the seller either being unable to produce any evidence they had the software or sending us a terribly edited photo from one of our public screenshots or videos. This occasion was however different, and the seller showed us enough credible evidence to suggest that they either had some components of the software, or knew someone who did. We agreed to purchase the software from the seller so that we could do our own analysis on what they had.

Once we’d obtained a copy, we were able to quickly confirm that it was a genuine but heavily modified copy of the teamserver and C2 client software, with the licensing restrictions removed. While this was disappointing, thanks to our watermarking, we were able to quickly identify the customer, an internal red team at a large US financial, as the source of the leak. While it was never determined how the leak occurred, from our analysis of the build we were able to attribute the cracked copy had been rebundled by a Chinese actor due to some Jetbrains metadata left behind.

At this stage, we decided there were a number of short, medium and longer term actions that we needed to take.

The first was we immediately contacted the customer and informed them of the leak and asked them to investigate it. To limit any further damage or leaks of newer versions of the software, we disabled their access and terminated their licenses due to breach of our software EULA.

At this time, we don’t believe the software was being widely shared and because we were able to pro-actively identify it early, we had an opportunity to limit any future damages it might cause should it re-engineered to be functional. As such, in early January we decided to contact a number of defensive vendors, inform them about the leak and offer some detection support. Specifically, we reached out to Microsoft, CrowdStrike, SentinelOne, Palo Alto, Elastic and Huntress providing them with some intelligence and detection support. While we noted that the existing public Elastic Yara rule was able to detect this older version of the software, it was somewhat incomplete; we provided them with a more extensive version targeted only at the leaked build, that would detect both x86 and x64 versions of the beacon irrespective of configuration. We’re now publicly sharing this below:

import "pe"
 
rule leaked_nighthawk_0_2_1_x64 {
    meta:
        author = "MDSec Consulting Ltd"
        id = "33c3476a-cc96-43c5-979d-1d0f6a1cb017"
        creation_date = "2025-01-09"
        last_modified = "2025-01-09"
        reference_sample = "e180751a9d9c34c3daf62b90f5750999fb0232bfb336915661189b7f751add10"
        threat_name = "Nighthawk.Leaked.0-2-1"
        severity = 100
        arch_context = "x64"
        scan_context = "file, memory"
        os = "windows"
    strings:
               $nh_shellcode_sequence_2 = { 00 00 00 48 8D 15 78 42 0E 00 48 8D 8D 40 07 00 00 E8 B8 A1 00 00 48 8D 95 40 07 00 00 48 8D 8D }
               $nh_shellcode_sequence_3 = { 48 2B C6 48 83 C0 F8 48 83 F8 1F 0F 87 B7 00 00 00 48 8B CE E8 CF 48 01 00 4C 8B 6D B0 45 8B 46 }
               $nh_shellcode_sequence_8 = { 68 02 00 00 48 83 C7 7F 33 C0 49 8B CD F3 AA 48 89 B5 90 00 00 00 48 89 B5 A0 00 00 00 48 89 95 }
               $nh_shellcode_sequence_9 = { FF FF 75 05 39 70 74 74 12 48 8D BD F8 65 00 00 48 83 C7 7F 33 C0 8D 48 0D F3 AA 48 89 74 24 68 }
               $nh_shellcode_sequence_10 = { 24 10 48 89 74 24 18 48 89 7C 24 20 55 41 56 41 57 48 8B EC 48 83 EC 70 48 8B FA 48 8B F1 41 BE }
               $nh_shellcode_sequence_11 = { 87 01 00 E1 06 46 18 88 0C 00 D5 05 F4 87 01 00 E1 06 46 18 88 0C 00 15 07 F4 87 01 00 E1 06 46 }
               $nh_shellcode_sequence_12 = { 1C 01 00 48 8B D0 48 8D 8D 80 0C 00 00 E8 84 DA FF FF 90 48 8B D0 48 8D 4C 24 20 E8 9E 13 01 00 }
               $nh_shellcode_sequence_13 = { 60 74 74 0F 48 8D 7D 28 48 83 C7 7F 33 C0 8D 48 0D F3 AA 4C 89 23 BE 0F 00 00 00 48 89 73 18 4C }
               $nh_shellcode_sequence_14 = { 74 05 E8 F6 F4 02 00 48 89 7B 20 48 89 6B 28 66 89 7B 10 48 8B 5C 24 30 48 8B 6C 24 38 48 83 C4 }
               $nh_shellcode_sequence_15 = { 08 00 00 00 07 00 00 00 08 00 00 00 07 00 00 00 08 00 00 00 07 00 00 00 08 00 00 00 00 00 00 00 }
               $nh_shellcode_sequence_17 = { 0C 00 8E 18 88 0C 00 05 03 F0 42 02 00 01 07 46 62 AC 0E 00 2E 18 88 0C 00 96 18 88 0C 00 DD 04 }
               $nh_shellcode_sequence_20 = { 00 00 CC D8 11 00 00 00 00 00 E2 D8 11 00 00 00 00 00 00 00 00 00 00 00 00 00 17 00 00 00 00 00 }
               $nh_shellcode_sequence_21 = { 48 C7 45 FF 0F 00 00 00 C6 45 E7 00 B9 50 00 00 00 E8 80 03 02 00 48 8B D8 41 B8 42 00 00 00 4C }
               $nh_shellcode_sequence_22 = { FD FF FF FF 75 06 83 78 74 00 74 12 48 8D BD 98 0F 00 00 48 83 C7 7F 33 C0 8D 48 0D F3 AA 48 83 }
               $nh_shellcode_sequence_23 = { 57 C0 F3 0F 7F 44 24 20 48 8D 95 10 01 00 00 E8 E7 1F 00 00 90 48 8D 95 30 01 00 00 E8 8A 22 00 }
               $nh_shellcode_sequence_24 = { 50 4C 8B C0 48 8B 95 C8 03 00 00 E8 14 F9 FF FF 90 4C 39 6C 24 78 72 10 48 8B 4C 24 60 48 85 C9 }
               $nh_shellcode_sequence_25 = { 75 D8 4C 8B 45 38 48 8B 45 E8 41 2B F0 44 89 74 24 28 44 8B CE BA 01 00 00 00 48 89 7C 24 20 8B }
               $nh_shellcode_sequence_26 = { F0 08 00 00 48 39 B5 28 09 00 00 72 11 48 8B 8D 10 09 00 00 48 85 C9 74 05 E8 47 A1 FD FF 4C 89 }
               $nh_shellcode_sequence_27 = { 89 BD 60 02 00 00 48 89 9D 68 02 00 00 41 B8 12 00 00 00 48 8D 15 8C 4F 07 00 48 8D 8D 50 02 00 }
               $nh_shellcode_sequence_28 = { D0 48 0F 42 D8 48 8D 53 01 E8 33 2A FE FF 48 8B 4C 24 68 4E 8D 34 75 02 00 00 00 4C 89 7F 10 45 }
               $nh_shellcode_sequence_29 = { CC 40 53 48 83 EC 30 48 8B D9 48 8D 4C 24 20 E8 65 75 00 00 48 83 F8 04 77 1A 8B 54 24 20 B9 FD }
               $nh_shellcode_sequence_30 = { 8B D0 48 8D 4C 24 20 E8 60 14 01 00 48 8B C8 E8 04 55 01 00 0F B6 C0 89 05 37 39 11 00 48 39 B5 }
               $nh_shellcode_sequence_31 = { 48 8D 4D D0 4C 8B C7 41 8B D4 E8 A5 FB FF FF EB A9 45 8B CE 48 8D 4D D0 4C 8B C7 41 8B D4 E8 71 }
               $nh_shellcode_sequence_32 = { 00 49 03 FC 33 C0 8D 48 0D F3 AA 48 89 5D 00 48 89 5D 10 4C 89 7D 18 41 B8 16 00 00 00 48 8D 15 }
               $nh_shellcode_sequence_34 = { 48 03 C9 48 8D 41 10 48 3B C8 48 1B C9 48 23 C8 74 53 48 3B CA 77 35 48 8D 41 0F 48 3B C1 77 0A }
               $nh_shellcode_sequence_35 = { 41 8B DE 45 39 32 76 1F 41 8B 52 04 41 8B 4A FC 8B C3 41 03 DF 48 03 C8 48 03 D0 8A 04 3A 42 88 }
               $nh_shellcode_sequence_36 = { 8B FB 33 C0 F3 AA FF 15 C2 9A 06 00 48 8B C8 4C 8B C3 33 D2 FF 15 9C 9A 06 00 48 89 75 90 48 C7 }
               $nh_shellcode_sequence_37 = { E8 F6 32 03 00 85 C0 75 05 40 B7 01 EB 03 40 32 FF F6 C3 01 74 1B 83 E3 FE 48 83 7C 24 58 10 72 }
               $nh_shellcode_sequence_38 = { E8 61 70 0A 00 C6 04 33 00 EB 13 48 8B D6 48 89 74 24 20 48 8B CF E8 83 02 00 00 48 8B F8 49 83 }
               $nh_shellcode_sequence_40 = { 0F B6 01 4C 8D 15 67 D6 07 00 42 8A 04 10 88 01 48 8D 49 04 49 83 E8 01 75 E6 48 FF C2 49 83 E9 }
               $nh_shellcode_sequence_41 = { 06 0D 00 00 48 8B D8 48 85 C0 0F 84 AE 00 00 00 8B 30 65 48 8B 0C 25 30 00 00 00 48 8B 51 60 48 }
               $nh_shellcode_sequence_42 = { 48 83 EC 20 48 8B FA 48 8B D9 FF 15 1E 17 08 00 33 C9 48 89 7C 24 30 49 B8 25 23 22 84 E4 9C F2 }
               $nh_shellcode_sequence_44 = { 0A 48 8B CD FF 15 6D 7C 06 00 90 48 83 7F 18 08 72 0D 48 8B 0F 48 85 C9 74 05 E8 A4 62 FE FF 4C }
               $nh_shellcode_sequence_46 = { AA FF 15 91 43 06 00 48 8B C8 4C 8B C3 33 D2 FF 15 6B 43 06 00 4C 89 74 24 30 48 C7 44 24 38 0F }
               $nh_shellcode_sequence_47 = { 00 00 00 48 C7 45 CF 0F 00 00 00 E8 87 CA 01 00 48 8D 55 B7 48 8D 4D 17 E8 72 89 00 00 48 8B D0 }
               $nh_shellcode_sequence_48 = { 8B 48 60 48 8B 41 30 F7 40 70 FD FF FF FF 75 06 83 78 74 00 74 12 48 8D BD 98 0F 00 00 48 83 C7 }
               $nh_shellcode_sequence_49 = { 8B 85 F8 00 00 00 48 83 C0 F8 48 C7 85 B8 0A 00 00 40 00 00 00 48 89 85 98 0A 00 00 48 8B 44 24 }
               $nh_shellcode_sequence_50 = { E8 7C FE FF FF F6 C3 01 74 0D BA 48 01 00 00 48 8B CF E8 A6 F3 08 00 48 8B 5C 24 30 48 8B C7 48 }
               $nh_shellcode_sequence_51 = { 48 8B 50 10 4C 39 78 18 72 03 48 8B 00 4C 8B 43 10 48 8B CB 4C 39 7B 18 72 03 48 8B 0B 4C 3B C2 }
               $nh_shellcode_sequence_52 = { 24 48 E8 F7 14 F9 FF 48 8B F8 48 8D 15 D9 4A 07 00 48 8D 8D 40 0A 00 00 E8 A9 1D F9 FF 48 8B D0 }
               $nh_shellcode_sequence_53 = { 48 8B C8 48 8B FE 33 C0 F3 AA FF 15 3C B0 0C 00 48 8B C8 4C 8B C6 33 D2 FF 15 16 B0 0C 00 48 83 }
               $nh_shellcode_sequence_54 = { 4C 8B C6 33 D2 FF 15 B4 EF 08 00 4C 89 7C 24 50 4C 89 6C 24 58 66 44 89 7C 24 40 41 B8 20 00 00 }
               $nh_shellcode_sequence_55 = { 83 E9 01 0F 84 8A 00 00 00 83 E9 01 74 59 83 E9 01 74 27 83 F9 01 0F 85 84 01 00 00 B9 10 01 00 }
               $nh_shellcode_sequence_56 = { 48 89 44 24 20 4C 8D 4D 7F 4C 8D 45 BF 48 8B CB E8 25 F9 FF FF 44 8B E8 48 8B 7D EF 85 C0 0F 84 }
               $nh_shellcode_sequence_57 = { 31 00 2D 00 32 00 2D 00 32 00 00 00 00 00 00 00 00 00 00 00 61 00 70 00 69 00 2D 00 6D 00 73 00 }
               $nh_shellcode_sequence_58 = { 48 8D 43 10 4C 8D 4B 28 48 89 44 24 20 48 8D 8B 68 04 00 00 48 8D 54 24 34 E8 3A 01 00 00 FF C7 }
               $nh_shellcode_sequence_59 = { 00 00 70 54 0F 80 01 00 00 00 80 54 0F 80 01 00 00 00 88 54 0F 80 01 00 00 00 98 54 0F 80 01 00 }
               $nh_shellcode_sequence_62 = { 48 89 7D 48 33 D2 48 8B CE E8 49 FD FF FF 4C 8B 7D 40 41 B8 01 00 00 00 48 8B 55 48 49 8B CF E8 }
               $nh_shellcode_sequence_63 = { B9 89 0E 00 E8 89 0E 00 6C AB 10 00 E8 89 0E 00 17 8A 0E 00 6C AB 10 00 17 8A 0E 00 46 8A 0E 00 }
               $nh_shellcode_sequence_64 = { 8B 0B 48 85 C9 74 05 E8 BC F8 02 00 48 89 7B 10 48 89 6B 18 66 89 3B 48 8B 5C 24 30 48 8B 6C 24 }
        condition:
        12 of ($nh_shellcode_sequence*)
}
 
import "pe"
 
rule leaked_nighthawk_0_2_1_x86 {
    meta:
        author = "MDSec Consulting Ltd"
        id = "eb9c0a18-8f92-4326-b42b-9050c32ef7dc"
        creation_date = "2025-01-09"
        last_modified = "2025-01-09"
        reference_sample = "ed2a3e937467e6420c368a6d9a204eb116e59a2522ada747b42294540afb4972"
        threat_name = "Nighthawk.Leaked.0-2-1"
        severity = 100
        arch_context = "x86"
        scan_context = "file, memory"
        os = "windows"
    strings:
               $nh_shellcode_sequence_1 = { 8D 93 B0 00 00 00 8D 8D 64 FF FF FF E8 D5 9D FF FF 59 83 78 14 08 72 02 8B 00 8D 4D 98 51 6A 00 }
               $nh_shellcode_sequence_4 = { 32 FB 32 1C 33 36 33 3D 33 54 33 58 33 5C 33 60 33 64 33 68 33 6C 33 70 33 74 33 78 33 7C 33 80 }
               $nh_shellcode_sequence_6 = { FF 74 0A 8D 55 F8 8B CB E8 FD F5 FF FF 8B C6 5F 5E 5B C9 C3 55 8B EC 83 EC 0C B9 46 A3 C8 D8 53 }
               $nh_shellcode_sequence_7 = { E8 E9 FB FF FF 81 47 04 94 00 00 00 EB 08 50 8B CF E8 27 04 00 00 83 4D FC FF 8D 8D 20 FF FF FF }
               $nh_shellcode_sequence_8 = { 08 03 D0 8B 45 FC 40 89 45 FC FF 45 FC 0F B6 00 D3 E0 03 D0 83 C7 10 8B 45 E4 8B 4D D4 23 C2 8B }
               $nh_shellcode_sequence_9 = { 43 01 00 8B CF E8 7F 89 00 00 83 C4 18 FF 75 D4 E8 E1 FA FF FF 83 C4 1C E9 2F FF FF FF 89 65 D8 }
               $nh_shellcode_sequence_10 = { 00 68 FF FF 00 00 FF B0 8C 00 00 00 FF 15 D8 A5 09 10 03 75 F4 8D 86 00 00 10 00 50 57 6A 00 FF }
               $nh_shellcode_sequence_11 = { DC F7 FF 8D 4D 9C E9 A8 DD F7 FF 8D 8D E0 FE FF FF E9 8E A7 F7 FF 8D 4D E4 E9 25 DA F7 FF CC CC }
               $nh_shellcode_sequence_12 = { 57 04 00 00 B8 04 0A 10 5A 04 00 00 C8 04 0A 10 65 04 00 00 D8 04 0A 10 6B 04 00 00 E8 04 0A 10 }
               $nh_shellcode_sequence_13 = { 56 0C 8B 0E 85 D2 74 4B 83 7A 04 01 89 4D E0 75 42 FF 76 10 B9 B8 8D 0C 10 E8 02 A5 FB FF 8B 4E }
               $nh_shellcode_sequence_14 = { 19 41 83 E8 01 75 F8 8B 4D F8 51 FF 15 74 A2 09 10 39 5D FC 74 22 FF 75 FC E8 CB A1 03 00 59 8B }
               $nh_shellcode_sequence_15 = { C3 02 00 00 83 EF 04 83 C4 0C 8B C7 83 E0 FC 83 F8 08 7D CA EB 5B 8B 03 89 5C 24 14 89 44 24 18 }
               $nh_shellcode_sequence_16 = { FF E8 AA 3C 07 00 85 C0 75 27 6A FE E8 5F 41 07 00 85 C0 75 1C 68 A0 19 00 10 68 50 6B 0C 10 E8 }
               $nh_shellcode_sequence_18 = { A2 A9 FC FF 83 EC 18 8D 85 54 FF FF FF 8B F4 83 EC 18 8B CC 50 E8 4E A5 FC FF 8B CE E8 9D FE 01 }
               $nh_shellcode_sequence_20 = { 88 00 00 00 4C 27 00 00 8A 00 00 00 33 27 00 00 8C 00 00 00 66 00 00 00 A8 BA 09 10 64 00 00 00 }
               $nh_shellcode_sequence_21 = { 00 89 45 E4 8B 45 EC 03 C6 8B 35 B8 84 0C 10 89 45 D8 8B CE 8D 45 E0 50 6A 40 8D 45 DC 50 8D 45 }
               $nh_shellcode_sequence_22 = { FF FF FF E5 6E 07 10 09 6F 07 10 00 00 00 00 FE FF FF FF 00 00 00 00 D0 FF FF FF 00 00 00 00 FE }
               $nh_shellcode_sequence_23 = { F8 05 0A 10 04 0C 00 00 04 06 0A 10 07 0C 00 00 10 06 0A 10 09 0C 00 00 1C 06 0A 10 0A 0C 00 00 }
               $nh_shellcode_sequence_24 = { FF 15 B4 A3 09 10 8B 75 F0 56 FF 15 B0 A3 09 10 6A 0C 8D 45 B8 53 50 E8 C8 09 05 00 8B 45 E8 83 }
               $nh_shellcode_sequence_25 = { 32 C0 C3 83 79 2C 00 75 E7 3C 6A 0F 8F B1 00 00 00 0F 84 A2 00 00 00 3C 49 74 43 3C 4C 74 33 3C }
               $nh_shellcode_sequence_27 = { 57 FF 75 0C FF 15 9C A3 09 10 8B F0 FF 15 10 A3 09 10 8B 7D 08 3B F0 0F 85 96 00 00 00 8D 45 08 }
               $nh_shellcode_sequence_29 = { 0C 8B CE FF 15 70 A6 09 10 FF D6 5E C3 33 C0 40 5E C3 8B FF 55 8B EC 56 68 24 E9 09 10 68 1C E9 }
               $nh_shellcode_sequence_30 = { D0 89 7D E0 0F 43 45 D0 66 89 88 00 00 01 00 EB 0D 2B 7D E0 8D 4D D0 53 57 E8 D4 9C FE FF 83 7D }
               $nh_shellcode_sequence_31 = { 4C 35 50 35 54 35 58 35 5C 35 60 35 64 35 68 35 6C 35 70 35 74 35 78 35 7C 35 80 35 84 35 88 35 }
               $nh_shellcode_sequence_32 = { 8E A4 00 00 00 8D 0C 4D 04 00 00 00 E8 19 0E 01 00 8B D0 89 96 A0 00 00 00 85 D2 74 36 8B 0D B4 }
               $nh_shellcode_sequence_33 = { 83 C4 10 83 F8 FF 74 21 6A FF 40 8B CF 50 8D 44 24 2C 50 E8 81 FA FE FF 50 8B CF E8 A3 FB FE FF }
               $nh_shellcode_sequence_34 = { 8B 47 04 33 DB 43 8B 08 8A 02 88 45 EE 0F B6 C0 8A 44 08 04 0F B6 C0 83 F8 11 0F 87 73 01 00 00 }
               $nh_shellcode_sequence_35 = { C3 5B 64 89 0D 00 00 00 00 C9 C2 0C 00 55 8B EC 83 EC 2C 53 56 57 8B F9 83 7F 08 01 75 51 8B 1F }
               $nh_shellcode_sequence_37 = { 04 FD FB FF 85 F6 0F 84 FC 01 00 00 8B 75 F0 8B 7D EC 8D 8D D8 FE FF FF E8 8A C7 FF FF 8B 4D B4 }
               $nh_shellcode_sequence_38 = { E8 A2 CC FE FF 85 C0 74 7A 8B B3 90 00 00 00 8B 9B 94 00 00 00 EB 5C 56 8D 4D A0 E8 77 00 00 00 }
               $nh_shellcode_sequence_39 = { F3 75 F1 8B 37 8B 47 08 2B C6 83 E0 E0 50 56 E8 3B 35 FE FF 59 59 5B 8B 45 0C 8B 4D 08 C1 E0 05 }
               $nh_shellcode_sequence_40 = { 87 14 01 00 00 89 45 F4 8B 46 14 89 45 F8 74 0D 3B 41 10 75 08 8B 45 F4 89 41 0C EB 06 8B 45 F8 }
               $nh_shellcode_sequence_42 = { FC 09 8B 5D D0 53 FF 15 30 A4 09 10 8D 43 10 50 FF 15 30 A4 09 10 8D 43 20 50 FF 15 30 A4 09 10 }
               $nh_shellcode_sequence_43 = { 4D E0 6A 08 0F 4F D8 E8 F1 0D 00 00 0B C2 59 59 74 5D 8B 55 E4 4E 89 37 8B 0A 0F B6 06 8A 44 08 }
               $nh_shellcode_sequence_44 = { 4D D0 E8 A5 57 03 00 83 C4 18 39 78 14 72 02 8B 00 50 FF 75 EC E8 BD A9 FF FF 8D 4D D0 89 85 6C }
               $nh_shellcode_sequence_45 = { 55 B4 8B 45 10 89 45 B0 8B 45 14 89 45 D0 8B 45 E0 89 45 AC 83 65 F4 00 83 65 EC 00 83 65 F4 00 }
               $nh_shellcode_sequence_46 = { C0 89 55 C4 72 02 8B 06 8D 4D C0 51 8D 4D C8 51 52 50 FF 15 48 A1 09 10 8D 8F A8 00 00 00 85 C0 }
               $nh_shellcode_sequence_47 = { E8 1F 71 FC FF 33 F6 BA 2A B6 B8 B0 56 6A 04 56 51 56 8B C8 E8 FF 76 FC FF 59 59 50 56 56 FF 75 }
               $nh_shellcode_sequence_48 = { 8B 9D 5C FC FF FF 13 D2 41 3B CB 75 E8 85 D2 74 4C 83 FB 73 73 16 89 94 9D 60 FC FF FF 8B 9D 5C }
               $nh_shellcode_sequence_50 = { CC CC CC CC CC CC CC CC CC CC CC CC 56 8B F1 83 7E 3C 00 74 22 83 7E 40 00 74 0F FF 76 3C FF 15 }
               $nh_shellcode_sequence_52 = { 3E 83 C4 0C 89 75 CC 8D 45 CC 89 5D FC 50 8B 47 54 8B CF 2B 47 4C 50 6A 09 E8 63 E2 FF FF 8B 45 }
               $nh_shellcode_sequence_53 = { 89 0D 84 51 0C 10 89 15 80 51 0C 10 89 1D 7C 51 0C 10 89 35 78 51 0C 10 89 3D 74 51 0C 10 66 8C }
               $nh_shellcode_sequence_55 = { 75 EC 8B 75 EC 8B 46 04 89 45 E4 EB 03 8B 75 EC 3B F8 74 93 8B 45 E0 2B C7 89 45 E0 57 8D 0C 38 }
               $nh_shellcode_sequence_56 = { 4D 09 10 1C 00 00 00 29 4D 09 10 22 05 93 19 04 00 00 00 E4 5E 0B 10 00 00 00 00 00 00 00 00 00 }
               $nh_shellcode_sequence_57 = { 73 0B 10 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 }
               $nh_shellcode_sequence_58 = { 56 FF 75 08 8B F1 E8 74 82 FC FF C7 06 08 C1 09 10 8B C6 5E 5D C2 04 00 55 8B EC 83 EC 10 53 8B }
               $nh_shellcode_sequence_59 = { 5F 65 72 72 6F 72 40 73 74 64 40 40 00 B0 C7 09 10 00 00 00 00 2E 3F 41 56 72 75 6E 74 69 6D 65 }
               $nh_shellcode_sequence_61 = { 00 51 50 FF 15 58 A3 09 10 85 C0 0F 84 35 04 00 00 6A 07 59 33 C0 8D BD 28 FF FF FF F3 AB 8D 8D }
               $nh_shellcode_sequence_62 = { 11 6A 10 E8 AE 14 06 00 59 8B 4E 04 89 04 B9 8B 4E 04 FF 75 08 8B 0C B9 E8 C2 00 00 00 FF 46 10 }
               $nh_shellcode_sequence_63 = { 0A B1 10 0F B7 86 BC 16 00 00 FF 46 14 2A C8 83 86 BC 16 00 00 F3 66 D3 EF 0F B7 C7 EB 18 8D 41 }
               $nh_shellcode_sequence_64 = { C2 AC FD FF 8D 46 30 C6 45 FC 01 50 8D 4F 30 E8 B2 AC FD FF 8B 4D F4 8B C7 5F 5E 64 89 0D 00 00 }
        condition:
        12 of ($nh_shellcode_sequence*)
}

We continued to monitor the underground forums for chatter about the software, and particular thanks to Palo Alto’s Unit42 for supporting us in extending our visibility by providing us with threat intelligence data. Everything that we saw indicated that the software was not fully functional and due to the missing components could not be made to work. Over the coming months, we saw the software became more widely shared/traded on Telegram and other platforms including virus total. While it’s impossible to control this, we attempted to thwart the spread by making it less publicly available by alerting the hosting platforms and issuing DMCA takedowns where necessary.

When we first became aware of the leak, we also realised that we needed to do better at protecting the software. While we still believe that strict vetting, issuing the software on a named user basis and watermarking are a strong deterrent and push for a responsible customer, they can’t prevent accidental or intentional disclosure of the software. Once any component is in the hands of a bad actor, the only fallback you have is your technical controls, and in this case what we had was insufficient for protecting it being used.

With the above in mind, we felt we were at a cross roads and had a choice of either continuing on with business as normal, focussing on building new features and evasions or try and give our full attention to mitigating the risks of any future leaks by giving the technical protections a serious re-architecture. In our mind, the weight and risks of potential abuse far outweighed any X Internet points for new evasion and we made the conscious decision that we would not release any further versions of the software under the current licensing format. We didn’t want to spend the next ten years paying lip service to threat actor abuse before making the choice to improve our controls.

Sometime in January we began redesigning our licensing solution, basing our efforts on one key concept; that we should always be able to retain control of the software, even if it leaked. This ultimately meant that we needed to change how the software worked, as historically we had designed it to be able to offer a fully offline solution as this is a key requirement for certain types of customers. However, the downside to that model is you lose a degree of control.

As of Nighthawk 0.3.4, online connectivity is required to start both the API server and the UI, including on restart in the case of the API server. Both will operate offline once they have been launched, but should they be closed, online connectivity will again be required for the API. This online requirement empowers us as the software vendor as it means we now have the ability to prevent the software functioning if we need to revoke it. In its on-disk format, all components of the software are unusable in the software bundle until it is online activated; meaning that if the software leaked in future it would simply be unusable.

To limit any potential spread of the software even with a legitimate license, we also introduced hardware locking. The hardware locking is intertwined with the online activation, with users only able to concurrently activate up to the number of purchased licenses. To make this as manageable for customers as possible, we added the ability to deactivate the license seat to the UI. We felt that this was a reasonable compromise for users who may be using per engagement operator VMs for example. The software bundles continues to remain only available behind an MFA protected portal.

To protect our new controls from reverse engineering and cracking, we also wrapped them in a number of commercial and homegrown protections and obfuscators.

We’re not saying what we’ve developed is perfect or even uncrackable, we’re hackers as well after all and recognise the limitations of any type of licensing solution, but we feel it’s a significant step in the right direction for protecting the product from abuse. However, at the same time we’re not intending on writing a blog post on how to crack it ourselves, even in satire.

We still regularly check-in with various EDR vendors to see if they have seen any in the wild abuse of the software. To date, we have not been made aware of a single instance and we suspect this is predominantly due to the leaked copy being incomplete. However, we also recognise this was more luck than it being impossible. If any blue teams are looking for support in trying to determine the legitimacy of a Nighthawk artifact, we’ve setup the abuse@nighthawkc2.io mailbox and we’d encourage anyone with any suspicions to get in touch.

What’s New

In April, we made two new additions to the Nighthawk team; GigelV41464 and saab_sec, bringing the team to five full time developers. The team has been exceptionally busy, building new features, tools and performing R&D and there’s a number of exciting new developments in the works that we expect to be pushed over the next few releases.

In the 0.3.4 release, in addition to a number of bug fixes and minor OpSec improvements like stretching the beacon call stack masking to our execute-bof and execute-exe harnesses, we added a number of new features.

Asynchronous BOF Support

In September last year at the Redtreat conference, the Outflank team presented a talk on Asynchronous BOFs and with us and several other c2 vendors, discussed the possibility of introducing this concept as a new standard. The idea being that a number of new beacon API calls would be introduced to support asynchronous execution and implemented such that the same BOF would work regardless of what framework you were using.

The concept behind asynchronous BOFs is that the BOF should be able to execute and run independently, irrespective of the beacon’s state in its sleep cycle. We’re not going to dive in to this topic in any greater detail as our friends at Outflank already published a post on it and we recommend you check this out first if you haven’t already.

As mentioned, the Async BOF API includes a number of new methods to support this design; the full specification will be released by Outflank in due course.

Within this release, we included a number of examples of Async BOFs:

  • alert_logon_async: this BOF will continue to execute while the beacon remains in it’s encrypted sleep state, waking the beacon when a specific user logs on.
  • alert_process_async: this BOF will continue to execute while the beacon remains in it’s encrypted sleep state, waking the beacon when a specific process is created.

In addition to this, we also ported our beacon’s call stack masking feature to our BOF harness and execute-exe harnesses such that the thread for both BOF and exe executions occur with a fully spoofed call stack.

Check out this example that monitors for notepad.exe being created while the core beacon continues to remain in its encrypted sleep cycle:

Revamped Injectors

Remote process injection can be a common detection point in post-exploitation tradecraft. The reason for this is that conceptually there are only a finite number of ways to achieve it and for the most part they all involve the common steps of opening handles, allocating memory and using some form of trigger to execute it in a new or hijacked thread. This allows EDRs to closely monitor for this kind of behaviour and alert on anything following these steps. In our previous release, we added a new and unpublished injection vector to our injector chains which avoided some of the common IoCs associated with remote process injection. In this release, we improved this by adding a number of permutations that improved the reliability of the technique, specifically the ExperimentalHijackNoUIThread, ExperimentalHijackCreateThread and ExperimentalHijackCreateThreadIndirect configuration options for ExecuteMemory. We don’t intend to elaborate at this time on how this thread hijacking technique works to prolong its effectiveness.

Further to this, we added a new injector chain configuration option delay-executememory. When set, this configuration option will add a timer to the final step of shellcode execution, irrespective of the injector chain being used. Through our own testing, we found that in many cases adding a sufficiently large delay of 5 to 10 minutes or more to a process injection technique would sufficiently disrupt the EDR timeline that it would not accurately correlate the process injection steps correctly, meaning that even basic injector chains using known primitives such as SetThreadContext or CreateThread would still be effective.

Good things come to those who wait ;)

Improvements to C2 Protocols

Nighthawk’s C2 protocol was originally built across a number of steps that would asynchronously complete each task using a specific sequence of request and responses. This protocol had the benefits of compact requests, reliability and error checking with a tradeoff against the volume of requests.

In our latest release, we introduced a new C2 protocol named sync. When using sync, the beacon and C2 server will batch tasks across a single set of request and responses, significantly reducing the number of C2 requests and therefore dramatically improving speed, against the tradeoff of larger request/response sequences.

This protocol is ideal when high performance is required, including scenarios such as SOCKs, hidden-desktop or screenwatch.

Native Kerberos Support

One of the things that’s been on our agenda for some time was improving the beacon’s support for kerberos tickets. This release made our first steps in that direction, introducing a number of additional built-in commands to handle various kerberos related tradecraft. Specifically, the following commands that will run natively inside beacon are now available:

  • klist: list out the kerberos tickets available in memory,
  • dump: dump the current kerberos tickets from memory,
  • ptt: inject a ticket to a specific logon ID,
  • luid: list the current logon ID

We have a number of follow on posts planned to outline these and other features in Nighthawk, so stay tuned - happy hacking!

updated_at 02-09-0025