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

Portswigger靶场之Blind SQL injection with conditional errorsPRACTITIONERLAB

一、分析题目

该实验室存在一个盲 SQL 注入漏洞。该应用程序使用跟踪 cookie 进行分析,并执行包含所提交 cookie 值的 SQL 查询。该 SQL 查询的结果并未被返回,而且无论查询是否返回任何行,应用程序的反应都相同。

这里值得注意的是,如果 SQL 查询出现错误,那么应用程序就会返回一个自定义的错误消息。我们这次是要根据返回的报错页面来进行注入。

该数据库中有一个名为“users”的不同表,该表包含“username”(用户名)和“password”(密码)两列。您需要利用盲 SQL 注入漏洞来找出管理员用户的密码。要解决此问题,请以管理员用户身份登录。


二、判断类型

1、猜测注入类型

这里我们尝试输入一个单引号时报错,输入两个单引号时页面显示正常:

因为输入数据库的理解结果一个单引号 (')这是一个字符串的开始或结束符,导致字符串被意外截断,引发语法冲突,最终导致SQL 语法错误 ;

两个单引号 ('')这是一个转义序列,代表字符串内部的一个实际的单引号字符执行成功。

所以猜测是布尔注入

由于这里页面没有回显任何信息,所以只能通过SQL语句的正确性来判断注入,如果SQL查询语句是正确的,则返回200,如果SQL语句查询是错误的,则返回500.

2、判断数据库类型

这里我们利用oracle的一个“小规矩”,在 Oracle 数据库中,任何 SELECT 语句,哪怕只是查询一个常量或一个空值,都必须有一个 FROM 子句。

其他很多数据库(如 MySQL, PostgreSQL)允许你直接写 SELECT '',但 Oracle 不行,这在 Oracle 中是无效的语法。

我们在语句正确的基础上,加上拼接符||来进行字符串的拼接。

TrackingId=ts02O7zolrYMc60w'||(select '')||'

此时,出现报错

语句改为下列语句,正常,说明了是oracle数据库

ts02O7zolrYMc60w'||(select '' from dual)||'

注意:在 Oracle 中进行注入测试,只要你的子查询不是从一个实际的表里查询数据,就一定要在后面加上 FROM DUAL

三、执行SQL注入

1、确认表的存在

提示说到数据库中有一个名为“users”的不同表,我们通过下面语句确定确实存在

TrackingId=AwKRCnDIzIDp0fCp'||(select '' from users where rownum=1)||'

在你的SQL注入查询中加上 where rownum=1 是一个至关重要的优化,优化如下

对比项不加 rownum=1加上 rownum=1 (推荐)
性能扫描全表,大表极慢只取一行,速度恒定且极快
可靠性可能因超时导致误判结果清晰,避免超时干扰
隐蔽性高负载,容易被监控发现

低负载,难以被察觉

小延伸:这里当从 Oracle 切换到 MySQL 时,只要要将 rownum=1 换成 LIMIT 1,但是也要将整个注入的思路从“值构造”切换为“条件注入”,在标准 MySQL 中

  • 拼接符不同:在标准 MySQL 中,|| 是一个逻辑“或”运算符(OR),而不是字符串拼接符。MySQL 中拼接字符串通常使用 CONCAT() 函数。

  • 注入策略不同:由于拼接符的差异,在 MySQL 中,通过 ANDOR 添加一个旁路的逻辑条件,通常比构造一个复杂的 CONCAT() 语句要简单和普遍得多。

对应语句如下:

TrackingId=some_value' AND (SELECT 1 FROM users LIMIT 1) IS NOT NULL --+

2、猜解密码长度原理

下面是甲骨文数据库的语法:

SELECT CASE WHEN (YOUR-CONDITION-HERE) THEN TO_CHAR(1/0) ELSE NULL END FROM dual

这条SQL语句使用了SELECT CASE WHEN结构,这是一种条件表达式,如果条件表达式为真,则执行THEN后面的函数;如果为假,则执行ELSE后面的函数。

在上面这条语句中,TO_CHAR函数的作用是转换成字符,可是TO_CHAR(1/0)中的1/0实际上是个除法,0为分母本身就是错误的,在大多数数据库中会抛出一个错误。

条件1=2是错误的,所以走的是else,页面返回了200。

TrackingId=LXmhABdSfCwrY1Vw'||(select CASE WHEN 1=2 THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'

当改成1=1,执行THEN后的函数,是TO_CHAR(1/0)语句报错,所以页面也报错。

TrackingId=LXmhABdSfCwrY1Vw'||(select CASE WHEN 1=1 THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'

理解以后,我们就可以利用WHEN来注入,判断密码的长度。执行下面语句,说明密码长度是大于1的:

TrackingId=LXmhABdSfCwrY1Vw'||(select CASE WHEN length(password)>1 THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'

执行这条语句,说明密码长度没有大于1000

 TrackingId=poRLmpaOHgRgbmXs'||(select CASE WHEN length(password)>1000 THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'

3、进行密码长度爆破

明白原理之后,设置猜测范围为1-25,设置关键字匹配:Internal Server Error进行爆破

按照上面的理论判断,没有出现报错,说明when的条件判断是正确的,所以执行了else以后的语句,得出密码长度为20

4、暴破密码字符

把when以后的条件判断用substr函数替换,爆破猜解具体密码字符。

TrackingId=poRLmpaOHgRgbmXs'||(select CASE WHEN substr(password,1,1)='a' THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'

substr(password,1,1)='a' 中第一个1就是猜的第一个位置,a为猜测第一个位置的字母

说明第一个字符不是a,接下来进行爆破前的设置

四、通关

拿到密码后,提示已经给出帐号,登陆即通关

学习参考:归去来兮-zangcc  【送书活动第2期】打靶Portswigger系列—— 一口气通关18个SQL注入靶场详细流程(文末送书)

http://www.xdnf.cn/news/1363807.html

相关文章:

  • 36 NoSQL 注入
  • 大模型微调 Prompt Tuning与P-Tuning 的区别?
  • Java多态大冒险:当动物们开始“造反”
  • leetcode-hot-100 (二分查找)
  • 实用电脑小工具分享,守护电脑隐私与提升效率21/64
  • LengthFieldBasedFrameDecoder 详细用法
  • excel 破解工作表密码
  • 无锁队列的设计与实现
  • 记一次 element-plus el-table-v2 表格滚动卡顿问题优化
  • 【学习记录】CSS: clamp、@scope
  • 一键编译安装zabbix(centos)
  • Go编写的轻量文件监控器. 可以监控终端上指定文件夹内的变化, 阻止删除,修改,新增操作. 可以用于AWD比赛或者终端应急响应
  • go-redis库使用总结
  • 跨语言统一语义真理及其对NLP深层分析影响
  • 人体工学优化:握力环直径 / 重量设计与便携性、握持舒适度的协同分析
  • Spring Security(第五篇):从单体到前后端分离 —— JSON 响应与处理器实战
  • 0826xd
  • QtExcel/QXlsx
  • 力扣82:删除排序链表中的重复元素Ⅱ
  • 《Password Guessing Using Large Language Models》——论文阅读
  • 离线可用的网络急救方案
  • JavaScript Intl.RelativeTimeFormat:自动生成 “3 分钟前” 的国际化工具
  • [React]Antd Select组件输入搜索时调用接口
  • 基于RFM模型的客户群体大数据分析及用户聚类系统的设计与实现
  • 【Flink】运行模式
  • 文献阅读笔记:KalmanNet-融合神经网络和卡尔曼滤波的部分已知动力学状态估计
  • Zabbix Vs. Grafana
  • win11中系统的WSL安装Centos以及必要组件
  • nmcli命令详解
  • Docker:网络连接