core-jmp core-jmpdeath of core jump

Red Heron Exploits Gitea n-day CVE-2026-60004, Exposing JITTERLY and the SIXZUT Linux Rootkit

Acronis TRU: Red Heron turned CVE-2026-60004 into a Gitea steal-and-pivot factory within days of the PoC, hit five countries, and dropped JITTERLY with a new LD_PRELOAD rootkit, SIXZUT. Open registration plus Git 2.32 was enough.

oxfemale September 16, 2026 37 min read 213 reads
Export PDF
Red Heron Exploits Gitea n-day CVE-2026-60004, Exposing JITTERLY and the SIXZUT Linux Rootkit
Original text: "Red Heron exploits Gitea n-day flaw in multinational campaign, exposing new Linux rootkit"Subhajeet Singha, Acronis Threat Research Unit (13 September 2026). Figures, sector/command/IOC tables and published commands below follow the source. We do not re-host a working Gitea exploit or unredact operator keys.
A self-hosted git rack with a heron-shaped shadow
The n-day is a public Git trick. The campaign is a heron standing in someone else’s pond.

Executive Summary

On 13 September 2026 Acronis TRU published the anatomy of a campaign they track as Red Heron: a Chinese-speaking operator who, within days of Gitea’s July 2026 advisory, turned CVE-2026-60004 (CVSS 9.8, versions 1.17–1.27.0, fixed in 1.27.1) into an automated steal-the-repos factory. They scanned 1,386 internet Gitea instances across seven countries, kept a separate 477-host Taiwan list, tagged targets in Simplified Chinese (defense, elections, energy, aerospace, telecom, government, research), and left confirmed compromises in Canada, Argentina, Taiwan, the United States and Sri Lanka. One path went from a Synology-hosted Gitea to root on a three-node Proxmox cluster and vzdump of the VMs.

TRU found this because an implant they call JITTERLY (C++ Linux agent, Adaptix-Gopher-shaped, AES-128-GCM) pointed at an open staging directory. Inside the binary: SIXZUT, a previously unpublished LD_PRELOAD rootkit dropped as libglthread.so.2. Attribution is moderate-confidence PRC-linked context, not a named APT. This draft keeps the source’s figures, tables and IOCs, then adds kitchen translations and hunts that do not need the PoC.

The campaign demonstrates how quickly n-day vulnerabilities in self-hosted development platforms can expose source code, credentials, secrets, and connected infrastructure.

Acronis TRU, 13 September 2026
Kitchen table: A self-hosted Git website is not “just source control.” It is the office that holds every keycard photocopy: deploy keys, JWTs, Docker maps, the NAS next door. CVE-2026-60004 is a trick with a patch file that plants a Git hook. Open registration is a sign-in sheet with no bouncer. Red Heron filled the sheet, planted the hook, and walked the building.

Summary

  • Red Heron weaponized CVE-2026-60004 against internet Gitea: source theft, persistence, credentials, lateral movement, including root on a three-node Proxmox cluster.
  • An exposed staging server held tools, FOFA/JSON target DBs, bash history, stolen repos, and malware — rare operator visibility.
  • 1,386 Gitea hosts in seven countries; 477 Taiwan assets; Simplified Chinese sector tags; confirmed victims in CA, AR, TW, US, LK.
  • Days after the July 2026 PoC: auto-register, exploit, dump filesystem, wipe selected Gitea DB traces.
  • JITTERLY: C++ implant, 30+ commands, tunnels, PTY. Embedded SIXZUT: hide files/PIDs/conns, block kill, relaunch via ld.so.preload.
  • Moderate confidence PRC-linked context. Not tied to a previously named cluster.

Introduction

TRU were hunting a Linux implant, traced it to an open directory on 4 August, and walked into Red Heron’s workshop. A related sample had already been publicly tied to Adaptix C2 by dmpdump; TRU connected it to this operator and found the rootkit nobody had named. The same infra also touched a separate 18-site, 10-country Joomla-ish campaign before the Gitea n-day. What follows is n-day speed, victimology, tradecraft, JITTERLY/SIXZUT, and why they say PRC-linked without naming an APT.

For operators: If you run Gitea 1.17–1.27.0 on the internet with open registration and Git ≥ 2.32, treat this as a presumed-breach bulletin until you are on 1.27.1+ and have reviewed accounts created after 28 July 2026.

Anatomy of CVE-2026-60004: exploiting Gitea’s patch workflow

CVE-2026-60004 is RCE in Gitea’s diffpatch endpoint, CVSS 9.8, 1.17 through 1.27.0, patched 27 July 2026 in 1.27.1, advisory plus working PoC the next day. Reporter: Shai Rod (NightRang3r).

Public disclosure of CVE-2026-60004 and the Gitea diffpatch RCE advisory
Public disclosure of CVE-2026-60004 and the associated Gitea diffpatch RCE advisory. Source: original article.

Vulnerable code runs git apply --index --recount --cached --binary in a bare temporary clone, and on Git 2.32+ adds -3 (three-way merge fallback). Submit the same crafted patch twice: first write lands in the index; second is an add/add collision that forces checkout to disk even though the call was meant to stay index-only. Because the clone is bare, repo root is $GIT_DIR, so a file at hooks/post-index-change is a live Git hook and runs as the Gitea service user the next time Git touches the index.

git apply --index --recount --cached --binary -3

Write access to a repo is required — and Gitea ships with open registration on. Register, create a repo, submit the patch, get a shell. No prior account. 1.27.1 switches the temp clone to non-bare so the root is no longer $GIT_DIR and the hook trick dies.

Kitchen table: Imagine a librarian who only stamps the card catalog (the index) and never puts books on shelves. Git 2.32’s “three-way merge” is a clerk who, when two stamps collide, actually photocopies the page onto the shelf. In a bare library the catalog room IS the shelf room. A page named hooks/post-index-change is a fire alarm that Git will pull. That is the CVE. We are not printing the photocopy.
For operators: Preconditions TRU lists: Git ≥ 2.32, diffpatch enabled, writable+executable tmp, and — for unauth — open registration. Disable signup even if you patch. Hunt child processes of the Gitea service: it should never spawn a shell.

Timeline: from proof of concept to active exploitation

Timeline graphic for CVE-2026-60004 weaponization
On July 27 Gitea 1.27.1; advisory and PoCs the next day. Source: original article.

