Rapport CTI technique du 8 septembre 2026
Résumé exécutif
Rapid7 Labs a documenté le 4 septembre 2026 une boîte à outils Linux jusque-là inconnue, utilisée contre des organisations sud-coréennes des secteurs automobile et média. La pièce maîtresse est un backdoor baptisé ted par ses propres chaînes de débogage, compilé directement dans les sources de HAProxy 2.8.12 chez la victime. Il ne s'agit pas d'un module chargé de l'extérieur mais d'un plugin intégré au binaire, qui enregistre un filtre HAProxy natif, accroche le parseur HTTP et lit le trafic après terminaison TLS. Le répartiteur de charge continue de servir le trafic normalement pendant que l'implant journalise les requêtes intéressantes, vole des cookies de session et remplace le corps des réponses pour des clients choisis par adresse IP ou par jeton opérateur.
Autour de ce backdoor gravitent un keylogger SSH, un stager et un RAT nommé curlRAT, greffé dans des versions trojanisées de crond, agetty, atd et polkitd. Rapid7 attribue l'ensemble avec un niveau de confiance moyen à des APT nord-coréens, sur la base du ciblage régional, des chiffres XOR et de substitution employés, et de la présence des C2 codés en dur dans des listes associées à APT37 par ThreatFox et maltrail. Les premiers échantillons sur VirusTotal remontent au milieu de 2025 et la campagne semble active depuis le début de 2025. Le point d'entrée initial n'est pas établi : les deux victimes exposaient un portail Groupware sur le port 443 et un serveur de messagerie sur le port 25, deux surfaces cohérentes avec le mode opératoire documenté de Kimsuky, mais aucune CVE n'est confirmée à ce stade.
Chronologie
| Date | Événement |
|---|---|
| 22 novembre 2024 | Publication de HAProxy 2.8.12-0fdb194, plus ancienne date de compilation possible pour ce build trojanisé |
| Novembre 2024 à février 2025 | Operation SyncHole (Lazarus, documentée par Kaspersky), campagne de point d'eau contre des sites média sud-coréens dont la fenêtre recoupe celle-ci |
| Début 2025 | Début estimé des campagnes utilisant ted backdoor et curlRAT |
| Mi-2025 | Premiers dépôts d'échantillons sur VirusTotal |
| Début 2026 | Kimsuky observé exploitant des RCE sur des serveurs de messagerie exposés pour compromettre des éditeurs de groupware sud-coréens |
| Juillet 2026 | ENKI WhiteHat signale un vecteur d'accès initial similaire, suggérant une exploitation potentiellement toujours en cours |
| 4 septembre 2026 | Publication du rapport Rapid7 Labs avec IOC et cartographie ATT&CK |
| 7 septembre 2026 | Reprise par The Hacker News, SecurityWeek et GBHackers |
Fiche campagne
Acteur : APT nord-coréens, attribution de confiance moyenne. Composants : ted backdoor, curlRAT, stager, keylogger SSH. Cibles observées : deux organisations sud-coréennes, secteurs automobile et média.
Les éléments d'attribution retenus par Rapid7 sont le ciblage de logiciels régionaux (portail Groupware très répandu dans les entreprises coréennes), l'usurpation du domaine de contenu statique de Naver via img.responsive.pstatic.autos, l'emploi de chiffrements XOR simples et d'un chiffre de substitution, le modèle de point d'eau déjà documenté dans Operation Code on Toast (APT37) et Operation SyncHole (Lazarus), et enfin l'association des C2 codés en dur à APT37 dans ThreatFox et maltrail. Rapid7 rappelle que APT37 et Lazarus sont deux grappes distinctes, rattachées selon Mandiant à des agences différentes, le Ministry of State Security pour la première, le Reconnaissance General Bureau pour la seconde.
La présence de routines préfixées ngx_ dans le backdoor suggère une réutilisation de code venant d'un backdoor nginx. Rapid7 note un rapprochement de nommage avec la campagne Funnull, où un filtre nginx personnalisé accrochait le trafic HTTP avec une configuration chiffrée en XOR simple, mais précise qu'aucun recouvrement de code significatif ne permet d'établir un lien plus fort.
Vulnérabilité exploitée : aucune CVE confirmée. Le vecteur d'accès initial reste indéterminé faute de preuves forensiques suffisantes, et le schéma d'attaque publié par Rapid7 pose par hypothèse une exploitation du portail Groupware exposé.
PoC disponible : sans objet, il s'agit d'une campagne d'acteur et non d'une vulnérabilité produit.
Mitigation : contrôle d'intégrité des binaires système et des composants de bordure, corrélation réseau indépendante des journaux du composant lui-même.
Diagramme de la chaîne d'attaque

