Markdown解析器:开发者博客平台Hashnode的意外漏洞揭秘

背景介绍

Hashnode是一个专为开发人员设计的博客平台,提供免费自定义域名托管服务,涵盖丰富功能。其中之一是“批量Markdown导入器”,该功能使用户能够迁移博客时更为便利。在我将博客从Jekyll转移到Hashnode的过程中,我迫切需要使用Markdown导入器,但由于导入需要遵循特定格式,我在此过程中一直遇到问题。尽管Hashnode提供了导入器,但由于缺乏UI上的详细错误提示,我无法准确找出问题所在。直至我查看了Burp中的响应数据,才发现了一个潜在的Bug。

图片[1]-Markdown解析器:开发者博客平台Hashnode的意外漏洞揭秘-山海云端论坛

漏洞利用

寻找 LFI

Markdown有自己的怪癖和功能,允许在文件中引用图像,要在博客文章或任何MD文件中包含图像可以使用以下语法:


![image.png](https://image.url/image_file.png)

Hashnode的Bulk Importer接受一个包含所有要发布的Markdown帖子的ZIP文件,这是他们的示例帖子格式的外观:


---
title: "Why I use Hashnode"
date: "2020-02-20T22:37:25.509Z"
slug: "why-i-use-hashnode"
image: "Insert Image URL Here"
---

Lorem ipsum dolor sit amet

需要将此.md文件压缩到存档中才能上传到平台,这是响应在Burp Suite中的样子

图片[2]-Markdown解析器:开发者博客平台Hashnode的意外漏洞揭秘-山海云端论坛

这只是一个正常的Markdown解析帖子格式,这让我们想知道Markdown功能允许用户通过指定路径来插入图像

![anotherimage.png](/images/blog.jpg)

在Burp Suite中观察时,发现Hashnode触发了一个ENOENT错误,指出它无法找到该文件,如下面的屏幕截图所示

图片[3]-Markdown解析器:开发者博客平台Hashnode的意外漏洞揭秘-山海云端论坛

为了从服务器获取内部文件,我们决定给出一个实际文件的位置,而不是一个不存在的路径,就像/etc/passwd希望它能在响应中给我们文件内容一样,下面是我们用作最终有效负载的Markdown文件:


---
title: "Why I use Hashnode"
date: "2020-02-20T22:37:25.509Z"
slug: "why-i-use-hashnode"
image: "Insert Image URL Here"
---

![notimage.png](../../../../../etc/passwd)

这一次应用程序尝试使用路径中指定的位置来获取图像,而不是直接使用Markdown正文中显示的图像,应用程序遍历目录并passwd为我们获取文件,但它没有将内容显示在响应中而是将文件上传到Hashnode CDN

图片[4]-Markdown解析器:开发者博客平台Hashnode的意外漏洞揭秘-山海云端论坛

contentMarkdown参数为CDN URL提供了上传内部文件的路径,我们能够直接下载/etc/passwd,由于我们已经从passwd文件中获得了用户的名称和他们的主目录的路径,因此我们考虑将其升级为进一步尝试RCE,之后计划去创建SSH密钥,它会存储在~/.ssh/id_rsa私有密钥和~/.ssh/id_rsa.pub公共密钥的默认位置,我们相应地修改了我们的有效负载以从服务器获取私钥并且很幸运它也被上传到CDN,现在我们进入服务器所需要做的就是找到IP地址,因为它隐藏在Cloudflare后面

![notimage.png](../../../../../home/username/.ssh/id_rsa)
寻找真IP

寻找历史DNS记录以找到IP地址但没有成功,之后查看文件/proc/net/tcp,发现这些/proc接口提供有关当前活动TCP连接的信息:

图片[5]-Markdown解析器:开发者博客平台Hashnode的意外漏洞揭秘-山海云端论坛

kernel.org文档很好地解释了该表

图片[6]-Markdown解析器:开发者博客平台Hashnode的意外漏洞揭秘-山海云端论坛

我们感兴趣的列是本地地址,这些地址存储为反向IP地址的十进制表示法的十六进制值,这是我在互联网上找到的一个漂亮的单行代码,可以完成所有工作并以人类可读的格式返回IP

grep -v "rem_address" /proc/net/tcp | awk  '{x=strtonum("0x"substr($2,index($2,":")-2,2)); for (i=5; i>0; i-=2) x = x"."strtonum("0x"substr($2,i,2))}{print x":"strtonum("0x"substr($2,index($2,":")+1,4))}'

这有效地为我们提供了我们正在寻找的东西-服务器的IP地址以及端口22

图片[7]-Markdown解析器:开发者博客平台Hashnode的意外漏洞揭秘-山海云端论坛

文末小结

谁会想到Markdown解析器可以导致服务器上的命令执行呢?当与其他漏洞链接时,即使是最小的低严重性问题也可能升级,在这里描述性堆栈跟踪中的一个简单信息泄露错误帮助我们找出了markdown解析器的行为,这反过来又允许我们从服务器获取内部文件

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容