<html> <head> <title>Monitoring Tool</title> <script> functioncheck(){ ip = document.getElementById("ip").value; chk = ip.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/); if (!chk) { alert("Wrong IP format."); returnfalse; } else { document.getElementById("monitor").submit(); } } </script> </head> <body> <h1>Monitoring Tool ver 0.1</h1> <form id="monitor" action="index.php" method="post" onsubmit="return false;"> <p> Input IP address of the target host <input id="ip" name="ip" type="text"> </p> <input type="button" value="Go!" onclick="check()"> </form> <hr>
<?php $ip = $_POST["ip"]; if ($ip) { // super fancy regex check! if (preg_match('/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/',$ip)) { exec('ping -c 1 '.$ip, $cmd_result); foreach($cmd_resultas$str){ if (strpos($str, '100% packet loss') !== false){ printf("<h3>Target is NOT alive.</h3>"); break; } elseif (strpos($str, ', 0% packet loss') !== false){ printf("<h3>Target is alive.</h3>"); break; } } } else { echo"Wrong IP Format."; } } ?> <hr> <a href="index.txt">index.php source code</a> </body> </html>
In the PHP code, the exec command execution is badly escaped so we can append some code to be executed on the server side. But we are blind because there is no output, so if we want to do a ls we have to pipe it into base64 and append the result to a HTTP request with curl to a controlled remote server where we will be able to see the web server logs or traces.
$ printf %s 'SGVyZSBpcyB5b3VyIGZsYWc6IHBpY29DVEZ7bjN2M3JfdHJ1c3RfYV9iMHhfOTEzNDViMDR9Cgo=' | base64 -d Here is your flag: picoCTF{n3v3r_trust_a_b0x_91345b04}