Release notes called it “Fix: git patch apply.” Public PoCs appeared immediately. Red Heron cloned HORKimhab/CVE-2026-60004 and started building on 29 July.

viminfo history of the exploit script
viminfo showing repeated edits and execution of the CVE-2026-60004 exploit script. Source: original article.
  • 29 Jul — clone PoC; iterate in vim; lab then live, skipping Taiwan first.
  • 30 Jul — 1,386-host scan, 50 threads, open-signup probes → master_scanned.json.
  • 31 Jul — tw_assets.json (477 Taiwan hosts, external metadata); hands-on vs biofuel and “Voter Dashboard” titles.
  • Early Aug — exp_enhanced.py: JSON in, word_word_NNN accounts, dump FS, Gitea DB cleanup. SSH keys on Green Oil. Hashcat on staging.
  • 3 Aug — 50-target Taiwan batch; mixed timeouts.
  • 4 Aug — five more downloaded_repo/ folders; SSH to a TW NAS on 45000 as root. TRU finds the open directory.

Red Heron’s target taxonomy

Example target record with sector tags
Example target record showing host metadata, source tags, sector classification, and registration state. Source: original article.
Sector taxonomy recovered from reconnaissance data
Sector taxonomy recovered from the operator’s reconnaissance data. Source: original article.
Target record classified under elections
Additional target record illustrating PRC-style classification metadata targeting Elections. Source: original article.

Pipeline: FOFA → 1,386 Gitea hosts / 7 countries / 50-thread VPS probes for open registration. Labels in Simplified Chinese with 高/中/低 confidence and tags like critical_infra, notable_public. 128 open-signup hosts → open_sites.json. Separate 477 Taiwan hosts → tw_assets.json.

Taiwan-focused target collection
Taiwan-focused target collection showing externally supplied source metadata. Source: original article.

tw_assets.json carries source: Given authorized website — not self-scanned. Combined with exec.sh mirroring loot from another machine and ssh vps in history, TRU infers more than one person.

Broader reconnaissance dataset entry
Example target entry from the broader reconnaissance dataset, including classification and confidence fields. Source: original article.

Election/voting boxes were in scope (选举/民主/公民, 选举/投票系统). RCE on “voter dashboard” titles, public_sector tag; exfil not confirmed. master_scanned.json also swept a U.S. political-party-affiliated org (非营利/基金会, 政府/法院, notable_public) that had auth on — not the open-reg path, but it shows the shopping list.

Sector (Chinese)Sector (English)CountCountries
国防/军工关联Defense / military2US (2)
选举/民主/公民Elections / democracy / civic2US (2)
选举/投票系统Election / voting systems2US (2)
能源企业Energy3US (3)
航天/空间Aerospace / space3US (3)
电信企业Telecom1US (1)
政府/市政/公共服务Government / municipal2US (2)
公共安全/应急Public safety / emergency2US (2)
科研机构/实验室Research labs3US (3)
NGO/人道主义NGO / humanitarian3US (2), CA (1)
教育机构 (.edu)Education (.edu)1TW (1)
教育/教学(非.edu)Education (non .edu)3US (2), CA (1)
量化/高频交易Quantitative / HFT trading1US (1)
航空/交通运输Aviation / transport1US (1)
海洋/气象/环境Marine / meteorology / environment1US (1)
半导体/硬件Semiconductor / hardware1US (1)
公共媒体/广播Public media / broadcasting1US (1)
开发工具/DevOpsDeveloper tooling / DevOps24US (21), CA (3)
云计算/SaaSCloud / SaaS13US (5), TW (5), CA (3)
游戏Gaming13US (11), CA (2)
非营利/基金会 (.org)Non-profit / foundation11TW (4), CA (4), US (3)
FAANG/巨头FAANG / big tech10US (8), CA (2)
图书馆/博物馆/文化Libraries / museums / culture8US (8)
开源/社区项目Open source / community6US (5), CA (1)
CDN/托管/基础设施CDN / hosting / infrastructure5CA (4), US (1)
自动驾驶/电动汽车Autonomous vehicles / EV4US (3), TW (1)
企业IT/咨询Enterprise IT / consulting3US (3)
AI/机器学习AI / machine learning1CA (1)
Targets across operational files. Source: original article.
Kitchen table: This is not a teenager grepping Shodan for fun. It is a filing cabinet labeled in the language of a mainland collection shop, with Taiwan filed as a province and a second list that says “given authorized website.” DevOps and games pad the counts. Defense, votes, and energy are why TRU wrote the post.

Operator’s tradecraft

Before Gitea comes Joomla

Bash history of pre-Gitea Joomla activity
Bash history showing the pre-Gitea Joomla activity and subsequent transition to the Gitea PoC. Source: original article.

History opens with exp.py –shell against 18 sites in 10 countries. 17 of 18 were Joomla. Vulnerability not recovered; mid-2026 Joomla CVEs overlap but TRU will not guess. An Indian overseas-education consultancy still ran JCE editor 2.9.99. A U.S. MSP was hit; they will not name it (honeypot risk).

N-day weaponization

Command history of CVE-2026-60004 tooling setup
Command history documenting setup and iterative testing of the CVE-2026-60004 exploitation tooling. Source: original article.

git clone, then comedy setup: python -m venv without 3, missing python3.12-venv, wrong script name gitea_diffpatch_rce_poc.py, ls, then cve-2026-60004.py three times against a U.S. security company (abc, ac, slash on/off). Did not work. Re-export GITEA_PASSWORD, fork to exp.py, hammer username dsaopk, add -k for TLS. Pattern: vim, run, vim, run. Then id → ls → cat /etc/issue. “Voter Dashboard Git” ate 14 sessions in poc-results.

Backdoors and persistence

Bash history of backdoor check-ins
Bash history showing repeated backdoor check-ins and subsequent Gitea exploitation commands. Source: original article.

Raw TCP backdoor, auth key redacted, netcat:

echo "[auth key]:id" | nc <target> 48931
echo "[auth key]:ls" | nc <target> 48931

Key:command over TCP. They mistyped the key (missing a 7) — typed by hand, not a script. Argentine quant firm: typo’d the domain, then RCE. –dump-fs for repos and gitea.db.

