11

Hibernate对注入的简单测试 | WooYun知识库

 6 years ago
source link:
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Hibernate对注入的简单测试

0x00 背景


前段时间遇到一个使用了Hibernate框架的站,以前没怎么接触过(由于是Java盲,所以大家勿喷),再注入的事情发生了许多奇奇怪怪的事情,于是向本地搭一个看看是个神马情况。Hibernate配备了一种非常强大的查询语言,这种语言看上去很像SQL。但是不要被语法结构上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查询。

0x01 测试


本次测试的环境是JDK5.0+Tomcat8+Hibernate3.0+Servlet。数据库情况如下:

2013112511500521075.png

通过百度知道Hibernate的查询大概有5、6种,通过分析对注入能产生不同影响的应该有如下三种:

1、HQL方式
2、原生SQL方式
3、Criteria方式

重点是HQL方式,HQL相当于Hibernate自己有一套SQL语法,在用Hibernate作为查询中间层的时候,它会将你写的HQL翻译成对应数据库的SQL语句,Hibernate支持N种数据库。

会一丢丢Java的童鞋都知道Hibernate的使用流程:

首先要告诉Hibernate数据库的连接信息,hibernate.cfg.xml文件:

#!xml
<?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"> 
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration> 
  <session-factory> 
    <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>  
    <property name="connection.url">jdbc:oracle:thin:@192.168.79.151:1521:orcl</property>  
    <property name="connection.username">system</property>  
    <property name="connection.password">xxoo</property>  
    <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>  
    <property name="myeclipse.connection.profile">oracle_connet</property>  
    <mapping resource="com/mytest/map/Userlist.hbm.xml"/>//这里是包含表的映射文件
  </session-factory> 
</hibernate-configuration>

其实是映射你想使用的数据表(系统会按照表明自动生成文件,比如我的Userlist表会生成Userlist.hbm.xml),Userlist.hbm.xml文件:

分别将ID、USERNAME、USERPWD列映射为id、username、userpwd,而在实际环境中,开发者可能映射成他们喜欢的名字。

注:

1、未映射的表是不能查询的;
2、使用映射后表名、列名时大小写敏感;
3、不能使用数据库中的列名,比如USERNAME映射为username之后,不能再使用USERNAME,否则报错。
#!xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Mapping file autogenerated by MyEclipse Persistence Tools --> 
<hibernate-mapping> 
  <class name="com.mytest.map.Userlist" table="USERLIST" schema="SYSTEM"> 
    <id name="id" type="java.math.BigDecimal"> 
      <column name="ID" precision="22" scale="0"/>  
      <generator class="assigned"/> 
    </id>  
    <property name="username" type="java.lang.String"> 
      <column name="USERNAME" length="20" not-null="true"/> 
    </property>  
    <property name="userpwd" type="java.lang.String"> 
      <column name="USERPWD" length="30" not-null="true"/> 
    </property> 
  </class> 
</hibernate-mapping>

1、原生的HQL方式:大概代码:

try{
    s=HibernateSessionFactory.getSession();
    tx=s.beginTransaction();
    Query query=s.createQuery("from Userlist as u where username='" +userName + "'");
    Qstring=query.getQueryString(); //
    Iterator it = query.iterate();
    //这是Iterate数据返回方式
    List it=query.list();//这是List数据返回方式 //
    ul = (Userlist) it.next();
    ul=(Userlist)it.get(0);
    mUserPwd=ul.getUserpwd();
}catch (Exception e) {
    System.out.println(e.getMessage());
    return e.getMessage();
}//这里加了返回抛出的异常的代码
tx.commit(); //关闭连接
HibernateSessionFactory.closeSession();

上面提到的Iterate和List数据返回方式没发现对注入产生多大的影响,他们呢的具体差别请google。

使用单引号测试(有返回异常的代码,数据库报错):

2013112511511598103.png

使用单引号测试(没有返回异常的代码,默认情况,Tomcat报错):

2013112511514496111.png

And 'a'='a 

2013112511522315773.png

And 'a'='b

2013112511525569278.png

跨库查系统表?想都不要想:

2013112511532221767.png

*号也是不能用滴:

2013112511534553955.png

不支持union:

2013112511541396421.png

单独内嵌select作为条件(正常执行):

2013112511544292137.png

单独执行substr(),ASCII()函数没问题:

2013112511550372977.png

但是执行

ASCII(SUBSTR((select userpwd from Userlist where ROWNUM=1),1,1))>0

就不行了:

2013112511552223471.png

结论:这里能爆的列还得看前面那个select的心情。

小刺猬和它的小伙伴们都惊呆了:

2013112511554437592.png

对于第二种使用原生SQL的方式,写法大概是这样:

s=HibernateSessionFactory.getSession();
tx=s.beginTransaction();
Query query=s.createSQLQuery("select USERPWD from Userlist where USERNAME='" +userName + "'"); 
Qstring=query.getQueryString(); 
List it = query.list(); 
mUserPwd=(String)it.get(0);

就不多说了,就可普通注入一样。毫无压力:

2013112511561333503.png

说说第三种,写法大概是这样:

s=HibernateSessionFactory.getSession();
List UserLists=s.createCriteria(Userlist.class).add(Restrictions.eq("username",userNameString)).list();
Userlist u=(Userlist)UserLists.get(0); 
mUserPwd=u.getUserpwd();

如果说我们在HQL下还能用

ascii(substr(userpwd,1,1))>1

来猜解前面SELECT中选择的列中有的列的内容的话,那么在第三种Criteria方式下,基本就绝望了:

2013112511564296588.png

2013112511565763376.png

2013112511571458944.png

2013112511573196321.png

本来要结束的时候,我发现了第四种,是HQL的另一种写法,大概代码这么写:

s=HibernateSessionFactory.getSession();
tx=s.beginTransaction();
Query query=s.createSQLQuery("select {p.*} from Userlist {p} where {p}.USERNAME="+userNameString).addEntity("p", Userlist.class); 
Qstring=query.getQueryString();
List it = query.list();
mUserPwd=(String)it.get(0);

貌似这样的也没得玩,歇菜了:

2013112511581343139.png

2013112511581991918.png

0x02 总结


最后:时间有限,只做了字符型的简单粗浅表面测试,抛个砖,希望有更多经验的留言啊,毕竟这方面的资料网上真心极少,为了方便大众,请大牛们现身说法。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK