当前位置: 代码迷 >> 综合 >> sqli-labs学习教程less-1
  详细解决方案

sqli-labs学习教程less-1

热度:12   发布时间:2023-09-26 14:26:23.0

虽然sql注入接触过不少,其实也不太多,但是不系统,那就通过sqli-libs系统学习总结一下吧

注:第一个就说得详细一点,后面的有新知识才会说,所以第一个一定要看!!!如果第一个还有不明白的地方,欢迎评论提问,注意一定自己要先实践。

 

我的学习的方法是什么呢?

先自己尝试一下注入,实在不行就看源码,再不行就看别人的指导,反正就是要弄懂

 

开篇先说说一些基础知识,当然一些基本的sql语句就自己去学吧(根据学习进程更新),less1的基础知识也是比较多的!!,学到学不动了再写个总结吧

url编码:一般的url编码其实就是那个字符的ASCII值得十六进制,再在前面加个%

具体可以看http://www.w3school.com.cn/tags/html_ref_urlencode.html,这里可以查到每个字符的url编码,当然自己编程或者用该语言应该也有自带的函数,去实现url编码

常用的写出来吧: 空格是%20,单引号是%27, 井号是%23,双引号是%22

判断sql注入(显错和基于错误的盲注):单引号,and 1=1  和and 1=2,双引号,反斜杠,注释等

判断基于时间的盲注:在上面的基础上,加个sleep函数 ,如sleep(5) (函数不同数据库有所不同)例子:   ' and sleep(5)    " and sleep(5)

 

sql 注入的基本步骤(这个跟sqlmap的步骤基本一致吧)


判断是什么类型注入,有没过滤了关键字,可否绕过


获取数据库用户,版本,当前连接的数据库等信息


获取某个数据库表的信息


获取列信息


最后就获取数据了

 

为了方便学习查看,可以在源码中的$sql下一句语句写以下php语句(就是输出拿到数据库查询的完整语句是怎么样的)

 

echo "你的 sql 语句是:".$sql."<br>";

 

注:下面的可能有很多种注入方法,仅举例一种

less 1   GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入)

 

直接在后面加个单引号(当然你要在后面先加?id=一个数字),单引号被自动url编码了

sqli-labs学习教程less-1

发现报了sql语句的语法错误,那么应该存在sql注入,因为没过滤单引号,我们就可以闭合单引号注入什么的

SELECT * FROM users WHERE id='1''  这样拿去查询肯定报错啊,单引号都不匹配

 

接下来猜字段,由于出了点问题,原来浏览器没帮我把#url编码

sqli-labs学习教程less-1

'#'url编码后就是%23,如果是post注入提交#不用编码也行

sqli-labs学习教程less-1

可以看到没有第四列,所以只有3个字段

sqli-labs学习教程less-1sqli-labs学习教程less-1

下面直接用union 语句查询,先看看1,2,3

sqli-labs学习教程less-1

怎么没有1,2,3中的两个出现呢,直接将语句复制到数据库的命令行也是可以查询到两行的啊!

sqli-labs学习教程less-1

不急,我们看一下源码,可以看到函数mysql_fetch_array只被调用了一次,而mysql_fetch_array() 函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有,具体看你第二个参数是什么,具体可以看http://www.w3school.com.cn/php/func_mysql_fetch_array.asp,所以这里无论怎么折腾最后只会出来第一行的查询结果

疑问:为什么$row中的数据为

array(6) { 
[0]=> string(1) "1" 
["id"]=> string(1) "1" 
[1]=> string(4) "Dumb" 
["username"]=> string(4) "Dumb" 
[2]=> string(4) "Dumb" 
["password"]=> string(4) "Dumb" }

sqli-labs学习教程less-1

这里我们先来看看如何把结果集的所有行都取出来呢,看下面的代码

 

while ($row = mysql_fetch_array($result)) {echo "<font size='5' color= '#99FF00'>";echo 'Your Login name:'. $row['username'];echo "<br>";echo 'Your Password:' .$row['password'];echo "</font>";}

 

那么我们只要让第一行查询的结果是空集(即union左边的select子句查询结果为空),那么我们union右边的查询结果自然就成为了第一行,就打印在网页上了,这个id他一般传的是数字,而且一般都是从1开始自增的,我们可以把id值设为非正数(负数或0),浮点数,字符型或字符串都行,下面的就是分别举例了

 

sqli-labs学习教程less-1
 

下面就真正查询数据库的各种信息了(可以看到只有第2列和第3列的结果显示在网页上),所以我们就只能用2,3这个位置了,但是两个位置应该是不够用的,这时我们就用到数据库的连接函数了,常用的就concatconcat_ws,其中concat_ws的第一个参数是连接字符串的分隔符,还会用到group__concat(可以把查询出来的多行连接起来)