TargetSessionsCountrySector
Renewable energy company22Canada能源企业
Election-titled Gitea instance14US选举/投票系统
Code developer7Taiwan
Hotels6Taiwan非营利/基金会
Municipal platform2US政府/市政/公共服务
Municipal platform2US政府/市政/公共服务
Quantitative trading firm2Argentina量化/高频交易
Industrial automation (Synology NAS)2Taiwan
Industrial automation company1Taiwan
Media/creative studio1US
Education platform (Forgejo)1Canada教育/教学
IT consultancy1Sri Lanka
Confirmed poc-results targets; names redacted in source. Eleven hosts, five countries. Source: original article.

Post-exploitation, exfiltration and lateral movement

Gitea stores bcrypt in gitea.db. –dump-fs takes the data dir. Hashcat on staging.

Hashcat / staging artefact
Enumeration-adjacent artefact from the operator staging server. Source: original article.
Enumeration output from the Argentine Gitea
Enumeration output associated with the compromised Argentine Gitea instance. Source: original article.

Argentine HFT: temp files, auth configs, syslog, nginx, bash_history, Gitea logs, nginx conf, ends WS OK (backdoor up). Second channel was Gitea metrics, not raw TCP:

curl -k 'hxxps://gitea[.]redacted[.]com[.]ar/api/v1/metrics?k=[auth key]&x=id'

Looks like Prometheus. Spaces in curl defeated them (quotes, URL-encoding, smart quotes from a messenger). They fell back to one-word commands.

Timestamped downloaded_repo directories
Timestamped directories containing recovered repository data. Source: original article.

downloaded_repo/: five hosts. Taiwan industrial automation was huge: surveillance/SCADA/HMI, IoT, sniffer, server configs, internal apps, 130+ leftover poc-* dirs (cleanup failed = hit count). Qatar LMS/chatbot/automation/WP plugins. Three batch targets timed out. Four more in a two-minute window: Sri Lankan IT, Canadian cloud, Qatar personal, U.S. Azure — the batcher.

Canadian renewable energy: 22 sessions, the deepest application theft — HR, CRM, auth, intranet, reports, APIs, JWT/internal tokens/SSH host keys from Gitea config, HCM staging deploy key.

Files from the energy-company compromise
Recovered files associated with the energy company compromise. Source: original article.
Confirmed access inside the energy infrastructure
Confirmed access inside Oil infrastructure. Source: original article.

Persistence: three authorized_keys lines, two unique keys, comments [victim]-backdoor and root-shell, plus a reverse shell. Staging held 61 DB dumps via 41 auto-accounts. Docker map, SQLite, full dev infra.

Taiwan syno02[.]redacted[.]com[.]tw (Hsinchu Synology): account pvenum02 after dsaopk returned blank. TRU reads pve=Proxmox, enum, 02=retry.

Proxmox post-exploitation on the Taiwanese NAS
Evidence of Proxmox-related post-exploitation activity on the Taiwanese Synology-hosted environment. Source: original article.

root@pam ticket, snippet storage, payloads on tapve01/02/03, vzdump across the cluster — full VM disks, not just Git. Gitea on a NAS to hypervisor root. Deepest move in the set.

Kitchen table: They did not stop at photocopying the binder. In Canada they copied HR and the door codes. In Taiwan they found the basement that runs the virtual offices and pressed “backup all three buildings to my USB.” vzdump as root is not reconnaissance. It is moving house.

JITTERLY implant

Open directory listing with JITTERLY
Exposed directory listing containing the JITTERLY implant and related campaign files. Source: original article.

C++ ELF, not Go. Same protocol/config/registration/commands as Adaptix Linux agent, but std::unordered_map, std::ifstream, libstdc++ strings. Central routine TRU names implant_main.

Daemonization and process initialization
Decompiled logic associated with JITTERLY’s daemonization and process initialization. Source: original article.

Double-fork, setsid, /dev/null on 0/1/2 (XOR path at byte_4F3690), chdir. If root: readlink /proc/self/exe else fallback name configd. Loop off_4CA5A0 checking known install paths.

Embedded C2 configuration handling
Decompiled logic showing extraction and handling of the embedded C2 configuration. Source: original article.

512-byte .data blob, after 16-byte NUL prefix cleartext C2:

s2[.]981666[.]xyz[:]8082
JITTERLY decrypting embedded SIXZUT
JITTERLY logic responsible for decrypting and extracting the embedded SIXZUT rootkit. Source: original article.
SIXZUT decrypt continued
Continuation of rootkit decryption logic. Source: original article.

AES-128-CTR, key 3a1e96289832518bff2feeb868bc61a4, ~49 KB blob → ELF .so. Not downloaded from C2. Baked in.

C2 configuration extraction continued
Extraction and handling of the embedded C2 configuration (continued). Source: original article.
Config decryption subroutine
Config decryption related to the JITTERLY implant. Source: original article.
Root install path construction
When running as root, JITTERLY builds /usr/lib//. Source: original article.

If /proc/self/exe ≠ install path: copy, delete original, re-exec with -nodel so the next start does not loop. Reboot persistence mechanism not established.

Host profiling
Username, hostname, outbound IP via UDP-to-8.8.8.8 getsockname. Source: original article.

USER/LOGNAME, gethostname, UDP connect 8.8.8.8:80 then getsockname (no payload). SHA-1 of user+host+IP+static ID+path = beacon ID.

Registration message contents
Registration: process, PID, user, host, IP, root, os-release, 16-byte AES session key, sleep/jitter, transport, rootkit-on. Source: original article.
C2 framing pipeline
Outbound: msgpack → AES-128-GCM → 4-byte BE length. Source: original article.
[4-byte BE length] [12-byte GCM nonce] [encrypted msgpack] [16-byte GCM tag]
Msgpack envelope fields
type, beacon_id, task_batch_id, accepted_task_ids, object[] of command_id/job_id/data. Source: original article.
C2 capability configuration
Decompiled configuration structure associated with the implant’s C2 capabilities. Source: original article.
Command dispatcher
Management commands vs 30+ operations handler. Source: original article.

Command map from TRU:

IDCapability
1Get cwd
2chdir
3Execute program
4Exit
5File download (1MB chunks, 100ms throttle)
6File upload
7, 27List directory
8Copy file
9Move / rename
10mkdir -p mode 0755
11Delete file or directory
12Remove file
13Get system info
14Kill (SIGKILL)
15Stat
16Screenshot (not supported on Linux)
17Execute with captured stdout/stderr
18List jobs
19Kill job
21Set sleep / jitter
22Timestomp
23chmod
24Move file (alt)
25Create empty file
26Write file
31Open SOCKS/TCP tunnel
32Close network channel
35Interactive PTY
36Close terminal
37Pivot data relay
38Port scan / connect check
39Pivot read
40Resize terminal
43Rootkit status
44Uninstall
45Start reverse port forward
46Stop reverse port forward
47List interfaces
54–57Persistence list/save/update/remove
58Environment enumeration
JITTERLY command IDs. Source: original article.

SOCKS, reverse forwards, pivot relay, PTY+resize: this is a foothold, not a toy. Protocol matches Adaptix Gopher except template AES-256-GCM vs JITTERLY AES-128-GCM (16-byte keys). Older template, custom build, or shorter-key choice. dmpdump independently saw Adaptix on a cousin sample.

A fishing net over server cables
Kitchen: SIXZUT is a net over ls, ps, and ss. The fish are still there.

SIXZUT rootkit

Encrypted blob in JITTERLY → LD_PRELOAD rootkit. First public report in this campaign, per TRU. AES-128-CTR, different key from C2. Drops libglthread.so.2 (fake OpenGL thread lib), writes ld.so.preload. Lockfile /tmp/.X11-unix.lk as fake X11 lock.

Initialization

XOR’d configuration inside SIXZUT
XOR’d configuration present inside SIXZUT. Source: original article.

Constructor .init_proc: XOR strings with 0x3C (JITTERLY uses 0x9C). dlsym the 15 hooked libc functions:

FunctionPurpose
getdents / getdents64Directory listing
open / open64File access
stat / lstat / fstatat / __xstat / __lxstat / __fxstatatMetadata
accessExistence
readContent
socketSocket create
recvmsgNetlink/ss
closefd cleanup
killSignals
SIXZUT hooks. Source: original article.

Then AES-128 (its own impl) on an 18,704-byte config; magic ADLGTBL1 + CRC32 or the hide table is empty. Entries 584 bytes: 64-byte name, 520-byte IP:port list, up to 128 pairs, wildcard ports. The recovered config had no names/IPs — clean template, not yet tasked, or incomplete sample. TRU does not pick.

Hiding-table related logic
Rootkit hiding / registration-adjacent logic. Source: original article.

stat/lstat/fstatat/open/fopen/access/readdir/getdents go through five checks: exact /etc/ld.so.preload, exact /tmp/.X11-unix.lk, hide table, substring libglthread.so.2, substring .ld_aux_cahe (source spelling). Hit → ENOENT or skip dent.

Path filtering before real libc
Every listing call is filtered before libc. Source: original article.

/proc listing: read cmdline, NULs→spaces, match hide table, drop PID.

Network hiding covers three Linux paths:

