Created
August 18, 2013 16:00
-
-
Save nmcv/6262374 to your computer and use it in GitHub Desktop.
Dynamic FORM parameters against SQLMap et al.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /* | |
| Sample script to illustrate the problem described here: | |
| http://security.stackexchange.com/q/40811/20422 | |
| **/ | |
| // Based on UNIX timestamp in seconds hash | |
| $timehash = sha1(time()); | |
| /* | |
| @DEBUG | |
| print($timehash); | |
| print "<br>"; | |
| print substr($timehash, 0, strlen($timehash) / 2); | |
| print "<br>"; | |
| print substr($timehash, -strlen($timehash) / 2); | |
| @@ | |
| */ | |
| // Generate one-time tokens | |
| $username_nonce = ''; // substr($timehash, 0, strlen($timehash) / 2); | |
| $password_nonce = ''; // substr($timehash, -strlen($timehash) / 2); | |
| $db = mysqli_connect('localhost', 'root', 'root', 'demo_db', '8889'); | |
| if (!$db) | |
| { | |
| printf("Connect failed: %s\n", mysqli_connect_error()); | |
| exit(); | |
| } | |
| // Looking for anything that may look like | |
| // our username and password field names | |
| $keys = array_keys($_POST); | |
| $usernameMatch = preg_grep('/^username(.*)$/', $keys); | |
| $passwordMatch = preg_grep('/^password(.*)$/', $keys); | |
| if (sizeof($usernameMatch) === 1 && sizeof($passwordMatch) === 1) | |
| { | |
| $usernameFieldName = array_values($usernameMatch); | |
| $passwordFieldName = array_values($passwordMatch); | |
| $username = $_POST[$usernameFieldName[0]]; | |
| $password = $_POST[$passwordFieldName[0]]; | |
| // Get the both parts of the hash back | |
| $lHash = substr($usernameFieldName[0], strlen('username')); | |
| $rHash = substr($passwordFieldName[0], strlen('password')); | |
| //@DEBUG | |
| //printf("Time hash:<br>%s<br>Reconstructed hash from client:<br>%s:%s", | |
| // $timehash, $lHash, $rHash); | |
| //@@ | |
| $found = false; | |
| // If the request has been received within 3 | |
| // seconds of token generation... | |
| for ($i=0;$i<=3;$i++) | |
| { | |
| if ( $lHash . $rHash === sha1(time()-$i) ) | |
| { | |
| printf("<br>%s", "You nailed it!"); | |
| auth($db, $username, $password); | |
| $found = true; | |
| break; | |
| } | |
| } | |
| // Too late submitting the form | |
| if (!$found) | |
| printf("<br>%s", "You are too slow..."); | |
| } | |
| function auth($mysqli_link, $username, $password) | |
| { | |
| //@DEBUG | |
| // printf("Username: %s, password: %s", $username, $password); | |
| // printf("<br>%s", "SELECT * FROM settings WHERE user='${username}' AND password='${password}'"); | |
| //@@ | |
| if (isset($username) && isset($password)) | |
| { | |
| // SQLi here ofc. | |
| $result = mysqli_query($mysqli_link, "SELECT id, user, password FROM settings WHERE user='${username}' AND password='${password}'") | |
| or die("<br/><br/>" ."Couldn't execute the query. " . mysqli_error($mysqli_link)); | |
| $row = mysqli_fetch_assoc($result); | |
| if ($row) | |
| { | |
| // Dumps out on successful retrieval from DB | |
| print("<br>Result dump:<br>"); | |
| var_dump($row); | |
| } | |
| } | |
| } | |
| ?> | |
| <doctype html> | |
| <head> | |
| <title>SQLMap dynamic parameters workaround</title> | |
| </head> | |
| <body> | |
| <form id="sqliForm" action="<?=$_SERVER['SCRIPT_NAME']?>" method="POST"> | |
| <input id="username" type="text" name="username<?=$username_nonce?>"> | |
| <input id="password" type="password" name="password<?=$password_nonce?>"> | |
| <input type="submit" value="Submit"> | |
| </form> | |
| <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script> | |
| <script> | |
| document.addEventListener | |
| ? | |
| document.addEventListener('DOMContentLoaded', init, false ) | |
| : | |
| document.attachEvent('onreadystatechange', init) | |
| function init() | |
| { | |
| var form = document.getElementById('sqliForm'); | |
| form.addEventListener | |
| ? | |
| form.addEventListener('submit', submitForm, false) | |
| : | |
| form.attachEvent('submit', submitForm); | |
| } | |
| function submitForm() | |
| { | |
| var u = document.getElementById('username'); | |
| var p = document.getElementById('password'); | |
| var ts = (new Date()).getTime().toString().substr(0, 10); | |
| var hash = CryptoJS.SHA1(ts).toString(); | |
| u.name = 'username' + hash.substr(0, 20); | |
| p.name = 'password' + hash.substr(20); | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment