Java代码审计之SSH框架

  • A+

SSH框架代码审计学习

一、Hibernate框架学习

0x01Hibernate介绍

它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库

0x02 ORM介绍

是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。

20200510_080459.png

## 0x03Hibernate配置文件

hibernate核心配置文件
核心配置文件有俩种方式:hibernate.cfg.xml、hibernate.properties
它主要是hibernate框架所使用的,它主要包含了连接数据库相关信息,hibernate相关配置等。
位置:在src下创建一个hibernate.cfg.xml
约束:约束文件所在位置:hiberante核心jar包下的org.hibernate包下

```html
<?xml version='1.0' encoding='UTF-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

&lt;hibernate-configuration&gt;

  &lt;session-factory&gt;


      &lt;property name="hibernate.connection.driver_class"&gt;com.mysql.jdbc.Driver &lt;/property&gt;

      &lt;property name="hibernate.connection.url"&gt;jdbc:mysql://localhost:3306/dbname&lt;/property&gt;

      &lt;property name="hibernate.connection.username"&gt;root &lt;/property&gt;

      &lt;property name="hibernate.connection.password"&gt;123456 &lt;/property&gt;

      &lt;property name="hibernate.dialect"&gt;org.hibernate.dialect.MySQLDialect &lt;/property&gt;



      &lt;property name="jdbc.use_scrollable_resultset"&gt;false &lt;/property&gt;

      &lt;property name="Connection.useUnicode"&gt;true &lt;/property&gt;

      &lt;property name="connection.characterEncoding"&gt;utf-8 &lt;/property&gt;


      &lt;property name="hibernate.connection.pool.size"&gt;20 &lt;/property&gt;

       &lt;property name="hibernate.c3p0.max_size"&gt;30&lt;/property&gt;
       &lt;property name="hibernate.c3p0.min_size"&gt;10&lt;/property&gt; 
       &lt;property name="hibernate.c3p0.timeout"&gt;5000&lt;/property&gt;



      &lt;property name="jdbc.fetch_size"&gt;50 &lt;/property&gt;

      &lt;property name="jdbc.batch_size"&gt;23 &lt;/property&gt;




      &lt;property name="hibernate.show_sql"&gt;true &lt;/property&gt;



      &lt;property name="hibernate.hbm2ddl.auto"&gt;update&lt;/property&gt;


      &lt;property name="hibernate.cache.use_second_level_cache"&gt;true&lt;/property&gt;
      &lt;propertyname name="hibernate.cache.provider_class"&gt;org.hibernate.cache.EhCacheProvider&lt;/propertyname&gt;
      &lt;property name="hibernate.cache.use_query_cache"&gt;true&lt;/property&gt;



      &lt;mapping resource="org/mxg/UserInfo.hbm.xml"&gt;

</session-factory>

</hibernate-configuration>

```
②Hibernate映射文件
映射配置文件主要是用于描述实体类与数据表之间的映射关系。
位置:要与实体类在同一个包下.
名称:类名.hbm.xml
约束:hibernate核心jar包下的org.hibernate包下hibernate-mapping-3.0.dtd文件中查找

20200510_080754.png

0x04Hibernate工作流程

language
1、通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件。
2、由hibernate.cfg.xml中的&lt;mappingresource="xx/xx/xxx.hbm.xml"/&gt;读取解析映射信息。
3、通过config.buildSessionFactory();//得到sessionFactory。
4、sessionFactory.openSession();//得到session。
5、session.beginTransaction();//开启事务。
6、persistentoperate;
7、session.getTransaction().commit();//提交事务
8、关闭session;
9、关闭sessionFactory;

0x05 Hibernate执行数据库查询的三种方式

1、HQL(Hibernate Query Language)
```language
@Override
public SysUser findUserByLoginName(String pLoginName) {
String hql = "from SysUser as u where u.loginName = ?";
List<SysUser> users = getHibernateTemplate().find(hql, pLoginName); //pLoginName对应?
return users.isEmpty() ? null : users.get(0);
}

2、SQL(Structured Query Language)language
static List sql() {
  Session s = HibernateUtil.getSession();
Query q = s.createSQLQuery("select * from user").addEntity(User.class);
List<User> rs = q.list();
s.close();
return rs;
}

```
3、QBC(Query By Criteria)

这种方式比较面向对象方式,重点是有三个描述条件的对象:Restrictions,Order,Projections。使用QBC查询,一般需要以下三个步骤:
1. 使用Session实例的createCriteria()方法创建Criteria对象;
2. 使用工具类Restrictions的方法为Criteria对象设置查询条件,Order工具类的方法设置排序方式,Projections工具类的方法进行统计和分组.
3. 使用Criteria对象的list()方法进行查询并返回结果。
language
//查询匹配的账户adminList
Criteria API(类似于PreparedStatement)会转义参数,不会导致恶意SQL被执行。
//查找age等于(eq)20或(or)age为空(isNull)的User
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.or( Restrictions.eq("age", new Integer(20)), Restrictions.isNull("age") ));
List users = criteria.list();
//实际上它产生的对应的sql如下
Hibernate:
select
this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_
from
T_USER this_
where
(this_.age=? or this_.age is null)