/proc/net/* fopen filter
fopen on tcp/tcp6/udp/udp6 rewritten to a filtered tempfile — beats netstat. Source: original article.
open/read filter on proc net fds
open/open64 tracks fds; read() filters — beats raw read. Source: original article.
AF_NETLINK recvmsg filter
socket NETLINK_INET_DIAG + recvmsg memmove — beats ss. Source: original article.
kill() protection
kill() reads cmdline; match → -1 ESRCH; kill -9 “succeeds” and the process lives. Source: original article.
Watchdog relaunch
If root and implant missing/not running: double-fork, execl -nodel. Next process start via preload brings it back. Source: original article.
For operators: Do not hunt SIXZUT with ls/find/ps/netstat/ss on the live box. They lie. Use EDR telemetry, a known-good kernel, or an offline image. Rebuild, do not clean. TRU is explicit.
Kitchen table: The rootkit is a stagehand who erases the actor from the program, the phone list, and the guest book, then tells security “no such person” when you try to throw them out. If you do throw them out, the next intern who walks in the door (every new process) hires them again. That is ld.so.preload.

Attribution and confidence

Moderate confidence: Chinese-speaking operator, PRC-linked context, alias Red Heron. Not a named APT.

  • Language: recon DBs, taxonomy, FOFA metadata in Simplified Chinese; sectors match a collection shop’s labels.
  • Taiwan as CN/TW: country CN, region TW across metadata — mainland institutional habit.
  • Tasking: tw_assets.json “Given authorized website”; exec.sh HTTP mirror from another host; team not solo.
  • Tools: public GitHub PoC, Adaptix, FOFA — no private crown jewels required.

Conclusion

Public PoC to factory in days. Structured shopping list plus opportunistic DevOps/gaming padding. Elections, defense, energy, government, research are the intent; open Gitea is the door. The staging server tied the operator to JITTERLY and SIXZUT. Internet Git is credentials, deploy keys, and the hypervisor behind the NAS. Patch, close registration, watch the service account.

Mitigation and hunting guidance

Independent of vendor. Exploit needs Git ≥ 2.32, diffpatch on, writable+executable tmp. Open registration is the unauth on-ramp, not the bug.

Reduce exposure

  • Gitea 1.27.1 or later.
  • Disable open registration; restrict diffpatch if unused.
  • Do not put Gitea on the internet if VPN or an authenticating proxy is possible.

Investigate for prior compromise

  • Accounts/repos since the advisory. Throwaway word_word_NNN and dsaopk/pvenum02.
  • Logs: diffpatch; /api/v1/metrics with odd k= and x=.
  • Gitea spawning shells, interpreters, curl — it should not.
  • /etc/ld.so.preload changes.
  • libglthread.so.2, .ld_aux_cahe, /tmp/.X11-unix.lk — from EDR/offline, not live ls.
  • authorized_keys you cannot explain; reverse shells; odd egress.
  • Rotate every secret that lived in that Gitea (DB, JWT, SSH host keys, deploy keys).

If compromise is confirmed

  • Rebuild. Do not clean. SIXZUT restores and blocks kill.
  • Assume repos left the building; grep them for more secrets before you call it contained.

Detection by Acronis

TRU states Acronis EDR/XDR detects and blocks this threat:

Acronis detection screenshot
Detection by Acronis EDR / XDR. Source: original article.

Indicators of compromise

File hashes

FileSHA256Description
agent.elfB441F793C87E54CB7E3F7205E25442AA19920D325CB6AF41D2AFDC8A0B5CF54FJITTERLY implant
rootkit.so28B132AD55BD310BB5CF3DDB4ACE580529AD735204A48CF388830D9039843D8ESIXZUT (decrypted from JITTERLY)
File hashes. Source: original article.

Network

IndicatorType
s2.981666.xyzC2 domain
981666.xyzParent domain
8082C2 port
72.11.138.109Staging server
8888Staging server port
48931Backdoor port
48932Backdoor port (alternate)
[auth key redacted]Backdoor auth key
/api/v1/metrics?k=<key>&x=<cmd>Backdoor endpoint
xcyoibfhuufz.comRelated domain
Network IOCs. Source: original article.

Host

IndicatorType
libglthread.so.2SIXZUT filename
.ld_aux_caheSIXZUT config (source spelling)
/tmp/.X11-unix.lkLock file
/etc/ld.so.preloadModified for preload
configdJITTERLY fallback name
/usr/lib/<name>/<name>Install path
ADLGTBL1SIXZUT config magic
Host IOCs. Source: original article.

Exploitation

IndicatorType
P@ssw0rdDefault password
<word>_<word>_<3digits>Account naming
dsaopkManual test account
pvenum02Proxmox enum account
gitea: sanitizeBackdoor process disguise
systemd-network-helper.serviceFake persistence
systemd-resolved-helper.serviceFake persistence
gitea-rce-poc/4.0Exploit user-agent
@poc.localAccount email domain
Exploitation IOCs. Source: original article.

SSH backdoor keys

Key NameType
[victim]-backdoored25519 (planted on victim)
root-shelled25519, comment decodes to globserver jumpbox
SSH keys. Source: original article.

Encryption keys

KeyValueUsage
SIXZUT AES key3a1e96289832518bff2feeb868bc61a4Rootkit decrypt AES-128-CTR
SIXZUT config key88264a49750b3280e63894fb7445a9c2Config decrypt AES-128-CTR
JITTERLY XOR key0x9CString obfuscation
SIXZUT XOR key0x3CString obfuscation
Keys as published. Source: original article.

A glossary

TermKitchenOperator
GiteaThe office binder of every repo.Self-hosted Git; open reg by default.
diffpatch / -3Clerk who photocopies onto the shelf when stamps collide.git apply –cached –binary -3 in a bare clone.
open registrationSign-in sheet, no bouncer.Unauth on-ramp to write+RCE.
JITTERLYThe intern who lives in /usr/lib/configd.C++ Adaptix-like agent, AES-128-GCM.
SIXZUTStagehand who erases the intern from the program.LD_PRELOAD; libglthread.so.2.
vzdumpUSB of the entire virtual office.Proxmox VM backup as root@pam.
Dual-audience glossary.

Why n-day Git is a country-level collection tool

Red Heron did not need a 0-day. They needed FOFA, a GitHub PoC, open registration, and a week. That is the lesson for anyone who still treats self-hosted Git as an internal wiki with a nice web UI. The Canadian energy box shows the blast radius: HR, CRM, JWTs, deploy keys, Docker. The Taiwan NAS shows the floor below: hypervisors. Election-titled instances in the shopping list are why “it’s just a git server” is not a brief you want to give a CISO after 31 July 2026.

We are not adding a better exploit. The public PoC and TRU’s git apply description are enough for a lab you own. They are also enough for a defender to write the two hunts that matter: Gitea children that are shells, and ld.so.preload that was empty yesterday.

The week on a calendar, without the screenshots

If you only remember one strip of dates: 27 July patch, 28 July advisory+PoC, 29 July viminfo, 30 July 1,386-host scan, 31 July Taiwan list plus voter-dashboard sessions, early August automation and hashcat, 3 August 50-target batch, 4 August more loot plus a root NAS and an open directory that TRU tripped over. That is not “APT tradecraft of the decade.” It is a public Git bug plus a VPS plus a person who types vim a lot. The collection taxonomy is what makes it a campaign instead of a crime spree.

Date (2026)What Red Heron didWhy it matters
27 JulGitea 1.27.1 ships “Fix: git patch apply”The honest window starts closing
28 JulAdvisory + working PoCn-day clock starts
29 JulClone HORKimhab PoC; vim loopOperator is a fork, not an author
30 Jul1,386 hosts / 50 threads / open signupIndustrial, not opportunistic-only
31 Jultw_assets.json (477); voter + biofuel hands-onTasking + priority sectors
Early Augexp_enhanced.py; SSH keys; hashcatFactory + persistence + credential theft
3 Aug50-target Taiwan batchScale
4 AugMore downloaded_repo/; NAS:45000 root; TRU finds stagingThe leak that wrote this paper
Compressed from TRU’s timeline. Dates: original article.

What “bare clone plus git apply -3” means if you maintain Gitea

Three-way merge (-3) is a Git feature for humans applying patches that do not apply cleanly. Gitea wired it into an API that was supposed to stay in the index. A bare repository has no working tree, so Git treats the repository directory as GIT_DIR. Hooks therefore live at the same path an attacker can make git checkout write during the collision. The patch is not “Git is insecure.” The patch is “do not run apply -3 in a bare temp clone that is also your hook directory.” 1.27.1’s non-bare temp clone is the one-line philosophy of the fix.

Open registration is the amplifier, not the bug. A locked-down Gitea with SSO and no public signup still has a write-access RCE for anyone who already has a repo. That is still a High. The Critical-feeling 9.8 is the default internet appliance with the bouncer off. Disable signup even on patched boxes. Restrict diffpatch if your users never apply patches through the UI.

For operators: Gitea spawn of git apply is normal. Gitea spawn of /bin/sh, python, curl, or a hook under a temp GIT_DIR that contains post-index-change is not. Audit hook directories on the service account after 28 July. If you cannot explain a hook, it is this CVE or a cousin.

Reading .bash_history as a personality test

TRU’s history dump is unusually human. They forgot python3, installed venv, typed the wrong PoC filename, ls’d, retried slashes, echo’d a password to confirm the env var, mistyped a backdoor key, mistyped an Argentine domain, and pasted smart quotes from a chat app into curl. That is a person at a keyboard, not a fully automated APT launcher — until exp_enhanced.py exists, at which point the same person becomes a batch job. The 7-missing-digit key typo is the tell that 48931 check-ins were hands-on. The two-minute four-target window is the tell that downloaded_repo/ also had a script.

Joomla first, Gitea second, is also a personality. This VPS was already a crime workshop. The n-day did not create Red Heron. It gave them a better door for the shopping list they already had in Chinese. If you only hunt Gitea you will miss the 17 Joomla sites. If you only hunt Joomla you will miss vzdump. The staging server is why those two campaigns share a name in this paper.

Kitchen table: Imagine catching a burglar’s notebook. The first pages are a different neighborhood (Joomla). Then they photocopy a public lockpicking flyer (the GitHub PoC). Then they try the wrong key three times on a security company’s door. Then they get good. Then they bring a photocopier that runs itself. The notebook still has coffee stains. The photocopier does not.

Metrics-as-C2 and other “looks like monitoring” tricks

The Argentine box is the one to brief SOCs on. Same auth key as the raw TCP implant, delivered as /api/v1/metrics?k=&x=. Prometheus scrapes look like that if you squint. x=id, x=ls, and a struggle with spaces are not Prometheus. If you allow the Gitea metrics route from the internet, you just grew a second command channel for whoever planted k=.

gitea: sanitize as a process name, systemd-network-helper.service and systemd-resolved-helper.service as unit files — those are blending, not brilliance. They work on boxes where nobody lists units. They fail on boxes where Gitea’s service account is not allowed to write systemd.

# proxy / WAF
~ /api/v1/metrics\?k=
~ /diffpatch
# process
parent_comm == gitea and comm in (sh,bash,curl,python,python3,nc,ncat)
# accounts
user ~ '^[a-z]+_[a-z]+_[0-9]{3}$' or user in (dsaopk, pvenum02)
email ~ '@poc\.local$'

SIXZUT versus “I’ll just kill -9 it”

Userland rootkits are unfashionable because EDR exists. They remain fashionable on self-hosted Git boxes that have no EDR, which is most of the 1,386. SIXZUT’s three-path network hide is the part that still surprises people: netstat reads /proc/net/tcp; some agents read() the same file; ss uses NETLINK_INET_DIAG. Hooking only fopen is amateur hour. Hooking fopen, read, and recvmsg is why TRU says do not hunt with ss on the live host.

kill() returning ESRCH is psychological. The admin thinks the PID is gone. The next ls does not show it. The next process start — cron, sshd child, apt — reloads ld.so.preload and execl’s configd -nodel if the binary is still in /usr/lib. That is why “confirmed compromise → rebuild” is not vendor marketing. It is the only sentence that matches the code.

Empty hide table in the recovered sample is a gift and a warning. Gift: maybe this staging copy never hid anything. Warning: the 584-byte entries are a remote-shaped config. Assume a live victim can be tasked with names and IP:port pairs you will never see in this paper.

For operators: Offline: strings the libc-hooked .so for ADLGTBL1, libglthread.so.2, .ld_aux_cahe, X11-unix.lk. Live: EDR file events on /etc/ld.so.preload, not readdir. Network: 8082 to s2.981666.xyz and raw 48931, which SIXZUT would hide from ss if the table were filled.

JITTERLY as Adaptix with a shorter key

Defenders who already parse Adaptix Gopher can almost reuse parsers. Msgpack envelope, beacon_id, task batches, command IDs 1–58 with holes, SOCKS 31, PTY 35, persistence 54–57 — that is Gopher-shaped. Do not copy an AES-256-GCM decoder and call it done. This build is AES-128-GCM, 16-byte session key in the first registration, 12-byte nonce, 16-byte tag, 4-byte big-endian length. C++ not Go means different section names and libstdc++ but the wire is the hunt.

Registration is a full HR file on the host: name, PID, user, hostname, outbound IP (the 8.8.8.8 UDP trick), root or not, os-release, whether the rootkit is loaded, sleep/jitter. If you see that blob once, the operator already knows whether they can hide. Command 43 asks again. Command 44 uninstalls — do not wait for them to be polite.

Proxmox is the paragraph CISOs will screenshot

pvenum02 is a confession in a username. First account dsaopk saw a Gitea. Second account went looking for PVE. root@pam is cluster admin. vzdump is every disk. If your Gitea is a container or a VM on the same Proxmox that runs production, CVE-2026-60004 is a hypervisor bug for you, even though the CVE text never says Proxmox. Synology in Hsinchu was the stepping stone. The three nodes tapve01–03 were the prize. Treat NAS-hosted Git as in-scope for datacenter IR, not “the developers’ toy.”

Kitchen table: The binder was in a filing cabinet (NAS) in the same basement as the building’s master electrical panel (Proxmox). They did not just copy the binder. They booked a moving truck for every office on floors 1, 2, and 3 (vzdump). That is the screenshot.

A CISO one-pager

  1. Internet Gitea with open registration and Git ≥ 2.32 was unauthenticated RCE from 1.17 until 1.27.1. Patch and close signup today.
  2. Assume repos, JWTs, deploy keys, and bcrypt hashes left any box that was scanned after 28 July if it was vulnerable.
  3. If Gitea sat on Proxmox/Synology, open a hypervisor incident, not a git ticket.
  4. Do not trust ps/ss on a suspect Linux Git host. Image it.
  5. This actor files Taiwan as China and shops defense, votes, and energy. If you are on that list, your Gitea is not a side project.

Hunt recipes that do not need the GitHub PoC

# 1. Gitea must not grow a shell
auditctl -a always,exit -F uid=$(id -u git) -S execve
# 2. preload
stat /etc/ld.so.preload; sha256sum /etc/ld.so.preload 2>/dev/null
# 3. names TRU published
ls -la /usr/lib/configd /usr/lib/*/configd /tmp/.X11-unix.lk /lib*/libglthread.so.2 2>/dev/null
# 4. from a live response distro, not the infected libc
# 5. accounts
# SELECT name, email FROM user WHERE email LIKE '%poc.local%' OR name LIKE '%_%_%';

