{"id":761,"date":"2020-12-03T19:57:14","date_gmt":"2020-12-03T18:57:14","guid":{"rendered":"http:\/\/pentester.blog\/?p=761"},"modified":"2021-01-04T22:52:20","modified_gmt":"2021-01-04T21:52:20","slug":"windows-une-technique-dinjection-de-code-dans-des-processus-sans-faire-appel-a-des-fonctions","status":"publish","type":"post","link":"https:\/\/hacktarus.fr\/?p=761","title":{"rendered":"[Windows] Une technique d&rsquo;injection de code dans des processus sans faire appel \u00e0 des fonctions !"},"content":{"rendered":"\n<p>Il y a quelques temps j&rsquo;avais r\u00e9dig\u00e9 un petit <a href=\"https:\/\/hacktarus.fr\/?p=448\">article<\/a> sur les techniques d&rsquo;injection de code dans des processus en cours d&rsquo;ex\u00e9cution.<\/p>\n\n\n\n<p>Toutes ces techniques avaient un point en commun, l&rsquo;utilisation de fonctions de l&rsquo;API Windows.<\/p>\n\n\n\n<p>Quel est le probl\u00e8me ?<\/p>\n\n\n\n<p>L&rsquo;analyse comportementale des antivirus et EDR reposent en partie sur le tra\u00e7age de fonctions suspectes de l&rsquo;API Windows.<\/p>\n\n\n\n<p>Comment cela fonctionne ?<\/p>\n\n\n\n<p>A chaque fois qu&rsquo;un processus Windows est lanc\u00e9, l&rsquo;antivirus le d\u00e9tecte et modifie les appels API des DLL charg\u00e9es en m\u00e9moire.<\/p>\n\n\n\n<p>Cela para\u00eet compliqu\u00e9 mais en fait c&rsquo;est assez simple.<\/p>\n\n\n\n<p>Au d\u00e9but de chaque fonction Windows, l&rsquo;antivirus ajoute dynamiquement un petit \u00ab\u00a0JUMP\u00a0\u00bb vers lui-m\u00eame histoire de faire son analyse puis, si rien d&rsquo;anormal n&rsquo;a \u00e9t\u00e9 d\u00e9tect\u00e9, retourne tranquillement dans le code de la fonction , c&rsquo;est du \u00ab\u00a0API Hooking\u00a0\u00bb.<\/p>\n\n\n\n<p>Pour que l&rsquo;injection de code r\u00e9ussisse et \u00e9viter de se faire tracer et bloquer il faut donc soit \u00ab\u00a0d\u00e9faire\u00a0\u00bb le JUMP, c&rsquo;est \u00e0 dire faire du \u00ab\u00a0anti API Hooking\u00a0\u00bb ou bien faire appel \u00e0 des couches plus basses dans le syst\u00e8me.<\/p>\n\n\n\n<p>La strat\u00e9gie anti-api-hooking fonctionne dans certains cas mais a ses limites car les antivirus et EDR v\u00e9rifie r\u00e9guli\u00e8rement que leur JUMP est toujours l\u00e0.<\/p>\n\n\n\n<p>Int\u00e9ressons-nous aux couches basses des API Windows.<\/p>\n\n\n\n<p>Les API Windows utilis\u00e9es pour de l&rsquo;injection classique de code dans un process reposent toutes sur la librairie kernel32.dll<\/p>\n\n\n\n<p>Contrairement \u00e0 son nom, kernel32.dll n&rsquo;est pas une librairie de bas niveau mais plut\u00f4t de haut niveau (et oui on chez Microsoft tout est tr\u00e8s logique&#8230;).<\/p>\n\n\n\n<p>Les fonctions d\u00e9finies dans kernel32.dll font en fait des appels vers des fonctions de plus bas niveaux, elles sont d\u00e9finies dans ntdll.dll<\/p>\n\n\n\n<p>Le souci avec cette DLL c&rsquo;est que volontairement il n&rsquo;y a pas de documentation officielle de la part de Microsoft. C&rsquo;est gr\u00e2ce au travail de nombreux reverseurs que l&rsquo;on peut assez facilement faire des appels aux fonctions de cette DLL de bas niveau.<\/p>\n\n\n\n<p>Mais ce n&rsquo;est pas suffisant, on retombe toujours sur le probl\u00e8me du API Hooking, continuons la descente dans les couches du syst\u00e8me.<\/p>\n\n\n\n<p>La librairie ntdll.dll est la derni\u00e8re librairie dans l&rsquo;espace utilisateur, le code des fonctions \u00e0 l&rsquo;int\u00e9rieur font ensuite des appels syst\u00e8mes vers l&rsquo;espace kernel.<\/p>\n\n\n\n<p>Vous voyez o\u00f9 je veux en venir.<\/p>\n\n\n\n<p>Plut\u00f4t que de faire des appels \u00e0 des fonctions d\u00e9finies dans kernel32.dll ou dans ntdll.dll pourquoi ne pas faire des appels directs au syst\u00e8me en assembleur ? <\/p>\n\n\n\n<p>Et bien c&rsquo;est ce que j&rsquo;ai fait !<\/p>\n\n\n\n<p>Avec cette technique on peut bypasser toutes les solutions de d\u00e9tections bas\u00e9es sur du API Hooking dans l&rsquo;espace utilisateur car justement on ne fait plus du tout appel \u00e0 des fonctions !<\/p>\n\n\n\n<p>Une chose importante \u00e0 savoir, les appels syst\u00e8mes  sont tr\u00e8s d\u00e9pendant de la version exacte de Windows, il faut donc au pr\u00e9alable d\u00e9terminer le build de Windows avant de pouvoir faire les bons appels syst\u00e8mes.<\/p>\n\n\n\n<p>C&rsquo;est gr\u00e2ce au travail d&rsquo;un membre de l&rsquo;\u00e9quipe de Google Project Zero (<a href=\"https:\/\/j00ru.vexillium.org\/syscalls\/nt\/64\/\">https:\/\/j00ru.vexillium.org\/syscalls\/nt\/64\/<\/a>) que l&rsquo;on peut maintenant avoir acc\u00e8s facilement \u00e0 l&rsquo;ensemble des valeurs \u00e0 utiliser pour les registres assembleurs.<\/p>\n\n\n\n<p>Concr\u00e8tement et sans trop de d\u00e9tails :<\/p>\n\n\n\n<p>Lors de l&rsquo;injection de code on utilise tr\u00e8s souvent \u00e0 la fin la fonction CreateRemoteThread de la DLL kernel32.dll<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>HANDLE WINAPI CreateRemoteThread(\n  __in   HANDLE hProcess,\n  __in   LPSECURITY_ATTRIBUTES lpThreadAttributes,\n  __in   SIZE_T dwStackSize,\n  __in   LPTHREAD_START_ROUTINE lpStartAddress,\n  __in   LPVOID lpParameter,\n  __in   DWORD dwCreationFlags,\n  __out  LPDWORD lpThreadId\n);<\/code><\/pre>\n\n\n\n<p>Cette fonction fait en fait appel \u00e0 la fonction NtCreateThreadEx de la DLL ntdll.dll<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>EXTERN_C NTSTATUS NtCreateThreadEx(\n\tOUT PHANDLE ThreadHandle,\n\tIN ACCESS_MASK DesiredAccess,\n\tIN POBJECT_ATTRIBUTES ObjectAttributes,\n\tIN HANDLE ProcessHandle,\n\tIN PVOID StartRoutine, \/\/ PUSER_THREAD_START_ROUTINE\n\tIN PVOID Argument,\n\tIN ULONG CreateFlags, \/\/ THREAD_CREATE_FLAGS_*\n\tIN SIZE_T ZeroBits,\n\tIN SIZE_T StackSize,\n\tIN SIZE_T MaximumStackSize,\n\tIN PPS_ATTRIBUTE_LIST AttributeList\n);\n<\/code><\/pre>\n\n\n\n<p>Qui elle-m\u00eame fait un \u00ab\u00a0syscall\u00a0\u00bb vers le kernel avec ces param\u00e8tres  sous Windows 10 :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>; NtCreateThreadEx\n; Windows 10\n; 1507\t\t 1511\t\t 1607\t\t 1703\t\t 1709\t\t 1803\t\t 1809\t\t 1903\t\t 1909\t\t 2004\t\t20H2\n; 0x00b3 \t 0x00b4 \t 0x00b6 \t 0x00b9 \t 0x00ba \t 0x00bb \t 0x00bc \t 0x00bd \t 0x00bd \t 0x00c1 \t 0x00c1\n\nNtCreateThreadEx proc\n\t\tmov r10, rcx\n\t\tmov eax, 0bdh\n\t\tsyscall\n\t\tret\nNtCreateThreadEx endp<\/code><\/pre>\n\n\n\n<p>Alors voila, tout mis bout \u00e0 bout j&rsquo;ai d\u00e9velopp\u00e9 une injection de code sans faire aucun appel \u00e0 des fonctions API.<\/p>\n\n\n\n<p>Et \u00e7a marche du tonnerre ! <\/p>\n\n\n\n<p>Ci-joint un screenshot de l&rsquo;ex\u00e9cution o\u00f9 l&rsquo;on voit l&rsquo;injection de la dll testlib64.dll avec le \u00ab\u00a0Hello from testlib\u00a0\u00bb dans le processus sublime_text.exe (au passage c&rsquo;est du 64 bits, encore plus compliqu\u00e9) :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1367\" height=\"847\" src=\"https:\/\/hacktarus.fr\/wp-content\/uploads\/2020\/12\/ProcessInjectionDirectSyscall.png\" alt=\"\" class=\"wp-image-765\"\/><\/figure>\n\n\n\n<p>Je mettrai quand j&rsquo;aurai un moment l&rsquo;int\u00e9gralit\u00e9 du code sur mon Github.<\/p>\n\n\n\n<p>[MAJ 06\/12\/2020] <a href=\"https:\/\/github.com\/kahlon81\/Process-Injection-Direct-Syscall\">code disponible<\/a> <\/p>\n\n\n\n<p>Alors comment contrer ce genre de techniques ?<\/p>\n\n\n\n<p>Et bien il faut faire de l&rsquo;API Hooking mais au niveau kernel, en d\u00e9veloppant des drivers, c&rsquo;est ce que font les bons antivirus !<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Il y a quelques temps j&rsquo;avais r\u00e9dig\u00e9 un petit article sur les techniques d&rsquo;injection de code dans des processus en cours d&rsquo;ex\u00e9cution. Toutes ces techniques avaient un point en commun, l&rsquo;utilisation de fonctions de l&rsquo;API Windows. Quel est le probl\u00e8me ? L&rsquo;analyse comportementale des antivirus et EDR reposent en partie sur le tra\u00e7age de fonctions &hellip; <a href=\"https:\/\/hacktarus.fr\/?p=761\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">[Windows] Une technique d&rsquo;injection de code dans des processus sans faire appel \u00e0 des fonctions !<\/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-761","post","type-post","status-publish","format-standard","hentry","category-malware"],"_links":{"self":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/761","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=761"}],"version-history":[{"count":13,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/761\/revisions"}],"predecessor-version":[{"id":776,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/761\/revisions\/776"}],"wp:attachment":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}