1.第79篇:记一次Oracle注入漏洞提权的案例案例艰难过程
2.用java将一条数据插入oracle,需要查看原数据库中是源码否有此条记录
第79篇:记一次Oracle注入漏洞提权的艰难过程
大家好,我是案例案例ABC_。我近期遇到了一个Oracle注入漏洞,源码是案例案例搜索型的盲注漏洞,只能通过折半法一个字符一个字符的源码离心公式源码猜解数据。经过判断,案例案例发现这是源码DBA权限的注入点。接下来,案例案例我将分享如何通过这个注入点获取操作系统的源码权限,并且分享了在技术研究过程中遇到的案例案例问题和解决方法。
在解决这个问题时,源码我进行了两方面的案例案例优化来加快SQL注入的速度。首先,源码房源码在那查询我在search=%语句中加入了存在结果很少的案例案例搜索值,比如将search=%,只显示出一条搜索结果,这样可以减少数据库的检索量和HTTP返回的数据包大小,从而加快SQL注入的速度。其次,我修改了SQLmap的默认个线程限制,这需要修改SQLmap的源码,这里就不详细解释了。
在Oracle注入提权的语句方面,我注意到很多文章给出的语句通常分为三个步骤,其中第二步就是赋予当前Oracle账号相关的JAVA权限。然而,告白墙网页源码这个语句包含了大量的单引号和左右尖括号,有时候会被转义掉导致注入失败,而且这个语句异常复杂,容易出错。因此,我使用了一个简单的语句替代,效果更佳。这个语句的格式是BEGIN开头,然后end;结尾,代表一个PL/SQL语句块,如下所示:select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''grant javasyspriv to test''; end;') from dual。
我使用了SQLmap的--sql-shell命令将上述语句执行,但是源码.sql怎么导入最后执行的命令没有成功。在处理这种情况时,我通常有两种可能:一是执行命令被拦截,二是Java代码没有执行成功。因此,我使用了如下SQL语句进行判断,结果返回0,说明函数没有添加成功。经过一系列测试,我发现是SQLmap的SQL-shell下功能下,上述复杂的SQL语句根本没执行成功。
为了更方便地执行Oracle的复杂SQL语句,我将SQL注入语句进行了修改,通过and (插入SQL语句) is 恒信支付源码not null的方式,可以在左右括号中插入各种Oracle的SQL语句。然而,这种方法也遇到了WAF拦截的问题。为了解决这个问题,我使用了Oracle特有的编码方式,将SQL语句成功执行。再次执行查询LinuxUtil是否存在的SQL语句,发现返回count()不为0,说明Java代码成功添加执行。然而,LinuxUtil命令依然无法执行,我怀疑是Java权限没有添加成功。我执行了查询当前用户权限的语句,发现当前用户具有CONNECT、RESOURCE、JAVASYSPRIV权限,说明Java相关权限确实是添加成功了。然而,为什么还是无法调用LinuxUtil命令呢?我重新搭建了测试环境,使用Navicat执行Oracle提权语句后,发现报了权限错误。
在查阅大量国外文章后,我发现判断当前用户是否有Java权限,需要查询session_roles表。该表用于显示当前会话中的角色信息,必须session_roles中有JAVASYSPRIV权限才行。我尝试断开Oracle当前账号的连接,重新连接之后,session_roles表中就有相应权限了。然而,我们是在SQL注入点,无法断开重连,那么如何使Java权限立即生效呢?国外文章给出了几种方法,但执行后仍然无法解决问题。
在等待第二天后,惊奇地发现session_roles中存在JAVASYSPRIV角色了,我也不清楚原因,但此时可以通过select LinuxExecHanshu('whoami') from dual执行命令。然而,盲注过程太麻烦,我选择结合SQLmap的SQL-shell终端来盲注入,因为该SQL语句比较简短,SQLmap的SQL-shell模式猜解是完全无压力的。最终,我们成功获取了系统权限。
总结来说,这个dbms_xmlquery.newcontext函数在高版本的Oracle数据库中已经不能提权成功,甚至不能使用,需要使用其他方法进行提权。在本地搭建的Oracle环境中,大多数情况下可以直接提权成功,但极少数情况下需要断开重连,具体原因不明。如果文章中有错误,欢迎批评指正。后续,我将继续分享Oracle提权的其他方法,敬请期待。
用java将一条数据插入oracle,需要查看原数据库中是否有此条记录
需要用两个类来实现,DB类用来加载数据库驱动,建立数据库连接,Opdb类用来查询和插入数据
OPDB类我只写了测试用的main方法,需要调用DB类来做查询和插入数据的操作
OPDB.java的源码如下
public class Opdb {
public static void main(String[] args) {
DB db = new DB();
String sql = "select * from user_info where user_name = '李明'";
db.doPstm(sql);//查询数据库中是否存在李明的记录
if(db.geRs()==null)//如果查询的结果为空,则插入数据{
String sql2 = "inset into user_info values("李明","男","","唱歌")";
db.doPstm(sql2);//执行插入的sql语句
}
db.close;//关闭数据库连接
}
}
DB.java的源代码如下
package com.yxq.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DB {
private Connection con;
private PreparedStatement pstm;
private String user="username";
private String password="password";
private String className="oracle.jdbc.driver.OracleDriver";
private String url="jdbc:oracle:thin:@localhost:orcl";
public DB(){
try{
Class.forName(className);
}catch(ClassNotFoundException e){
System.out.println("加载数据库驱动失败!");
e.printStackTrace();
}
}
/**创建数据库连接*/
public Connection getCon(){
try {
con=DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
System.out.println("创建数据库连接失败!");
con=null;
e.printStackTrace();
}
return con;
}
public void doPstm(String sql,Object[] params){
if(sql!=null&&!sql.equals("")){
if(params==null)
params=new Object[0];
getCon();
if(con!=null){
try{
System.out.println(sql);
pstm=con.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
for(int i=0;i<params.length;i++){
pstm.setObject(i+1,params[i]);
}
pstm.execute();
}catch(SQLException e){
System.out.println("doPstm()方法出错!");
e.printStackTrace();
}
}
}
}
public ResultSet getRs() throws SQLException{
return pstm.getResultSet();
}
public int getCount() throws SQLException{
return pstm.getUpdateCount();
}
public void closed(){
try{
if(pstm!=null)
pstm.close();
}catch(SQLException e){
System.out.println("关闭pstm对象失败!");
e.printStackTrace();
}
try{
if(con!=null){
con.close();
}
}catch(SQLException e){
System.out.println("关闭con对象失败!");
e.printStackTrace();
}
}
}