﻿﻿{"id":1613,"date":"2025-11-18T12:23:08","date_gmt":"2025-11-18T11:23:08","guid":{"rendered":"https:\/\/elearningsamba.com\/index.php\/twoface-quand-les-sandbox-deviennent-inutiles\/"},"modified":"2025-11-18T12:23:08","modified_gmt":"2025-11-18T11:23:08","slug":"twoface-quand-les-sandbox-deviennent-inutiles","status":"publish","type":"page","link":"https:\/\/elearningsamba.com\/index.php\/twoface-quand-les-sandbox-deviennent-inutiles\/","title":{"rendered":"TwoFace &#8211; Quand les sandbox deviennent inutiles"},"content":{"rendered":"<p>\n<a href=\"https:\/\/github.com\/synacktiv\/twoface\">TwoFace<\/a><br \/>\nest un outil d\u00e9velopp\u00e9 par<br \/>\n<a href=\"https:\/\/www.synacktiv.com\/\">Synacktiv<\/a><br \/>\nqui permet de cr\u00e9er des binaires Linux ayant 2 comportements bien distincts. Un comportement parfaitement inoffensif qui s\u2019active dans 99% des cas et un comportement malveillant qui ne se d\u00e9clenche que sur une machine cibl\u00e9e sp\u00e9cifiquement pour l\u2019occasion.<\/p>\n<p>Comme \u00e7a, votre sandbox verra toujours la version \u201cpropre\u201d parce qu\u2019elle n\u2019aura pas le bon UUID de partition.<\/p>\n<p>D\u2019apr\u00e8s la doc de Synacktiv,<br \/>\n<a href=\"https:\/\/www.synacktiv.com\/en\/publications\/creating-a-two-face-rust-binary-on-linux\">voici comment \u00e7a fonctionne<\/a><br \/>\n: Vous avez deux binaires en fait\u2026 Y\u2019en a un qui est inoffensif et un autre malveillant. TwoFace les fusionne alors en un seul ex\u00e9cutable. Ainsi, au moment du build, le binaire malveillant est chiffr\u00e9 avec une cl\u00e9 d\u00e9riv\u00e9e depuis l\u2019UUID des partitions disque de la machine cible. Cet UUID est unique, difficile \u00e0 deviner, et stable dans le temps ce qui est parfait pour identifier une machine sp\u00e9cifique.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/korben.info\/cdn-cgi\/image\/width=1200,fit=scale-down,quality=90,f=avif\/twoface-sandboxes-inutiles-malware-contextuel\/twoface-sandboxes-inutiles-malware-contextuel-1.webp\" alt=\"\" loading=\"lazy\"><\/p>\n<p>Ensuite au lancement, quand le binaire s\u2019ex\u00e9cute, il extrait l\u2019UUID du disque de la machine. Pour ce faire, il utilise HKDF (Hash-based Key Derivation Function) pour g\u00e9n\u00e9rer une cl\u00e9 de d\u00e9chiffrement depuis cet UUID et tente de d\u00e9chiffrer le binaire malveillant cach\u00e9. Si le d\u00e9chiffrement r\u00e9ussit (parce que l\u2019UUID match), il ex\u00e9cute le binaire malveillant. Par contre, si \u00e7a \u00e9choue (parce que l\u2019UUID ne correspond pas), il ex\u00e9cute le binaire inoffensif.<\/p>\n<p>Le projet est \u00e9crit en Rust et c\u2019est open source ! Et c\u2019est une belle d\u00e9mo (PoC) d\u2019un probl\u00e8me que tous ceux qui font de l\u2019analyse de binaires ont. En effet, d\u2019ordinaire, pour r\u00e9v\u00e9ler le vrai comportement d\u2019un malware on l\u2019ex\u00e9cute dans une sandbox et on peut ainsi observer en toute s\u00e9curit\u00e9 ce qu\u2019il fait, les fichiers qu\u2019il cr\u00e9es, les connexions r\u00e9seau qu\u2019il \u00e9tablit etc\u2026<\/p>\n<p>Mais avec TwoFace \u00e7a casse cette fa\u00e7on de faire. Et c\u2019est pareil pour les antivirus qui verront toujours la version inoffensive tant que l\u2019UUID ne correspond pas.<\/p>\n<p>Techniquement, TwoFace utilise <code>memfd_create()<\/code> pour ex\u00e9cuter le binaire d\u00e9chiffr\u00e9 en m\u00e9moire, sans toucher au disque, ce qui veut dire z\u00e9ro trace sur le syst\u00e8me de fichiers. Le binaire malveillant appara\u00eet directement en RAM, s\u2019ex\u00e9cute, puis dispara\u00eet. Et si vous utilisez io_uring pour l\u2019\u00e9criture m\u00e9moire, il n\u2019y a m\u00eame pas de trace syscall visible via <code>strace<\/code>.<\/p>\n<p>Et \u00e7a, c\u2019est la version basique car le document de Synacktiv mentionne \u00e9galement d\u2019autres techniques avanc\u00e9es possibles comme du d\u00e9chiffrement dynamique page par page du binaire ELF, des m\u00e9canismes anti-debugging, des chained loaders multi-niveaux\u2026etc\u2026<\/p>\n<p>Le parall\u00e8le avec la<br \/>\n<a href=\"https:\/\/korben.info\/backdoor-linux-faille-securite-critique-xz-utils.html\">backdoor XZ Utils<\/a><br \/>\nbackdoor est tr\u00e8s instructif car celle-ci a failli compromettre des millions de serveurs Linux parce qu\u2019un seul mainteneur a pouss\u00e9 du code malveillant dans une lib compress\u00e9e. Elle a alors \u00e9t\u00e9 d\u00e9couverte parce qu\u2019un dev a remarqu\u00e9 un ralentissement SSH bizarre et a creus\u00e9\u2026 Et TwoFace montre qu\u2019on peut faire encore pire sans toucher \u00e0 la supply chain.<\/p>\n<p>Pas besoin de corrompre un mainteneur de projet, de pousser un commit suspect chez Github. L\u00e0 suffit d\u2019\u00e9crire du code parfaitement propre, de le compilez avec TwoFace pour une machine sp\u00e9cifique, et de le d\u00e9ployez. Le code source sera alors auditable ainsi que le binaire mais l\u2019audit ne r\u00e9v\u00e8lera rien parce qu\u2019il se fera dans un environnement qui n\u2019aura pas le bon UUID.<\/p>\n<p>Apr\u00e8s, techniquement, une d\u00e9fense existe. Vous pouvez par exemple d\u00e9tecter les appels \u00e0 <code>memfd_create()<\/code>, monitorer les ex\u00e9cutions en m\u00e9moire, tracer les d\u00e9chiffrements crypto \u00e0 la vol\u00e9e\u2026etc., mais \u00e7a demande du monitoring profond, avec un co\u00fbt performance non-n\u00e9gligeable. Et \u00e7a suppose aussi que vous savez ce que vous cherchez\u2026<\/p>\n<p>Bref, si \u00e7a vous int\u00e9resse, c\u2019est dispo sur<br \/>\n<a href=\"https:\/\/github.com\/synacktiv\/twoface\">GitHub<\/a><br \/>\n!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TwoFace est un outil d\u00e9velopp\u00e9 par Synacktiv qui permet de cr\u00e9er des binaires Linux ayant 2 comportements bien distincts. Un comportement parfaitement inoffensif qui s\u2019active dans 99% des cas et un comportement malveillant qui ne se d\u00e9clenche que sur une machine cibl\u00e9e sp\u00e9cifiquement pour l\u2019occasion. Comme \u00e7a, votre sandbox verra toujours la version \u201cpropre\u201d parce qu\u2019elle n\u2019aura pas le bon UUID de partition. D\u2019apr\u00e8s la doc de Synacktiv, voici comment \u00e7a fonctionne : Vous avez deux binaires en fait\u2026 Y\u2019en a un qui est inoffensif et un autre malveillant. TwoFace les fusionne alors en un seul ex\u00e9cutable. Ainsi, au moment du build, le binaire malveillant est chiffr\u00e9 avec une cl\u00e9 d\u00e9riv\u00e9e depuis l\u2019UUID des partitions disque de la machine cible. Cet UUID est unique, difficile \u00e0 deviner, et stable dans le temps ce qui est parfait pour identifier une machine sp\u00e9cifique. Ensuite au lancement, quand le binaire s\u2019ex\u00e9cute, il extrait l\u2019UUID du disque de la machine. Pour ce faire, il utilise HKDF (Hash-based Key Derivation Function) pour g\u00e9n\u00e9rer une cl\u00e9 de d\u00e9chiffrement depuis cet UUID et tente de d\u00e9chiffrer le binaire malveillant cach\u00e9. Si le d\u00e9chiffrement r\u00e9ussit (parce que l\u2019UUID match), il ex\u00e9cute le binaire malveillant. Par contre, si \u00e7a \u00e9choue (parce que l\u2019UUID ne correspond pas), il ex\u00e9cute le binaire inoffensif. Le projet est \u00e9crit en Rust et c\u2019est open source ! Et c\u2019est une belle d\u00e9mo (PoC) d\u2019un probl\u00e8me que tous ceux qui font de l\u2019analyse de binaires ont. En effet, d\u2019ordinaire, pour r\u00e9v\u00e9ler le vrai comportement d\u2019un malware on l\u2019ex\u00e9cute dans une sandbox et on peut ainsi observer en toute s\u00e9curit\u00e9 ce qu\u2019il fait, les fichiers qu\u2019il cr\u00e9es, les connexions r\u00e9seau qu\u2019il \u00e9tablit etc\u2026 Mais avec TwoFace \u00e7a casse cette fa\u00e7on de faire. Et c\u2019est pareil pour les antivirus qui verront toujours la version inoffensive tant que l\u2019UUID ne correspond pas. Techniquement, TwoFace utilise memfd_create() pour ex\u00e9cuter le binaire d\u00e9chiffr\u00e9 en m\u00e9moire, sans toucher au disque, ce qui veut dire z\u00e9ro trace sur le syst\u00e8me de fichiers. Le binaire malveillant appara\u00eet directement en RAM, s\u2019ex\u00e9cute, puis dispara\u00eet. Et si vous utilisez io_uring pour l\u2019\u00e9criture m\u00e9moire, il n\u2019y a m\u00eame pas de trace syscall visible via strace. Et \u00e7a, c\u2019est la version basique car le document de Synacktiv mentionne \u00e9galement d\u2019autres techniques avanc\u00e9es possibles comme du d\u00e9chiffrement dynamique page par page du binaire ELF, des m\u00e9canismes anti-debugging, des chained loaders multi-niveaux\u2026etc\u2026 Le parall\u00e8le avec la backdoor XZ Utils backdoor est tr\u00e8s instructif car celle-ci a failli compromettre des millions de serveurs Linux parce qu\u2019un seul mainteneur a pouss\u00e9 du code malveillant dans une lib compress\u00e9e. Elle a alors \u00e9t\u00e9 d\u00e9couverte parce qu\u2019un dev a remarqu\u00e9 un ralentissement SSH bizarre et a creus\u00e9\u2026 Et TwoFace montre qu\u2019on peut faire encore pire sans toucher \u00e0 la supply chain. Pas besoin de corrompre un mainteneur de projet, de pousser un commit suspect chez Github. L\u00e0 suffit d\u2019\u00e9crire du code parfaitement propre, de le compilez avec TwoFace pour une machine sp\u00e9cifique, et de le d\u00e9ployez. Le code source sera alors auditable ainsi que le binaire mais l\u2019audit ne r\u00e9v\u00e8lera rien parce qu\u2019il se fera dans un environnement qui n\u2019aura pas le bon UUID. Apr\u00e8s, techniquement, une d\u00e9fense existe. Vous pouvez par exemple d\u00e9tecter les appels \u00e0 memfd_create(), monitorer les ex\u00e9cutions en m\u00e9moire, tracer les d\u00e9chiffrements crypto \u00e0 la vol\u00e9e\u2026etc., mais \u00e7a demande du monitoring profond, avec un co\u00fbt performance non-n\u00e9gligeable. Et \u00e7a suppose aussi que vous savez ce que vous cherchez\u2026 Bref, si \u00e7a vous int\u00e9resse, c\u2019est dispo sur GitHub !<\/p>\n","protected":false},"author":1,"featured_media":1614,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"give_campaign_id":0,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_kadence_starter_templates_imported_post":false,"footnotes":""},"class_list":["post-1613","page","type-page","status-publish","has-post-thumbnail","hentry"],"campaignId":"","_links":{"self":[{"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/pages\/1613","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/comments?post=1613"}],"version-history":[{"count":0,"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/pages\/1613\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/media\/1614"}],"wp:attachment":[{"href":"https:\/\/elearningsamba.com\/index.php\/wp-json\/wp\/v2\/media?parent=1613"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}