20200510_081132.png

二:Structs框架学习

0x01Structs执行流程

structs2的核心控制器默认会处理以.action为后缀的url,或者没有后缀的url

20200510_081235.png

20200510_081244.png

1、客户发送一个请求到服务器首先经过FilterDispatcher,这是一个核心控制器(StrutsPrepareAndExecuteFilter2.几版本之后 的核心控制器)
2、FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(HttpServlet Request)请求,
如果ActionMapper决定需要调用某个Action(读取如下映射)FilterDispatcher则把请求的处理交给ActionProxy。

20200510_081338.png
3、ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类
4、ActionProxy创建一个ActionInvocation实例,同时ActionInvocation通过代理模式调用Action。但在调用之前,ActionInvocation会根据配置加载Action相关的所有Interceptor(拦截器)
5、Action执行完毕后,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果result

0x02 Structs配置文件学习

structs2中的6个配置文件,加载顺序如下:
1、default.properties
配置了是否允许动态方法调用,开发者模式,上传文件路径和大小,template的路径
2、structs-default.xml
struts-default.xml文件会自动被包含在struts.xml文件中,配置了拦截器(<package name="default" extends="struts-default">),
language
&lt;interceptors&gt;
&lt;interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/&gt;
&lt;interceptor name="autowiring" class="com.opensymphony.xwork2.&lt;a href="http://lib.csdn.net/base/javaee" class='replace_word' title="Java EE知识库" target='_blank' style='color:#df3434; font-weight:bold;'&gt;spring</a>.interceptor.ActionAutowiringInterceptor"/&gt;
&lt;interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/&gt;
&lt;interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/&gt;
&lt;interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/&gt;
&lt;interceptor&gt;

对拦截器进行分组

20200510_081508.png
3、structs-plugin.xml
如果不是开发插件的话,是不需要编写这个配置文件的
4、structs.xml
引入其他配置文件(多在团队协作开发使用)
<include file="com/wang/struts/user.xml"/>
package包

20200510_081628.png

5、structs.properties
该文件定义了Struts 2框架的大量属性,struts.properties文件的内容均可在struts.xml中以<constant name="" value=""></constant>

6、web.xml
```language
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">

<display-name>Struts 2</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>

<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

</web-app>
```

三:案例演示

0x01登录处代码审计

1、访问首页进行登录,抓取数据包,数据包如下

20200510_081858.png
2、去源代码中的structs.xml中寻找对应的Action类即可

20200510_081908.png
```language
这里对红框中的配置做解释,user_中的和method={1}的值是一致的。配置了拦截器userInterceptor
和默认的defaultStack的拦截器栈,这里拦截器中的param name=execludeMethods属性使用来排除当前
Action中那些方法不会经过拦截器,name=incldeMethod则是该Action中需要经过拦截器的方法
<result>表示返回的页面,类型为redirect到该页面。

```
3、全局搜索userAction类,去看下具体的代码,跟进service中的方法调用了login方法,一直跟进到UserDao的login方法

20200510_081917.png
4、使用了QBC的查询方式,是不存在SQL注入的

20200510_081927.png

0x02文件上传漏洞

1、找到文件上传的路径进行文件上传,在structs.xml文件中搜素

20200510_081946.png
2、配置文件中设置了默认的上传拦截器,限制了上传文件的类型

20200510_081957.png
3、去全局structsdefault.xml文件中查看默认拦截器中找到上传的拦截器路径
<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
4、这里不去看源码,直接去找对应的Action中的方法去看,直接对文件名进行了uuid的处理,然后复制文件内容到文件中

20200510_082006.png
最后总结
像是SSH框架的代码审计中三个主要的配置文件structs.xml,该文件中配置了action和返回页面和和拦截器的关系。web.xml配置了默认的过滤器(structs核心控制器)和其他过滤器,扫描Spring配置文件。hibernate的核心配置文件 hibernate.cfg.xml配置了数据库的相关信息和hibernate映射配置文件。Structs的拦截器和过滤器都可能会进行过滤操作

相关推荐: Primary Access Token Manipulation Attack(令牌操作攻击上)

令牌操纵攻击是APT组织所使用的一种常见技术,恶意软件可在受害者的系统上获得更高的特权或代表任何其他用户(假冒)执行某些操作。 这是一些MITRE上面使用的令牌操作攻击技术的APT和工具的示例: 我们可以看到里面包含了常见的cobalt strike的make…