daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

trojanized-system-daemons-and-reverse-proxies.md (8104B)


      1 ---
      2 title: "Trojanized System Daemons and Reverse Proxies"
      3 section: "Linux"
      4 sectionSlug: "linux-hardening"
      5 sourcePath: "src/linux-hardening/post-exploitation/linux-post-exploitation/trojanized-system-daemons-and-reverse-proxies.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/linux-hardening/post-exploitation/linux-post-exploitation/trojanized-system-daemons-and-reverse-proxies.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Trojanized System Daemons and Reverse Proxies
     14 
     15 A root-level intruder can replace a trusted daemon or compile malicious logic into it, obtaining the daemon's expected name, privilege, startup lifecycle, and network position while keeping the legitimate service functional. This is **post-compromise persistence**, not a privilege-escalation technique: the installer must already be able to replace root-owned executables.<sup>[[1]](#references)</sup>
     16 
     17 ## In-place daemon trojanization
     18 
     19 A reusable deployment pattern is to fingerprint the distribution, release, kernel, and CPU architecture, select a compatible ELF, decrypt it only in memory, overwrite the packaged executable, and restart its service. Embedding a RAT thread inside `crond`, `agetty`, `atd`, or `polkitd` then provides command execution, file transfer, reconnaissance, reverse shells, or a PTY without adding an obviously new long-running process. Reconnaissance of active services and listening ports can also let the operator choose a daemon that is installed and routinely active on that particular host.<sup>[[1]](#references)</sup>
     20 
     21 Merely checking `ps` output is therefore weak: both the process name and normal service behavior may look correct. Validate the on-disk executable against the distribution package, inspect build IDs and symbols, and compare the running `/proc/<pid>/exe` object with a clean package copy.<sup>[[1]](#references)</sup>
     22 
     23 ### SSH password interception before authentication
     24 
     25 Instead of modifying PAM, an attacker can patch the SSH server's password-authentication path itself. A change inside OpenSSH's `userauth_passwd()` can copy the submitted plaintext password, omit attacker-controlled master passwords from collection, encrypt the remaining records, and then continue normal authentication. Successful and failed logins consequently behave as expected, while the trojanized `sshd` silently writes credential material.<sup>[[1]](#references)</sup>
     26 
     27 This distinction matters during triage: clean PAM configuration and modules do **not** prove that SSH password handling is clean. Verify the OpenSSH package and investigate files opened or written by `sshd`; one observed implementation stored encrypted credentials below `/var/lib/sshd/`.<sup>[[1]](#references)</sup>
     28 
     29 ## Reverse-proxy-native backdoors
     30 
     31 A reverse proxy is an unusually powerful implant location because it handles traffic **after TLS termination**. Rather than using `LD_PRELOAD` or a separate proxy, malicious code can be compiled into HAProxy and register native filter callbacks, reuse its HTX parsed-message representation, memory pools, scheduler, body-editing API, master-worker lifecycle, and IPC. Legitimate forwarding continues, while the implant gains plaintext visibility into requests, responses, headers, and cookies.<sup>[[1]](#references)</sup>
     32 
     33 ### Edge-only C2 hidden from backends
     34 
     35 A proxy implant can reserve an innocuous URL as a command endpoint and consume it entirely at the edge. One implementation extracted `HTX_BLK_DATA` request blocks into connection-specific FIFOs and then cleared channel fields such as `to_forward`, `output`, `buf.head`, and `buf.data`; the request was treated as consumed and never reached the upstream application. The dispatcher supported file upload/download, command execution, and configuration replacement, then used `send()` on the client socket to return an ordinary-looking HTTP response outside HAProxy's normal response path.<sup>[[1]](#references)</sup>
     36 
     37 Because proxy-version-specific code can also decrement active-connection, cumulative-request, byte, and peak-rate counters, neither backend access logs nor the proxy dashboard is an authoritative record. Correlate independent edge packet or flow telemetry, operating-system sockets, HAProxy statistics, and backend logs; a client-visible request/response with no corresponding upstream transaction is a high-signal discrepancy.<sup>[[1]](#references)</sup>
     38 
     39 ### Selective response injection
     40 
     41 Native filters can make a watering-hole payload extremely selective. The observed design gated injection on exact or `/24` source addresses, URL and `Referer` regexes, `User-Agent` and architecture, then rechecked response status and `Content-Type`. It also parsed attacker fields such as `mrt`, `msc`, and `mst` from `Accept-Language`; a valid operator identifier bypassed IP filtering, turning a common browser header into a covert authentication and control channel.<sup>[[1]](#references)</sup>
     42 
     43 After selecting a transaction, the filter can replace available HTX body chunks, adjust later filters' offsets when the length changes, and append the remaining payload during repeated scheduler passes. Rewriting `Content-Type`/`Content-Disposition`, removing `Accept-Ranges`, and forcing `200 OK` helps conceal the substitution and permits a payload larger than the legitimate body.<sup>[[1]](#references)</sup>
     44 
     45 ## Anti-forensics
     46 
     47 Daemon replacement can be followed by copying timestamps from a trusted executable and selectively removing only deployment-related lines from shell history, authentication, audit, and syslog files. This is less conspicuous than deleting entire logs. A staging file in `/tmp` may be used to rewrite each original, so preserve filesystem metadata and compare local records with remote or immutable logging before attempting cleanup.<sup>[[1]](#references)</sup>
     48 
     49 ## Triage and hunting
     50 
     51 Package provenance, running-image inspection, filesystem artifacts, and cross-layer network correlation are more reliable than process-name allowlists for this technique.<sup>[[1]](#references)</sup>
     52 
     53 <details>
     54 <summary>Daemon and reverse-proxy triage commands</summary>
     55 
     56 ```bash
     57 # Verify packaged daemons (run the command appropriate for the distribution)
     58 dpkg --verify openssh-server cron util-linux at policykit-1 haproxy 2>/dev/null
     59 rpm -V openssh-server cronie util-linux at polkit haproxy 2>/dev/null
     60 
     61 # Resolve the actual executable backing each suspicious daemon
     62 pgrep -x 'sshd|cron|crond|agetty|atd|polkitd|haproxy' | while read -r p; do
     63   printf '%s  ' "$p"; readlink -f "/proc/$p/exe"
     64 done
     65 
     66 # Compare ELF identity and timestamps with clean vendor-package copies
     67 readelf -n /usr/sbin/sshd /usr/sbin/haproxy 2>/dev/null | grep -E 'File:|Build ID'
     68 stat -c '%n | birth=%w | mtime=%y | ctime=%z' /usr/sbin/sshd /usr/sbin/haproxy 2>/dev/null
     69 
     70 # Hunt example state/config/FIFO artifacts and unusual HAProxy control headers
     71 grep -RIE 'mrt=|msc=|mst=' /var/log/haproxy* 2>/dev/null
     72 find /root /var/lib /tmp -xdev \( -path '*/cache/haproxy-100?.cache*' -o -name 'c8c68e629bba773a10ac80012d10bf19' -o -name 'g580' -o -name 'g105' -o -name 't*_w.pipe' -o -name 'jasper-log' \) -ls 2>/dev/null
     73 strings -a /usr/sbin/{sshd,haproxy,crond} 2>/dev/null | grep -E 'ted_|atd_|favorite_list_2x_m500_ico'
     74 ```
     75 
     76 </details>
     77 
     78 Also inspect HAProxy's process environment for unexpected `HAPROXY_MWORKER_PP_READ` or `HAPROXY_MWORKER_PP_WRITE` pipe descriptors that persist across reloads, search the binary for non-vendor filter callbacks or debug-name families, and compare locally recorded counters with upstream flow data. Timestamp equality is only a clue: on Linux, attacker-controlled `mtime` does not necessarily agree with inode `ctime`, package metadata, journal history, or remote audit records.<sup>[[1]](#references)</sup>
     79 
     80 ## References
     81 
     82 - [1] [Rapid7 Labs - DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors](https://rapid7.com/blog/post/tr-dprk-apts-ted-backdoor-curlrat-target-south-korean-media-automotive-sectors)