目录php
0. 引言 1. 黑客针对WEB Server会有那些攻击面 2. 针对Tomcat Server能够作的安全加固 3. Managing Security Realms with JMX 4. 实现对TOMCAT配置信息的动态修改(hot dynamic edit) 5. Tomcat manager弱口令入侵部署WEBSHELL防护 6. Tomcat远程war包部署攻防
0. 引言html
most weaknesses in Apache Tomcat come from incorrect or inappropriate configuration. It is nearly always possible to make Tomcat more secure than the default out of the box installation.
WEB容器(WEB Server)是运行在操做系统上的一个应用级软件,对服务器的配置(config文件)进行加固处理是防护WEB相关漏洞的一个有效的手段。对于实现WEB服务器的配置加固,咱们须要达到以下几个目标java
1. 使用加固后的标准版的配置文件(config file)对原始文件进行替换 2. 对配置文件替换操做须要实现回滚操做 3. 对配置文件进行加固后,须要能马上生效,并对当前服务器的业务运行产生尽可能少的影响 1) 配置文件热加载(hot reload) 2) 重启web server
Relevant Link:mysql
https://www.owasp.org/index.php/Securing_tomcat
1. 黑客针对WEB Server会有那些攻击面linux
黑客攻击网站时,有一个简单的杀手锏,即寻找常见的漏洞,例如程序员
1. 使用WEB Server默认的帐户 1) tomcat默认安装后,后台管理界面的登陆采用basic authentication的身份验证方式,而这个默认的帐户是系统默认设置的tomcat、tomcat(在tomcat-users.xml文件中) 2. 账户密码很弱或者没有 1) IIS使用内置或默认账户。黑客通常会寻找这些账户。若是这些帐户没有从系统中删除的话,就会被发现并被更改 2) 用户为了方便管理,经常在tomcat的后台管理界面的basic authentication登陆中使用弱口令,很容易遭到黑客的暴力破解 3. 大量的开放端口 每一位访问者,不管是善意仍是恶意,均可以经过开放端口链接到站点和系统。在默认状况下,Windows与IIS的开放端口远远多于为了正常运行所需的端口。保持系统的开放端口应该保持最少数量,这一点很重要。全部其余的端口都须要关闭。 1) Windows License Logging Service溢出 经过发送一条通过特殊格式化的信息到运行License Logging Service的Web服务器,黑客可以对未检查的缓冲区进行攻击。这能够致使服务失效,为黑客打开一个开放端口,从而使用“System”权限在服务器上执行代码。 2) 微软服务器信息块(SMB)漏洞 服务器信息块协议被Windows用于文件和打印机的共享以及计算机之间的通讯。黑客的SMB服务器能够利用这项功能来使用"System"权限,对客户机执行任意代码。 4. 服务器扩展、模块的漏洞 1) ISAPI扩展缓冲区溢出 IIS安装后,就会自动安装多个Internet ISAPI服务器扩展。ISAPI服务器扩展其实是动态连接库(DLL),是用来加强IIS服务器的功能的。一些动态连接库,好比idq.dll ,包含编程错误,可以让黑客发送数据到ISAPI服务器扩展,这就是"缓冲区溢出"攻击 所以,攻 5. WEB脚本漏洞 针对WEB脚本(asp、php、jsp)的攻击原则上来讲是代码层的攻击,可是从纵深防护的原则上来看,咱们在服务器的代码执行层面也是能够部署一些限制的 1) 利用执行路径限制,将当前web路径强制限定在某个路径下 2) API白名单、黑名单限制
0x1: Tomcat默认配置 web
1. tomcat-users.xml Tomcat默认配置了2个角色: tomcat、role1 tomcat默认配置了3个账号: both、tomcat、role1的默认密码都是tomcat /* <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="both" password="tomcat" roles="tomcat,role1"/> <user username="role1" password="tomcat" roles="role1"/> */ 可是这些账号都不具有直接部署应用的权限,默认须要有manager权限才可以直接部署war包,Tomcat默认须要安装Administration Web Application。Tomcat默认没有配置任何用户以及角色,没办法用默认账号登陆,在正常状况下,若是管理员须要登陆manager页面使用管理以及远程部署功能,须要新增一个manager角色,并将指定账号赋予这个角色,以后管理员才可使用这个账号登陆manager页面 2. context.xml Tomcat的上下文,通常状况下若是用Tomcat的自身的数据源多在这里配置。找到数据源便可用对应的账号密码去链接数据库 /* <Context> <WatchedResource>WEB-INF/web.xml</WatchedResource> <Resource name="jdbc/u3" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="xxxxx" password="xxxx" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.0.xxx:3306/xxx?autoReconnect=true"/> </Context> */ 3. server.xml Server这个配置文件价值很是高,一般的访问端口、域名绑定和数据源能够在这里找到,若是想知道找到域名对应的目录能够读取这个配置文件。若是有用Https,其配置也在这里面可以找到 4. web.xml 项目初始化的时候会去调用这个配置文件
0x2: manager页面部署WAR Getshellsql
1. 查看部署状况。从"tomcat-users.xml"文件中、或者直接经过猜解默认密码获取的具备管理员权限的用户名和密码,验证经过后进入部署管理页面 2. 部署管理页面中能够"Start"(启动)、"Stop"(中止)、"Reload"(重载)、"Undeploy"(删除部署)已经部署的项目,单击"Undeploy"会对文件进行物理删除 3. 部署的文件夹是以*.war文件的名称,例如上传的文件是job.war,则在Tomcat目录中会对应生成一个"job"文件夹 4. 部署JSP WebShell后门程序。在部署管理页面的下方有一个"WAR file to deploy",单击浏览选择一个已经设置好的后门war文件,在本例中的后门程序为job.war,单击“deploy”将该文件部署到服务器上 5. 上传文件后,tomcat会自动进行部署并运行 http://127.0.0.1:8080/job/job.jsp[/url]
Relevant Link:shell
http://www.searchsecurity.com.cn/showcontent_11382.htm http://www.searchsecurity.com.cn/guide/webseversetting.htm http://blog.csdn.net/ablipan/article/details/7840103 http://drops.wooyun.org/tips/604 http://oss.org.cn/ossdocs/apache/tomcat/l-tomcat.htm
2. 针对Tomcat Server能够作的安全加固数据库
0x1: 升级到官方最新版
The first step is to make sure you are running the latest stable releases of software
1. Java Runtime Environment (JRE) or SDK 2. Tomcat 3. Third-party libraries
Many software projects, including Tomcat and Java, maintain multiple branches. New features are added to more recent branches, the older branches receive only bug-fixes and security updates. This allows developers to advance the software without disrupting production environments. Be aware of which branch you have deployed, and track new releases within that branch.
For example, if you are running Tomcat 5.5.26, you should watch for new versions within the 5.5 branch (e.g. 5.5.27) and upgrade to this bug-fix version. If you are content to stick with the Tomcat 5.5 branch then it is not necessary to upgrade to a new 6.0.18 version.
0x2: 最小权限默认安装
1. UNIX 1) Create a tomcat user/group 2) Download and unpack the core distribution (referenced as CATALINA_HOME from now on) 3) Change CATALINA_HOME ownership to tomcat user and tomcat group 4) Change files in CATALINA_HOME/conf to be readonly (400) 5) Make sure tomcat user has read/write access to /tmp and write (300 - yes, only write/execute) access to CATALINA_HOME/logs //值得注意的是,在LINUX/UNIX系统上,tomcat能够实现降权运行 2. Windows 1) Download the core windows service installer 2) Start the installation, click Next and Agree to the licence 3) Untick native, documentation, examples and webapps then click Next 4) Choose an installation directory (referenced as CATALINA_HOME from now on), preferably on a different drive to the OS. 5) Choose an administrator username (NOT admin) and a secure password that complies with your organisations password policy. 6) Complete tomcat installation, but do not start service. 3. Common 1) Remove everything from CATALINA_HOME/webapps (ROOT, balancer, jsp-examples, servlet-examples, tomcat-docs, webdav) 2) Remove everything from CATALINA_HOME/server/webapps (host-manager, manager). Note that it can be useful to keep the manager webapp installed if you need the ability to redeploy without restarting Tomcat. If you choose to keep it please read the section on Securing the Manager WebApp. 3) Remove CATALINA_HOME/conf/Catalina/localhost/host-manager.xml and CATALINA_HOME/conf/Catalina/localhost/manager.xml (again, if you are keeping the manager application, do not remove this). 4) Make sure the default servlet is configured not to serve index pages when a welcome file is not present. In CATALINA_HOME/conf/web.xml /* <servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>false</param-value> <!-- make sure this is false --> </init-param> <load-on-startup>1</load-on-startup> </servlet> */ 5) Remove version string from HTTP error messages by repacking CATALINA_HOME/server/lib/catalina.jar with an updated ServerInfo.properties file. 6) ename CATALINA_HOME/conf/server.xml to CATALINA_HOME/conf/server-original.xml and rename CATALINA_HOME/conf/server-minimal.xml to CATALINA_HOME/conf/server.xml. The minimal configuration provides the same basic configuration, but without the nested comments is much easier to maintain and understand. Do not delete the original file as the comments make it useful for reference if you ever need to make changes - e.g. enable SSL. 7) Replace the server version string from HTTP headers in server responses, by adding the server keyword in your Connectors in CATALINA_HOME/conf/server.xml /* <Connector port="8080" ... server="Apache" /> <!-- server header is now Apache --> */
0x3: 错误页面版本隐藏
Remove version string from HTTP error messages by repacking CATALINA_HOME/server/lib/catalina.jar with an updated ServerInfo.properties file. Note that making this change may prevent Lambda Probe (popular Tomcat monitoring webapp) to initialise as it cannot determine the Tomcat version.
1. unpack catalina.jar cd CATALINA_HOME/server/lib jar xf catalina.jar org/apache/catalina/util/ServerInfo.properties 2. update ServerInfo.properties by changing server.info line to server.info=Apache Tomcat 3. repackage catalina.jar jar uf catalina.jar org/apache/catalina/util/ServerInfo.properties 4. remove CATALINA_HOME/server/lib/org (created when extracting the ServerInfo.properties file)
0x4: HTTP响应版本隐藏
Replace the server version string from HTTP headers in server responses, by adding the server keyword in your Connectors in CATALINA_HOME/conf/server.xml
<Connector port="8080" ... server="Apache" /> <!-- server header is now Apache -->
0x5: Protecting the Shutdown Port
Tomcat uses a port (defaults to 8005) as a shutdown port. What this means is that to stop all webapps and stop Tomcat cleanly the shutdown scripts make a connection to this port and send the shutdown command. This is not as huge a security problem as it may sound considering the connection to the port must be made from the machine running tomcat(必须从本机发起这个关闭请求,没法经过RCE完成) and the shutdown command can be changed to something other than the string SHUTDOWN. However, it's wise to take the following precautions
1. if you are running a publicly accessible server make sure you prevent external access to the shutdown port by using a suitable firewall. 2. change the shutdown command in CATALINA_HOME/conf/server.xml and make sure that file is only readable by the tomcat user. /* <Server port="8005" shutdown="ReallyComplexWord"> */
0x6: Securing Manager WebApp
1. By default there are no users with the manager role. To make use of the manager webapp you need to add a new role and user into the CATALINA_HOME/conf/tomcat-users.xml file.
<role rolename="manager"/> <user username="darren" password="ReallyComplexPassword" roles="manager"/>
2. When you access the password-protected manager webapp, the password you enter will be sent over the network in (nearly) plain text, ripe for interception. By using an SSL connection instead, you can transport the password securely
Fortunately, this is simple to accomplish. After configuring an SSL Connector in server.xml (see your Tomcat documentation), simply add the following to CATALINA_HOME/webapps/manager/WEB-INF/web.xml inside of the <security-constraint></security-constraint> tags.
<user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint>
This will force an SSL connection to be used when accessing the manager webapp. Plus, with a little more work, the SSL Connector can be configured to require a client certificate.
3. Using a valve to filter by IP or hostname to only allow a subset of machines to connect (i.e. LAN machines). Add one of the following within the Context tag in CATALINA_HOME/conf/Catalina/localhost/manager.xml
<!-- allow only LAN IPs to connect to the manager webapp --> <!-- contrary to the current Tomcat 5.5 documation the value for allow is not a regular expression --> <!-- future versions may have to be specified as 192\.168\.1\.* --> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192.168.1.*" /> <!-- allow only LAN hosts to connect to the manager webapp --> <!-- contrary to the current Tomcat 5.5 documation the value for allow is not a regular expression --> <!-- future versions may have to be specified as *\.localdomain\.com --> <Valve className="org.apache.catalina.valves.RemoteHostValve" allow="*.localdomain.com" />
4. Rename the manager webapp
This is 'security through obscurity'. Although widely maligned, obscurity is a useful adjunct security measure on a one-off basis. A would-be attacker seeking to gain access to the manager webapp will look for it in its usual location. By renaming it, you force the attacker to guess URLs or assume that it is not installed. It is important to note that you are not relying upon this obscurity for security, but rather using it as a backup measure in case someone finds a way around the remote valve filter you have configured as described above.
To rename the manager webapp, decide on the new name (we'll use foobar in this example), and:
1. Move CATALINA_HOME/conf/Catalina/localhost/manager.xml to CATALINA_HOME/conf/Catalina/localhost/foobar.xml 2. Update the docBase attribute within CATALINA_HOME/conf/Catalina/localhost/foobar.xml to ${catalina.home}/server/webapps/foobar 3. Move CATALINA_HOME/server/webapps/manager to CATALINA_HOME/server/webapps/foobar
0x7: Logging
As of tomcat 5.5 logging is now handled by the commons-logging framework allowing you to choose your preferred logging implementation - log4j or standard JDK logging. By default the standard JDK logging is used (or a compatible extension called juli to be more precise), storing daily log files in CATALINA_HOME/logs.
By default additional webapp log entries are added to CATALINA_HOME/logs/catalina.YYYY-MM-DD.log and System.out/System.err are redirected to CATALINA_HOME/logs/catalina.out. To place webapp log entries in individual log files create a logging.properties file similar to the following within CATALINA_HOME/webapps/APP_NAME/WEB-INF/classes (change the APP_NAME value to create a unique file for each webapp)
handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler org.apache.juli.FileHandler.level = ALL org.apache.juli.FileHandler.directory = ${catalina.base}/logs org.apache.juli.FileHandler.prefix = APP_NAME.
0x8: Java Security
1. Running Tomcat with a Security Manager The default Tomcat configuration provides good protection for most requirements, but does not prevent a malicious application from compromising the security of other applications running in the same instance. To prevent this sort of attack, Tomcat can be run with a Security Manager enabled which strictly controls access to server resources. Tomcat documentation has a good section on enabling the Security Manager. It's always a good idea to start tomcat with the "-security" parameter. This also makes sure (among other things), that a webapplication isn't able to read/write/execute any file on the local filesystem without enabling it in the catalina.policy file. This effectively stops web shells like described here from working.
0x9: 后台管理界面登陆密码强化
这个问题属于口令安全的范畴,我在其余的文章中涉及到了这方面的知识
http://www.cnblogs.com/LittleHann/p/3567908.html http://www.cnblogs.com/LittleHann/p/3541989.html http://www.cnblogs.com/LittleHann/p/3543681.html
0x10: 禁用tomcat manage管理页面
禁用Tomcat Manage的后台管理页面,能够经过修改tomcat-users.xml配置文件中和角色,帐户身份有关的配置来实现,在研究如何禁用管理界面以前,咱们先来学习一下tomcat的身份验证机制
1. tomcat中的Reaml身份验证、管理
1. UserDatabaseRealm //className="org.apache.catalina.realm.UserDatabaseRealm" UserDatabaseRealm is an implementation of the Tomcat Realm interface that uses a JNDI resource to store user information. By default, the JNDI resource is backed by an XML file. It is not designed for large-scale production use. At startup time, the UserDatabaseRealm loads information about all users, and their corresponding roles, from an XML document (by default, this document is loaded from $CATALINA_BASE/conf/tomcat-users.xml). The users, their passwords and their roles may all be editing dynamically, typically via JMX. Changes may be saved and will be reflected in the XML file. 对于使用 的身份验证,可使用JMX API接口动态的修改tomcat的身份认证配置,并自动映射到磁盘上的配置文件tomcat-users.xml 2. JDBCRealm //className="org.apache.catalina.realm.JDBCRealm JDBCRealm is an implementation of the Tomcat Realm interface that looks up users in a relational database accessed via a JDBC driver. There is substantial configuration flexibility that lets you adapt to existing table and column names, as long as your database structure conforms to the following requirements: 1) There must be a table, referenced below as the users table, that contains one row for every valid user that this Realm should recognize. 2) The users table must contain at least two columns (it may contain more if your existing applications required it): 3) Username to be recognized by Tomcat when the user logs in. Password to be recognized by Tomcat when the user logs in. This value may in cleartext or digested 4) The user roles table must contain at least two columns (it may contain more if your existing applications required it): 4.1) Username to be recognized by Tomcat ( 4.2) 2014/10/27Role name of a valid role associated with this user. /* create table users ( user_name varchar(15) not null primary key, user_pass varchar(15) not null ); create table user_roles ( user_name varchar(15) not null, role_name varchar(15) not null, primary key (user_name, role_name) ); */ When a user attempts to access a protected resource for the first time, Tomcat will call the authenticate() method of this Realm. Thus, any changes you have made to the database directly (new users, changed passwords or roles, etc.) will be immediately reflected. 对于JDBCRealm来讲,对保存帐户信息的数据库的修改,会实时的映射到tomcat中 3. DataSourceRealm //className="org.apache.catalina.realm.DataSourceRealm" DataSourceRealm is an implementation of the Tomcat Realm interface that looks up users in a relational database accessed via a JNDI(JNDI(Java Naming and Directory Interface,Java命名和目录接口) named JDBC DataSource. 本质上和JDBCRealm认证原理相似,差异在于使用JNDI接口进行数据源数据获取 4. JNDIRealm //className="org.apache.catalina.realm.JNDIRealm" JNDIRealm is an implementation of the Tomcat Realm interface that looks up users in an LDAP directory server accessed by a JNDI provider (typically, the standard LDAP provider that is available with the JNDI API classes). The realm supports a variety of approaches to using a directory for authentication. 5. MemoryRealm MemoryRealm is a simple demonstration implementation of the Tomcat Realm interface. It is not designed for production use. At startup time, MemoryRealm loads information about all users, and their corresponding roles, from an XML document (by default, this document is loaded from $CATALINA_BASE/conf/tomcat-users.xml). Changes to the data in this file are not recognized until Tomcat is restarted. 6. JAASRealm //className="org.apache.catalina.realm.JAASRealm" JAASRealm is an implementation of the Tomcat Realm interface that authenticates users through the Java Authentication & Authorization Service (JAAS) framework which is now provided as part of the standard Java SE API. 7. CombinedRealm //className="org.apache.catalina.realm.CombinedRealm" CombinedRealm is an implementation of the Tomcat Realm interface that authenticates users through one or more sub-Realms. Using CombinedRealm gives the developer the ability to combine multiple Realms of the same or different types. This can be used to authenticate against different sources, provide fall back in case one Realm fails or for any other purpose that requires multiple Realms. Sub-realms are defined by nesting Realm elements inside the Realm element that defines the CombinedRealm. Authentication will be attempted against each Realm in the order they are listed. Authentication against any Realm will be sufficient to authenticate the user. 8. LockOutRealm //className="org.apache.catalina.realm.LockOutRealm" LockOutRealm is an implementation of the Tomcat Realm interface that extends the CombinedRealm to provide lock out functionality to provide a user lock out mechanism if there are too many failed authentication attempts in a given period of time. To ensure correct operation, there is a reasonable degree of synchronisation in this Realm. This Realm does not require modification to the underlying Realms or the associated user storage mechanisms. It achieves this by recording all failed logins, including those for users that do not exist. To prevent a DOS by deliberating making requests with invalid users (and hence causing this cache to grow) the size of the list of users that have failed authentication is limited. Sub-realms are defined by nesting Realm elements inside the Realm element that defines the LockOutRealm. Authentication will be attempted against each Realm in the order they are listed. Authentication against any Realm will be sufficient to authenticate the user.
咱们重点来研究一下tomcat默认的身份验证方式,UserDatabaseRealm的相关知识
... <Realm className="org.apache.catalina.realm.LockOutRealm"> <!-- This Realm uses the UserDatabase configured in the global JNDI resources under the key "UserDatabase". Any edits that are performed against this UserDatabase are immediately available for use by the Realm. --> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> ...
UserDatabaseRealm类接口
public class UserDatabaseRealm extends RealmBase //Implementation of Realm that is based on an implementation of UserDatabase made available through the global JNDI resources configured for this instance of Catalina. Set the resourceName parameter to the global JNDI resources name for the configured instance of UserDatabase that we should consult.
UserDatabaseRealm is an implementation of the Tomcat Realm interface that uses a JNDI resource to store user information. By default, the JNDI resource is backed by an XML file. It is not designed for large-scale production use. At startup time, the UserDatabaseRealm loads information about all users, and their corresponding roles, from an XML document (by default, this document is loaded from $CATALINA_BASE/conf/tomcat-users.xml). The users, their passwords and their roles may all be editing dynamically, typically via JMX. Changes may be saved and will be reflected in the XML file.
2. tomcat中用户角色
tomcat采用"用户角色"的方式对用户的访问权限进行管理,每一个用户都被划分到了一个"用户角色"中,toncat的默认预设角色有
1. manager-gui allows access to the HTML GUI and the status pages 也就是咱们经常使用到的 http://localhost:8080/manager/html 2. manager-script allows access to the text interface and the status pages 3. manager-jmx allows access to the JMX proxy and the status pages 4. manager-status allows access to the status pages only
结合以上知识,咱们能够得出若是须要对tomcat manager页面进行禁用,能够采起以下的方法
1. 将tomcat-users.xml中的<user .../>节点中,设置为"manager-gui"的帐户所有修改成"tomcat" 由于只有manager-gui这个role才具备访问tomcat web后台界面的权限,所以,这样实现对tomcat后台页面的禁用 2. 修改403.jsp页面 对tomcat-users.xml文件进行修改后,管理员在使用原始的账号密码登陆后台的时候,会被Realm验证模块拒绝,显示403.jsp页面。咱们须要在这个页面显示咱们的修复动做和可能产生的后果,并告知修改回滚的接口地址 3. 修复消息通知推送 经过手机短信的方式通知到管理员tomcat的后台管理界面已经被禁用
3. 删除\webapps\manager\WEB-INF\web.xml文件
Relevant Link:
http://tomcat.apache.org/tomcat-8.0-doc/index.html http://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html http://www.cnblogs.com/lanhuahua/archive/2011/08/10/2133685.html http://blog.csdn.net/feng88724/article/details/7164983 https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/realm/UserDatabaseRealm.html
011: 禁用tomcat manager管理界面的WAR Remote Deploy远程部署
0x12: 禁止列目录(index travel)
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
Relevant Link:
https://www.owasp.org/index.php/Securing_tomcat http://tomcat.apache.org/tomcat-7.0-doc/security-howto.htm http://media.techtarget.com/tss/static/articles/content/TomcatSecurity/TomcatSecurity.pdf https://www.mulesoft.com/tcat/tomcat-security
3. Managing Security Realms with JMX(java management extensions)
和IIS的自动化API操做相似,tomcat一样提供了对外暴露的安全配置接口
//IIS API automatic config相关知识请参阅 http://www.cnblogs.com/LittleHann/p/3988923.html
Java Management Extensions, or JMX, is a Java technology designed for remote administration and monitoring of Java components. All versions of Tomcat 5.x or later natively support the JMX protocol.
整个tomcat的安全配置体系架构能够分为一个三层的结构
1. the Instrumentation Level The Instrumentation Level contains the components and resources that you would like to manage. These resources are represented by one or more specialized JavaBeans known as Managed Beans, or MBeans for short MBeans are Java Beans that implement additional components which allow them to be managed and monitored via the JMX framework. Each MBean represents a single resource running on the JVM, which is exposed for remote management using JMX. 在这一层就是所谓的providers MBeans 2. the Agent Level There are a few different types of MBeans, each with different functionalities, which offer a greater degree flexibility when designing your administrative framework. Any MBean that you wish to expose is registered with the MBeanServer, which makes up JMX's Agent Level. The Agent Level is composed of an intermediate agent called MBeanServer. The job of this layer is to receive requests or commands from the Remote Management Level, and relay them to the appropriate MBean. It also can receive notifications from its MBeans, such as state changes, and forward them to the Remote Management Layer. 在这一层就是所谓的security service(APIS) 3. the Remote Management Level The Remote Management Layer is made up of client programs, connectors, and adaptors, and allows the user to send requests to the Agent layer for relay and receive the results of these requests. Users can connect to the MBeanServer either 1) through a connector, using a client program such as JConsole and a protocol such as RMI or IIOP 对应于tomcat-users.xml中的manager-jmx role 2) or through an adaptor, which adapts the MBeanServer API to another protocol, such as HTTP, allowing JMX to be used with custom web-based GUIs. 对应于tomcat-users.xml中的manager-gui role In summary, a user at the Remote Management Level sends a request or command to the Agent Level, which contacts the appropriate MBean at the Instrumentation Level, and relays the response back to the user.
This distributed system allows users to build highly customized administrative frameworks from scratch.
0x1: Security Realms
A security realm comprises mechanisms for protecting WebLogic resources. Each security realm consists of a set of configured security providers, which are modular components that handle specific aspects of security. You can
1. create a JMX client that uses the providers in a realm to add or remove security data such as users and groups. 2. You can also create a client that adds or removes providers 3. makes other changes to the realm configuration.
0x2: Understanding the Hierarchy of Security MBeans
Like other subsystems, the "WebLogic Server security framework" organizes its MBeans in a hierarchy that JMX clients can navigate without constructing JMX object names. However
1. the set of MBean types that are available in a security realm depends on which security providers you have installed in the realm 2. the set of services that each security provider enables depends on how the provider was created.
tomcat使用层次结构的MBeans对安全域进行组织管理,每一个Mbeans对应于不一样方面的安全配置,程序员能够经过JMX Clients链接这些Mbeans,对tomcat的对应的安全配置进行动态的读写
security providers -> security realm(一个realm能够包含多个providers) -> MBean Proxy -> security service(APIS)
而之因此说tomcat的Mbeans是层次结构的,是由它的类继承关系决定的
Each security provider must extend a base provider type. For example
1. DefaultAuthorizerMBean extends AuthorizerMBean 2. any custom or third-party authorization provider also extends AuthorizerMBean. //If a JMX client gets the value of the RealmMBean Authorizers attribute, the MBean server returns all MBeans in the realm that extend AuthorizerMBean. The JMX client can iterate through the list of providers and select one based on the value of its Name attribute or other criteria.
Base provider types can be enhanced by extending a set of optional mix-in interfaces. For example
1. if an authentication provider extends the UserEditorMBean, then the provider can add users to the realm.
0x3: Security Providers(the Instrumentation Level)
咱们知道,对tomcat中某个MBeans的操做实质上就是在对MBeans后面的Provider的操做,在tomcat的providers中,和安全身份认证有关的providers有
1. AuthenticationProviderMBean The base MBean for all MBean implementations that manage Authentication providers. If your Authentication provider uses the WebLogic Security SSPI to provide login services, then your MBean must extend weblogic.management.security.authentication.Authenticator. If your Authentication provider uses the WebLogic Security SPI to provide identity-assertion services, then your MBean must extend weblogic.management.security.authentication.IdentityAsserter. 2. AuthenticatorMBean The SSPI MBean that all Authentication providers with login services must extend. This MBean provides a ControlFlag to determine whether the Authentication provider is a REQUIRED, REQUISITE, SUFFICENT, or OPTIONAL part of the login sequence. 3. IdentityAsserterMBean The SSPI MBean that all Identity Assertion providers must extend. This MBean enables an Identity Assertion provider to specify the token types for which it is capable of asserting identity. 4. ServletAuthenticationFilterMBean The SSPI MBean that all Servlet Authentication Filter providers must extend. This MBean is just a marker interface. It has no methods on it.
0x4: MBean Mixin Interfaces for Security Providers
在tomcat中,providers模块是数据提供者,而MBeans则提供了对外访问的接口,用来对tomcat的配置进行动态地修改
.... 1. UserEditorMBean:Provides a set of methods for creating, editing, and removing users 2. UserReaderMBean:Provides a set of methods for reading data about users. 3. RoleEditorMBean:Provides a set of methods for creating, editing, and removing roles. 4. RoleReaderMBean:Provides a set of methods for reading roles. ...
0x5: 经过JMX操做tomcat配置信息编程示例
链接tomcat的JMX Proxy有2种方法
1. HTTP URL方式:tomcat manager内置了一个轻量级的JMP HTTP Proxy 2. 使用java编写client connector/adaptor客户端程序
1. HTTP方式
The JMX Proxy Servlet is a lightweight proxy to get and set the tomcat internals
JXMProxy HTTP有如下几种操做方式
1. JMX Query command 1) look for a specific MBean by the given name http://localhost:8080/manager/jmxproxy/?qry=Catalina%3Atype%3DEnvironment%2Cresourcetype%3DGlobal%2Cname%3DsimpleValue 2) locate all workers which can process requests and report their state http://localhost:8080/manager/jmxproxy/?qry=*%3Atype%3DRequestProcessor%2C* 3) return all loaded servlets http://localhost:8080/manager/jmxproxy/?qry=*%3Aj2eeType=Servlet%2c* 2. JMX Get command 1) fetch the value of a specific MBean's attribute http://localhost:8080/manager/jmxproxy/?get=BEANNAME&att=MYATTRIBUTE&key=MYKEY 2) fetch the current heap memory data: http://localhost:8080/manager/jmxproxy/?get=java.lang:type=Memory&att=HeapMemoryUsage 3) fetch the current heap memory data and only want the "used" key http://localhost:8080/manager/jmxproxy/?get=java.lang:type=Memory&att=HeapMemoryUsage&key=used 3. JMX Set command 1) general format http://localhost:8080/manager/jmxproxy/?set=BEANNAME&att=MYATTRIBUTE&val=NEWVALUE 2) turn up debugging on the fly for the ErrorReportValve http://localhost:8080/manager/jmxproxy/?set=Catalina%3Atype%3DValve%2Cname%3DErrorReportValve%2Chost%3Dlocalhost&att=debug&val=10 4. JMX Invoke command The invoke command enables methods to be called on MBeans 1) general format http://localhost:8080/manager/jmxproxy/?invoke=BEANNAME&op=METHODNAME&ps=COMMASEPARATEDPARAMETERS 2) call the findConnectors() method of the Service use http://localhost:8080/manager/jmxproxy/?invoke=Catalina%3Atype%3DService&op=findConnectors&ps= 3) 修改指定用户的密码 http://localhost:8080/manager/jmxproxy/?set=Users:type=User,username="test",database=UserDatabase&att=password&val=hello //将test这个帐户的密码修改成hello
Relevant Link:
http://docs.oracle.com/cd/E11035_01/wls100/secintro/index.html http://docs.oracle.com/cd/E11035_01/wls100/jmx/accessWLS.html#wp1112969 http://tomcat.apache.org/tomcat-8.0-doc/manager-howto.html#Using_the_JMX_Proxy_Servlet http://tomcat.apache.org/tomcat-8.0-doc/manager-howto.html http://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html#MemoryRealm http://docs.oracle.com/cd/E11035_01/wls100/jmx/editsecurity.html http://www.360doc.com/content/10/1005/14/39755_58581727.shtml
2. JAVA Client Connector/adaptor方式:Creating WebLogic users programmatically from a standalone Java client
使用java编写client connector/adaptor这种方式要求服务端的tomcat服务器要开启"JMX_REMOTE_CONFIG",即tomcat须要监听一个JMX Proxy端口,默认状况下,tomcat是不会开启这个接口的,因此要进行这个实验,咱们还须要对tomcat的启动脚本增长一些额外的配置
1. 先修改Tomcat的启动脚本 1) windows下为bin/catalina.bat 2) linux下为catalina.sh 添加如下内容 set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG% /* 1. 8999是jmxremote使用的端口号 2. 第二个false表示不须要鉴权 */ 2. 要注意以上语句的位置不能太后面 大概在200行左右这个位置就能够了,太前面也不行 3. 启动/重启tomcat 1) D:\tomcat\apache-tomcat-8.0.14\bin 2) catalina.bat run
咱们配置了无鉴权模式的8999端口jmxproxy监听服务,如今能够开始编写java代码,经过jmx api链接到jmxproxy上了,从而对tomcat的MBeans进行动态的读写
import java.util.HashMap; import java.util.Map; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; public class JMXTest { public static void main(String[] args) { try { String jmxURL = "service:jmx:rmi:///jndi/rmi://127.0.0.1:8999/jmxrmi";//tomcat jmx url /* * JMXServiceURL用于标识JMXConnectorServer,它是采用如下形式的字符串 * service:jmx:<protocol>://[[[ <host>]: <port>]/ <path>] 1. "protocol" 指定了协议,例如 1) rmi 2) iiop 3) jmxmp 4) soap 2. "host"(可选) 3. "port"(可选) 4. "path"(可选) */ JMXServiceURL serviceURL = new JMXServiceURL(jmxURL); Map<String, String[]> map = new HashMap<String, String[]>(); String[] credentials = new String[] { "monitorRole" , "QED" }; map.put("jmx.remote.credentials", credentials); /* * The client end of a JMX API connector. An object of this type can be used to establish a connection to a connector server. * A newly-created object of this type is unconnected. Its connect method must be called before it can be used. However, objects created by JMXConnectorFactory.connect are already connected. */ JMXConnector conneactor = JMXConnectorFactory.connect(serviceURL, map); MBeanServerConnection mbsc = conneactor.getMBeanServerConnection(); /* ObjectName threadObjNameSet = new ObjectName("Catalina:type=Valve,host=localhost,context=/host-manager,name=BasicAuthenticator"); Attribute attrVal = new Attribute("stateName", "STOPED"); mbsc.setAttribute(threadObjNameSet, attrVal); */ /* * 填写须要获取的ObjectName对象名,即MBeans Idntifier */ ObjectName threadObjName = new ObjectName("Catalina:type=Valve,host=localhost,context=/host-manager,name=BasicAuthenticator"); String attrName = "stateName"; //经过MBeans的getter方法获取对应的属性值 System.out.println("password: " + mbsc.getAttribute(threadObjName, attrName)); } catch (Exception e) { e.printStackTrace(); } } }
能够经过URL的jmxproxy方式验证咱们得到的结果
http://localhost:8080/manager/jmxproxy/?get=Catalina:type=Valve,host=localhost,context=/host-manager,name=BasicAuthenticator&att=stateName result: OK - Attribute get 'Catalina:type=Valve,host=localhost,context=/host-manager,name=BasicAuthenticator' - stateName = STARTED
Relevant Link:
http://whitesock.iteye.com/blog/246186 http://www.programcreek.com/java-api-examples/index.php?api=javax.management.MBeanServerConnection http://pic.dhe.ibm.com/infocenter/wxsinfo/v8r6/index.jsp?topic=%2Fcom.ibm.websphere.extremescale.doc%2Ftxsmbeanprog.html http://blog.csdn.net/airobot008/article/details/3951524 http://sharpspeed.iteye.com/blog/2009770 http://www.blogjava.net/japper/archive/2012/09/05/387092.html
4. 实现对TOMCAT配置信息的动态修改(hot dynamic edit)
了解了tomcat jmx api编程以后,咱们回到咱们本文的中心,就是自动化的tomcat配置加固,即动态的修改内存中的tomcat配置,实现对tomcat的MBeans(保存tomcat全部维度信息的基本单位)配置信息的动态修改
1. HTTP URL JMXPROXY 经过这种方式对tomcat的配置进行动态修改存在以下几个条件、限制 1) 调用URL接口的用户必须自己是具备"manager-jmx"的角色,而且须要处于登陆后的状态才能够调用这个接口 2) tomcat的MBeans大多数不提供setter接口,而只提供getter接口,不少的设置是不能修改的,例如 2.1) 取消basic认证 2.2) 修改帐户的role角色 2. JAVA CLIENT JXMPROXY API 经过这种方式对tomcat的配置进行动态修改存在以下几个条件、限制 1) 须要tomcat服务端开启了JMXPROXY端口监听服务,而tomcat默认是不开启这个端口监听的,须要手动设置并重启 2) tomcat的MBeans大多数不提供setter接口,而只提供getter接口,不少的设置是不能修改的,例如 2.1) 取消basic认证 2.2) 修改帐户的role角色
须要注意的是,tomcat的jmx自动化操做方式是针对须要对tomcat进行实时性能监控而产生的,因此咱们会发现jmx接口中大多数是getter方法,并且无论是ur方式、仍是java client方式,在默认状况下tomcat都不支持,须要额外的配置才能启用,因此,咱们想要经过tomcat jmx方式对tomcat进行配置加固是有困难的
5. Tomcat manager弱口令入侵部署WEBSHELL防护
0x1: 直接删除manager页面对应的jsp文件、manager目录
或者直接删除\webapps\manager\WEB-INF\web.xml文件,一样获得禁用manager页面的效果
0x2: 修改tomcat-users.xml文件配置
1. 将弱密码修改成强密码 2. 取消用户的manager-gui,即降权,达到禁止用户访问manager页面的目的 //须要重启tomcat才能使新配置生效
0x3: 针对web应用的轻量级重启:修改应用中的web.xml的和身份认证、禁止登陆、POST WAR的相关配置
在开始研究tomcat应用程序的web.xml配置以前,咱们先针对这个思路和apache的配置进行一个类比
http://man.chinaunix.net/newsoft/Apache2.2_chinese_manual/howto/htaccess.html
在apache架构的网站应用中.htaccess文件(或者"分布式配置文件")提供了针对每一个目录(web应用)改变配置的方法,即在一个特定的目录中放置一个包含指令的文件,其中的指令做用于此目录及其全部子目录
对于tomcat,咱们也能够采起相同的思路,从本质上来讲,manager这个后台管理界面属于一个J2EE的应用,咱们能够直接修改manager目录下的web.xml文件,对其配置项进行修改禁止管理员访问,而后直接重启manager这个应用便可
1. tomcat web.xml配置
The web.xml Deployment Descriptor file describes how to deploy a web application in a servlet container such as Tomcat.
The location of the file is always the same: application root/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <!-- ========================================================== --> <!-- General --> <!-- ========================================================== --> <!-- Name the application --> <display-name>Example App</display-name> <description>An example application which is used to play with some of the features of Tomcat</description> <!-- This app is cluster-ready --> <distributable /> <!-- Set timeout to 120 minutes --> <session-config> <session-timeout>120</session-timeout> </session-config> <!-- ========================================================== --> <!-- Custom Tag Libraries --> <!-- ========================================================== --> <!-- Taglib declarations are no longer required since JSP 2.0, see Removing taglib from web.xml --> <!-- The <taglib> did not need to be a child of <jsp-config> in earlier versions but is required as of Tomcat 7 --> <!-- Note that you can only have one <jsp-config> element per web.xml --> <!-- <jsp-config> <taglib> <taglib-uri>mytags</taglib-uri> <taglib-location>/WEB-INF/jsp/mytaglib.tld</taglib-location> </taglib> </jsp-config> --> <!-- ========================================================== --> <!-- JSP Configuration --> <!-- ========================================================== --> <jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <include-prelude>/WEB-INF/jspf/prelude1.jspf</include-prelude> <include-coda>/WEB-INF/jspf/coda1.jspf</include-coda> </jsp-property-group> </jsp-config> <!-- ========================================================== --> <!-- Context Parameters --> <!-- ========================================================== --> <context-param> <description>Enable debugging for the application</description> <param-name>debug</param-name> <param-value>true</param-value> </context-param> <context-param> <description>The email address of the administrator, used to send error reports.</description> <param-name>webmaster</param-name> <param-value>address@somedomain.com</param-value> </context-param> <!-- ========================================================== --> <!-- JNDI Environment Variables --> <!-- ========================================================== --> <env-entry> <env-entry-name>webmasterName</env-entry-name> <env-entry-value>Ms. W. Master</env-entry-value> <env-entry-type>java.lang.String</env-entry-type> </env-entry> <env-entry> <env-entry-name>cms/defaultUserSettings/recordsPerPage</env-entry-name> <env-entry-value>30</env-entry-value> <env-entry-type>java.lang.Integer</env-entry-type> </env-entry> <env-entry> <env-entry-name>cms/enableXMLExport</env-entry-name> <env-entry-value>false</env-entry-value> <env-entry-type>java.lang.Boolean</env-entry-type> </env-entry> <env-entry> <env-entry-name>cms/enableEmailNotifications</env-entry-name> <env-entry-value>true</env-entry-value> <env-entry-type>java.lang.Boolean</env-entry-type> </env-entry> <!-- ========================================================== --> <!-- Servlets --> <!-- ========================================================== --> <!-- Simple Servlet, provide a name, class, description and map to URL /servlet/SimpleServlet --> <servlet> <servlet-name>Simple</servlet-name> <servlet-class>SimpleServlet</servlet-class> <description>This is a simple Hello World servlet</description> </servlet> <servlet-mapping> <servlet-name>Simple</servlet-name> <url-pattern>/servlet/SimpleServlet</url-pattern> </servlet-mapping> <!-- CMS Servlet, responds to *.cms URL's --> <servlet> <!-- Identification --> <servlet-name>cms</servlet-name> <servlet-class>com.metawerx.servlets.ContentManagementSystem</servlet-class> <description>This servlet handles requests for the CMS (it is a controller in an MVC architecture)</description> <!-- This servlet has two parameters --> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>2</param-value> </init-param> <!-- Load this servlet when the application starts (call the init() method of the servlet) --> <load-on-startup>5</load-on-startup> <!-- <run-at>0:00, 6:00, 12:00, 18:00</run-at> This tag is only valid for Resin --> </servlet> <!-- Map some URLs to the cms servlet (demonstrates *.extension mapping) --> <servlet-mapping> <!-- For any URL ending in .cms, the cms servlet will be called --> <servlet-name>cms</servlet-name> <url-pattern>*.cms</url-pattern> </servlet-mapping> <!-- Rewriter Servlet, responds to /content/* and /admin/RewriterStatistics URL's --> <!-- Define a servlet to respond to /content/* URL's --> <servlet> <servlet-name>rewriter</servlet-name> <servlet-class>com.metawerx.servlets.URLRewriter</servlet-class> </servlet> <!-- Map some URL's to the rewriter servlet (demonstrates /path/* and specific URL mapping) --> <servlet-mapping> <!-- For any URL starting with /content/, the rewriter servlet will be called --> <servlet-name>rewriter</servlet-name> <url-pattern>/content/*</url-pattern> </servlet-mapping> <servlet-mapping> <!-- The rewriter servlet can also be called directly as /admin/RewriterStatistics, to return stats --> <servlet-name>rewriter</servlet-name> <url-pattern>/admin/RewriterStatistics</url-pattern> </servlet-mapping> <!-- PathJSP Servlet, maps /shop/item/* URL's to a JSP file --> <!-- Define a JSP file to respond to /shop/item/* URL's --> <servlet> <servlet-name>pathjsp</servlet-name> <jsp-file>pathfinder.jsp</jsp-file> </servlet> <!-- Map some URL's to the pathjsp servlet (demonstrates /long/path/* URL mapping) --> <servlet-mapping> <!-- For any URL starting with /shop/item/, the pathjsp servlet will be called --> <servlet-name>pathjsp</servlet-name> <url-pattern>/shop/item/*</url-pattern> </servlet-mapping> <!-- ========================================================== --> <!-- Filters --> <!-- ========================================================== --> <!-- Example filter to set character encoding on each request (from Tomcat servlets-examples context) --> <filter> <filter-name>Set Character Encoding</filter-name> <filter-class>filters.SetCharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>EUC_JP</param-value> </init-param> </filter> <filter-mapping> <filter-name>Set Character Encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Example filter to dump the HTTP request at the top of each page (from Tomcat servlets-examples context) --> <filter> <filter-name>Request Dumper Filter</filter-name> <filter-class>filters.RequestDumperFilter</filter-class> </filter> <filter-mapping> <filter-name>Request Dumper Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- ========================================================== --> <!-- Listeners --> <!-- ========================================================== --> <!-- Define example application events listeners --> <listener> <listener-class>com.metawerx.listener.ContextListener</listener-class> </listener> <listener> <listener-class>com.metawerx.listener.SessionListener</listener-class> </listener> <!-- ========================================================== --> <!-- Security --> <!-- ========================================================== --> <!-- Define roles --> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>cms_editors</role-name> </security-role> <!-- Define a constraint to restrict access to /private/* --> <security-constraint> <display-name>Security constraint for the /private folder</display-name> <web-resource-collection> <web-resource-name>Protected Area</web-resource-name> <url-pattern>/private/*</url-pattern> <!-- If you list http methods, only those methods are protected. --> <!-- Leave this commented out to protect all access --> <!-- <http-method>DELETE</http-method> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> --> </web-resource-collection> <auth-constraint> <!-- Only only administrator and CMS editors to access this area --> <role-name>admin</role-name> <role-name>cms_editors</role-name> </auth-constraint> </security-constraint> <!-- FORM based authentication --> <!-- Leave this commented out, we will use BASIC (HTTP) authentication instead --> <!-- <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/error.jsp</form-error-page> </form-login-config> </login-config> --> <!-- This application uses BASIC authentication --> <login-config> <auth-method>BASIC</auth-method> <realm-name>Editor Login</realm-name> </login-config> <!-- Define a constraint to force SSL on all pages in the application --> <security-constraint> <web-resource-collection> <web-resource-name>Entire Application</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <!-- ========================================================== --> <!-- Error Handler --> <!-- ========================================================== --> <!-- Define an error handler for 404 pages --> <error-page> <error-code>404</error-code> <location>/error404.jsp</location> </error-page> <!-- Define an error handler for java.lang.Throwable --> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/errorThrowable.jsp</location> </error-page> <!-- ========================================================== --> <!-- Extra MIME types --> <!-- ========================================================== --> <!-- Set XML mime-mapping so spreadsheets open properly instead of being sent as an octet/stream --> <mime-mapping> <extension>xls</extension> <mime-type>application/vnd.ms-excel</mime-type> </mime-mapping> <!-- ========================================================== --> <!-- Locale --> <!-- ========================================================== --> <!-- Set Locale Encoding --> <locale-encoding-mapping-list> <locale-encoding-mapping> <locale>ja</locale> <encoding>Shift_JIS</encoding> </locale-encoding-mapping> </locale-encoding-mapping-list> <!-- ========================================================== --> <!-- Welcome Files --> <!-- ========================================================== --> <!-- Define, in order of preference, which file to show when no filename is defined in the path --> <!-- eg: when user goes to http://yoursite.com/ or http://yoursite.com/somefolder --> <!-- Defaults are provided in the server-wide web.xml file, such as index.jsp, index.htm --> <!-- Note: using this tag overrides the defaults, so don't forget to add them here --> <welcome-file-list> <!-- Use index.swf if present, or splash.jsp, otherwise just look for the normal defaults --> <welcome-file>index.swf</welcome-file> <welcome-file>splash.jsp</welcome-file> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
关于jsp和web.xml配置的相关知识,请参阅
http://www.cnblogs.com/LittleHann/p/3725886.html 搜索:2. web.xml基础语法
2. 配置web.xml禁用管理登陆manager后台页面
要达到禁用后台登陆的目的,咱们能够经过对web.xml做以下修改达到目的
1. <security-constraint>(fro html) -> <auth-constraint> -> <role-name> 2. 将"/html/*"(web-gui)的身份鉴权角色限制修改成一个自定义的角色名,例如"just4fun",这个名字要保证tomcat的默认角色配置不会覆盖到,即达到对管理员的角色降权,禁止管理员 3. 针对web.xml的配置修改是马上在tomcat中生效的,tomcat会对web.xml的修改自动作reload操做 4. manager页面会马上禁止管理员登陆
D:\tomcat\apache-tomcat-8.0.14\webapps\manager\WEB-INF\web.xml
修改后,当即生效
回滚后也当即生效
Relevant Link:
http://wiki.metawerx.net/wiki/Web.xml http://fangyunfeng.iteye.com/blog/1862251
0x4: Make A Brustattack Blocking Filter Or Listener Within Tomcat:向tomcat注册一个用于阻断后台manager页面的暴力破解阻断模块
filter、listener是tomcat中对http数据流进行pre(前置劫持)、after(后置处理)的一直机制,简单来讲,tomcat在整个http数据流的流程中给程序员暴露出了一些串行的hook点,容许程序员对http数据流进行修改
web.xml 的加载顺序是:context-param -> listener -> filter -> servlet ,而相同类型节点之间的程序调用的顺序是根据对应的mapping的顺序进行调用的
因此咱们能够选择编写tomcat filter,实现暴力破解阻断的功能
1. Tomcat Filter
关于tomcat filter的相关知识,请参阅另外一篇文章
http://www.cnblogs.com/LittleHann/p/3725886.html 搜索:0x3: Filter介绍
2. Code Example
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; /** * @author Administrator * */ public class LogFilter implements Filter { private FilterConfig filterConfig; public FilterConfig getFilterConfig() { System.err.println("...getFilterConfig..."); return filterConfig; } public void setFilterConfig(FilterConfig filterConfig) { System.err.println("...setFilterConfig..."); this.filterConfig = filterConfig; } /* (non-Javadoc) * @see javax.servlet.Filter#destroy() */ @Override public void destroy() { System.err.println("...filter destroy..."); } /* (non-Javadoc) * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.err.println("...doFilter..."); //传递下一个Filter chain.doFilter(request, response); } /* (non-Javadoc) * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) */ @Override public void init(FilterConfig filterConfig) throws ServletException { System.err.println("...init Filter..."); this.filterConfig = filterConfig; } }
2. 配置web.xml,向web应用注册一个Filter
<filter> <filter-name>LogFilter</filter-name> <filter-class>com.ee.filter.LogFilter</filter-class> </filter> <filter-mapping> <filter-name>LogFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
0x5: 经过classloader反射动态修改容器内类的配置实现修复配置修复
0x6: 经过java attach api实现远程代码注入,修复应用内存配置漏洞
0x7: Use LockOutRealm To Prevents Brute Force Attacks(org.apache.catalina.realm.LockOutRealm)
LockOutRealm is an implementation of the Tomcat Realm interface that extends the CombinedRealm to provide lock out functionality to provide a user lock out mechanism if there are too many failed authentication attempts in a given period of time.
To ensure correct operation, there is a reasonable degree of synchronization in this Realm.
This Realm does not require modification to the underlying Realms or the associated user storage mechanisms. It achieves this by recording all failed logins, including those for users that do not exist. To prevent a DOS by deliberating making requests with invalid users (and hence causing this cache to grow) the size of the list of users that have failed authentication is limited.
Sub-realms are defined by nesting Realm elements inside the Realm element that defines the LockOutRealm. Authentication will be attempted against each Realm in the order they are listed. Authentication against any Realm will be sufficient to authenticate the user.
The LockOutRealm implementation supports the following additional attributes.
1. allRolesMode This attribute controls how the special role name * is handled when processing authorization constraints in web.xml. By default, the specification compliant value of strict is used which means that the user must be assigned one of the roles defined in web.xml. The alternative values are authOnly which means that the user must be authenticated but no check is made for assigned roles and strictAuthOnly which means that the user must be authenticated and no check will be made for assigned roles unless roles are defined in web.xml in which case the user must be assigned at least one of those roles. 2. cacheRemovalWarningTime If a failed user is removed from the cache because the cache is too big before it has been in the cache for at least this period of time (in seconds) a warning message will be logged. Defaults to 3600 (1 hour). 3. cacheSize Number of users that have failed authentication to keep in cache. Over time the cache will grow to this size and may not shrink. Defaults to 1000. 4. failureCount The number of times in a row a user has to fail authentication to be locked out. Defaults to 5. 5. lockOutTime The time (in seconds) a user is locked out for after too many authentication failures. Defaults to 300 (5 minutes).
为了配置 CombinedRealm,须要建立一个 <Realm> 元素,并将其内嵌在 <Engine> 或 <Host> 元素中的 $CATALINA_BASE/conf/server.xml 文件内。一样,你也能够将其内嵌到 context.xml 文件下的 <Context> 节点
<Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine>
0x8: 修改\conf\tomcat-users.xml中的弱密码
缺点在于,须要重启Tomcat
Relevant Link:
http://docs.oracle.com/javase/7/docs/technotes/guides/attach/index.html
https://tomcat.apache.org/tomcat-7.0-doc/security-howto.html#Securing_Management_Applications
https://tomcat.apache.org/tomcat-7.0-doc/config/realm.html#LockOut_Realm_-_org.apache.catalina.realm.LockOutRealm
https://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html
http://wiki.jikexueyuan.com/project/tomcat/realms-aaa.html
0x9: 调用attach api动态修复JVM内存中配置
1. 列出当前主机上全部运行中JVM实例 2. 经过枚举进程列表、及其参数,找到tomcat进程PID 3. attach到目标JVM进程 4. 执行指定agent,注入指令,修改JVM的内存配置,关闭redirect、debug开关
6. Tomcat远程war包部署攻防
在windows环境下,tomcat的启动参数以下
D:\Java\bin\java.exe -Djava.util.logging.config.file="D:\Apache_Tomcat\conf\logging.properties" -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs="D:\Apache_Tomcat\endorsed" -classpath "D:\Apache_Tomcat\bin\bootstrap.jar;D:\Apache_Tomcat\bin\tomcat-juli.jar" -Dcatalina.base="D:\Apache_Tomcat" -Dcatalina.home="D:\Apache_Tomcat" -Djava.io.tmpdir="D:\Apache_Tomcat\temp" org.apache.catalina.startup.Bootstrap start
规则
proc:path:blurry:java:cmd:"Tomcat\conf" write file:path:blurry:/webapps/*.war deny //tomcat manager远程部署只会像webapps目录下写后缀为war的文件
Relevant Link:
Copyright (c) 2014 LittleHann All rights reserved