zoukankan      html  css  js  c++  java
  • Rand函数引发的安全问题 —— OSSN任意文件读取漏洞(CVE-2020-10560)

    前言

    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构造出任意文件读取链接,通过componentsOssnCommentsossn_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字符串是如何还原出文件路径以及如何被构造出来的

    上文链接对应的后台代码位于 componentsOssnCommentsossn_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进行打印。见下图红框:

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

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

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

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

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

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

    我们接着分析这个site_key是如何生成的,生成代码位于librariesossn.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方法在没有提供可选参数 min 和 max时,返回 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

  • 相关阅读:
    说一下spring bean的生命周期
    oracle是怎么分页的
    Zookeeper和eureka之间的区别?
    说一下zookeeper和eureka之间的区别?
    假如一张表有一亿条数据,你怎样提高查询效率
    equals和==的区别
    谈谈你对oracle序列的理解
    你们项目中权限是怎样做的?
    讲解一下spring cloud常见组件的作用?
    说一下你们项目中实体类都是怎样重写hashcode()和equals()的
  • 原文地址:https://www.cnblogs.com/0daybug/p/12801280.html
Copyright © 2011-2022 走看看