User-agent gitea-rce-poc/4.0 is a gift in access logs. word_word_NNN plus @poc.local is a gift in the user table. P@ssw0rd as the default they used for auto-reg is a gift if you still allow signup. None of those gifts require reproducing CVE-2026-60004.

The implant_main story, unpacked

TRU names the coordinator implant_main because that is what it does: init, config, persistence, host profile, C2. Daemonize is textbook Unix — fork, setsid, fork, parent dies, child dup2’s /dev/null onto 0/1/2 so nothing prints, chdir away from the drop directory. The XOR-encoded /dev/null path at byte_4F3690 is the same cheap string hide as the rest of the binary (key 0x9C). After that, root vs non-root splits the personality. Non-root still beacons. Root copies itself to /usr/lib/<basename>/<basename>, deletes the drop, re-execs with -nodel. configd is the name they want you to see next to systemd-resolved in a casual ps.

The 512-byte C2 blob in .data is operationally lazy and forensically kind: sixteen nulls, then s2.981666.xyz:8082 in cleartext, written into the persistence config so reboot still knows home. You do not need to decrypt AES to get the domain from a memory dump of a fresh sample. You do need AES-128-GCM plus the per-session key from registration to read later traffic. That split — static home, ephemeral session — is why sinking the domain still matters after you miss the first beacon.

