The following CTF can be found at: Contextis Password Reset. I did not create this CTF. You have identified a source code leakage vulnerability. Can you identify any other vulnerabilities? <?php include 'config.php'; echo "<html><title>Password Recovery</title></html>"; if(isset($_GET['name']) && $_GET['name']!='' && !preg_match('/and|or/i',$_GET['name'])) { $res = mysql_query("SELECT name,email FROM user where name='".$_GET['name']."'"); #echo "SELECT name,email FROM user where name='".$_GET['name']."'"; if(mysql_fetch_object($res)) { // Generation of new password //<topsecure content> // removed in phps file :) //</topsecure content> die("A new password was generated and sent to your email address!"); } else { $res = mysql_query("SELECT name,email FROM user where name sounds like '".$_GET['name']."'"); if(mysql_fetch_object($res)) { echo "We couldn't find your username, but it sounds like this user:<br>"; } else { $name = $_GET['name']; $name = str_replace('on','',$name); $name = str_replace('On','',$name); $name = str_replace('ON','',$name); $name = str_replace('oN','',$name); $name = str_replace('<script','',$name); die("We couldn't find your username!<br>Are you sure it is $name?"); } $res = mysql_query("SELECT name,email FROM user where name sounds like '".$_GET['name']."'"); #echo "SELECT name,email FROM user where name sounds like '".$_GET['name']."'"; while($row = mysql_fetch_object($res)) { echo $row->name; echo "<br>"; } } } else { echo "Dear users,<br>We had a security breach! Please use this site to generate your new password.<br><br><br>"; echo '<form action="#" method="get">Please enter your username: <br><input type="text" name="name"><br><input type="submit" name="submit" value="submit"></form>'; echo '<!-- .phps?-->'; } ?> After analyzing the code and doing some research it appears that this code is vulnerable to SQL injections, specifically with the lines:
($_GET['name']) and mysql_query("SELECT name,email FROM user where name='".$_GET['name']."'");. This arises because the code itself does not filter any inputs and instead trusts that the requests sent are valid. After doing more in-depth research I discovered that the statement mysql_query() and ($_GET['name']) whenever used together are usually vulnerable, and should instead be replaced by using prepared statements and parameterized queries. Instead you should use prepare('SELECT ...'); and execute(array('name' => $name)); or prepare('SELECT ...'); and bind_param('variable_type', $name);. This allows for a speed boost if the statement is executed more than once in a session as it will only be compiled once.
0 Comments
Leave a Reply. |