Rand函数引发的安全问题 —— OSSN任意文件读取漏洞(CVE-2020-10560)

2020-04-29 约 105 字 预计阅读 1 分钟

声明:本文 【Rand函数引发的安全问题 —— OSSN任意文件读取漏洞(CVE-2020-10560)】 由作者 熊本熊本熊 于 2020-04-29 09:24:00 首发 先知社区 曾经 浏览数 32 次

感谢 熊本熊本熊 的辛苦付出!

前言

Open Source Social Network(OSSN),是一款用PHP编写的社交网络软件。OSSN允许用户创建一个社交网站,帮助拥有相似专业或个人兴趣的人建立社交关系。该软件拥有约50万下载量。

OSSN官网地址:

https://www.opensource-socialnetwork.org/

漏洞简介

Open Source Social Network(OSSN)5.3之前版本中存在一处任意文件读取漏洞(CVE-2020-10560)。漏洞因OSSN生成的Site_Key强度过低从而可以遭受被暴力破解而产生,成功破解Site_Key的攻击者可以利用Site_Key构造出任意文件读取链接,通过components\OssnComments\ossn_com.php文件提供的文件预览接口,读取文件。

漏洞分析

Open Source Social Network应用可以从如下官网链接下载:

https://www.opensource-socialnetwork.org/download

应用首页如下图

OSSN中提供Comment功能,访问者可以对帖子进行评论,见下图:

评论帖子时,用户可以上传图片以及表情,如下图红框处:

当选择本地图片并上传后,将在评论中生成一个预览,见下图:

注意,这时还没有点击发布评论,上图图片只是上传成功后的一个预览图片。该临时图像文件存储于tmp目录并在前端呈现了预览。

我们来看下这个临时图片文件是如何获取并在页面中展示的。查看一下图片链接,如下图:

链接如下:

http://192.167.30.119/comment/staticimage?image=UiszT0RJYStoQll2N2g5cHhmQW9PRHlCNVgrSWFKVzFQRHE4eTJqSWthVUVjUFBIb3pxME1FNUJFdk5ER2pONXI4V2pyeXJSMm9VPQ==

我们可以猜测出image参数对应的字符串应该是文件地址的加密形式,只有构造出正确的base64字符串,攻击者就可以读取任意文件。

最重要的是,经过测试发现,访问这个链接并不需要用户登陆。任何人都可以通过这个链接直接访问我们上传的这个图片文件。

接下来分析下后台代码,看看这个base64字符串是如何还原出文件路径以及如何被构造出来的

上文链接对应的后台代码位于 \components\OssnComments\ossn_com.php

在ossn_com.php中case 'staticimage'分支里,程序将请求中image参数值取出,并进行base64_decode解码。见下图:

随后,对解码后的值再次base64_decode解码,然后利用ossn_string_decrypt方法解码并获取文件地址。见下图:

接着,通过ossn_validate_filepath方法对文件路径进行校验。见下图红框:

ossn_validate_filepath方法如下图所示,可见该方法对目录遍历进行了过滤

即使过滤了../ 我们仍然可以通过绝对路径来进行文件读取,例如直接读取/etc/passwd

最后,程序利用file_get_contents方法对文件内容进行读取,并使用echo进行打印。见下图红框:

通过阅读代码也可以验证之前的测试结果:该接口并未进行身份校验,未登录的用户依然可以通过该接口访问文件。

问题又回到了如何构造加密字符串上。我们首先来看一下程序是如何解码的,位于libraries\ossn.lib.system.php文件中

通过上图的代码看,在解码过程中,需要用到site_key值。

经过分析后发现,程序通过ossn_site_settings方法在数据库中读取site_key值,我们先来看一下存储于ossn_site_settings表中site_key值是什么,见下图:

site_key值为c1a725ed,可见是一个8位数

这样看来,只要破解出这个8位数的site_key,即可构造出指向任意文件路径的链接。

我们接着分析这个site_key是如何生成的,生成代码位于libraries\ossn.lib.upgrade.php文件中,见下图:

通过分析上图加密过程不难发现,该8位随机数是通过如下方式产生的:

  1. 以字符串“ ossn”开头。

  2. 通过rand方法生成一个随机数并拼接到“ ossn”字符串后。

  3. 计算此字符串的md5值。

  4. 将字符3-11取出作为site_key值。

本次漏洞就出在计算site_key值的第二步,也就是通过rand产生随机数这一步。

关于rand方法,可以参考php官网

在官网介绍页面中明确的给出了警告,见上图底部

警告

此函数不会生成加密安全值,并且不应将其用于加密目的。如果需要密码安全的值,请考虑改用random_int(),random_bytes()或openssl_random_pseudo_bytes()。

rand方法之所以不安全,其中一个比较重要的原因是它能产生的随机数范围有限:

rand方法在没有提供可选参数 minmax时,返回 0 到 RAND_MAX之间的伪随机整数.

在笔者的windows主机上,RAND_MAX值仅为32767

而在笔者的Linux环境中,这个值为2147483647

据资料显示,rand最大可能值为2,147,483,647

因此,只需要生成最多20亿个rand值,将其依次带入ossn_generate_site_secret计算出对应的site_key值,这些site_key值即为所有的site_key值可能值。如果运气好,目标主机是一台windows主机,这样的操作仅仅重复3万多次即可,因为windows主机下rand产生的最大值仅为32767。

在分析了弱密钥是如何生成之后,我们需要一种方法来识别生成的密钥是否有效。在临时图片文件被上传到服务器时,会被存储于ossn_data/tmp/photos文件夹中,见下图:

因此上文中的加密数据成功解码后,其字符串中一定会包含tmp/photos字符串。我们这里用我们的密钥解一下上文中的编码,看一下这个推论是否正确,结果如下图:

可见成功解开的文件路径中的确存在tmp/photos字符串

因此,暴力破解的思路很明朗了

1、攻击者在评论里上传一个图片,不点击发送,查看此时图片临时预览链接,获取链接中image参数值。例如:http://192.167.30.119/comment/staticimage?image=UiszT0RJYStoQll2N2g5cHhmQW9PRHlCNVgrSWFKVzFQRHE4eTJqSWthVUVjUFBIb3pxME1FNUJFdk5ER2pONXI4V2pyeXJSMm9VPQ==中的UiszT0RJYStoQll2N2g5cHhmQW9PRHlCNVgrSWFKVzFQRHE4eTJqSWthVUVjUFBIb3pxME1FNUJFdk5ER2pONXI4V2pyeXJSMm9VPQ==>

2、将数字0-2147483647依次带入ossn_generate_site_secret中计算出对应的site_key

3、依次将site_key与image值带入ossn_string_decrypt中,获取解密后的明文

4、如果明文中含有tmp/photos字符串,解密成功,此时的site_key即为正确的site_key值

漏洞利用

在获取site_key值后,可以通过ossn_string_encrypt方法,对想要读取的文件进行加密,通过http://192.167.30.119/comment/staticimage?image=接口进行读取即可

上文所涉及的工具如下:

site_key计算工具

https://github.com/LucidUnicorn/CVE-2020-10560-Key-Recovery

加密解密工具

https://github.com/kevthehermit/CVE-2020-10560

关键词:[‘安全技术’, ‘漏洞分析’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now