<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Maxime Meignan, Auteur</title>
	<atom:link href="https://www.riskinsight-wavestone.com/author/maxime-meignan/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.riskinsight-wavestone.com/en/author/maxime-meignan/</link>
	<description>Le blog cybersécurité des consultants Wavestone</description>
	<lastBuildDate>Mon, 09 Oct 2023 16:00:47 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.riskinsight-wavestone.com/wp-content/uploads/2024/02/Blogs-2024_RI-39x39.png</url>
	<title>Maxime Meignan, Auteur</title>
	<link>https://www.riskinsight-wavestone.com/en/author/maxime-meignan/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Un bypass EDR universel découvert dans Windows 10 </title>
		<link>https://www.riskinsight-wavestone.com/2023/10/un-bypass-edr-universel-decouvert-dans-windows-10/</link>
					<comments>https://www.riskinsight-wavestone.com/2023/10/un-bypass-edr-universel-decouvert-dans-windows-10/#respond</comments>
		
		<dc:creator><![CDATA[Maxime Meignan]]></dc:creator>
		<pubDate>Mon, 09 Oct 2023 16:00:44 +0000</pubDate>
				<category><![CDATA[Cybersecurity & Digital Trust]]></category>
		<category><![CDATA[Ethical Hacking & Incident Response]]></category>
		<category><![CDATA[bypass]]></category>
		<category><![CDATA[EDR]]></category>
		<category><![CDATA[Windows 10]]></category>
		<guid isPermaLink="false">https://www.riskinsight-wavestone.com/?p=21172</guid>

					<description><![CDATA[<p>En étudiant les mécanismes internes d’un système utilisé par tous les EDR pour obtenir de l’information sur les activités des processus sous Windows, nous avons découvert un moyen pour un processus malveillant de désactiver la génération de certains événements de...</p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/2023/10/un-bypass-edr-universel-decouvert-dans-windows-10/">Un bypass EDR universel découvert dans Windows 10 </a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com">RiskInsight</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p style="text-align: justify;">En étudiant les mécanismes internes d’un système utilisé par tous les EDR pour obtenir de l’information sur les activités des processus sous Windows, nous avons découvert un moyen pour un processus malveillant de <strong>désactiver la génération de certains événements de sécurité</strong> liés aux interactions entre processus. Cette technique pourrait être utilisée pour <strong>contourner la surveillance effectuée par un EDR</strong> et ainsi réaliser des opérations malveillantes telles que <em>dump</em> mémoire d’un processus, l’injection de code, ou le <em>process hollowing</em>.</p>
<p style="text-align: justify;"> </p>
<h2 style="text-align: justify;">Rappel sur les capacités de surveillance des EDR</h2>
<h3 style="text-align: justify;">Méthodes basées sur l’espace utilisateur vs. l’espace noyau</h3>
<p style="text-align: justify;">Sous Windows, les logiciels EDR utilisent principalement deux catégories de techniques pour surveiller les actions effectuées par les processus : les mécanismes <strong>côté espace utilisateur</strong> (« <em>userland</em> », ou « <em>userspace</em> »), tel que le <strong><em>hooking</em></strong> de fonctions, qui ciblent chaque processus individuellement, et ceux <strong>côté noyau</strong> (« <em>kernel land</em> », « <em>kernel space</em> »), qui s&rsquo;appuient sur les <strong>fonctions fournies par le système d&rsquo;exploitation</strong> pour collecter des données de télémétrie sur l&rsquo;activité des processus à l&rsquo;échelle du système.</p>
<p style="text-align: justify;">Les techniques de la <strong>première catégorie</strong> peuvent souvent être techniquement <strong>contournées par un processus malveillant</strong>, à condition qu&rsquo;il connaisse les moyens exacts employés par l&rsquo;EDR. En effet, le code de surveillance et le code surveillé <strong>s&rsquo;exécutent souvent dans le même « espace »,</strong> la <strong>mémoire du processus</strong>, ce qui revient à un jeu du chat et de la souris entre le logiciel malveillant et l&rsquo;EDR, étant donné que chacun peut interagir ou modifier le code de la « partie adverse ».</p>
<p style="text-align: justify;">Pour la <strong>deuxième catégorie</strong>, le code de surveillance s&rsquo;exécute <strong>dans l&rsquo;espace du noyau Windows</strong>, qui n&rsquo;est <strong>directement accessible par aucun processus</strong>, quel que soit son niveau de privilège. Cependant, ces capacités de surveillance sont <strong>fournies par Windows lui-même</strong> aux produits de sécurité installés, et tous les logiciels EDR sont obligés de les utiliser de manière presque identique pour obtenir une télémétrie des activités des processus (la manière de détecter une activité malveillante à partir de ces informations dépend évidemment de chaque logiciel EDR).</p>
<p style="text-align: justify;">Pour approfondir le sujet, ces deux types de mécanismes ont notamment été décrits dans <a href="https://connect-ed--diamond-com.translate.goog/misc/misc-116/tour-d-horizon-des-mecanismes-de-supervision-des-edr"><strong>notre article</strong></a> de la 116<sup>ème</sup> édition du magazine MISC. Aussi, pour mieux comprendre les enjeux de ce qui suit dans le présent article, nous recommandons aux lecteurs de consulter <a href="https://connect.ed-diamond.com/misc/misc-118/techniques-de-contournement-de-la-supervision-des-edr"><strong>notre autre article sur les contournements de surveillance EDR</strong></a> dans la 118<sup>ème</sup> édition du magazine MISC, ainsi que le README de notre outil, <a href="https://github.com/wavestone-cdt/EDRSandblast"><strong>EDRSandblast</strong></a>.</p>
<p style="text-align: justify;"> </p>
<h3 style="text-align: justify;">Event Tracing for Windows &#8211; Threat Intelligence</h3>
<p style="text-align: justify;">Parmi les mécanismes susmentionnés, <em>Event Tracing for Windows &#8211; Threat Intelligence</em> (abrégé en ETW-Ti dans cet article) permet de <strong>générer des événements</strong> lors d&rsquo;opérations du noyau <strong>critiques pour la sécurité</strong>, telles que la création de processus, la lecture/écriture de mémoire entre processus, la création de mémoire exécutable, etc. (voir notre article dans MISC 116 pour plus de détails).</p>
<p style="text-align: justify;">Le flux d&rsquo;événements produit par le mécanisme n&rsquo;est normalement « consommable » que par les produits de sécurité, qui doivent être des processus protégés (<strong><em>PROTECTED_ANTIMALWARE_LIGHT</em></strong>), signés cryptographiquement comme tels par Microsoft.</p>
<p style="text-align: justify;">La création de ces événements de sécurité est gérée par le noyau Windows et est mise en œuvre par de simples appels à des fonctions <strong><em>EtwTi*</em></strong> dédiées, intégrées à chaque fonction du noyau présentant un intérêt. L&rsquo;image suivante montre l&rsquo;appel à <strong><em>EtwTiLogReadWriteVm</em></strong> à l&rsquo;intérieur de la fonction <strong><em>MiReadWriteVirtualMemory</em></strong>, cette dernière étant responsable des lectures et écritures de mémoire entre les processus.</p>
<figure id="attachment_21135" aria-describedby="caption-attachment-21135" style="width: 405px" class="wp-caption aligncenter"><img fetchpriority="high" decoding="async" class="wp-image-21135 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-callToEtwTI.png" alt="A call to EtwTiLogReadWriteVm highlighted in a control-flow graph" width="405" height="602" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-callToEtwTI.png 405w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-callToEtwTI-128x191.png 128w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-callToEtwTI-26x39.png 26w" sizes="(max-width: 405px) 100vw, 405px" /><figcaption id="caption-attachment-21135" class="wp-caption-text"><span style="font-size: revert; color: initial;"> Figure 1: Appel à </span><strong style="font-size: revert; color: initial;"><em>EtwTiLogReadWriteVm</em></strong><span style="font-size: revert; color: initial;"> au sein de </span><strong style="font-size: revert; color: initial;"><em>MiReadWriteVirtualMemory</em></strong></figcaption></figure>
<p style="text-align: justify;"> </p>
<h2 style="text-align: justify;">Nos constats</h2>
<h3 style="text-align: justify;">Une exception bien commode</h3>
<p style="text-align: justify;">En examinant le graphique du flot de contrôle de la fonction ci-dessus, nous constatons que l&rsquo;appel à la fonction de journalisation de l&rsquo;ETW-Ti est toujours effectué lors d&rsquo;un appel réussi à <strong><em>MiReadWriteVirtualMemory</em></strong>, à moins que <strong><em>PsIsProcessLoggingEnabled</em></strong> ne renvoie la valeur <strong><em>FALSE</em></strong>.</p>
<p style="text-align: justify;">Cette dernière fonction, qui n&rsquo;est mentionnée nulle part dans la littérature consacrée au reverse engineering de Windows, permet d&rsquo;effectuer les opérations suivantes (note : les commentaires, les noms et les types de variables ont été obtenus par reverse engineering et/ou déduits des <a href="https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/2110%2021H2%20(November%202021%20Update)/_EPROCESS">symboles de débogage publics</a>) :</p>
<p style="text-align: justify;"><img decoding="async" class="aligncenter wp-image-21138 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-PsIsProcessLoggingEnabled.png" alt="decompiled source code of PsIsProcessLoggingEnabled" width="1299" height="787" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-PsIsProcessLoggingEnabled.png 1299w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-PsIsProcessLoggingEnabled-315x191.png 315w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-PsIsProcessLoggingEnabled-64x39.png 64w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-PsIsProcessLoggingEnabled-768x465.png 768w" sizes="(max-width: 1299px) 100vw, 1299px" /></p>
<p style="text-align: center;">Figure 2: Code source de <strong><em>PsIsProcessLoggingEnabled</em></strong> obtenu par reverse-engineering</p>
<p style="text-align: justify;">Comme nous pouvons le voir, la fonction vérifie l&rsquo;état d&rsquo;un flag parmi <strong><em>EnableReadVmLogging</em></strong>, <strong><em>EnableWriteVmLogging</em></strong>, <strong><em>EnableThreadSuspendResumeLogging</em></strong> et <strong><em>EnableProcessSuspendResumeLogging</em></strong>, indiquant si l&rsquo;action en cours (parmi une lecture de mémoire interprocessus, une écriture de mémoire, une suspension/reprise de thread ou une suspension/reprise de processus, respectivement) doit être effectivement enregistrée par ETW-Ti. Ces flags se trouvent dans différents <em>bitfields</em> de la structure <strong><em>_EPROCESS</em></strong> du processus ciblé.</p>
<p style="text-align: justify;"> </p>
<h3 style="text-align: justify;">Accès aux flags de journalisation</h3>
<p style="text-align: justify;">En recoupant l&rsquo;utilisation des flags susmentionnés dans le noyau, nous avons constaté que les fonctions <strong><em>NtQueryInformationProcess</em></strong> et <strong><em>NtSetInformationProcess</em></strong> étaient utilisés pour obtenir ou définir les bits spécifiques correspondant à ces flags de journalisation (<em>logging</em>).</p>
<p style="text-align: justify;">Bien que la plupart du temps non documentées, ces fonctions ont été examinées de près par les <em>reverse-engineers</em> s’intéressant aux mécanismes internes de Windows (et par les développeurs de logiciels malveillants) depuis longtemps, car elles gèrent les <strong>appels système </strong>éponymes <strong>accessibles à partir de l&rsquo;espace utilisateur</strong>. Le projet <a href="https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/2110%2021H2%20(November%202021%20Update)/_EPROCESS">System Informer</a> (anciennement connu sous le nom de Process Hacker) abrite une base de données impressionnante de prototypes de fonctions, de structures et d&rsquo;<em>enums</em> liés aux mécanismes internes de Windows.</p>
<p style="text-align: justify;">Le prototype de la fonction <strong><em>NtSetInformationProcess</em></strong> est le suivant :</p>
<p style="text-align: justify;"><img decoding="async" class="aligncenter wp-image-21141 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcess.png" alt="Reversed source code of NtSetInformationProcess" width="729" height="269" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcess.png 729w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcess-437x161.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcess-71x26.png 71w" sizes="(max-width: 729px) 100vw, 729px" /></p>
<p style="text-align: center;">Figure 3: Prototype de la fonction <strong><em>NtSetInformationProcess</em></strong></p>
<p style="text-align: justify;">Cette fonction gère une centaine de cas d&rsquo;utilisation, selon la valeur du paramètre <strong><em>ProcessInformationClass</em></strong>. La fonction est implémentée à l&rsquo;aide d&rsquo;une énorme instruction <em>switch</em>, et le code spécifique concernant les flags de journalisation est situé dans les <em>cases</em> <strong><em>ProcessEnableReadWriteVmLogging</em></strong> et <strong><em>ProcessEnableLogging</em></strong> (constantes non documentées, nommées ainsi par les développeurs de System Informer).</p>
<p style="text-align: justify;"><img loading="lazy" decoding="async" class="aligncenter wp-image-21144 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplem.png" alt="Reverse-engineered source code of NtSetInformationProcess" width="1767" height="922" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplem.png 1767w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplem-366x191.png 366w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplem-71x37.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplem-768x401.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplem-1536x801.png 1536w" sizes="auto, (max-width: 1767px) 100vw, 1767px" /></p>
<p style="text-align: center;">Figure 4: Code source de <strong><em>NtSetInformationProcess</em></strong> obtenu par reverse-engineering</p>
<p style="text-align: justify;">Le comportement du code ci-dessus peut être réduit aux points suivants :</p>
<ul style="text-align: justify;">
<li>La cohérence de l&rsquo;argument <strong><em>ProcessInformationLength</em></strong> est vérifiée par rapport à la structure <strong><em>ProcessInformation</em></strong> attendue (c&rsquo;est-à-dire que les flags sont stockés dans un <strong><em>BYTE</em></strong> ou dans un <strong><em>DWORD</em></strong>, voir les structures attendues pour <a href="https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/2110%2021H2%20(November%202021%20Update)/_EPROCESS"><strong><em>ProcessEnableReadWriteVmLogging</em></strong></a> et <a href="https://www.vergiliusproject.com/kernels/x64/Windows%2010%20%7C%202016/2110%2021H2%20(November%202021%20Update)/_EPROCESS"><strong><em>ProcessEnableLogging</em></strong></a>) ;</li>
<li>Les privilèges du processus sont vérifiés : l&rsquo;appel n&rsquo;est accepté que si au moins l&rsquo;un des privilèges <strong><em>SeDebugPrivilege</em></strong> ou <strong><em>SeTcbPrivilege</em></strong> est détenu par le processus appelant ;</li>
<li>L&rsquo;objet noyau (<strong><em>_EPROCESS</em></strong>) du processus cible est récupéré, tout en vérifiant que son <em>handle</em> possède bien le droit d&rsquo;accès <strong><em>PROCESS_SET_LIMITED_INFORMATION</em></strong> ;</li>
<li>Différents flags (provenant des champs <strong><em>Flags2</em></strong> et <strong><em>Flags3</em></strong> de la structure <strong><em>_EPROCESS</em></strong>) sont mis à jour, sur la base de la structure <strong><em>ProcessInformation</em></strong></li>
</ul>
<p style="text-align: justify;">Les flags qui peuvent être mis à jour par cette méthode sont les suivants :</p>
<ul style="text-align: justify;">
<li><strong><em>EnableProcessSuspendResumeLogging</em></strong> (ou <strong><em>EnableThreadSuspendResumeLogging</em></strong>) : détermine si un événement ETW-Ti est généré lors de la <strong>suspension</strong> ou de la <strong>reprise</strong> d&rsquo;un <strong>processus</strong> (ou d&rsquo;un <strong>thread</strong>). Ces opérations sont utilisées dans les techniques de <a href="https://attack.mitre.org/techniques/T1055/012/"><em>process hollowing</em></a>, par exemple ;</li>
<li><strong><em>EnableReadVmLogging</em></strong> : détermine si un événement ETW-Ti est généré lors de la lecture de la mémoire d&rsquo;un processus par un autre. Ces opérations sont généralement utilisées dans les techniques de dump de processus (<a href="https://attack.mitre.org/techniques/T1003/001/">LSASS</a>, notamment) ;</li>
<li><strong><em>EnableWriteVmLogging</em></strong> : idem, pour les écritures en mémoire entre processus. Ces opérations sont utilisées dans la plupart des techniques <a href="https://attack.mitre.org/techniques/T1055/012/">d&rsquo;injection de processus</a>.</li>
</ul>
<h3 style="text-align: justify;">Du point de vue offensif</h3>
<p style="text-align: justify;">En résumé, si le mécanisme ETW-Ti ne peut pas être désactivé globalement sur le système depuis l&rsquo;espace utilisateur (c&rsquo;est-à-dire par un processus), <strong>certaines de ses fonctionnalités peuvent être désactivées</strong> par un processus disposant du privilège <strong><em>SeDebugPrivilege</em></strong> ou <strong><em>SeTcbPrivilege</em></strong>, ce qui peut être le cas de n&rsquo;importe quel processus élevé.</p>
<p style="text-align: justify;">Comme indiqué précédemment, le flux d&rsquo;événements de l&rsquo;ETW-Ti n&rsquo;est normalement accessible qu&rsquo;aux produits de sécurité tels que les EDR. Cependant, dans la fonction ci-dessus, nous voyons que n&rsquo;importe quel processus non protégé peut désactiver certaines fonctions de journalisation d&rsquo;un autre processus <strong>sans prouver au système qu&rsquo;il est un consommateur légitime du flux ETW-Ti (ex. un EDR)</strong>.</p>
<p style="text-align: justify;">Il est important de noter que les EDR mettent souvent en <strong>corrélation plusieurs événements</strong> pour créer des alertes, afin de ne pas générer de résultats <strong>faussement positifs</strong>. Par exemple, un dump du processus LSASS est souvent divisé en plusieurs étapes :</p>
<ul style="text-align: justify;">
<li>L&rsquo;ouverture d&rsquo;un handle au processus <strong><em>exe</em></strong> ayant un accès <strong><em>PROCESS_VM_READ</em></strong> ;</li>
<li>La lecture effective de toutes les plages de mémoire concernées ;</li>
<li>La création d&rsquo;un fichier minidump.</li>
</ul>
<p style="text-align: justify;">Si seul l&rsquo;événement de création d&rsquo;un <em>handle</em> existe, mais que les événements de lecture <strong>ne sont pas enregistrés par ETW-Ti</strong> et que le fichier minidump est chiffré ou n&rsquo;a jamais été écrit sur le disque, l&rsquo;EDR <strong>peut ne pas émettre d&rsquo;alertes</strong> concernant le dump du processus LSASS, faute de preuves.</p>
<h2 style="text-align: justify;">Versions de Windows affectées</h2>
<h3 style="text-align: justify;">Différences entre Windows 10 et Windows 11</h3>
<p style="text-align: justify;">La même analyse a été effectuée sur le code <strong><em>NtSetInformationProcess</em></strong> du noyau de Windows 11.</p>
<p><img loading="lazy" decoding="async" class="wp-image-21146 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplemWin11.png" alt="Reverse-engineered source code of NtSetInformationProcess on Windows 11" width="1779" height="1268" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplemWin11.png 1779w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplemWin11-268x191.png 268w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplemWin11-55x39.png 55w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplemWin11-768x547.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-NtSetInformationProcessImplemWin11-1536x1095.png 1536w" sizes="auto, (max-width: 1779px) 100vw, 1779px" /></p>
<p style="text-align: center;">Figure 5: Code source de <strong><em>NtSetInformationProcess</em></strong> obtenu par reverse-engineering sous Windows 11</p>
<p style="text-align: justify;">Le code présente deux différences principales. La première, et la plus importante : le niveau de protection du processus appelant <strong><em>NtSetInformationProcess</em></strong> est vérifié comme étant « dominant » par rapport au niveau <strong><em>ANTIMALWARE_LIGHT</em></strong>, à l&rsquo;aide de l&rsquo;appel à <strong><em>EtwCheckSecurityLoggerAccess</em></strong>. Pour information, on dit qu&rsquo;un niveau de protection en domine un autre si les deux affirmations suivantes sont vraies :</p>
<ul style="text-align: justify;">
<li>Le type de protection (<strong><em>Protected</em></strong>, <strong><em>Protected light </em></strong>ou <strong><em>non protégé</em></strong>) est identique ou plus fort que l&rsquo;autre niveau de protection (<strong><em>Protected</em></strong> est « plus fort » que <strong><em>Protected light</em></strong>, qui est évidemment plus fort que <strong><em>non protégé</em></strong>).</li>
<li>Le signataire (<em>signer</em>) domine celui de l&rsquo;autre niveau de protection, selon des règles codées en dur dans le noyau Windows (analysées de la structure <strong><em>RtlProtectedAccess</em></strong>). Le graphique suivant décrit ces règles :</li>
</ul>
<p><img loading="lazy" decoding="async" class="wp-image-21148 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-ProtectedDomination.png" alt="Protected processes &quot;domination&quot; between different protection levels" width="878" height="443" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-ProtectedDomination.png 878w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-ProtectedDomination-379x191.png 379w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-ProtectedDomination-71x36.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2023/09/EDRbypass-ProtectedDomination-768x387.png 768w" sizes="auto, (max-width: 878px) 100vw, 878px" /></p>
<p style="text-align: center;">Figure 6: « Domination » des processus protégés entre les différents signataires</p>
<p style="text-align: justify;">Cela signifie que seul un processus <strong><em>protected</em></strong> ou <strong><em>protected</em></strong><em> <strong>light</strong></em> dont le signataire est <strong><em>WinSystem</em></strong>, <strong><em>WinTcb</em></strong>, <strong><em>Windows</em></strong> ou <strong><em>Antimalware</em></strong> (c&rsquo;est-à-dire un composant système ou un produit de sécurité <strong>signé cryptographiquement par Microsoft</strong> en tant que tel) est autorisé à utiliser l&rsquo;API <strong><em>NtSetInformationProcess</em></strong> pour désactiver les fonctions de journalisation ETW-Ti sous Windows 11. Il s&rsquo;agit d&rsquo;une amélioration importante, car elle établit une <strong>frontière cohérente</strong> entre les <strong>produits et fonctions de sécurité </strong>d&rsquo;une part, et les <strong>autres processus</strong> d&rsquo;autre part.</p>
<p style="text-align: justify;">La deuxième différence entre les implémentations de <strong><em>NtSetInformationProcess</em></strong> sous Windows 10 et Windows 11 est que de nouveaux flags de journalisation ETW-Ti semblent être modifiables avec l&rsquo;API : <strong><em>EnableProcessLocalExecProtectVmLogging</em></strong> et <strong><em>EnableProcessRemoteExecProtectVmLogging</em></strong>, apparemment utilisés pour activer/désactiver la surveillance des opérations <strong>rendant la mémoire exécutable</strong>.</p>
<p style="text-align: justify;">À titre d&rsquo;information, cette fonctionnalité semble toutefois être boguée ou n&rsquo;est pas encore complètement implémentée, puisque dans le code présenté plus haut, les bits correspondant ne sont pas mis à zéro par l&rsquo;opération AND bit-à-bit (<strong><em>InterlockedAnd</em></strong>), les fonctionnalités correspondantes ne peuvent donc pas être désactivées à l&rsquo;aide de cette API.</p>
<p style="text-align: justify;"> </p>
<h3 style="text-align: justify;">Périmètre exact des versions affectées</h3>
<p style="text-align: justify;">L&rsquo;analyse de diverses versions du noyau dans différentes versions de Windows a montré <strong>que la première version disponible de Windows 11</strong> (21H2, version 10.0.22000.194) <strong>met déjà en œuvre</strong> le contrôle de sécurité effectué par <strong><em>EtwCheckSecurityLoggerAccess</em></strong> décrit plus haut.</p>
<p style="text-align: justify;">En revanche, dans la <strong>dernière version disponible de Windows 10</strong> au moment de la rédaction (22H2, version 10.0.19041.3393), la <strong>vérification de sécurité est toujours absente</strong>, alors que cette version est plus récente de 2 ans. Cela indique selon toute vraisemblance que Microsoft est bien conscient du problème et ne corrige pas la faiblesse volontairement, probablement pour des raisons de rétrocompatibilité.</p>
<p style="text-align: justify;">Les différents flags de journalisation et leur traitement associé par <strong><em>NtSetInformationProcess</em></strong> sont apparus progressivement au cours de la vie du produit Windows 10. Le tableau suivant résume les versions concernées :</p>
<table>
<tbody>
<tr>
<td width="130">
<p> </p>
</td>
<td width="130">
<p>Win10</p>
<p>1507 -&gt; 1703</p>
</td>
<td width="130">
<p>Win10</p>
<p>1709 -&gt; 1803</p>
</td>
<td width="130">
<p>Win10</p>
<p>1809 -&gt; 22H2</p>
</td>
<td width="130">
<p>Win11</p>
<p>21H2 -&gt; 22H2</p>
</td>
</tr>
<tr>
<td width="130">
<p>Opération de lecture mémoire</p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
</tr>
<tr>
<td width="130">
<p>Opération d’écriture mémoire</p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
</tr>
<tr>
<td width="130">
<p>Opérations d’arrêt/reprise d’un processus</p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
</tr>
<tr>
<td width="130">
<p>Opérations d’arrêt/reprise d’un thread</p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
<td width="130">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
</td>
</tr>
</tbody>
</table>
<p style="text-align: justify;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> : La fonction de journalisation ETWTi n’existe pas encore <br /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> : La journalisation ETWTi peut être désactivée<br /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> : La journalisation ETWTi ne peut pas être désactivée</p>
<h2 style="text-align: justify;">Le mot de la fin</h2>
<p style="text-align: justify;">En conclusion, le mécanisme décrit dans cet article permet de fait à un <strong>programme</strong> <strong>malveillant</strong> s’exécutant avec des <strong>privilèges élevés</strong> et souhaitant effectuer des <strong>actions néfastes</strong> (injection de processus, dump LSASS, <em>process hollowing</em>, etc.) de <strong>désactiver soigneusement la télémétrie</strong> associée avant de le faire, supprimant ainsi des preuves critiques de la surveillance EDR, ce qui améliore grandement ses chances de <strong>ne pas être détecté</strong>.</p>
<p style="text-align: justify;">De nombreux éléments montrent que <strong>Microsoft est conscient de la faiblesse</strong>, mais <strong>ne modifie pas le comportement de l&rsquo;API rétroactivement</strong> sur Windows 10, probablement en raison de problèmes de rétro-compatibilité.</p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/2023/10/un-bypass-edr-universel-decouvert-dans-windows-10/">Un bypass EDR universel découvert dans Windows 10 </a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com">RiskInsight</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.riskinsight-wavestone.com/2023/10/un-bypass-edr-universel-decouvert-dans-windows-10/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>L’été cybersécurité de Wavestone</title>
		<link>https://www.riskinsight-wavestone.com/2022/10/lete-cybersecurite-de-wavestone/</link>
					<comments>https://www.riskinsight-wavestone.com/2022/10/lete-cybersecurite-de-wavestone/#respond</comments>
		
		<dc:creator><![CDATA[Maxime Meignan]]></dc:creator>
		<pubDate>Fri, 14 Oct 2022 08:00:00 +0000</pubDate>
				<category><![CDATA[Eclairage]]></category>
		<category><![CDATA[Ethical Hacking & Incident Response]]></category>
		<category><![CDATA[camp]]></category>
		<category><![CDATA[hackers]]></category>
		<guid isPermaLink="false">https://www.riskinsight-wavestone.com/?p=18801</guid>

					<description><![CDATA[<p>Cette année encore, nous avons été ravis de pouvoir partager nos connaissances lors du Hacker Summer camp (conférences sur la cybersécurité qui se déroulent à peu près en même temps chaque année à Las Vegas : BlackHat, BSides Las Vegas...</p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/2022/10/lete-cybersecurite-de-wavestone/">L’été cybersécurité de Wavestone</a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com">RiskInsight</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p style="text-align: justify;"><em>Cette année encore, nous avons été ravis de pouvoir partager nos connaissances lors du Hacker Summer camp (conférences sur la cybersécurité qui se déroulent à peu près en même temps chaque année à Las Vegas : BlackHat, BSides Las Vegas et DEFCON).</em></p>
<p style="text-align: justify;"><em>(Thomas est absent sur cette photo car il a déjà quitté DEFCON pour participer au SANS DFIR Summit à Houston, Texas).</em></p>
<p style="text-align: justify;"><em>Dans cet article, nous partageons les supports &amp; code utilisés pour nos conférences, ateliers et démonstrations d&rsquo;outils.</em></p>
<h2 style="text-align: justify;"> </h2>
<h2 style="text-align: justify;">CI/CD security</h2>
<p style="text-align: justify;">Les pipelines CI/CD font de plus en plus partie de l&rsquo;infrastructure standard des équipes de développement. Avec la montée en puissance de nouvelles approches telles que l&rsquo;Infrastructure as Code, le niveau de sensibilité de ces pipelines augmente rapidement. En cas de compromission, ce ne sont plus seulement les applications qui sont en danger mais les systèmes sous-jacents eux-mêmes et bien souvent l&rsquo;ensemble du système d&rsquo;information.</p>
<p style="text-align: justify;">Nous pensons que ces infrastructures, bien qu&rsquo;elles ne soient pas ciblées par les attaquants pour le moment, deviendront un point de mire privilégié pour les attaquants dans les années à venir. À la fois en raison des informations d&rsquo;identification manipulées par les pipelines et du manque habituel de surveillance de ces environnements.</p>
<p style="text-align: justify;">Lors du Hacking Summer Camp, nous avons expliqué comment les attaquants commencent à exploiter ces faiblesses à la fois pour des attaques de chaînes d&rsquo;approvisionnement mais aussi pour élever leurs privilèges au sein du SI victime. Nous avons commencé par une présentation au BSides Las Vegas qui illustrait un chemin d&rsquo;attaque que nous avions déjà exploité en opération réelle. Ensuite, nous avons organisé deux workshops, aux BSides Las Vegas et à la DEFCON, pour permettre aux participants d&rsquo;exploiter ces attaques dans un laboratoire grandeur nature.</p>
<p style="text-align: justify;"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-18804" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2022/09/etecyberWSImage2.png" alt="" width="1068" height="766" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2022/09/etecyberWSImage2.png 1068w, https://www.riskinsight-wavestone.com/wp-content/uploads/2022/09/etecyberWSImage2-266x191.png 266w, https://www.riskinsight-wavestone.com/wp-content/uploads/2022/09/etecyberWSImage2-54x39.png 54w, https://www.riskinsight-wavestone.com/wp-content/uploads/2022/09/etecyberWSImage2-768x551.png 768w" sizes="auto, (max-width: 1068px) 100vw, 1068px" /></p>
<p style="text-align: justify;">Les slides et les ressources techniques seront bientôt publiées sur notre GitHub (https://github.com/wavestone-cdt/DEFCON-CICD-pipelines-workshop).</p>
<p style="text-align: justify;">Le replay de la conférence à Bsides Las Vegas est disponible sur YouTube : <a href="https://youtu.be/a3SeASgtINY">https://youtu.be/a3SeASgtINY</a>.</p>
<p style="text-align: justify;"><em>Par Rémi ESCOURROU (@remiescourrou), Gauthier SEBAUX (@zeronounours) et Xavier GERONDEAU (@reivaxxavier1).</em></p>
<p style="text-align: justify;"> </p>
<h2 style="text-align: justify;">Systèmes de contrôle industriel</h2>
<p style="text-align: justify;">Cette année, nous avons animé deux workshops sur la cybersécurité des SI industriels à la DEFCON :</p>
<h3 style="text-align: justify;">Une version actualisée de notre très populaire atelier « Pentesting ICS 101 »:</h3>
<p style="text-align: justify;">Nous avons abordé les bases du SI industriel et partagé un retour d&rsquo;expérience sur l&rsquo;état de la cybersécurité de ces environnements. Ensuite, à l&rsquo;aide de machines virtuelles préconfigurées, nous avons appris à échanger des données avec des automates. Ces connaissances ont ensuite été mises en pratique sur du matériel réel avec notre maquette de train :</p>
<p style="text-align: justify;"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-18807" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2022/09/Image3-summercamps.jpg" alt="" width="1050" height="849" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2022/09/Image3-summercamps.jpg 1050w, https://www.riskinsight-wavestone.com/wp-content/uploads/2022/09/Image3-summercamps-236x191.jpg 236w, https://www.riskinsight-wavestone.com/wp-content/uploads/2022/09/Image3-summercamps-48x39.jpg 48w, https://www.riskinsight-wavestone.com/wp-content/uploads/2022/09/Image3-summercamps-768x621.jpg 768w" sizes="auto, (max-width: 1050px) 100vw, 1050px" /></p>
<p style="text-align: justify;"> </p>
<h2 style="text-align: justify;">Un tout nouvel atelier sur la sécurité du code PLC</h2>
<p style="text-align: justify;">Nous avons également commencé par une introduction aux ICS, puis nous nous sommes plongés dans la programmation d&rsquo;un automate logiciel et avons montré comment l&rsquo;application des pratiques du <a href="https://www.plc-security.com/">PLC TOP20</a> peut prévenir les attaques et/ou aider à les détecter.</p>
<p style="text-align: justify;">Pour ce faire, nous avons également créé une simulation de processus très simplifiée qui se connecte au simulateur de PLC, que nous publions également. Cette simulation pourrait être utilisée et adaptée pour la sensibilisation et la formation aux SCI.</p>
<p style="text-align: justify;">Les slides sont disponible ici : <a href="https://github.com/wavestone-cdt/plc-code-security">GitHub &#8211; wavestone-cdt/plc-code-security: Experiments with the Top 20 Secure PLC Coding Practices</a></p>
<p style="text-align: justify;">Vous pouvez trouver notre simulation de processus ici : <a href="https://github.com/arnaudsoullie/simple-process-simulation">https://github.com/arnaudsoullie/simple-process-simulation</a></p>
<p style="text-align: justify;"> </p>
<h2 style="text-align: justify;"><span style="color: revert; font-size: revert; font-weight: revert;">DEFCON30 demo lab: EDRSandblast</span></h2>
<p style="text-align: justify;">Nous avons partagé une version nouvelle et améliorée d&rsquo;EDRSandblast lors des sessions Demo Lab à DEFCON 30. Ce fut l&rsquo;occasion de présenter et de détailler les mécanismes de détection employés par les EDRs (user-land hooking, kernel callbacks, ETW Threat Intelligence provider &#8230;), de montrer comment les contourner, ainsi que de présenter les nouvelles fonctionnalités de notre outil. La liste des mises à jour est la suivante : un nouveau mécanisme de détection est reconnu et contourné par l&rsquo;outil, plusieurs pilotes vulnérables sont désormais pris en charge, EDRSandblast peut désormais être inclus en tant que bibliothèque dans un projet tiers, et bien plus encore !</p>
<p style="text-align: justify;"> </p>
<p style="text-align: justify;">Vous pouvez trouver la liste complète des mises à jour, ainsi que la présentation sur GitHub : <a href="https://github.com/wavestone-cdt/EDRSandblast/blob/DefCon30Release/DEFCON30-DemoLabs-EDR_detection_mechanisms_and_bypass_techniques_with_EDRSandblast-v1.0.pdf">https://github.com/wavestone-cdt/EDRSandblast/blob/DefCon30Release/DEFCON30-DemoLabs-EDR_detection_mechanisms_and_bypass_techniques_with_EDRSandblast-v1.0.pdf</a></p>
<p style="text-align: justify;"><em>Par Maxime MEIGNAN (@th3m4ks) et Thomas DIOT (@_Qazeer).</em></p>
<p style="text-align: justify;"> </p>
<h2 style="text-align: justify;">SANS DFIR Summit 2022</h2>
<p style="text-align: justify;">Dans cette présentation, nous avons donné un bref aperçu de la procédure de récupération d&rsquo;une forêt AD et nous nous sommes concentrés sur les différents moyens de persistance utilisés par les attaquants sur Active Directory, certains bien connus, d&rsquo;autres moins. Certaines fonctionnalités de la nouvelle boîte à outils PowerShell de FarsightAD ont également été présentées, comme la détection d&rsquo;objets entièrement ou partiellement cachés à l&rsquo;aide du protocole Directory Replication Service.</p>
<p style="text-align: justify;">Vous pouvez trouver les slides et l’outil FarsightAD ici : <a href="https://github.com/Qazeer/FarsightAD">https://github.com/Qazeer/FarsightAD</a></p>
<p style="text-align: justify;">Par Thomas DIOT (@_Qazeer).</p>
<p style="text-align: justify;">Bonne lecture, bon tests, <em>Hack the Planet</em> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60a.png" alt="😊" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p style="text-align: justify;"> </p>
<p style="text-align: justify;"> </p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/2022/10/lete-cybersecurite-de-wavestone/">L’été cybersécurité de Wavestone</a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com">RiskInsight</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.riskinsight-wavestone.com/2022/10/lete-cybersecurite-de-wavestone/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Malwarebytes challenge write-up</title>
		<link>https://www.riskinsight-wavestone.com/2018/06/malwarebytes-challenge-write-up/</link>
		
		<dc:creator><![CDATA[Maxime Meignan]]></dc:creator>
		<pubDate>Tue, 12 Jun 2018 09:00:39 +0000</pubDate>
				<category><![CDATA[Cybersecurity & Digital Trust]]></category>
		<category><![CDATA[Deep-dive]]></category>
		<category><![CDATA[Ethical Hacking & Incident Response]]></category>
		<category><![CDATA[hackers]]></category>
		<category><![CDATA[malware]]></category>
		<guid isPermaLink="false">https://www.riskinsight-wavestone.com/?p=15584</guid>

					<description><![CDATA[<p>Malwarebytes published on April 27th a new reverse engineering challenge, an executable mixing malware behavior with a traditional crackme look. It came in the form of a Windows executable This document describes the solving step of the challenge. Lightweight analysis...</p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/2018/06/malwarebytes-challenge-write-up/">Malwarebytes challenge write-up</a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com">RiskInsight</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div class="separator" style="clear: both; text-align: center;">
<figure id="post-15585 media-15585" class="align-none"><img loading="lazy" decoding="async" class="size-full wp-image-15585 aligncenter" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I1.png" alt="" width="320" height="150" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I1.png 320w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I1-71x33.png 71w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure>
</div>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: left;"><span style="text-align: justify;">Malwarebytes published on April 27th a new reverse engineering challenge, an executable mixing malware behavior with a traditional crackme look. It came in the form of a Windows executable</span></div>
<p>This document describes the solving step of the challenge.</p>
<h2><span style="text-align: center;">Lightweight analysis of “mb_crackme_2.exe”</span></h2>
<div style="text-align: justify;">
<p>As we would do with any real malware, we start by performing some basic information gathering on the provided executable. Even if the static and dynamic approaches gave us similar conclusions on the executable’s nature (see 2.4), the different methods have been described nonetheless in the following sections.</p>
<h3>Basic static information gathering</h3>
<p>Using <b>Exeinfo PE</b>, a maintained successor of the renowned (but outdated) <b>PEiD</b> software, gives us some basic information about the binary:</p>
<ul>
<li> The program is a <b>32 bits Portable Executable</b> (PE), meant to be run in console (no GUI);</li>
<li> It seems to be compiled from C++ using Microsoft Visual C++ 8;</li>
<li> No obvious sign of packing is detected by the tool.</li>
</ul>
</div>
<div style="text-align: justify;"></div>
<div style="text-align: justify;">
<div style="text-align: justify;">
<div style="text-align: center;">
<figure id="post-15587 media-15587" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15587 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I2.png" alt="" width="518" height="255" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I2.png 518w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I2-388x191.png 388w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I2-71x35.png 71w" sizes="auto, (max-width: 518px) 100vw, 518px" /></figure>
<p><i><span style="font-size: x-small;">Output of Exeinfo PE</span></i>
</div>
<p>Looking for printable strings in the binary already gives us some hints about the executable’s nature:
</p></div>
<div style="background-color: black; border: 1px solid white; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre><span style="font-family: inherit;"><span style="font-size: small;">$ strings -n 10 mb_crackme_2.exe_
[...]
<span style="color: red;"><b>pyi</b></span>-windows-manifest-filename
[...]
<span style="color: red;"><b>Py</b></span>_IgnoreEnvironmentFlag
Failed to get address for <b><span style="color: red;">Py</span></b>_IgnoreEnvironmentFlag
<span style="color: red;"><b>Py</b></span>_NoSiteFlag
Failed to get address for <span style="color: red;"><b>Py</b></span>_NoSiteFlag
Py_NoUserSiteDirectory
[...]
m<span style="color: red;"><b>pyi</b></span>mod01_os_path
m<span style="color: red;"><b>pyi</b></span>mod02_archive
m<span style="color: red;"><b>pyi</b></span>mod03_importers
s<span style="color: red;"><b>pyi</b></span>boot01_bootstrap
s<span style="color: red;"><b>pyi</b></span>_rth__tkinter
bCrypto.Cipher._AES.<span style="color: red;"><b>pyd</b></span>
bCrypto.Hash._SHA256.<span style="color: red;"><b>pyd</b></span>
bCrypto.Random.OSRNG.winrandom.<span style="color: red;"><b>pyd</b></span>
bCrypto.Util._counter.<span style="color: red;"><b>pyd</b></span>
bMicrosoft.VC90.CRT.manifest
bPIL._imaging.<span style="color: red;"><b>pyd</b></span>
bPIL._imagingtk.<span style="color: red;"><b>pyd</b></span>
[...]
o<span style="color: red;"><b>pyi</b></span>-windows-manifest-filename another.exe.manifest
[...]
zout00-PYZ.<span style="color: red;"><b>pyz</b></span>
<span style="color: red;"><b>python27.dll</b></span></span></span>
</pre>
</div>
<p>Many references to <b>Python libraries</b>, <b>PYZ</b> archives and “<b>pyi</b>” substring indicates the use of the <b>PyInstaller</b> utility to build a PE executable from a Python script.</p>
<h3>Basic dynamic information gathering</h3>
<p>Running the executable (in a sandboxed environment) gives us the following message:</p>
<figure id="post-15672 media-15672" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15672 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I3-1.png" alt="" width="454" height="785" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I3-1.png 454w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I3-1-110x191.png 110w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I3-1-23x39.png 23w" sizes="auto, (max-width: 454px) 100vw, 454px" /></figure>
<figure id="post-15589 media-15589" class="align-none"></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<p>Using <b>Process Monitor</b>, from <a href="https://docs.microsoft.com/en-us/sysinternals/">SysInternals Tools Suit</a><a href="https://www.blogger.com/null">e</a> , allows us to quickly get a glimpse of the actions performed by the executable:</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-15591 size-full" style="text-align: center;" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I4.png" alt="" width="640" height="328" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I4.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I4-373x191.png 373w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I4-71x36.png 71w" sizes="auto, (max-width: 640px) 100vw, 640px" /></p>
<div class="separator" style="clear: both; text-align: center;"></div>
<p>A temporary directory named “<b>_MEI5282</b>” is created under user’s “<b>%temp%</b>” directory, and filled with <b>Python-related resources</b>. In particular, “<b>python27.dll</b>” and “<b>*.pyd</b>” libraries are written and later loaded by the executable.</p>
<p>This behavior is typical of executables generated by PyInstaller.
</p></div>
<div style="text-align: justify;">
<div style="text-align: justify;">
<figure id="post-15593 media-15593" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15593 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I5.png" alt="" width="640" height="312" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I5.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I5-392x191.png 392w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I5-71x35.png 71w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
</div>
<h3 style="text-align: justify;">Error-handling analysis</h3>
<div style="text-align: justify;">Without tools, it is often possible to quickly get information about a binary’s internals by <b>testing its error handling</b>. For example, inserting an <b>EOF</b> (End-Of-File) signal in the terminal (“Ctrl+Z + Return” on Windows Command Prompt) makes the program crash, printing the following information:</div>
<div class="separator" style="clear: both; text-align: center;">
<figure id="post-15595 media-15595" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15595 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I6.png" alt="" width="461" height="262" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I6.png 461w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I6-336x191.png 336w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I6-69x39.png 69w" sizes="auto, (max-width: 461px) 100vw, 461px" /></figure>
</div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Python stack trace printed after a crash</span></i></div>
<p>This allows us to identify the presence of a Python program embedded inside the executable and gives us the name of the main script:<b> another.py.</b> The error message “[$PID] Failed to execute script $scriptName” is typical of <b>PyInstaller</b>-produced programs.
</div>
<h3 style="text-align: justify;">Python files extraction and decompilation</h3>
<div style="text-align: justify;">Every lightweight analysis presented previously points out that the executable has been built using <b>PyInstaller</b>.<br />
The <a href="https://0xec.blogspot.fr/2017/11/pyinstaller-extractor-updated-to-v19.html"><b>PyInstaller Extractor</b></a>  program can be used to extract python-compiled resources from the executable.</div>
<div style="text-align: justify;"></div>
<div style="background-color: black; border: 1px solid white; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>$ python pyinstxtractor.py mb_crackme_2.exe
[*] Processing mb_crackme_2.exe
[*] Pyinstaller version: 2.1+
[*] Python version: 27
[*] Length of package: 8531014 bytes
[*] Found 931 files in CArchive
[*] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap
[+] Possible entry point: pyi_rth__tkinter
[+] Possible entry point: <b><span style="color: red;">another</span></b>
[*] Found 440 files in PYZ archive
[*] Successfully extracted pyinstaller archive: mb_crackme_2.exe

You can now use a python decompiler on the pyc files within the extracted directory</pre>
</div>
<p>&nbsp;</p>
<div style="text-align: justify;">As previously seen, the most interesting file is “<b>another</b>”, as it should contain the “main” function.</div>
<div class="separator" style="clear: both; text-align: center;">
<figure id="post-15597 media-15597" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15597 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I7.png" alt="" width="400" height="88" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I7.png 400w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I7-71x16.png 71w" sizes="auto, (max-width: 400px) 100vw, 400px" /></figure>
</div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Files extracted by PyInstaller Extractor</span></i></div>
<p>&nbsp;
</p></div>
<div style="text-align: justify;">A quick <a href="https://hshrzd.wordpress.com/2018/01/26/solving-a-pyinstaller-compiled-crackme/">Internet search</a>  informs us that in a PYZ archive, the main file is in fact a *<b>.pyc file</b> (Python bytecode) from which the<b> first 8 bytes</b>, containing its signature, <b>have been removed</b>. Looking the hex dump of <b>another *.pyc </b>file of the archive confirms this statement and gives us the correct signature for Python 2.7 bytecode files (in purple).</div>
<div style="text-align: justify;"></div>
<div style="background-color: black; border: 1px solid white; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>$ hexdump -C another | head -n 3
00000000  <span style="color: red;"><b>63 00 00 00 00 00 00 00  00 03 00 00 00 40 00 00</b></span>  |c............@..|
00000010  00 73 03 02 00 00 64 00  00 5a 00 00 64 01 00 5a  |.s....d..Z..d..Z|
00000020  01 00 64 02 00 5a 02 00  64 03 00 64 04 00 6c 03  |..d..Z..d..d..l.|
$ hexdump -C out00-PYZ.pyz_extracted/cmd.pyc | head -n 3
00000000  <b><span style="color: purple;">03 f3 0d 0a 00 00 00 00</span></b>  <span style="color: red;"><b>63 00 00 00 00 00 00 00</b></span>  |.ó......c.......|
00000010  <span style="color: red;"><b>00 03 00 00 00 40 00 00</b></span>  00 73 4c 00 00 00 64 00  |.....@...sL...d.|
00000020  00 5a 00 00 64 01 00 64  02 00 6c 01 00 5a 01 00  |.Z..d..d..l..Z..|</pre>
</div>
<p>Restoring the file’s signature produces a correct Python bytecode file.</p>
<div style="background-color: black; border: 1px solid white; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>$ cat &lt;(printf "\x03\xf3\x0d\x0a\x00\x00\x00\x00") another &gt; another.pyc
$ file another.pyc
another.pyc: python 2.7 byte-compiled</pre>
</div>
</div>
<div style="text-align: justify;">
<div style="text-align: justify;"></div>
<div style="text-align: justify;">Using the <a href="https://github.com/rocky/python-uncompyle6">uncompyle6</a>  decompilation tool, we can easily recover the original source code of <b>another.py</b>.</div>
<div style="text-align: justify;"></div>
<div style="background-color: black; border: 1px solid white; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>$ uncompyle6 another.pyc &gt; another.py</pre>
</div>
<div style="text-align: justify;"></div>
<h1 style="text-align: justify;">Stage 1: login</h1>
<div style="text-align: justify;">Looking at the <b>main()</b> function of <b>another.py</b>, we see that the first operations are performed by the <b>stage1_login()</b> function.</div>
<div style="text-align: justify;"></div>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre><span style="color: blue;">def</span> <span style="color: magenta;">main</span>():
    key = <span style="color: red;">stage1_login</span>()
    <span style="color: blue;">if not</span> check_if_next(key):
        <span style="color: blue;">return</span>
    <span style="color: blue;">else</span>:
        content = decode_and_fetch_url(key)
        <span style="color: blue;">if </span>content <span style="color: blue;">is None</span>:
            <span style="color: blue;">print </span><span style="color: #666666;">'Could not fetch the content'</span>
            <span style="color: blue;">return </span>-<span style="color: red;">1</span>
        decdata = get_encoded_data(content)
        <span style="color: blue;">if not </span>is_valid_payl(decdata):
            <span style="color: blue;">return </span>-<span style="color: red;">3</span>
        <span style="color: blue;">print </span>colorama.Style.BRIGHT + colorama.Fore.CYAN
        <span style="color: blue;">print </span><span style="color: #666666;">'Level #2: Find the secret console...'</span>
        <span style="color: blue;">print </span>colorama.Style.RESET_ALL
        <span style="color: #6aa84f;">#load_level2(decdata, len(decdata))</span>
        dump_shellcode(decdata, len(decdata))
        user32_dll.MessageBoxA(<span style="color: blue;">None</span>, <span style="color: #666666;">'You did it, level up!'</span>, 'Congrats!', <span style="color: red;">0</span>)
        <span style="color: blue;">try</span>:
            <span style="color: blue;">if </span>decode_pasted() == <span style="color: blue;">True</span>:
                user32_dll.MessageBoxA(<span style="color: blue;">None</span>, <span style="color: #666666;">'''Congratulations! Now save your flag
and send it to Malwarebytes!'''</span>, <span style="color: #666666;">'You solved it!'</span>, <span style="color: red;">0</span>)
                <span style="color: blue;">return </span><span style="color: red;">0</span>
            user32_dll.MessageBoxA(<span style="color: blue;">None</span>, <span style="color: #666666;">'See you later!'</span>, <span style="color: #666666;">'Game over'</span>, <span style="color: red;">0</span>)
        <span style="color: blue;">except</span>:
            <span style="color: blue;">print </span>'Error decoding the flag'
        <span style="color: blue;">return</span></pre>
</div>
<div style="text-align: justify;"></div>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre><span style="color: blue;">def </span><span style="color: magenta;">stage1_login</span>():
    show_banner()
    <span style="color: blue;">print </span>colorama.Style.BRIGHT + colorama.Fore.CYAN
    <span style="color: blue;">print </span><span style="color: #666666;">'Level #1: log in to the system!'</span>
    <span style="color: blue;">print </span>colorama.Style.RESET_ALL
    login = raw_input('login: ')
    password = getpass.getpass()
    <span style="color: blue;">if not </span>(<span style="color: red;">check_login</span>(login) <span style="color: blue;">and </span><span style="color: red;">check_password</span>(password)):
        <span style="color: blue;">print </span><span style="color: #666666;">'Login failed. Wrong combination username/password'</span>
        <span style="color: blue;">return </span>None
    <span style="color: blue;">else</span>:
        PIN = raw_input('PIN: ')
        <span style="color: blue;">try</span>:
            key = <span style="color: red;">get_url_key</span>(int(PIN))
        <span style="color: blue;">except</span>:
            <span style="color: blue;">print </span><span style="color: #666666;">'Login failed. The PIN is incorrect'</span>
            <span style="color: blue;">return None</span>
        <span style="color: blue;">if not </span><span style="color: red;">check_key</span>(key):
            <span style="color: blue;">print </span><span style="color: #666666;">'Login failed. The PIN is incorrect'</span>
            <span style="color: blue;">return None</span>
        <span style="color: blue;">return </span>key</pre>
</div>
<p>Three user inputs are successively checked: the user’s <b>login</b>, <b>password </b>and <b>PIN </b>code.</p>
<h3>Finding the login</h3>
<div style="text-align: justify;">The check_login() function&rsquo;s code is completely transparent :</div>
<div style="text-align: justify;"></div>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre><span style="color: blue;">def </span><span style="color: magenta;">check_login</span>(login):
    <span style="color: blue;">if </span>login == <span style="color: red;">'hackerman'</span>:
        <span style="color: blue;">return True</span>
    <span style="color: blue;">return False</span></pre>
</div>
<p>We have found the login, let&rsquo;s search for the password.</p>
<figure id="post-15599 media-15599" class="align-none"><img loading="lazy" decoding="async" class="size-full wp-image-15599 aligncenter" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I8.jpg" alt="" width="320" height="180" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I8.jpg 320w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I8-69x39.jpg 69w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Expected login</span></i></div>
<div class="separator" style="clear: both; text-align: left;"></div>
</div>
<h3>Finding the password</h3>
<p>The <b>check_password</b>() function hashes user’s input using the <b>MD5 </b>hash function, and compares the result with an hardcoded string:</p>
<div style="text-align: justify;"></div>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre><span style="color: blue;">def </span><span style="color: magenta;">check_password</span>(password):
    my_md5 = hashlib.md5(password).hexdigest()
    <span style="color: blue;">if </span>my_md5 == '42f749ade7f9e195bf475f37a44cafcb':
        <span style="color: blue;">return True</span>
    <span style="color: blue;">return False</span></pre>
</div>
<p>A quick Internet search of this string gives us the corresponding cleartext password: <b>Password123</b>.</p>
<figure id="post-15601 media-15601" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15601 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I9.png" alt="" width="640" height="240" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I9.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I9-437x164.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I9-71x27.png 71w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Finding the password on a search engine</span></i></div>
<h3>Finding the PIN code</h3>
<p>The PIN code is read from standard input, converted into an<b> integer</b> (cf. stage1_login()<b> </b>function), and passed to the <b>get_url_key() </b>function:</p>
<div style="text-align: justify;"></div>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre><span style="color: blue;">def</span> <span style="color: magenta;">get_url_key</span>(my_seed):
    random.seed(my_seed)
    key = ‘’
    <span style="color: blue;">for </span>I <span style="color: blue;">in </span>xrange(0, 32):
        id = random.randint(0, 9)
        key += str(id)
    <span style="color: blue;">return </span>key</pre>
</div>
<p>This function derives a<b> pseudo-random 32 digits</b> key from the PIN code, using it as a <b>seed </b>for Python’s PRNG. The generated key is then verified using the <b>check_key()</b> function, where its MD5 sum is checked against another hardcoded value.</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre><span style="color: blue;">def </span><span style="color: magenta;">check_key</span>(key):
    my_md5 = hashlib.md5(key).hexdigest()
    <span style="color: blue;">if </span>my_md5 == '<span style="color: red;">fb4b322c518e9f6a52af906e32aee955</span>':
        <span style="color: blue;">return </span>True
    <span style="color: blue;">return </span>False</pre>
</div>
<p>The key space is obviously <b>too large to be brute-forced</b>, as a 32-digits string corresponds to 10^32 (~2^106) possible combinations. However, <b>we can brute-force the PIN</b> code, being an integer, using the following code:</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre><span style="color: blue;">from </span>another <span style="color: blue;">import </span>get_url_key, check_key
PIN = 0
<span style="color: blue;">while True</span>:
    key = get_url_key(PIN)
    <span style="color: blue;">if </span>check_key(key):
        <span style="color: blue;">print </span>PIN
        <span style="color: blue;">break</span>
    PIN += 1</pre>
</div>
<p>The solution is obtained in a few milliseconds:</p>
<div style="background-color: black; border: 1px solid white; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>$ python bruteforcePIN.py
9667</pre>
</div>
<h3>Testing credentials</h3>
<p>Using the credentials found in the previous step completes the first stage of the challenge.</p>
<figure id="post-15603 media-15603" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15603 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I10.png" alt="" width="400" height="148" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I10.png 400w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I10-71x26.png 71w" sizes="auto, (max-width: 400px) 100vw, 400px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Validating stage 1</span></i></div>
<p>Clicking “Yes” makes the executable pause after printing the following message in the console:</p>
<div class="separator" style="clear: both; text-align: center;">
<figure id="post-15605 media-15605" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15605 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I11.png" alt="" width="320" height="96" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I11.png 320w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I11-71x21.png 71w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure>
</div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Waiting for us to find a « secret console »</span></i></div>
<p>Let’s find that secret console!</p>
<h1>Stage 2: the secret console</h1>
<h3>Payload download and decoding</h3>
<p>Continuing our analysis of the main() function, the next function to be called after credentials verification is <b>decode_and_fetch_url()</b>, with the previously calculated 32-digits key given as argument:</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre><span style="color: blue;">def </span><span style="color: magenta;">decode_and_fetch_url</span>(key):
    <span style="color: blue;">try</span>:
        encrypted_url = <span style="color: #444444;">'\xa6\xfa\x8fO\xba\x7f\x9d\[...]\xfe'</span>
        aes = AESCipher(bytearray(key))
        output = aes.decrypt(encrypted_url)
        full_url = output
        content = fetch_url(full_url)
    <span style="color: blue;">except</span>:
        <span style="color: blue;">return None</span>
    <span style="color: blue;">return </span>content</pre>
</div>
<p>A URL is decrypted using an <b>AES </b>cipher and the 32-digits key. The resource at this URL is then downloaded and its content returned by the function.<br />
To get the decrypted URL, we simply add some <b>logging</b> instructions to the original code of another.py, which can be run independently of mb_crackme_2.exe (given that the required dependencies are present on our machine).</p>
<div style="background-color: black; border: 1px solid white; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>[...]
        full_url = output
        print "DEBUG : URL fetched is : %s " % full_url #added from original code
        content = fetch_url(full_url)
[...]</pre>
</div>
<p>The result execution is the following:</p>
<div style="background-color: black; border: 1px solid white; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre>login: hackerman
Password:
PIN: 9667
<span style="color: red;">DEBUG : URL fetched is : https://i.imgur.com/dTHXed7.png</span></pre>
</div>
<p>The decrypted URL hosts the PNG image displayed bellow:</p>
<figure id="post-15607 media-15607" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15607 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12.png" alt="" width="267" height="267" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12.png 267w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-191x191.png 191w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-39x39.png 39w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-32x32.png 32w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-64x64.png 64w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-96x96.png 96w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-128x128.png 128w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-70x70.png 70w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-175x175.png 175w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-130x130.png 130w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-115x115.png 115w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I12-30x30.png 30w" sizes="auto, (max-width: 267px) 100vw, 267px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Image downloaded by the executable</span></i></div>
<p>The “malware” then reads the <b>Red, Green and Blue components of each of the image’s pixels</b>, interprets them as <b>bytes </b>and constructs a buffer from their concatenation.</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre><span style="color: blue;">def </span><span style="color: magenta;">get_encoded_data</span>(bytes):
    imo = Image.open(io.BytesIO(bytes))
    rawdata = list(imo.getdata())
    tsdata <span style="color: blue;">= </span>''
    <span style="color: blue;">for </span>x <span style="color: blue;">in </span>rawdata:
        <span style="color: blue;">for </span>z <span style="color: blue;">in </span>x:
            tsdata += chr(z)
    <span style="color: blue;">del </span>rawdata
    <span style="color: blue;">return </span>tsdata</pre>
<pre></pre>
</div>
<p>This technique is sometimes used by real malware to download malicious code <b>without raising suspicion of traffic-analysis tools</b>, hiding the real nature of the downloaded resource.<br />
Using the “Extract data…” function of the <b>Stegsolve</b> tool  allows to quickly preview the data encoded in the image, which appears to be a PE file (and more specifically, a DLL):</p>
<figure id="post-15609 media-15609" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15609 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I13.png" alt="" width="640" height="494" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I13.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I13-247x191.png 247w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I13-51x39.png 51w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I13-156x121.png 156w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I13-155x120.png 155w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Output of the stegsolve tool</span></i></div>
<p>The function <b>is_valid_payl()</b> is then used to check whether the decoded payload is correct:</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre><span style="color: blue;">def </span><span style="color: magenta;">is_valid_payl</span>(content):
    <span style="color: blue;">if </span>get_word(content) != <span style="color: red;">23117</span>:
        <span style="color: blue;">return False</span>
    next_offset = get_dword(content[<span style="color: red;">60</span>:])
    next_hdr = content[next_offset:]
    <span style="color: blue;">if </span>get_dword(next_hdr) != <span style="color: red;">17744</span>:
        <span style="color: blue;">return False</span>
    <span style="color: blue;">return True</span></pre>
</div>
<p>The<b> 23117 and 17744</b> constants represent the “MZ” and “PE” magic bytes present in the headers of a PE.</p>
<div style="background-color: black; border: 1px solid white; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre>&gt;&gt;&gt; import struct
&gt;&gt;&gt; struct.pack("&lt;H", 23117)
'MZ'
&gt;&gt;&gt; struct.pack("&lt;H", 17744)
'PE'</pre>
</div>
<p>The decoded file is then passed to the<b> load_level2()</b> function, which is a wrapper around <b>prepare_stage()</b>.</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre><span style="color: blue;">def </span><span style="color: magenta;">load_level2</span>(rawbytes, bytesread):
    <span style="color: blue;">try</span>:
        <span style="color: blue;">if </span>prepare_stage(rawbytes, bytesread):
            <span style="color: blue;">return True</span>
    <span style="color: blue;">except</span>:
        <span style="color: blue;">return False</span></pre>
</div>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre><span style="color: blue;">def </span><span style="color: magenta;">prepare_stage</span>(content, content_size):
    virtual_buf = kernel_dll.VirtualAlloc(0, content_size, 12288, 64)
    <span style="color: blue;">if </span>virtual_buf == 0:
        <span style="color: blue;">return False</span>
    <span style="color: blue;">res </span>= memmove(virtual_buf, content, content_size)
    <span style="color: blue;">if </span>res == 0:
        <span style="color: blue;">return False</span>
    MR = WINFUNCTYPE(c_uint)(virtual_buf + 2)
    MR()
    <span style="color: blue;">return True</span></pre>
</div>
<p>This function starts by allocating enough space to store the downloaded code, using the VirtualAlloc API function call. The allocated space is <b>readable, writable and executable</b>, as the provided arguments reveal (12288 being equal to “MEM_COMMIT | MEM_RESERVE”, and 64 to PAGE_EXECUTE_READWRITE).<br />
The downloaded code is then written in the allocated space using the memmove function, and executed like a shellcode from offset 2.</p>
<p>To get a clean dump of the downloaded code (once decrypted), we <b>add a piece of code in the prepare_stage()</b> function, as follows:</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre><span style="color: blue;">def </span><span style="color: magenta;">prepare_stage</span>(content, content_size):
    <span style="color: blue;">with </span>open("dumped_pe.dll", "wb") as f:
        f.write(content[:content_size])
        print "DEBUG : File dumped in dumped_pe.dll"
    virtual_buf = kernel_dll.VirtualAlloc(0, content_size, 12288, 64)
    <span style="color: blue;">if </span>virtual_buf == 0:
        return False
    res = memmove(virtual_buf, content, content_size)
    <span style="color: blue;">if </span>res == 0:
        <span style="color: blue;">return </span>False
    MR = WINFUNCTYPE(c_uint)(virtual_buf + 2)
    MR()
    <span style="color: blue;">return True</span></pre>
</div>
<p>After re-executing the program, we observe that the obtained file is indeed a valid 32 bits Windows DLL:</p>
<div style="background-color: black; border: 1px solid white; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>$ file dumped_pe.dll
dumped_file.ext: PE32 executable (DLL) (console) Intel 80386, for MS Windows</pre>
</div>
<p>Time for us to open our favorite disassembler !</p>
<h2>Downloaded DLL’s reverse-engineering</h2>
<p><b>Reflective loading</b><br />
From the offset 2 of the file, a little shellcode located in the DOS headers<b> transfers the execution</b> to another code that implements <b>Reflective DLL injection</b>. This technique is used to load the library itself from memory, instead of normally loading the DLL from disk using the LoadLibrary API call.<br />
&nbsp;</p>
<figure id="post-15611 media-15611" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15611 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I14.png" alt="" width="640" height="118" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I14.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I14-437x81.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I14-71x13.png 71w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Disassembly of the first bytes of the downloaded DLL</span></i></div>
<p>The reflective loader’s code, located at 0x6E0, is documented in Stephen Fewer’s GitHub  and will not be described in this write-up. Since, in the end, the library is loaded by this mechanism as it would be after a normal LoadLibrary call, this downloaded file will be analyzed like a standard DLL in the rest of this write-up.</p>
<p>The list of exported functions being empty (except for the DllEntryPoint function), we start our analysis at the <b>entry point of the DLL</b>.</p>
<figure id="post-15613 media-15613" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15613 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I15.png" alt="" width="400" height="43" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I15.png 400w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I15-71x8.png 71w" sizes="auto, (max-width: 400px) 100vw, 400px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Exports list</i></span></div>
<p><b>Entry point</b><br />
Our first goal is to search for the <b>DllMain()</b> function from the entry point. If the reverser is not used to analyzing Windows DLLs, a simple way to start would be to open any random non-stripped 32bit DLL, which (with a little luck) would be compiled with the same compiler (Visual C++ ~7.10 here), and which would have a similar CFG structure for the DllEntryPoint function.<br />
An example of CFG comparisons between the analyzed DLL (left) and another non-stripped 32bit DLL (right) is presented below:<br />
&nbsp;</p>
<figure id="post-15615 media-15615" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15615 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I16.png" alt="" width="640" height="298" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I16.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I16-410x191.png 410w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I16-71x33.png 71w" sizes="auto, (max-width: 640px) 100vw, 640px" /><i></i></figure>
<div style="text-align: center;"><i><span style="font-size: x-small;">DLLEntryPoints in our DLL v/s another non-stripped DLL</span></i></div>
<div class="separator" style="clear: both; text-align: center;"></div>
<figure id="post-15617 media-15617" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15617 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I17.png" alt="" width="640" height="451" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I17.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I17-271x191.png 271w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I17-55x39.png 55w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
<div style="text-align: center;"><i><span style="font-size: x-small;">DllMainCTRStartup in our DLL / in another non-stripped DLL</span></i></div>
<div class="separator" style="clear: both; text-align: center;"></div>
<p>This technique allows us to quickly find the DllMain function in our DLL, here being located at 0x10001170.<br />
<b>DllMain (0x10001170)</b><br />
The function starts by checking if it has been called during the first load of the DLL by a process, by comparing the value of the fdwReason argument  against the DLL_PROCESS_ATTACH constant.<br />
The DllMain() function then <b>registers two exception handlers</b> using the AddVectoredExceptionHandler  API call. The handlers are named <b>“Handler_0” and “Handler_1”</b> in the screenshot below:</p>
<figure id="post-15619 media-15619" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15619 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I18.png" alt="" width="640" height="453" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I18.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I18-270x191.png 270w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I18-55x39.png 55w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I18-345x245.png 345w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>DllMain function</i></span></div>
<p>An exception is then manually raised using the “int 3” interruption instruction, triggering the execution of Handler_0.<br />
<b>Interlude: debugging a DLL in IDA Pro</b><br />
To make the reverse-engineering of some functions easier, debugging the code to observe function inputs and outputs can be an effective method.<br />
One simple way to <b>debug a DLL inside IDA </b>is to load the file as usual, then go to “Debugger -&gt;Process options&#8230;” and modify the following value:</p>
<ul>
<li>Application:
<ul>
<li> On a 64 bits version of Windows:
<ul>
<li>  “C:\Windows\SysWOW64\rundll32.exe” to debug a 32 bits library</li>
<li>  “C:\Windows\System32\rundll32.exe” to debug a 64 bits library</li>
</ul>
</li>
<li> On a 32 bits version of Windows:
<ul>
<li>  “C:\Windows\System32\rundll32.exe” to debug a 32 bits library</li>
<li>  Obviously, you cannot run (therefore debug) a 64 bits library on a 32 bits version of Windows</li>
</ul>
</li>
</ul>
</li>
<li> Parameters:
<ul>
<li>  “PATH_OF_YOUR_DLL”,functionToCall [function parameters if any]</li>
</ul>
</li>
</ul>
<p>Note: The file extension <b>must be “*.dll” </b>for rundll32.exe to accept it.</p>
<figure id="post-15621 media-15621" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15621 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I19.png" alt="" width="320" height="179" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I19.png 320w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I19-71x39.png 71w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>IDA « Process options&#8230; » menu</i></span></div>
<div class="separator" style="clear: both; text-align: center;"></div>
<p>To test the configuration, just place a <b>breakpoint </b>at the entry point of the DLL:</p>
<figure id="post-15623 media-15623" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15623 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I20.png" alt="" width="640" height="353" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I20.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I20-346x191.png 346w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I20-71x39.png 71w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Placing a breakpoint on the entry point</i></span></div>
<p>Run your debugger (F9). If configured correctly, your debugger should break at the DLL entry point, allowing you to debug any DLL function</p>
<p><b>Handler_0 (0x10001260)</b><br />
Looking at Handler_0’s CFG (given below), we see that the function calls <b>two unknown functions </b>(0x100092C0 and 0x1000E61D). To quickly identify these functions, let’s debug the DLL, and look at the functions inputs/outputs:</p>
<p><u>sub_100092C0</u></p>
<figure id="post-15625 media-15625" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15625 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I21.png" alt="" width="178" height="91" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I21.png 178w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I21-71x36.png 71w" sizes="auto, (max-width: 178px) 100vw, 178px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Function sub_100092C0() call</span></i></div>
<p>The function seems to take 3 arguments:</p>
<ul>
<li>A buffer (here named “Value”);</li>
<li>A value (here 0);</li>
<li>The size of the buffer (here 0x104).</li>
</ul>
<p>Let&rsquo;s look at the buffer’s content <b>before and after the function call</b>:</p>
<figure id="post-15627 media-15627" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15627 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I22.png" alt="" width="320" height="134" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I22.png 320w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I22-71x30.png 71w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>« Value » buffer before and after the call</i></span></div>
<p>The function prototype and its side effects correspond to the <b>memset </b>function.<u><br />
</u><br />
<u>sub_1000E61D</u></p>
<figure id="post-15629 media-15629" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15629 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I23.png" alt="" width="207" height="110" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I23.png 207w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I23-71x39.png 71w" sizes="auto, (max-width: 207px) 100vw, 207px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Function sub_1000E61D() call</i></span></div>
<p>The function seems to take 4 arguments:</p>
<ul>
<li>An <b>integer </b>(here the PID of the process);</li>
<li>A <b>buffer </b>(here named “Value”);</li>
<li>The <b>size of the buffer</b> (here 0x104);</li>
<li>A <b>value </b>(here 0xA, or 10).</li>
</ul>
<p>Looking at the provided buffer’s content after the function call, we see that the representation in base 10 of the first integer passed in parameter is written in the provided buffer.</p>
<figure id="post-15631 media-15631" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15631 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I24.png" alt="" width="214" height="168" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I24.png 214w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I24-50x39.png 50w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I24-156x121.png 156w" sizes="auto, (max-width: 214px) 100vw, 214px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Value buffer after the call</i></span></div>
<p>The function prototype and its side effects correspond to the <b>_itoa_s</b> function .</p>
<p><u>Handler_0 whole CFG and pseudo-code</u><br />
Here is the graph of the Handler_0 function:</p>
<figure id="post-15633 media-15633" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15633 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I25.png" alt="" width="400" height="365" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I25.png 400w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I25-209x191.png 209w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I25-43x39.png 43w" sizes="auto, (max-width: 400px) 100vw, 400px" /></figure>
<figure id="post-15633 media-15633" class="align-none">
<figure id="post-15633 media-15633" class="align-none">
<figure id="post-15675 media-15675" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15675 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I25bis.png" alt="" width="400" height="255" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I25bis.png 400w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I25bis-300x191.png 300w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I25bis-61x39.png 61w" sizes="auto, (max-width: 400px) 100vw, 400px" /></figure>
</figure>
</figure>
<figure id="post-15635 media-15635" class="align-none"></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>CFG of function Handler_0()</i></span></div>
<p>This corresponds to the following pseudo code:</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>if isloaded(“python.dll”):
   pid = getpid()
else:
   pid = 0
setEnvironmentVariable(“mb_chall”, str(pid))
return EXCEPTION_CONTINUE_SEARCH</pre>
</div>
<p>The function<b> checks the presence of the python27.dll</b> library (normally loaded by the main program mb_crackme_2.exe) in the process address space, and sets the <b>“mb_chall” environment variable </b>consequently.<br />
This may be seen as an “anti-debug” trick, because running the DLL independently in a debugger makes the execution follow a different path.</p>
<p><b>Handler_1 (0x100011D0)</b><br />
The code of this handler is quite self-explanatory, being similar to the previous handler’s code:</p>
<figure id="post-15635 media-15635" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15635 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I26.png" alt="" width="400" height="350" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I26.png 400w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I26-218x191.png 218w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I26-45x39.png 45w" sizes="auto, (max-width: 400px) 100vw, 400px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;">
<figure id="post-15677 media-15677" class="align-none"><img loading="lazy" decoding="async" class="alignnone wp-image-15677 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I26bis.png" alt="" width="400" height="248" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I26bis.png 400w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I26bis-308x191.png 308w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I26bis-63x39.png 63w" sizes="auto, (max-width: 400px) 100vw, 400px" /></figure>
</div>
<div class="separator" style="clear: both; text-align: center;"></div>
<p>Once again, this corresponds to the following pseudo code:</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>if getpid() == int(getenv(“mb_chall”):
   tmp = 6
else:
   tmp = 1
exceptionInfo-&gt;Context._Eip += tmp
return EXCEPTION_CONTINUE_EXECUTION</pre>
</div>
<p>After this handler, execution restarts at the address of original interruption (“int 3”) +1 or +6 (as presented in the pseudo-code above), whether performed checks pass or not.</p>
<figure id="post-15637 media-15637" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15637 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I27.png" alt="" width="640" height="150" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I27.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I27-437x102.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I27-71x17.png 71w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<p>We thus continue the analysis at the <b>not_fail function</b> (0x100010D0).</p>
<p><b>not_fail (0x100010D0)</b><br />
The function only starts a thread and waits for it to terminate.</p>
<figure id="post-15639 media-15639" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15639 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I28.png" alt="" width="319" height="231" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I28.png 319w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I28-264x191.png 264w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I28-54x39.png 54w" sizes="auto, (max-width: 319px) 100vw, 319px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>CFG of not_fail() function</i></span></div>
<p>The created thread executes the <b>MainThread</b> (0x10001110) function, where our analysis continues.</p>
<p><b>MainThread (0x10001110)</b><br />
The function loops and calls the <b>EnumWindows</b>  API every second, which in turn calls the provided callback function (<b>EnumWindowsCallback</b>) on every window present on the desktop.<br />
<b><br />
</b></p>
<figure id="post-15641 media-15641" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15641 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I29.png" alt="" width="284" height="400" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I29.png 284w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I29-136x191.png 136w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I29-28x39.png 28w" sizes="auto, (max-width: 284px) 100vw, 284px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>CFG of MainThread() function</i></span></div>
<p><b>EnumWindowsCallback function (0x10005750)</b><br />
The function, called on each window, uses the <b>SendMessageA</b>  API with the WM_GETTEXT message to retrieve the window’s title.</p>
<figure id="post-15643 media-15643" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15643 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I30.png" alt="" width="320" height="175" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I30.png 320w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I30-71x39.png 71w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>SendMessageA() call in MainThread()</i></span></div>
<p>After being converted to C++ std::string, the substrings <b>“Notepad”</b> and <b>“secret_console”</b> are searched in the window’s title.</p>
<div class="separator" style="clear: both; text-align: center;">
<figure id="post-15645 media-15645" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15645 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I31.png" alt="" width="363" height="404" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I31.png 363w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I31-172x191.png 172w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I31-35x39.png 35w" sizes="auto, (max-width: 363px) 100vw, 363px" /></figure>
</div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Strings « Notepad » and « secret_console » searched for in window title</i></span></div>
<p>If both substrings are present, the window’s title is replaced by the hardcoded string <b>“Secret Console is waiting for the commands&#8230;”</b>, using the SendMessageA API along with the WM_SETTEXT message. The window is placed to the <b>foreground,</b> using the ShowWindow API call.</p>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;">
<figure id="post-15647 media-15647" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15647 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I32.png" alt="" width="295" height="330" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I32.png 295w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I32-171x191.png 171w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I32-35x39.png 35w" sizes="auto, (max-width: 295px) 100vw, 295px" /></figure>
<p><span style="font-size: x-small;"><i>Modification of the window&rsquo;s title using SendMessageA()</i></span>
</div>
<p>The PID of the process corresponding to the window is then written in the “malware”’s console, and sub-windows of this window are enumerated, using the EnumChildWindows  API.The function <b>EnumChildWindowsCallback</b> (0x100034C0) is thus called on every sub-window.</p>
<figure id="post-15649 media-15649" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15649 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I33.png" alt="" width="438" height="309" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I33.png 438w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I33-271x191.png 271w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I33-55x39.png 55w" sizes="auto, (max-width: 438px) 100vw, 438px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>EnumChildWindows() function call</i></span></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i> </i></span></div>
<p><b>EnumChildWindowsCallback function (0x100034C0)</b><br />
This function gets the content of the sub-window using the SendMessageA API call:</p>
<figure id="post-15651 media-15651" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15651 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I34.png" alt="" width="436" height="222" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I34.png 436w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I34-375x191.png 375w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I34-71x36.png 71w" sizes="auto, (max-width: 436px) 100vw, 436px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>SendMessageA() call in EnumChildWindowsCallback() function</i></span></div>
<p>The substring <b>“dump_the_key”</b> is then searched in the retrieved content:</p>
<figure id="post-15653 media-15653" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15653 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I35.png" alt="" width="328" height="254" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I35.png 328w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I35-247x191.png 247w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I35-50x39.png 50w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I35-156x121.png 156w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I35-155x120.png 155w" sizes="auto, (max-width: 328px) 100vw, 328px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Search for « dump_the_key »</i></span></div>
<p>If this string is found, this function calls a decryption routine <b>decrypt_buffer()</b> (0x100016F0) on a buffer (encrypted_buff), using the string “dump_the_key” as argument.</p>
<figure id="post-15655 media-15655" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15655 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I36.png" alt="" width="514" height="251" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I36.png 514w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I36-391x191.png 391w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I36-71x35.png 71w" sizes="auto, (max-width: 514px) 100vw, 514px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Decrypting a hardcoded buffer using « dump_the_key » as key</i></span></div>
<p>Then, the “malware” loads the <b>actxprxy.dll </b>library into the process memory space. The first 4096 bytes (i.e. the first memory page) of the library is made writable using the VirtualProtect API call, and the decrypted payload is written at this location.</p>
<figure id="post-15657 media-15657" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15657 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I37.png" alt="" width="640" height="395" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I37.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I37-309x191.png 309w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I37-63x39.png 63w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Loading a library and writing the decrypted buffer at its location</i></span></div>
<p>Since the actxprxy.dll library is not used anywhere in the analyzed DLL after being re-written, it may be seen as a <b>covert communication channel </b>between the analyzed DLL and the main program mb_crackme_2.exe. After this, the function clears every allocated memory and exits. The created thread (see 4.2.6) therefore also exits, and the DllEntryPoint function call terminates, giving the control back to the main python script.</p>
<h3>Triggering the secret console</h3>
<p>As seen in the DLL analysis, to trigger the required conditions, a file named<b> “secret_console – Notepad”</b> is opened in a text editor. As such, the window title contains the mentioned substrings:</p>
<figure id="post-15659 media-15659" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15659 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I38.png" alt="" width="320" height="219" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I38.png 320w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I38-279x191.png 279w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I38-57x39.png 57w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Opening a file named « secret_console_Notepad.txt » on Notepad++</span></i></div>
<p>As expected, the title of the window is changed to “Secret Console is waiting for the commands…” by the malware. Writing “dump_the_key” in the window validates the second stage.</p>
<figure id="post-15661 media-15661" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15661 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I39.png" alt="" width="320" height="242" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I39.png 320w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I39-253x191.png 253w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I39-52x39.png 52w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Writing « dump_the_key » in the text editor</i></span></div>
<h1>Stage 3: the colors</h1>
<p>After validating the previous step, a message is printed on the console, asking the user to “guess a color”:</p>
<figure id="post-15663 media-15663" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15663 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I40.png" alt="" width="640" height="67" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I40.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I40-437x46.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I40-71x7.png 71w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Level 3 Message</i></span></div>
<p>The <b>three components (R, G and B) of a specific color</b>, with values going from 0 to 255, need to be entered to validate this step.</p>
<figure id="post-15665 media-15665" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15665 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I41.png" alt="" width="320" height="144" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I41.png 320w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I41-71x32.png 71w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><span style="font-size: x-small;"><i>Level 3 failed guess message</i></span></div>
<h3>Understanding the code</h3>
<p>Looking back at the another.py’s main() function code, it seems that the corresponding operations are performed inside the <b>decode_pasted()</b> function.</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre>def main():
   [...]
      load_level2(decdata, len(decdata))
      user32_dll.MessageBoxA(None, 'You did it, level up!', 'Congrats!', 0)
      try:
         if decode_pasted() == True:
            user32_dll.MessageBoxA(None, '''Congratulations! Now save your flag and 
send it to Malwarebytes!''', 'You solved it!', 0)
            return 0</pre>
</div>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>def decode_pasted():
    my_proxy = kernel_dll.GetModuleHandleA('actxprxy.dll')
    if my_proxy is None or my_proxy == 0:
        return False
    else:
        char_sum = 0
        arr1 = my_proxy
        str = ''
        while True:
            val = get_char(arr1)
            if val == '\x00':
                break
            char_sum += ord(val)
            str = str + val
            arr1 += 1

        print char_sum
        if char_sum != 52937:
            return False
        colors = level3_colors()
        if colors is None:
            return False
        val_arr = zlib.decompress(base64.b64decode(str))
        final_arr = dexor_data(val_arr, colors)
        try:
            exec final_arr
        except:
            print 'Your guess was wrong!'
            return False

        return True</pre>
</div>
<p>&nbsp;</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre>def dexor_data(data, key):
    maxlen = len(data)
    keylen = len(key)
    decoded = ''
    for i in range(0, maxlen):
        val = chr(ord(data[i]) ^ ord(key[i % keylen]))
        decoded = decoded + val
    return decoded</pre>
</div>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre>def level3_colors():
    colorama.init()
    print colorama.Style.BRIGHT + colorama.Fore.CYAN
    print '''Level #3: Your flag is almost ready! But before it will be revealed
, you need to guess it's color (R,G,B)!'''
    print colorama.Style.RESET_ALL
    color_codes = ''
    while True:
        try:
            val_red = int(raw_input('R: '))
            val_green = int(raw_input('G: '))
            val_blue = int(raw_input('B: '))
            color_codes += chr(val_red)
            color_codes += chr(val_green)
            color_codes += chr(val_blue)
            break
        except:
            print 'Invalid color code! Color code must be an integer (0,255)'
    print 'Checking: RGB(%d,%d,%d)' % (val_red, val_green, val_blue)
    return color_codes</pre>
</div>
<p>According to the decode_pasted() function, the decrypted buffer stored at the start of actxprxy.dll’s address space is read and:<br />
base64-decoded;</p>
<ul>
<li>zlib-decompressed;</li>
<li>XOR’ed against the user-provided colors values;</li>
<li>Executed by the Python exec function.</li>
</ul>
<p>To start our cryptanalysis, we <b>modify the decode_pasted() function</b> to dump the val_arr buffer before the dexor_data() operation, and rerun another.py, providing all required credentials:</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre>[...]
if colors is None:
   return False
val_arr = zlib.decompress(base64.b64decode(str))
with open("val_arr.bin", "wb") as f:
   f.write(val_arr)
   print "val_arr dumped !"
exit()
final_arr = dexor_data(val_arr, colors)
[...]</pre>
</div>
<p>&nbsp;</p>
<figure id="post-15667 media-15667" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15667 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I42.png" alt="" width="213" height="118" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I42.png 213w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I42-71x39.png 71w" sizes="auto, (max-width: 213px) 100vw, 213px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Dumping the XOR&rsquo;ed array</span></i></div>
<h3>Decrypting the val_arr buffer</h3>
<p>Knowing that the buffer is a string passed to the “exec” Python statement after being decrypted, it should represent a <b>valid Python source code</b>.<br />
To find the right key, the naïve solution would be to run a brute-force attack on all the possible “(R, G, B)” combinations, and look for printable solutions. This solution would need to perform 256^3 = 16’777’216 dexor_data() calls, which is feasible but <b>inefficient</b>.<br />
Instead, we perform 3 independent brute-force attacks on each R, G and B component, therefore performing 256 x 3 = 768 dexor_data() calls. The 3 brute-force attacks are performed on different “slices” of the val_arr string (of each of stride 3). We then test each combination of potential values previously found for each component.<br />
For example, if our 3 brute-force attacks indicate that:</p>
<ul>
<li>R can take values 2 and 37,</li>
<li>G can take values 77 and 78,</li>
<li>and B can only take the value 3,</li>
</ul>
<p>Then we test the combinations (2,77, 3), (37,77, 3), (2,78, 3) and (37,78, 3).</p>
<p>The following code implements our attack:</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre>import string
import itertools
from colorama import *
from another import dexor_data

with open("val_arr.bin", "rb") as f:
    val_arr = f.read()

#lists of possible values for R, G and B
potential_solutions = [list(), list(), list()]
for color in range(3): # separate bruteforce on R, G and B
    for xor_value in range(256): #testing all potential values
        valid = True
        for b in val_arr[color::3]: #extracting one every 3 characters, from index 
        # "color" (i.e. extracting all characters xored by the same "color" value)
            if chr(ord(b) ^ xor_value) not in string.printable:
                valid = False
                break
        if valid:
            potential_solutions[color].append(xor_value)

print "Possible values for R, G and B :", potential_solutions

for colors in itertools.product(*potential_solutions):
    print "Testing ", colors
    plaintext = dexor_data(val_arr, map(chr, colors))
    print repr(plaintext)
    if not raw_input("Does it seems right ? [Y/n]\n").startswith("n"):
       print "Executing payload :"
       exec plaintext
       break</pre>
</div>
<p>Executing this code gives us the solution instantly:</p>
<figure id="post-15669 media-15669" class="align-none"><img loading="lazy" decoding="async" class="aligncenter wp-image-15669 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I43.png" alt="" width="640" height="199" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I43.png 640w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I43-437x136.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2021/04/I43-71x22.png 71w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
<div class="separator" style="clear: both; text-align: center;"></div>
<div class="separator" style="clear: both; text-align: center;"><i><span style="font-size: x-small;">Decrypting the payload</span></i></div>
<p>The final flag appears in the console:</p>
<div style="background-color: #dfd2ee; border: 1px solid black; padding-left: 1%; padding-right: 1%; width: 100%;">
<pre></pre>
<pre>flag{"Things are not always what they seem; the first appearance 
deceives many; the intelligence of a few perceives what has been 
carefully hidden." - Phaedrus}</pre>
</div>
<h2>Conclusion</h2>
<p>This challenge was very interesting to solve, because apart from being an original crackme, it also included various topics that could be found during a real malware analysis. These topics included:</p>
<ul>
<li>DLL-rewriting techniques, here used as a kind of covert communication channel between a DLL and its main process;</li>
<li>“Non-obvious” anti-debugging tricks, like checking the presence of a known library in the process’ memory space to identify standalone DLL debugging;</li>
<li>Concealed malware downloading, using « harmless » formats (like PNG) to hide an executable payload from basic traffic analysis;</li>
<li>PyInstaller-based malware, (yes, sometimes malware writers can be lazy).</li>
</ul>
<p>Thanks MalwareBytes for this entertaining challenge!</p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/2018/06/malwarebytes-challenge-write-up/">Malwarebytes challenge write-up</a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com">RiskInsight</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
