HEMA网站盲注SQL漏洞分析与利用

本文详细记录了在fasteditor.hema.com发现的盲注SQL注入漏洞。通过分析接口参数、构造时间延迟载荷,成功获取数据库用户名和服务器IP地址。文章包含漏洞复现过程、SQLMap工具使用技巧以及手动构造Payload的完整技术细节。

Blind SQL Injection at fasteditor.hema.com

概念验证:数据库用户的用户名以’hema’开头

背景

如今几乎每个网站都会使用数据库。当访问者请求网站数据时,服务器应用程序会构建查询语句发送给数据库。这些查询通常使用SQL语言。在构建数据库查询时,服务器应用程序需要考虑请求用户的访问级别,只应返回用户有权访问的数据。

但如果在这个过程中存在漏洞,允许你操纵发送到数据库的查询语句呢?你可能会获取数千条学校记录、私人财务数据或被入侵的防火墙。数据泄露是严重的问题。

因此,SQL注入(SQLi)被认为是严重漏洞,在漏洞赏金计划中通常提供最高奖励。

HEMA

正如我之前的报告所述,我喜欢HEMA。作为客户,我对他们的高质量产品感到满意;作为安全研究人员,我对他们的沟通方式(响应迅速且友好)感到满意。此外,他们允许我公开漏洞报告,这样你可以从他们的错误中学习,而且如果你发现严重漏洞,可能会获得真正惊人的香肠或苹果派。

有充分理由再次帮助他们,让他们的客户数据(包括我自己的照片)更加安全。

侦察,照片项目

今天我们从点击网站的照片项目部分开始。它允许你创建照片项目(如相册)和打印一批照片的服务。几小时后你可以在实体店取照片。HEMA为其服务使用不同的子域名,每个都有自己的API。

侦察,寻找有趣端点。等等,那是一个’orderby’参数吗?

易受攻击的端点

查询字符串和POST参数是我密切关注的对象。有什么线索表明它可能直接解析到SQL查询中吗?

我关注从SQL查询中识别的关键词:from、where、order by、select、limit、offset、id等。如果你对SQL有所了解会有所帮助;如果你是新手,可以去freeCodeCamp快速学习课程:-)。

HEMA为某些照片项目使用外部子域名:https://fasteditor.hema.com/

每当有人打开该URL时,网络浏览器首先发出的请求之一是指向端点:https://fasteditor.hema.com/api/user//products?offset=0&limit=8&orderby=id+DESC

该端点返回之前的照片项目列表。正确排序,按ID降序排列。

如果我们在orderby值中插入一个’,会发生什么?我们能破坏查询吗?

**搞定!**服务器返回SQL错误,这是我们可能遇到SQL注入漏洞的第一个迹象。

我们得到的错误看起来很有希望;它告诉我们使用了PDO(PHP数据对象),甚至包含了一部分SQL查询。我们的’在错误消息中没有被转义,这是一个巨大的危险信号。

在尝试利用漏洞时,尝试重建服务器代码总是有帮助的。我谷歌错误的不同部分,并尝试将我的发现组合成伪代码。例如,我找到了这个stackoverflow帖子,它提供了关于服务器端可能错误的线索。

但我不确定真正的原因是什么;所以请随意分享你对可能根本原因的想法,在评论中留言!

伪代码

1
2
3
4
$dbh = new PDO("photos");
$orderToUse = $_GET['orderby'];
$stmt = $dbh->prepare('SELECT * FROM photos where userId = :username ORDER BY '.$orderToUse.' LIMIT :limit');
$stmt->execute( array(':username' => $_REQUEST['username'], ':limit' => $_REQUEST['limit']) );

SQLMap

SQLMap是一个很棒的工具,可以帮助你发现和利用SQL注入漏洞。它可以返回概念验证载荷,甚至可以完全转储受害数据库。

让我们将可疑的易受攻击请求保存到文本文件中并运行SQLMap:使用-r加载文件,使用-p指定要测试的参数,使用-f进行广泛的数据库版本指纹识别。

