<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    原文地址:http://drops.wooyun.org/tips/748

                    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 總結


                    最后:時間有限,只做了字符型的簡單粗淺表面測試,拋個磚,希望有更多經驗的留言啊,畢竟這方面的資料網上真心極少,為了方便大眾,請大牛們現身說法。

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频