揭秘fasteditor.hema.com的盲注SQL注入漏洞

本文详细分析了fasteditor.hema.com存在的盲注SQL注入漏洞,包括漏洞发现过程、利用技巧、payload构造方法以及时间延迟攻击的实际演示,最终成功获取数据库用户名和服务器IP地址。

盲注SQL注入在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时,Web浏览器发出的第一个请求之一是到端点:https://fasteditor.hema.com/api/user//products?offset=0&limit=8&orderby=id+DESC

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

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

Gotcha! 服务器返回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

一个帮助你发现和利用SQL注入漏洞的强大工具是SQLMap。它可以返回概念验证payload,甚至可以对受害者数据库进行完整转储。

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

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

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

  • 基于布尔的盲注,我们可以根据内部数据操纵排序行为。例如:如果管理员用户名以’a’开头,我们在查询中按ID升序排序,否则按降序排序。这允许通过仅查看输出的排序方向来枚举用户名的每个字符。
  • 堆叠查询,我们可能向查询添加我们自己的查询。这个很棘手且相当危险。我们被允许用新查询扩展查询。这可能允许删除数据库内容、启动反向shell或轻松创建基于时间的SQL攻击(更多内容见下文)以检索数据。
  • 基于时间的盲注,大多数数据库支持SLEEP()函数。一个暂停查询执行一定秒数的函数。我们可以通过测量服务器发送回复所需的时间来使用此功能渗出数据。例如,如果服务器的当前数据库用户名以X开头,我们触发睡眠2秒,如果以Z开头,睡眠4秒,等等。对字符串中的每个位置重复此操作,通过查看请求的响应时间,你可以轻松重建完整的用户名。

创建有效payload

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

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

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

我想从最终payload开始,并逐段剖析:

1
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(不确定为什么,它在payload中没有用,所以忽略它)。我现在通过向字符串中注入;来结束原始查询。

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

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

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

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

概念验证

每当我们能自动化事情时,我们应该尝试自动化它。Burp Suite Intruder来救援。我们指示Intruder使用我们的payload,并用预定义列表中的字符替换§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参数)。请注意,即使查询日志有时也可能通过在payload中包含某些单词来绕过。

解决方案

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

讨论

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

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

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

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

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

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

奖励

€100 HEMA礼品卡 + 奖金(报告5个反射XSS漏洞、一个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 设计