看看怎么使用

sqli-labs学习教程less-1sqli-labs学习教程less-1再次强调concat_ws的一个参数是连接字符串的分隔符,这里很明显可以看到,但一般第一个参数一般都不是这样传过去的,因为会被html编码,要使用mysql的char函数将十进制ASCII码转化成字符,如下面的(:的十进制ASCII是58),当然这里的分隔符也可以多个字符

sqli-labs学习教程less-1

用的较多的就是这个啦,以后直接复制(32是空格的十进制ASCII)

 

concat_ws(char(32,58,32),user(),database(),version())

 

user():返回当前数据库连接使用的用户

database():返回当前数据库连接使用的数据库

version():返回当前数据库的版本

sqli-labs学习教程less-1
 

接下来查询security数据库中有哪些表

首先说一下mysql的数据库information_schema,他是系统数据库,安装完就有,记录是当前数据库的数据库,表,列,用户权限等信息,下面说一下常用的几个表

SCHEMATA:储存mysql所有数据库的基本信息,包括数据库名,编码类型路径等,show databases的结果取之此表。

TABLES表:储存mysql中的表信息,(当然也有数据库名这一列,这样才能找到哪个数据库有哪些表嘛)包括这个表是基本表还是系统表,数据库的引擎是什么,表有多少行,创建时间,最后更新时间等。show tables from schemaname的结果取之此表

COLUMNS:提供了表中的列信息,(当然也有数据库名和表名称这两列)详细表述了某张表的所有列以及每个列的信息,包括该列是那个表中的第几列,列的数据类型,列的编码类型,列的权限,猎德注释等。是show columns from schemaname.tablename的结果取之此表。 

 

详细请看:http://wenku.baidu.com/link?url=bIA38Slp-g2Bob4VDuTSVY8e04Beqq9Xac4I90UMC9ziQuzxiukpEh5abPK-woB9tuQ4DuY_KhKW-eTHH6ACSiMJmRhctiHvijOEFmENBbS

 

通过直接在mysql控制台实验我们可以看到,查询information_schema中的信息时,使用where语句,那个值不能直接用英文,要用单引号包裹着,当然用其十六进制表示也可以,数值类型的就不用单引号了,这对过滤单引号应该有指导意义,至于还有没有其他表示,暂不知道,知道的可以告诉我

 

sqli-labs学习教程less-1

基础讲完了,直接上了(为了方便还是用火狐,插件是hackbar)

sqli-labs学习教程less-1

这时我们又遇到一个问题,只能返回一个table(为什么上面已经说过了),这时我们就要用的limit了, 第一个参数是结果集中的第几个,跟C语言的数组的索引一致,第二个参数就是个数

limit是mysql的语法
select * from table limit m,n
其中m是指记录开始的index,从0开始,表示第一条记录
n是指从第m+1条开始,取n条。
select * from tablename limit 2,4
即取出第3条至第6条,4条记录

如 limit  1,2  :返回第二行和第三行,因为1表示是第二行,2表示行数是2

具体看图吧

第二个表

sqli-labs学习教程less-1

第4个表

sqli-labs学习教程less-1

不断变化limit的第一个参数即可枚举所有的表,一旦超出范围,会返回空集

sqli-labs学习教程less-1

可以看到跟phpmyadmin的显示是一致的

sqli-labs学习教程less-1

接下来列举users的列名,因为一般我们只关心用户的账号密码,有了它其他的登陆后一般就能查看了,拿到管理员的就最好不过了

sqli-labs学习教程less-1

同样也是用limit一个一个来,就知道字段有id,username,password

sqli-labs学习教程less-1

那么最后一步了,那就简单了,直接select出来就好

sqli-labs学习教程less-1

那么用户和密码就一个一个出来了

当然这里注入可以多样的,其实是换汤不换药,相同的都是用limit控制结果集的具体是那一行

如下面的,-- 后面要有空格(某些情况+可以代替空格,+浏览器会编码成空格吧好像),你可以直接放phpmyadmin中测试

 

http://localhost/sqli-labs/Less-1/?id=-1' or 1=1 union select 1,2,concat_ws(char(32,58,32),id,database(),password) from  users limit 1,1 --+
http://localhost/sqli-labs/Less-1/?id=-1' and 1=2 union select 1,2,concat_ws(char(32,58,32),id,database(),password) from  users limit 1,1 -- k

这个你们可以具体实践一下,最重要的就是实践了,我也喜欢,这里截个图吧,--有无空格的情况

 

sqli-labs学习教程less-1sqli-labs学习教程less-1

 

第一个就说得详细一点,后面的有新知识才会说

  相关解决方案