SQLMap发现orderby参数易受3种不同类型的SQL注入攻击

所以我们有3种不同类型的SQL注入攻击可能适用于此参数:

基于布尔的盲注:我们可以根据内部数据操纵排序行为。例如:如果管理员用户名以’a’开头,我们按查询中的ID升序排序,否则按降序排序。这允许通过仅查看输出的排序方向来枚举用户名的每个字符。

堆叠查询:我们可能向查询添加自己的查询。这很棘手且相当危险。我们被允许用新查询扩展查询。这可能允许删除数据库内容、启动反向shell或轻松创建基于时间的SQL攻击(下面更多介绍)以检索数据。

基于时间的盲注:大多数数据库支持SLEEP()函数。该函数暂停查询执行一定秒数。我们可以通过测量服务器发送回复所需的时间来渗出数据。例如,如果服务器的当前数据库用户名以X开头,我们触发睡眠2秒,如果以Z开头则睡眠4秒,等等。对字符串中的每个位置重复此操作,通过查看请求的响应时间,你可以轻松重建完整的用户名。

创建有效载荷

大多数时候SQLmap允许你轻松渗出数据,它有预定义的载荷在大多数情况下都有效。但今天运气不好。由于某些防火墙和其他限制,SQLmap遇到困难。我可能漏掉了技巧,所以如果我应该尝试其他命令,请留言:-)

尝试使用SQLmap –user选项获取当前登录的数据库用户。遗憾的是,没有返回数据。

让我们拿一些好的SQL注入备忘单并启动Burp Suite Repeater,我们将手工制作自己的载荷!

我想从最终载荷开始并逐段剖析:

orderby=width+DESC;SELECT+(CASE+WHEN+(SUBSTRING((user())FROM(1)FOR(1))='§h§')+THEN+SLEEP(8)+ELSE+SLEEP(1)+END)

今天我们要检索当前登录的数据库用户名,我们要运行USER()函数并检索其输出。

第一段是width+DESC;;我将ID改为width(不确定为什么,在载荷中没有用,所以忽略它)。我现在通过向字符串中注入;来结束原始查询。

我们要检索USER()函数的输出,该函数返回一个字符串(例如waldo@127.0.0.1)。如果我们可以将字符串中的每个位置与所有可能的字符进行比较呢?如果有匹配,我们让服务器睡眠8秒,否则睡眠1秒。为了做到这一点,我们需要选择USER()函数返回的字符串的第一个字符。我们可以使用SUBSTRING()函数仅获取字符串的一个字符:该函数的第一个参数是输入字符串,第二个参数是要检索的位置,第三个是返回多少字符。

是时候用个小技巧了。不知何故,此载荷中不允许使用,字符。无论我尝试什么包含,的载荷,返回的响应都没有触发任何睡眠函数(所有响应时间<500ms)。所以我们必须考虑一个变通方法。今天我学会了你可以使用FROM和FOR作为替代。怎么用?谷歌是你的朋友,我搜索了substring without comma sql injection,这引导我到了互联网上某个隐藏的博客。一条评论给了我如何绕过这个限制的线索,使用FOR和FROM!所以现在我们可以将SUBSTRING(user(),1,1)转换为SUBSTRING((user())FROM(1)FOR(1))。我们刚刚绕过了防火墙(或其他破坏我们载荷的东西)。

§h§部分被Burp Suite Intruder用作我们字符列表的注入点。

最后,CASE WHEN (<above substring check>) THEN SLEEP (8) ELSE SLEEP(1) END语句。这允许我们在命中时(USER()输出中的字符与Burp Suite Intruder注入的字符相同)让服务器睡眠8秒,如果子字符串检查未命中则睡眠1秒。我们将查询封装在SELECT ()中以确保数据库执行查询。

概念验证

每当我们能自动化事情时,我们应该尝试自动化它。Burp Suite Intruder来救援。我们指示Intruder使用我们的载荷,并用预定义列表(包含字母表所有字母、所有数字和一些常见特殊符号如_-。@)中的字符替换§h§部分。

我们发现登录数据库用户名的前4个字母:hema

运行攻击后,我们按"Response completed"列排序,该列显示每个字符返回服务器响应所需的时间。注意那些耗时超过8秒的响应,它们是命中!

当我们发现正确字符后,我们移动到字符串中的下一个位置。我们通过将(SUBSTRING((user())FROM(1)FOR(1))改为(SUBSTRING((user())FROM(2)FOR(1)),重新运行攻击并观察下一个+8秒的命中。不要忘记在PC旁边放一个老式笔记本,这样你可以记下每个字符。

一段时间后,我们得到字符串hema_live@10.0.102.192

恭喜,我们刚刚交付了概念验证,证明此服务器易受盲注SQL注入攻击,我们成功渗出了登录用户名和数据库服务器的本地IP地址。

限制

手动渗出数据需要大量工作。然而,过去已经证明SQLmap可以自动化这类攻击。我未能演示这一点,但我很想从我的读者那里学习他们在这种特定情况下的做法,在下面留言!

影响

每当发现SQL注入漏洞时,应考虑数据库已受损;大多数应用程序在应用程序级别进行访问级别检查,而不是在数据库本身。这意味着只要我们能够注入SQL代码,我们就拥有数据库中的无限制读/写访问权限。

拥有数据库查询日志很重要,以便正确检查此漏洞过去是否被滥用。仅依赖Web服务器日志通常不够(大多数Web服务器不记录查询的POST参数)。请注意,即使查询日志有时也可能通过在载荷中包含某些词来绕过。

解决方案

永远不要信任客户端输入。每当在查询中使用客户端输入时,应用适当的检查并实施保护查询的不同技术。

讨论

在研究此漏洞时,我对以下错误感到惊讶:

我们的SQL注入停止工作了?!我们被抓住了。高兴我们已经记录了概念验证视频!;-)

此特定应用程序的供应商检测到我的攻击并实施了热修复。在发现漏洞的几小时内就已经修复,太棒了!我迅速联系他们以表明自己是触发警报的人。向他们的开发人员致敬,如此迅速并实际监控他们的应用程序。

最后一个讨论点是交付的概念验证。有人可能能够利用此漏洞在操作系统上执行远程代码;SQLmap甚至有特殊功能帮助你做到这一点。有些公司允许你尝试升级已经严重的漏洞,有些则不允许。对于HEMA,我们尚不知道,所以在证明此(已经)严重漏洞后停止了。

为什么入侵可能处于困境的公司? COVID-19在2020年第一季度袭击,他们的债权人存在问题。有些人可能会说:“别管他们!”

在我看来,如果客户数据岌岌可危,公司的情况并不重要;漏洞越早发现和解决对每个人都越好。保护客户数据符合每个人的利益。如果公司处理得当,对所有各方都是双赢;公司避免了潜在的数据泄露,客户数据受到保护,通过发布报告,公众了解到公司认真对待漏洞。HEMA,继续保持良好工作!

奖励

€100 HEMA礼品卡 + 奖金(报告5个反射型XSS漏洞、1个SQL注入漏洞和许多其他漏洞的奖励)。

时间线

  • 11–05–20 发现漏洞,供应商部署热修复,撰写报告,通知HEMA
  • 11–05–20 与供应商电话联系披露发现,请求更多时间检查其他端点
  • 15–05–20 HEMA确认漏洞并通知已部署修复,奖励€100礼品卡(此漏洞和六个反射型XSS漏洞)
  • 26–05–20 向供应商请求更新,确认已修复并现在编写单元测试以避免未来SQL注入漏洞
  • 26–05–20 HEMA同意发布此报告
  • 05–06–20 HEMA奖励我所有努力的奖金
  • 06–08–20 修订报告,发布报告
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计