
预计阅读时间: 7 分钟
OCS-NG(Open Computer and Software Inventory Next Generation)是一款让用户对IT资产列表梳理的免费软件。可以收集装了OCS客户端程序的计算机硬件和软件的信息,然后通过Web界面将信息可视化。
笔者在OCS软件内部的几个核心函数里发现了这个漏洞,有问题的函数负责处理SNMP设置并且可以控制没过滤的“ SNMP_MIB_DIRECTORY”变量,与其他字符串连接后传给shell_exec函数执行。
经过身份验证后的用户可以设置这个选项,存储的变量没有被过滤,意味着笔者可以控制这个变量值写入恶意命令。
将恶意命令注入“ SNMP_MIB_DIRECTORY”值之后,还需要访问另一个调用这个变量值的页面触发Payload实现运行SNMP_MIB文件,执行恶意命令的操作。
使用RCEScanner脚本分析OCS代码里潜在的RCE漏洞结果如下:

CommandLine.php文件内容,执行命令的代码在34、35行:
函数" get_mid_oid()"带有一个" $file
"的参数变量,内部没有内容过滤。此外还可以看到" $values
" 的变量后连接了$file
直接传递给shell_exec()函数。而$values变量的内容是被“ look_config_default_values()”的函数处理过的。
如果控制了一个没有过滤的变量,就能能够注入命令。
分析require/function_commun.php中的look_config_default_values()
函数,可以找到以下代码:
look_config_default_values()函数作用是从数据库中查询数据(config表)并返回结果,这部分没有什么很有趣的地方,但是可以知道为什么从数据库里提取设置没过滤。
现在我们知道“ get_mib_oid()”函数在核心PHP文件ms_snmp_config.php里被调用,片段代码如下 :
PHP的完整文件路径是“plugins/main_sections/ms_config/ms_snmp_config.php”
,可以看到“ get_mib_oid()”函数被调用传递“$protectedPost ['mib_file']”
作为参数。
代码先检查“ update_snmp”
变量值是否在ProtectedPost
数组中,如果存在就把“$protectedPost ['mib_file']”
的变量值传递给容易受攻击的"get_mib_oid()"
函数,之前的代码提到过函数“ look_config_default_values()”
的输出是$value
变量值。
现在如果可以控制$protectedPost ['mib_file']
的值或$values ['tvalue'] ['SNMP_MIB_DIRECTORY']
的值,就可以通过注入恶意代码来实现代码执行,但是前提是要了解输入的处理方式,检查有没有应用过滤器处理了这些输入。
经过进一步分析,发现$protectedPost
数组是在header.php
文件中声明的,如下所示:
这两行代码会处理所有传入的GET请求、POST请求,并使用“ strip_tags_array()”函数删除任何标签,转换成数组形式保存在“$protectedGet”
、“$protectedPost”
变量里。
在这里可以看到PHP代码里没有对外部请求做过滤,意味着可以把Payload注入到可以控制的变量“$protectedPost ['mib_file']”
里。
为了再次确认没有额外的过滤,还需要分析“require/function_commun.php”
中的strip_tags_array()
函数:
从这段代码中可以看到函数作用是过滤输入中的某些标签,过滤后返回输出。
现在已经知道应用程序中有一个POST请求会传递给strip_tags_array()函数。然后发送并添加到$protectedPost
数组中,现在只需要搞清楚在哪里发送可以保存这个变量值。
在深入研究应用程序之后,发现可以通过使用以下页面设置选项来控制“$values ['tvalue']['SNMP_MIB_DIRECTORY']”
的值:

当拦截请求时,可以看到以下内容:

提交值后可以看到状态里的变量已更新完毕:

基于之前的分析,如果触发了“get_mib_oid()”
函数,可以调用“$values ['tvalue'] ['SNMP_MIB_DIRECTORY']”
值,在本例中为“Our Payload”,为了验证,添加一条PHP代码做调试语句,回显提交的值“ Our Payload”。
编辑“ CommandLine.php”文件然后加入一行PHP代码,如下所示:

在深入研究应用程序之后,发现可以使用以下页面触发该函数:

点击发送后,收到以下请求:

提交的“ update_snmp”值可以作为以下代码的判断条件:
网页里可以看到提交的值“Our Payload”
打印在页面上:

现在可以注入有效的命令语句来执行。
提交的Payload进入get_mib_oid()
函数会跟其他字符串串联在一起,类似于以下内容:
为了避免这种情况,需要将Payload更改为如下所示:
我们可以用netcat反向shell替换“Our Payload”
,如下所示:
使用“;”
转义命令,并在字符串后用“#”
注释掉多余的内容。
注入Payload然后触发。并且检查Netcat监听是否有回连:

还需要通过访问此页面来触发
623K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8U0p5%4x3W2)9J5k6e0p5$3i4K6u0W2x3e0b7%4i4K6u0W2x3e0t1&6i4K6u0r3L8$3y4K6M7X3g2H3L8%4u0@1M7#2)9J5c8X3W2F1k6r3g2^5i4K6u0W2M7r3S2H3i4K6y4r3k6Y4g2F1j5%4c8A6L8$3&6Q4x3@1c8e0e0V1#2b7i4K6g2X3j5$3!0F1k6X3W2Y4
正如之前获得以下HTTP请求一样:

提交后可以在NetCat上获得以下内容:

奥里给!弹出一个shell!
再编写一个利用程序实现自动利用,编写此EXP程序的过程中笔者玩得很开心,因为必须处理很多的CSRF令牌,表单和其他一些要求。
跟往常一样使用python编写漏洞利用程序,这是最终的exp代码:
运行漏洞利用程序之后,可以获得以下内容:

我们再次弹回一个shell~!
翻译地址:caeK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6K6K9r3g2D9L8s2y4Q4x3X3g2K6P5i4y4@1k6h3#2K6i4K6u0r3L8$3y4K6i4K6u0V1K9h3&6$3k6h3&6@1L8%4u0&6i4K6u0V1L8X3N6Q4x3X3c8$3x3W2)9J5k6o6N6Q4x3X3c8J5k6h3#2G2N6r3g2Q4x3X3c8U0L8$3#2E0j5h3&6V1i4K6u0V1k6i4S2W2j5%4g2@1K9h3!0F1i4K6u0V1j5%4k6W2i4K6u0V1x3U0l9J5x3q4)9J5k6o6p5@1z5e0b7%4i4K6u0r3
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2020-8-6 17:56
被lipss编辑
,原因: