# SIGS: PackClient stream-aware signatures and Core startup correlation

**URL:** https://community.emergingthreats.net/t/sigs-packclient-stream-aware-signatures-and-core-startup-correlation/3461
**Category:** Rule Signatures
**Tags:** suricata, malware, etopen
**Created:** [September 22, 2026, 10:36pm UTC](https://community.emergingthreats.net/t/sigs-packclient-stream-aware-signatures-and-core-startup-correlation/3461 "2026-09-22T22:36:55Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Ivan](https://sea2.discourse-cdn.com/flex016/user_avatar/community.emergingthreats.net/ivan/32/1489_2.png) [@Ivan](https://community.emergingthreats.net/u/Ivan)
#### Post date: [September 22, 2026, 10:36pm UTC](https://community.emergingthreats.net/t/sigs-packclient-stream-aware-signatures-and-core-startup-correlation/3461/1 "2026-09-22T22:36:56Z")

</div>

Hi y’all,

I REd PackClient and identified a TCP stream robustness issue in the existing ET PackClient Launcher signatures.

The current PLH1 / PLC1 / PLA1 / PLK1 detections (ET SIDs 2069878–2069882) rely on packet-boundary assumptions that hold for the observed capture layout, but equivalent PackClient traffic can be segmented or coalesced differently during normal TCP transport.

I reproduced this under Suricata 7.0.3 and prepared stream-aware equivalents that retain the existing PackClient protocol anchors while matching against the reassembled TCP stream.

I also included an optional PackClient Core startup correlation based on traffic recovered during my reverse engineering. It correlates:

`SYS|Q|EXT|STARTUP|PROBE|`

with:

`SYS|R|EXT|STARTUP|OK|tags=`

on the same established TCP flow before alerting.

I originally submitted this to [support@emergingthreats.net](mailto:support@emergingthreats.net) on September 11, but I’m posting it here as well for visibility and community review.

## Proposed rules

The SIDs in the rules below are temporary submission/validation identifiers only. For ET SIDs 2069878–2069882, the existing upstream SID/message/reference/metadata can be retained while replacing the packet-boundary-dependent predicates with the corresponding stream-aware logic.

```plaintext
# PackClient — ET Open stream robustness submission
#
# Mapping:
# 9900101 -> ET 2069878 (PLH1 length prefix)
# 9900102 -> ET 2069879 (PLH1 check-in body)
# 9900103 -> ET 2069880 (PLC1 C2 response)
# 9900104 -> ET 2069881 (PLA1 payload request)
# 9900105 -> ET 2069882 (PLK1 C2 response)
# 9900110/9900111/9900112 -> optional Core startup correlation

alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"PackClient PLH1 length prefix stream"; flow:established,to_server,only_stream; content:"|24 00 40 5a|"; fast_pattern; reference:url,www.proofpoint.com/us/blog/threat-insight/carry-compromise-ta4922-packs-packclient; reference:url,ivanimmanuel-dev.github.io/PackClient/; classtype:trojan-activity; sid:9900101; rev:1; metadata:attack_target Client_Endpoint, created_at 2026_09_11, deployment Perimeter, malware_family PackClient, confidence High, signature_severity Major, updated_at 2026_09_11;)

alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"PackClient PLH1 stream"; flow:established,to_server,only_stream; content:"|24 00 40 5a 15 00 00 00|PLH1"; fast_pattern; reference:url,www.proofpoint.com/us/blog/threat-insight/carry-compromise-ta4922-packs-packclient; reference:url,ivanimmanuel-dev.github.io/PackClient/; classtype:trojan-activity; sid:9900102; rev:1; metadata:attack_target Client_Endpoint, created_at 2026_09_11, deployment Perimeter, malware_family PackClient, confidence High, signature_severity Major, updated_at 2026_09_11;)

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"PackClient PLC1 stream"; flow:established,to_client,only_stream; content:"|1c 00 40 5a 15 00 00 00|PLC1"; fast_pattern; reference:url,www.proofpoint.com/us/blog/threat-insight/carry-compromise-ta4922-packs-packclient; reference:url,ivanimmanuel-dev.github.io/PackClient/; classtype:trojan-activity; sid:9900103; rev:1; metadata:attack_target Client_Endpoint, created_at 2026_09_11, deployment Perimeter, malware_family PackClient, confidence High, signature_severity Major, updated_at 2026_09_11;)

alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"PackClient PLA1 stream"; flow:established,to_server,only_stream; content:"|2c 00 40 5a 15 00 00 00|PLA1"; fast_pattern; reference:url,www.proofpoint.com/us/blog/threat-insight/carry-compromise-ta4922-packs-packclient; reference:url,ivanimmanuel-dev.github.io/PackClient/; classtype:trojan-activity; sid:9900104; rev:1; metadata:attack_target Client_Endpoint, created_at 2026_09_11, deployment Perimeter, malware_family PackClient, confidence High, signature_severity Major, updated_at 2026_09_11;)

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"PackClient PLK1 stream"; flow:established,to_client,only_stream; content:"|3c 00 40 5a 15 00 00 00|PLK1"; fast_pattern; reference:url,www.proofpoint.com/us/blog/threat-insight/carry-compromise-ta4922-packs-packclient; reference:url,ivanimmanuel-dev.github.io/PackClient/; classtype:trojan-activity; sid:9900105; rev:1; metadata:attack_target Client_Endpoint, created_at 2026_09_11, deployment Perimeter, malware_family PackClient, confidence High, signature_severity Major, updated_at 2026_09_11;)

# Optional Core startup correlation. Match each semantic message on reassembled
# stream data, then alert once both states are present on the same TCP flow.
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"PackClient Core startup probe state"; flow:established,to_client,only_stream; content:"SYS|7c|Q|7c|EXT|7c|STARTUP|7c|PROBE|7c|"; fast_pattern; flowbits:set,ET.packclient.core_startup_probe; flowbits:noalert; reference:url,ivanimmanuel-dev.github.io/PackClient/; classtype:trojan-activity; sid:9900110; rev:1; metadata:attack_target Client_Endpoint, created_at 2026_09_11, deployment Perimeter, malware_family PackClient, confidence High, signature_severity Major, updated_at 2026_09_11;)

alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"PackClient Core startup response state"; flow:established,to_server,only_stream; content:"SYS|7c|R|7c|EXT|7c|STARTUP|7c|OK|7c|tags="; fast_pattern; flowbits:set,ET.packclient.core_startup_response; flowbits:noalert; reference:url,ivanimmanuel-dev.github.io/PackClient/; classtype:trojan-activity; sid:9900111; rev:1; metadata:attack_target Client_Endpoint, created_at 2026_09_11, deployment Perimeter, malware_family PackClient, confidence High, signature_severity Major, updated_at 2026_09_11;)

alert tcp $HOME_NET any <> $EXTERNAL_NET any (msg:"PackClient Core startup probe and response"; flow:established; flowbits:isset,ET.packclient.core_startup_probe; flowbits:isset,ET.packclient.core_startup_response; flowbits:unset,ET.packclient.core_startup_probe; flowbits:unset,ET.packclient.core_startup_response; reference:url,ivanimmanuel-dev.github.io/PackClient/; classtype:trojan-activity; sid:9900112; rev:1; metadata:attack_target Client_Endpoint, created_at 2026_09_11, deployment Perimeter, malware_family PackClient, confidence High, signature_severity Major, updated_at 2026_09_11;)

```

## Validation

The submitted rules parse successfully under Suricata 7.0.3.

Engine-level testing confirmed that:

- the observed four-byte split layout satisfies the existing packet-oriented predicates;
- equivalent PackClient frames delivered as coalesced TCP payloads can bypass those predicates;
- segmentation within the PackClient framing can also prevent packet-oriented matching;
- the stream-aware Launcher signatures continue to match after TCP reassembly;
- the Core startup alert requires both the probe and response on the same TCP flow;
- a response without the corresponding probe does not produce the correlated alert;
- the Core startup correlation survives segmentation in both directions.

## References

**PackClient reverse-engineering research:**

> **[PackClient: Reverse Engineering a Modular RAT Framework](https://ivanimmanuel-dev.github.io/PackClient/)**
>
> This report follows PackClient from its signed-host carrier into a suspended 32-bit surrogate, the injected Donut package, Launcher execution, and a 985,088-byte Core recovered directly from historical PLK1 traffic. Reassembled sessions preserve...

**Original Proofpoint PackClient research:**

> **[Carry-On Compromise: TA4922 Packs PackClient | Proofpoint US](https://www.proofpoint.com/us/blog/threat-insight/carry-compromise-ta4922-packs-packclient)**
>
> Key Findings Proofpoint identified a command and control (C2) framework called PackClient sold on Telegram. It is being used by at least one threat actor, Chinese-speaking TA4922. With

Happy to adjust the signatures or provide additional captures/validation if useful.

Thanks,

Ivan Immanuel Shaji