SIXZUT’s 49 KB is not a download. It is a pregnancy. Decrypt at runtime, drop libglthread.so.2, splice ld.so.preload, lock /tmp/.X11-unix.lk. The constructor XOR (0x3C) is a different key from JITTERLY on purpose so a YARA for 0x9C strings does not light up the .so. Magic ADLGTBL1 plus CRC32 is how the hide table refuses garbage. Empty table in the staging sample does not mean empty table in Canada.

getdents/getdents64 plus the stat family plus open/open64 plus access plus read plus socket/recvmsg/close plus kill is not “a couple of hooks.” It is the syscall surface of ls, find, stat, cat, netstat, ss, and kill. Substring match on libglthread.so.2 and .ld_aux_cahe (their spelling) means a curious admin who greps those names from /proc also gets ENOENT. Exact match on ld.so.preload means cat /etc/ld.so.preload from a hooked process is a lie. That is why TRU repeats offline/EDR like a mantra.

The netlink path deserves a second paragraph. ss does not read /proc/net/tcp. It asks the kernel for INET_DIAG. SIXZUT’s socket() hook notices AF_NETLINK+NETLINK_INET_DIAG, recvmsg() walks the blob, memmove() compacting matching IP:port out of the buffer. Wildcard ports hide every connection to an IP. Up to 128 pairs. If the operator later fills the table with s2.981666.xyz’s resolved address, your ss -tpn will look clean while 8082 still flows. Pair netflow with ss, not ss alone.

Kitchen table: The intern (JITTERLY) carries a folded stagehand (SIXZUT) in his coat. When he gets a management office (root), he puts on a nametag that says configd and moves into the library stacks (/usr/lib). The stagehand tells every new clerk (every process) to forget the intern exists, forget the coat, forget the phone call to 8082, and if anyone fires the intern, hire him again. Cleaning the intern’s desk while the stagehand still works the lobby is how you keep losing.

What the Canadian and Taiwanese boxes actually cost

Twenty-two poc-results sessions against the Canadian renewable-energy Gitea is not “they liked the target.” It is a week of coming back: 41 auto-accounts, 61 database dumps, three authorized_keys lines, a reverse shell, Docker map, SQLite, HR, CRM, intranet, JWT, deploy key to HCM staging. That is a company-wide identity incident that started as a git CVE. Rotate users who only ever used Gitea SSO. Rotate users who reused those passwords. Treat the HCM staging key as production until proven otherwise.

Taiwan industrial automation: hundreds of repos, SCADA/HMI, sniffer, IoT, 130+ leftover poc-* because cleanup failed. That leftover is a defender gift — a hit counter in the victim’s own Gitea. If you still have those poc-* repos, you have a timeline. Do not delete them before you image. The NAS/Proxmox path is a second company: hypervisor tickets, three nodes, vzdump. ICS source code plus VM disks is a national-collection outcome from a default Gitea setting.

Election-titled instances with 14 sessions and no confirmed exfil is not a comfort. RCE without a downloaded_repo/ folder still means they could read gitea.db, plant 48931, or stand in the metrics endpoint. “We didn’t see a tarball” is not “they didn’t see the voters.”

For operators: For energy/ICS/elections Gitea: patch, then assume credential replay into every system that accepted those JWTs or deploy keys. For Synology+PVE: pull vzdump jobs, pve tickets, snippet storage, and qemu images created after 31 July. That is not optional IR.

Attribution without overclaiming

TRU’s moderate confidence is doing real work. Simplified Chinese + Taiwan-as-CN + “Given authorized website” + FOFA is a pattern, not a ministry stamp. Public PoC + Adaptix + mistyped keys is also a pattern: this is not a closed-source crown jewel shop. Both can be true: tasked like a collection unit, armed like a capable contractor. i-SOON-shaped world, no i-SOON hash. They say they have not linked a named APT. Believe that restraint. Track Red Heron as Red Heron until someone overlaps C2 or the Gopher build.

exec.sh mirroring loot to another host is the sentence that should stop “lone wolf” briefings. One VPS was sloppy enough to list directories. The other may not be. Sink s2.981666.xyz and 72.11.138.109, and still assume a second hop already has the tarballs.

How this sits next to every other n-day Git story

GitLab, Gitea, Forgejo, Gogs — internet source control with default signup is a class. CVE-2026-60004 is this month’s member. The Canadian Forgejo education box in poc-results is the reminder that patching “Gitea” in the CMDB is not the same as patching every fork. The user-agent gitea-rce-poc/4.0 will rot. The behavior — register, create repo, hit diffpatch twice, spawn a hook — will not. Write the detection on the behavior.

Acronis closing with “detected by our EDR” is vendor-normal. The hunting section before it is the part that travels: no vendor required. Upgrade, close signup, watch Gitea’s children, distrust ls, rebuild if preload moved. That paragraph is the article even if you never hear JITTERLY’s name again.

Kitchen table: Every office that put the binder in the street (internet Git, open signup) rented a mailbox to a heron. Some binders held games. Some held the keys to the power plant and the voting desk. The fix is not a new brand of lockpick-proof binder. It is bringing the binder inside and checking whether a stagehand already lives in the library stacks.

Open registration as a product decision, not a misconfig footnote

Gitea’s default open signup exists because the project wants GitHub-at-home for clubs and classrooms. On an internet IP it is a worldwide account factory. Red Heron’s 50-thread probe was only asking “does this instance still have the factory on?” 128 yeses became open_sites.json. That number should haunt maintainers more than the git apply flags. You can argue about -3 in a bare clone. You cannot argue that internet Gitea needed anonymous writers. Close it. SSO it. Put it off port 443 to the world.

word_word_NNN plus P@ssw0rd plus @poc.local is what a factory looks like in the user table. dsaopk is what a human looks like. pvenum02 is what a human who learned the building looks like. If you only grep for poc.local you will miss the second account. If you only grep pvenum you will miss the 41 Canadian autos. Dump the whole user table since 28 July and sort by created_unix.

Forgejo in the Canadian education row is the fork problem. CMDB says Gitea. Disk says Forgejo. The CVE and the PoC still apply if the diffpatch path was inherited. Inventory by binary and by /api/v1/version, not by the ticket title “git server.”