Reconstruction à partir du rapport Rapid7 Labs du 4 septembre 2026. Les délais de détection illustrés reprennent l'écart entre la date estimée de début de campagne et la publication.
Analyse technique
Étape 1 : pied dans la DMZ et récolte d'identifiants
Les deux victimes exposaient un serveur web de bordure avec les ports 80, 443 et 25 ouverts, le 443 servant le portail de connexion Groupware et le 25 un serveur de messagerie. L'attaquant obtient un accès sur cet hôte, y installe sa persistance et y dépose un keylogger SSH qui intercepte les mots de passe en clair dans userauth_passwd().
Le détail qui trahit l'outillage : la fonction commence par comparer les identifiants saisis à des mots de passe maîtres codés en dur, ce qui donne aux opérateurs une porte d'entrée directe en plus de la capture. Les identifiants capturés sont chiffrés avec un chiffre de substitution monoalphabétique de 67 entrées, puis encodés en base64 et écrits dans /var/lib/sshd/c8c68e629bba773a10ac80012d10bf19. Le même chiffre de substitution se retrouve dans le keylogger, dans les binaires trojanisés et dans le backdoor HAProxy, ce qui a permis de rattacher les composants entre eux.
L'hôte de bordure sert aussi de serveur de staging pour les ELF trojanisés distribués vers l'intérieur.
Étape 2 : le stager et le choix de la cible
Le stager déchiffre sa configuration avec un XOR d'un octet, vérifie qu'il tourne en root, puis profile la machine : nom d'hôte, distribution, identifiants de version, version du noyau, architecture. Ce profilage sert à sélectionner le bon binaire trojanisé parmi ceux embarqués. Les versions de crond supportées couvrent CentOS 7.7, 7.8, 7.9 et Ubuntu 22.04.
Il n'agit que si crond ou HAProxy tourne sur la machine, garde-fou qui limite le déploiement aux serveurs qui l'intéressent. Le déploiement consiste à déchiffrer le crond trojanisé en mémoire, à écraser le démon légitime et à redémarrer le service, puis à aligner l'horodatage de création du binaire sur celui de /usr/bin/ssh. Il termine par un nettoyage sélectif des journaux, en filtrant les mots clés tmp, wget, cron et crond dans /root/.bash_history, /var/log/messages, /var/log/audit/audit.log, /var/log/cmd.log, /var/log/secure, /var/log/syslog et /var/log/auth.log, via un fichier de travail nommé /tmp/jasper-log pour passer pour un artefact du moteur JSP d'un vieux Tomcat. Deux variantes du stager n'embarquent aucun payload et vont les chercher sur le serveur compromis de la victime.
Étape 3 : curlRAT, deux fils d'exécution greffés dans un démon système
Le RAT ajoute sa logique à crond sous forme de deux threads. Le premier crée un répertoire de travail snapd sous /var/lib, charge l'identifiant de victime depuis /var/lib/snapd/g580 et interroge le C2 par HTTPS avec repli en HTTP, en s'appuyant sur libcurl, d'où le nom. L'identifiant de victime est le MD5 en majuscules de la concaténation de la chaîne de version de cron, du nom d'hôte, de l'adresse IPv4 et de l'UUID matériel lu dans /sys/class/dmi/id/product_uuid, et il voyage dans l'en-tête User-token.
La configuration récupérée est déchiffrée par un chiffre XOR à rétroaction dont le premier octet du fichier initialise la graine, puis parsée sur trois délimiteurs à un caractère : le point d'exclamation termine le champ d'authentification, le dièse marque la section payload, l'astérisque sépare les arguments. Un octet de mode compris entre 0 et 5 sélectionne l'un des six gestionnaires par table de saut.
| Mode | Fonction | Description |
|---|---|---|
| 0 | Exécution de commandes | Décode base64 puis XOR une liste de commandes, exécute chaque ligne via popen avec stderr redirigé, renvoie la sortie dans un tampon de 1 Mo |
| 1 | Écriture de configuration | Décode et valide une nouvelle configuration, fixe l'intervalle de sondage et le drapeau de sondage rapide ; sur échec de validation, retour au C2 img.monderhouse.space |
| 2 | Dépôt de payload | POST authentifié vers le C2 avec un chemin de tâche en corps, écriture en fichier temporaire, décompression puis déplacement |
| 3 | Reverse shell | Ferme les descripteurs au-dessus de 2, appelle setuid(0) et setreuid(0, 0), puis se connecte en sortie |
| 4 | Balise | Remplit une structure d'informations système de 10 Ko et l'émet en check-in |
| 5 | Shell PTY | Shell interactif complet, payload de la forme ip:port |
L'intervalle de sondage par défaut est de 43 200 secondes, soit douze heures, réduit à 30 secondes quand l'opérateur active le mode rapide. La boucle réessaie jusqu'à six fois par cycle avec cinq secondes d'intervalle. Toutes les données sortantes passent par un XOR à rétroaction avec graine aléatoire puis base64, encapsulées dans un corps application/x-www-form-urlencoded.
Le second thread est un chien de garde HAProxy. Il vérifie d'abord la présence de /usr/lib/libvirtlog.so.0 pour s'assurer d'être dans un environnement virtualisé, sinon il dort six minutes et abandonne, ce qui est une évasion de bac à sable simple mais efficace. Ensuite il lit toutes les heures le PID dans /var/run/haproxy.pid et surveille le répertoire proc correspondant, en remontant au C2 un code d'état : 0 démarré, 1 arrêté, 2 redémarré (fichier PID modifié et nouveau PID), 3 rechargé (fichier PID modifié, PID identique). Sur les variantes CentOS, les fonctions sont masquées derrière des noms préfixés atd_ pour brouiller l'analyse statique.
Étape 4 : ted backdoor, le filtre HAProxy qui efface ses propres traces
L'implant est compilé avec le reste des sources de HAProxy 2.8.12, ce qui lui donne accès à l'API de filtres native, aux pools mémoire internes, à l'ordonnanceur de tâches et à la gestion de processus. Sa configuration vit dans ~/cache/haproxy-1000.cache, chiffrée en deux couches : un XOR chaîné dont la graine est le premier octet du fichier, puis une substitution monoalphabétique construite au démarrage dans ted_init_util à partir de la même chaîne de 67 caractères que le keylogger SSH. Les listes de contrôle d'accès par IP viennent de haproxy-1001.cache et haproxy-1002.cache. Le canal C2 est sauvegardé dans les variables d'environnement HAPROXY_MWORKER_PP_READ et HAPROXY_MWORKER_PP_WRITE pour survivre aux rechargements.
Le hook principal remplace trace_chn_start_analyze() et inspecte le buffer HTX, c'est-à-dire la zone mémoire où HAProxy stocke la requête HTTP déjà déchiffrée. Si l'URL demandée correspond à l'URI d'icône codée en dur, le filtre bascule en mode commande et contrôle.
C'est là que se joue la partie la plus intéressante côté détection. Avant tout traitement, l'implant décrémente les compteurs internes de HAProxy en tapant dans la structure proxy par des offsets codés en dur pour la 2.8.12 : beconn et feconn par backend, actconn global, puis les champs 64 bits de be_counters (cum_conn, cum_req, bytes_in, bytes_out) avec garde contre le débordement, et enfin les métriques de pic 32 bits (sps_max, conn_max, cps_max) uniquement quand elles valent exactement 1. Ensuite il remet à zéro to_forward, output, buf.head et buf.data sur le canal de requête, ce qui indique à HAProxy qu'il n'y a plus rien à transmettre. La requête de l'opérateur ne parvient donc jamais à un backend, aucun serveur applicatif ne la journalise, et les statistiques du répartiteur n'en gardent pas trace.
Les commandes transitent par des FIFO créées sous /tmp, avec bascule vers le processus maître si HAProxy tourne en mode master-worker. Le dispatcher accepte cinq opcodes : 0 balise renvoyant un bandeau de version avec l'identifiant de build 24112201 et la version HAProxy 2.8.12-0fdb194, 1 téléversement de fichier, 2 téléchargement de fichier, 3 exécution de commande via popen avec fusion de stdout et stderr, 9 mise à jour de configuration. Toutes les réponses portent un en-tête HTTP/1.0 200 OK écrit à la main et repartent par un send() direct sur la socket, sans passer par le chemin de réponse de HAProxy.
Étape 5 : injection sélective dans les pages servies
Hors mode C2, le filtre journalise le trafic correspondant aux expressions régulières de sa configuration, en extrayant IP source, Host, Referer et User-Agent dans un enregistrement à une ligne séparé par des points d'exclamation. Si le champ action est non nul, le chemin d'injection démarre et une requête doit franchir quatre conditions : présence d'un User-Agent correspondant au motif configuré, détection des octets x, 6 et 4 dans cet agent pour choisir entre payload 32 et 64 bits, correspondance simultanée des regex d'URL et de referer d'une règle, et enfin analyse de l'en-tête Accept-Language d'où sont extraits jusqu'à quatre champs opérateur (mrt pour une clé de 64 octets, msc pour un statut de 8 octets, mst pour un score de 8 octets, et un quatrième mot clé pour un blob d'information de 1 024 octets). Une clé mrt valide court-circuite entièrement le filtrage par IP, ce qui permet à l'opérateur d'atteindre la page depuis n'importe où. Sans clé, le filtrage retombe sur les listes blanches ou noires, testées deux fois, une fois avec le dernier octet mis à zéro pour une correspondance sur le /24 et une fois sur l'hôte exact.
La substitution elle-même se fait en trois callbacks. ted_http_headers_for_htx revérifie le Content-Type et la ligne de statut, ajuste la longueur, supprime Accept-Ranges pour empêcher le client de demander des plages d'octets et de repérer l'écart de taille, et force un 200 OK. ted_http_payload lit le fichier de payload par tranches, le déchiffre avec ngx_decrypt_script et le substitue via les appels d'édition de corps de HAProxy, en décalant les offsets des filtres restants quand la longueur change. trace_http_end ajoute le reliquat quand le payload est plus gros que le corps d'origine, en s'appuyant sur l'ordonnanceur de HAProxy pour étaler la livraison sur autant de passes que nécessaire.
L'infrastructure suit un schéma constant : domaines enregistrés sur des TLD bon marché (.store, .space, .site, .autos) avec un sous-domaine img. imitant un CDN d'images, dont img.responsive.pstatic.autos qui copie le domaine de contenu statique de Naver.
Indicateurs de compromission
| Type | Valeur |
|---|---|
| SHA-256 stager | 5db1b6d52faf60b4f32d6fd0c7c938e4d05d29a14c32ded4a9668357c08b6a91 |
| SHA-256 stager | 09739441ed4599bac2f8159028f772f71e4b25c8badfff95574e56d7384f3dbe |
| SHA-256 stager | fea1bc36632c71e5a839803469ef60ac47595d36b2c50934ac109ade6df06e61 |
| SHA-256 curlRAT | 83f7d565b0465546027052b597af46eae3a199e7a91fcc2ab936341147349130 |
| SHA-256 curlRAT | 7007a78d50a993cb174c685eba96eb442c9507e38fd9d8e5dffc712f613ec110 |
| SHA-256 curlRAT | 6cf1b5e92a9c0756f597a5ddefb38eba32961c52efac7ab2a0aa52c639a8fc53 |
| SHA-256 curlRAT | ed72f4cd8d467b5c5d95ae6aeca4aaeea14d79565d379c1ca5871a714727be16 |
| SHA-256 curlRAT | feeea9d0bf6ae7396d28271baa51ae50df5169ce5d32a516865856f91abc50b3 |
| SHA-256 curlRAT (cronie) | d53c760c23b4405eb04ad0f20ead375440344b3bdf1fb7854ed12e40d155eabe |
| SHA-256 curlRAT (agetty) | 2f02b09d61d432134e994ad671258f523bbf289ae6091fd4eae192c60bd51b6f |
| SHA-256 curlRAT (atd) | 8f30b57928934ae67478d0e690c91d046e35a638da098d02922a4a88a0fdb66c |
| SHA-256 curlRAT (polkitd) | a1d8af3a6acb731f07f72040eccb3450c1c83d40e29f736c2a63d35388660be4 |
| SHA-256 curlRAT | 12810854c8b2c391b23e2e18b013e873d0369b0637aa3cf993136c07188ba3b8 |
| SHA-256 curlRAT | 009a1e2d7a582a24e50cf2ffc2a005482c8e38f22bf5ed416053855f8d054e1e |
| SHA-256 keylogger SSH | 4bb923eb040aa13ca8fd409c31ee4729c60ddff32e350efe1c5a4a9168a065f5 |
| SHA-256 ted backdoor | 94630b96f628c96a6bff7904b40ffc9ad67c86f8a4ff6080c3b524831c93f402 |
| SHA-256 ted backdoor | 72e70936f0dbe459142a1d867617c35f8d0cce5d18c6a49e1090a2a5adc8e558 |
| SHA-256 ted backdoor | a8bfab4de81a1acb04aacdf757346946b0f5e30f0c9f402004016d0e425119c7 |
| Domaine C2 | img.monderhouse.space |
| Domaine C2 | img.smartnords.site |
| Domaine C2 | img.darklights.store |
| Domaine C2 | img.responsive.pstatic.autos |
| Domaine C2 | img.socialteams.store |
| Domaine C2 | img.worksongo.store |
| URI déclencheur C2 | /favorite_list_2x_m500_ico.jpg |
| Chemin fichier | /var/lib/sshd/c8c68e629bba773a10ac80012d10bf19 |
| Chemin fichier | /var/lib/snapd/g580 et /var/lib/snapd/g105 |
| Chemin fichier | ~/cache/haproxy-1000.cache, haproxy-1001.cache, haproxy-1002.cache |
| Chemin fichier | /tmp/jasper-log |
| Jeton API | api_token/ecd427ea8330a4ff73618483e00b9b41 |
| En-tête HTTP | User-token présent dans les requêtes sortantes vers les domaines img. |
MITRE ATT&CK
Cartographie publiée par Rapid7 Labs dans le rapport d'origine, reprise ici sous forme condensée.
| Tactique | Technique | ID | Justification |
|---|---|---|---|
| Accès initial | Exploit Public-Facing Application | T1190 | API de filtres HAProxy détournée comme point d'injection, livraison par point d'eau via le répartiteur compromis |
| Exécution | Command and Scripting Interpreter: Unix Shell | T1059.004 | popen() pour l'opcode 3 de ted, shell PTY en mode 5 et reverse shell en mode 3 de curlRAT |
| Exécution | Native API | T1106 | pthread_create et pthread_detach pour les threads détachés, pool_alloc et task_wakeup de HAProxy pour l'ordonnancement |
| Persistance | Hijack Execution Flow: Dynamic Linker | T1574.006 | Implant chargé comme filtre HAProxy au démarrage du processus, persistant à travers les redémarrages |
| Persistance | Create or Modify System Process | T1543 | crond légitime écrasé sur place, service redémarré, horodatage aligné sur /usr/bin/ssh |
| Élévation de privilèges | Abuse Elevation Control Mechanism | T1548 | setuid(0) et setreuid(0,0) avant le reverse shell, stager vérifiant root avant dépôt |
| Évasion défensive | Masquerading: Match Legitimate Name | T1036.005 | Noms crond, polkitd, agetty, atd, fonctions masquées en routines atd_ sur CentOS |
| Évasion défensive | Clear Linux Logs | T1070.002 | Effacement sélectif par mots clés dans bash_history, messages, audit.log, secure, syslog, auth.log |
| Évasion défensive | Timestomp | T1070.006 | Horodatage de création du crond backdooré copié sur /usr/bin/ssh |
| Évasion défensive | Disable or Modify OS Logging | T1562.006 | Compteurs de connexion HAProxy nettoyés atomiquement via offsets codés en dur |
| Évasion défensive | Obfuscated Files or Information | T1027 | XOR chaîné et substitution monoalphabétique sur configuration et scripts, XOR à rétroaction plus base64 sur le C2 |
| Évasion défensive | Virtualization/Sandbox Evasion | T1497.001 | Chien de garde vérifiant /usr/lib/libvirtlog.so.0 avant activation |
| Évasion défensive | Execution Guardrails | T1480 | Stager déployant uniquement si HAProxy ou cron est présent, validation du jeton victime, liste noire d'IP de scanners |
| Accès aux identifiants | Modify Authentication Process: PAM | T1556.003 | Keylogger SSH interceptant les mots de passe en clair |
| Accès aux identifiants | Steal Web Session Cookie | T1539 | Capture passive des sessions HTTP et des cookies par filtres regex |
| Découverte | System Information Discovery | T1082 | Profilage hôte, distribution, noyau, architecture par le stager, balise de 10 Ko de curlRAT |
| Découverte | Process Discovery | T1057 | Chien de garde interrogeant le PID HAProxy toutes les heures |
| Collecte | Browser Session Hijacking | T1185 | Corps de réponse remplacé ou complété par un script déchiffré via les callbacks de filtre HAProxy |
| Collecte | Automated Collection | T1119 | Journalisation horodatée par requête correspondante |
| Commande et contrôle | Application Layer Protocol: Web Protocols | T1071.001 | C2 de ted tunnelisé en HTTP à travers le répartiteur, curlRAT en HTTPS avec repli HTTP |
| Commande et contrôle | Data Encoding: Standard Encoding | T1132.001 | Base64 après XOR à rétroaction pour curlRAT, XOR roulant sur le protocole de pipe de ted |
| Commande et contrôle | Web Service | T1102 | Repli sur img.monderhouse.space, img.darklights.store comme hôte de configuration de secours |
| Commande et contrôle | Protocol Tunneling | T1572 | Shell interactif tunnelisé par FIFO nommées, réponse exfiltrée par send() direct hors journalisation HAProxy |
| Exfiltration | Exfiltration Over C2 Channel | T1041 | Identifiants SSH et sortie de commande renvoyés par le même canal |
| Exfiltration | Archive Collected Data | T1560 | Chiffrement par substitution avant écriture, XOR à rétroaction plus base64 en sortie |
Remédiation : checklist opérationnelle
- Vérifier l'intégrité des binaires HAProxy en production par comparaison d'empreinte avec les paquets officiels de la distribution ou avec une recompilation de référence. Un binaire de 18 Mo pour un HAProxy 2.8.12 doit être considéré comme suspect en soi.
- Rechercher immédiatement les empreintes et domaines listés en section IOC dans les journaux DNS, proxy et EDR, en remontant au moins à début 2025 compte tenu de la durée estimée de la campagne.
- Chercher sur les serveurs de bordure les chemins de cache haproxy-1000 à 1002, /var/lib/snapd/g580, /var/lib/sshd/c8c68e629bba773a10ac80012d10bf19, /tmp/jasper-log et les FIFO nommées sous /tmp.
- Alerter sur toute requête HTTP vers /favorite_list_2x_m500_ico.jpg au niveau du pare-feu applicatif ou de la capture réseau, indépendamment des journaux du répartiteur.
- Contrôler l'intégrité de crond, agetty, atd, polkitd et sshd sur les serveurs internes, en comparant aux paquets de la distribution plutôt qu'aux horodatages, qui sont falsifiés.
- Corréler le trafic réseau sortant des serveurs de bordure hors des journaux applicatifs. Le C2 de ted ne remonte dans aucun journal HAProxy et n'atteint aucun backend : seule une capture réseau ou un flux NetFlow indépendant le voit.
- Traquer les balises HTTPS régulières vers des sous-domaines img. sur des TLD .store, .space, .site et .autos, en tenant compte d'un intervalle par défaut de douze heures, qui échappe aux règles de détection calibrées sur des périodicités courtes.
- Faire tourner tous les identifiants SSH et applicatifs susceptibles d'avoir transité par un serveur de bordure compromis, y compris ceux des comptes de service.
- Traiter les composants de bordure gérant le trafic, la terminaison TLS ou des modules d'exécution avec le même niveau d'exigence que les serveurs applicatifs : durcissement, journalisation externalisée et contrôle d'intégrité périodique.
- Sur les environnements exposant un portail Groupware ou un serveur de messagerie sur Internet, prioriser la mise à jour de ces composants et la revue de leurs journaux d'authentification, le vecteur d'accès initial restant non confirmé.
Sources
- DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors, Rapid7 Labs, 4 septembre 2026
- New Ted Backdoor Hides Inside Victims Own HAProxy Builds to Intercept Web Traffic, The Hacker News
- North Korean Hackers Deploy New Linux Espionage Toolkit, SecurityWeek
- DPRK-Linked Hackers Backdoor HAProxy Servers to Spy on South Korean Organizations, GBHackers