What TRU did not publish, and why that is correct

Auth keys are redacted. Victim names are redacted. The working patch file is not in the post. We are not filling those gaps. The public GitHub PoC already exists; adding a cleaner one in a magazine article is how n-days stay n-days. Hashes, domains, ports, filenames, command IDs, AES keys, account patterns, and the git apply command line are the defender-complete set. If you need a lab, clone HORKimhab against a VM you own that you are about to wipe.

The empty SIXZUT hide table is also a non-publication: TRU did not invent a tasked config. Neither do we. Hunt the loader and the magic header. Do not pretend you know which PIDs a live operator hid last Tuesday.

For operators: Lab rule: 1.27.0 in a VM, Git 2.32+, open signup, no production secrets, snapshot before the PoC, destroy after. Production rule: 1.27.1+, signup off, Gitea not world-reachable, EDR on the box so preload is not your first signal.

A note on Adaptix and the Linux agent ecosystem

Adaptix is open source. Gopher-style Linux agents will keep showing up with swapped crypto and languages. JITTERLY is C++ and AES-128. The next sample may be Rust and AES-256. Command IDs 31/35/45/54 are the stable tell if the author kept the template. dmpdump’s unattributed implant was the breadcrumb. TRU’s open directory was the attribution. Without the directory, JITTERLY stays “another Gopher.” With it, Gopher is how a Gitea n-day became a three-node vzdump. Tooling is not motive. Motive is the Chinese taxonomy. Tooling is how fast motive ships.

Command 16 returning “not supported” on Linux is a leftover of a cross-platform template. Command 5’s 1MB chunks and 100ms throttle are how you steal SCADA repos without saturating a NAS uplink. Command 22 timestomp is how poc-* leftovers might have been harder to see if cleanup had worked. It did not work on the Taiwan automation box. Take the leftover.

Kitchen table: Open-source C2 is a mail-order toolkit. Red Heron did not invent the toolkit. They invented (or were handed) the shopping list, then bought the toolkit off the shelf, then found a Git door that was still propped open a day after the manufacturer mailed a wedge. The wedge is 1.27.1. The list is still out there. The toolkit will be forked again next month with a different lock on the suitcase.

If you only do five things after this article

  • Upgrade every Gitea/Forgejo/Gogs that can see the internet, then disable open registration even on patched hosts.
  • List users created after 28 July 2026; kill word_word_NNN, dsaopk, pvenum02, @poc.local, user-agent gitea-rce-poc/4.0 in logs.
  • Alert when the Gitea service account execs a shell or curl; alert diffpatch and metrics?k=.
  • On Linux Git hosts, verify /etc/ld.so.preload from EDR or an offline image; hunt libglthread.so.2 and configd.
  • If that Git host sat on Proxmox or Synology, open a hypervisor ticket and look for vzdump/root@pam after 31 July. Rotate every secret that lived in gitea.db.

A last word on speed

The distance between a Gitea release note that says “Fix: git patch apply” and a 1,386-host scan is one calendar day plus a public gist-quality PoC. That is now the expected tempo for any self-hosted dev tool with a CVSS 9.8 and default signup. If your patch SLA for internet Git is “next maintenance window,” Red Heron’s calendar is shorter than yours. TRU got the story because the operator left the workshop door open. The next operator will not. Patch on the advisory day, not on the blog day. This blog is 13 September. The advisory was 28 July. Everyone in downloaded_repo/ paid that gap.

If you have read this far as a Gitea admin: 1.27.1, signup off, Gitea off the raw internet, children of the service account audited, preload checked offline, secrets rotated, Proxmox/NAS in the same ticket if they share a basement. If you have read this far as a hunter: gitea-rce-poc/4.0, word_word_NNN, dsaopk, pvenum02, 48931, metrics?k=, libglthread.so.2, configd, s2.981666.xyz:8082, hashes for agent.elf and rootkit.so. That list is enough. The rest was scenery.

Key Takeaways

  • CVE-2026-60004: Gitea 1.17–1.27.0 diffpatch RCE via git apply -3 in a bare clone; 1.27.1 fixes by going non-bare. CVSS 9.8.
  • Red Heron: 1,386-host scan, Taiwan tasking list, Simplified Chinese taxonomy, confirmed victims on five continents-or-countries including a Proxmox cluster.
  • JITTERLY + baked-in SIXZUT (first public). Rebuild hosts; userland ls/ps/ss lie.
  • Open registration + internet Gitea is unauthenticated RCE on default configs with Git ≥ 2.32.
  • Moderate PRC-linked context. Public tools. Fast n-day. Rotate every secret that lived in Gitea.

Defensive Recommendations

  1. Patch. Gitea ≥ 1.27.1 now. Confirm Git version too.
  2. Signup. Disable open registration. Review accounts since 28 Jul 2026 (word_word_NNN, dsaopk, pvenum02, @poc.local).
  3. Network. Gitea off the internet or behind SSO/VPN. Alert diffpatch and /api/v1/metrics?k=.
  4. Process. Gitea UID must not spawn sh/bash/curl/python. Alert 48931/48932 raw TCP and s2.981666.xyz:8082.
  5. Rootkit. Check ld.so.preload from EDR/offline. Hunt libglthread.so.2, .ld_aux_cahe, /tmp/.X11-unix.lk, configd, /usr/lib/*/configd.
  6. Keys. Rotate Gitea DB bcrypt users, JWT, deploy keys, SSH host keys, authorized_keys comments *-backdoor and root-shell.
  7. Hypervisors. If Gitea sat on Synology/Proxmox, assume pve tickets and vzdump. That is a cluster incident, not a git incident.
  8. Rebuild. Confirmed SIXZUT/JITTERLY → reimage. Cleaning a preload rootkit on a live box is how you keep the intern.

Conclusion

A heron is a patient bird. This one waited one day after a public advisory, then fished 1,386 ponds. Some ponds were games and SaaS. Some were votes, oil, and a NAS that ran the virtual office. The implant brought its own stagehand. The staging server was left open, which is the only reason this post exists. Patch Gitea. Close the lobby book. Watch the service account. If the program lies, believe the disk image.

Original text: “Red Heron exploits Gitea n-day flaw in multinational campaign, exposing new Linux rootkit” by Subhajeet Singha at Acronis Threat Research Unit.

oxfemale Vulnerability research, reverse engineering, and exploit development.
// Discussion