矛计划 MazeSec 11s - Windows靶机设计流程
设计思路
利用链
8080 Apache(.git泄露)
↓
获取用户名kaada
↓
SMB爆破弱口令
↓
WinRM登录获取低权shell
↓
端口转发访问本地IIS(127.0.0.1:80)
↓
PHP文件上传获取WebShell
↓
SeImpersonatePrivilege → Potato系列提权
↓
SYSTEM
设计思路
安装系统
|
更新补丁
|
关闭防护
|
创建kaada弱密码
|
配置Apache
|
验证Apache运行身份
|
生成.git泄露
|
安装IIS
|
安装CGI
|
配置上传站点
|
验证IIS身份
|
验证SeImpersonatePrivilege
|
开启WinRM
|
开启SMB
|
删除kaada管理员权限
|
测试:
SMB认证
WinRM登录
IIS访问
Potato
|
快照
下载与说明
在MSDN Itellyou找到windows server2019操作系统的ed2k链接,使用迅雷下载,下载完成后使用虚拟机软件(如VMware或VirtualBox)安装操作系统
VMware安装虚拟机时,要求提供一个用户名,在windows server安装成功后,默认创建该用户并加入到管理员组中。
系统更新
在设置中找到更新和安全,点击检查更新,安装所有可用的更新,确保系统是最新的
后续命令行操作,大多数在管理员权限下进行。
修改密码
修改Administrator账户的密码
net user Administrator 'g00dMaze#'
修改普通用户的密码,配置一个弱口令
net user kaada Password1
Password1 在rockyou.txt中是第一个符合大写、小写、数字组合的弱口令,符合winddows密码复杂度策略
┌──(root㉿kali)-[~]
└─# grep '^Password1$' -n rockyou.txt
3505:Password1
关闭安全防护
在管理员powershell中,关闭防火墙
# 关闭 Windows Defender 防火墙:持久化、稳定
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
# 验证
Get-NetFirewallProfile
卸载Windows Defender防护,避免开机后自动开启防护
Uninstall-WindowsFeature -Name Windows-Defender
该操作仅移除防病毒引擎与相关监控组件,不影响 Windows Defender 防火墙,重启后不会自启恢复。
如需恢复:
Install-WindowsFeature -Name Windows-Defender
Restart-Computer
配置smb服务
管理员powershell中,检查是否开启了SMB服务
# 检查 LanmanServer 服务状态,默认开启
Get-Service LanmanServer
创建一个共享目录
mkdir C:\Share -Force
New-SmbShare -Name Public -Path C:\Share -ReadAccess "Authenticated Users"
Get-SmbShare
Set-Content -Path C:\Share\hello.txt -Value "Hello Windows"
# 中文内部通告
Set-Content -Path C:\Share\README-zh.txt -Value @"
【内部通告】
目前内网正在试运行临时文件中转服务,
开发正加速推进,近期拟安排上线。
服务现阶段仅限本机访问,严禁对外暴露。
如发现此文件出现在非授权设备,请立即上报运维组。
"@
# 英文内部通告
Set-Content -Path C:\Share\README-en.txt -Value @"
NOTICE (Internal Draft — Do Not Distribute)
An internal temporary file relay service is currently in pilot operation.
Development is being accelerated ahead of the planned production rollout.
Access at this stage is restricted to localhost only.
If this file is found on any unauthorized device, please report it to the
operations team immediately.
-- MazeSec Internal Ops
"@
查看锁定策略,如果输出内容存在锁定阈值: 从不或锁定阈值: Never,永不锁定,可以无限爆破。
net accounts
配置winrm服务
将kaada用户加入到winrm远程管理组中
net localgroup "Remote Management Users" kaada /add
查看
net localgroup "Remote Management Users"
开启winrm服务
Enable-PSRemoting -Force
# 验证
Get-Service WinRM
设置winrm服务开机自启
Set-Service WinRM -StartupType Automatic
Start-Service WinRM
配置Apache服务
安装phpstudy后,注册服务,让Apache以kaada身份运行。
cd /d C:\phpstudy_pro\Extensions\Apache2.4.39\bin
httpd.exe -k install -n "Apache"
sc config Apache obj= ".\kaada" password=Password1
sc config Apache start= auto
如果需要删掉这个服务
sc stop Apache
sc delete Apache
此阶段保持 phpstudy 默认权限,Apache 以 kaada 运行、写日志均可正常工作。目录 ACL 的收紧(限制 kaada 写权限、修复 IIS 共享 PHP 的执行权限等)统一放到后文「权限检查」章节一次性定稿,避免此处提前锁权后与后续 IIS 配置相互覆盖。
给 kaada 授予「作为服务登录」权限
图形化界面:
- 运行 secpol.msc
- 本地策略 → 用户权限分配 → 作为服务登录
- 双击打开,点「添加用户或组」,输入
.\kaada,点击「检查名称」,确认无误后点击「确定」 - 无需重启,策略即时生效
通过phpstudy图形化界面配置apache监听在8080端口,测试验证apache服务
在 phpstudy 面板切换/绑定 PHP 版本时,phpstudy会自动注入配置文件,此处极易踩的坑
net stop Apache
net start Apache
sc query Apache
# 查看apahce是否监听在0.0.0.0:8080端口
netstat -ano -p tcp | findstr :8080
可以发现 phpstudy 的apache的配置文件C:\phpstudy_pro\Extensions\Apache2.4.39\conf\httpd.conf中存在一行
Include conf/vhosts/*.conf
可以解释phpstudy在修改监听端口时会在C:\phpstudy_pro\Extensions\Apache2.4.39\conf\vhosts目录下生成一个listen文件,添加一条端口监听配置
Listen 8080
在本地kali初始化一个git项目,关联kaada用户信息
# 创建目录
mkdir maze-11s-www
cd maze-11s-www
# 初始化 Git
git init
# 配置身份(关键)
git config user.name "kaada"
git config user.email "kaada@11s.dsz"
# 创建文件(Linux 下 echo 默认 UTF‑8)
echo 'Hello Windows' > hello.txt
# 提交
git add hello.txt
git commit -m "Initial website deploy & author: kaada & TODO:change default password before release"
将该.git目录打包到靶机的phpstudy web目录下
apache 首页配置
notepad C:\phpstudy_pro\WWW\index.php
安装IIS服务
管理员powershell中,安装IIS服务
# 安装 IIS + 管理工具
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
# 验证 IIS 是否安装
Get-WindowsFeature Web-Server
删除IIS默认绑定的80端口,防止外部访问
Import-Module WebAdministration
Remove-WebBinding -Name "Default Web Site" -Protocol http -Port 80 -IPAddress "*"
设置IIS web服务器仅监听在本地,选手需自行完成端口转发以访问内网服务
New-WebBinding `
-Name "Default Web Site" `
-Protocol http `
-Port 80 `
-IPAddress 127.0.0.1
IIS 绑定 127.0.0.1:80后,netstat显示 0.0.0.0:80是因为 http.sys 驱动层监听所有IP,但请求路由层(URL ACLs) 会严格限制只有发往 127.0.0.1的请求才会被递交给 IIS 站点。外部直接访问 TargetIP:80会收到 404或 连接重置。
发起一次请求,确保IIS服务正常运行
Invoke-WebRequest -Uri http://127.0.0.1
查看运行账户
# IIS APPPOOL\DefaultAppPool
Get-CimInstance Win32_Process -Filter "Name='w3wp.exe'" | ForEach-Object {
$owner = Invoke-CimMethod -InputObject $_ -MethodName GetOwner
[PSCustomObject]@{
PID = $_.ProcessId
User = "$($owner.Domain)\$($owner.User)"
}
}
✅ 后续导出再导入从选手角度实测:DefaultAppPool 默认拥有 SeImpersonatePrivilege,可直接用于 Potato 类提权
在PHP7.x版本下测试发现不支持windows特性末尾点末尾空格绕过黑名单扩展名的玩法,在php5.x测试通过
此外,.user.ini的玩法在 PHP 5.3.0(2009 年)首次引入。
参考Added ".htaccess" style user-defined php.ini files support for CGI/FastCGI - PHP
安装 CGI 支持
Install-WindowsFeature Web-CGI
# 验证 CGI 是否安装
Get-WindowsFeature Web-CGI
wwwroot 保持 IIS 默认 ACL
在 IIS 中配置 PHP-CGI(FastCGI)
win 搜索IIS 管理器,点击左侧服务器名称,双击IIS池里的FastCGI设置,点击右侧“添加应用程序”
服务器名称
│
├── Application Pools
├── Sites
完整路径添入phpcgi路径,参数留空,其余保持默认
C:\phpstudy_pro\Extensions\php\php5.6.9nts\php-cgi.exe
添加 PHP 处理程序映射
IIS 管理器 → Default Web Site → Handler Mappings → Add Module Mapping
Default Web Site
↓
处理程序映射(Handler Mappings)
↓
右侧:添加模块映射(Add Module Mapping)
内容
请求路径 *.php
模块 FastCgiModule
可执行文件 C:\phpstudy_pro\Extensions\php\php5.6.9nts\php-cgi.exe
名称 PHP_via_FastCGI
弹窗提示“是否注册为 FastCGI”,点 Yes。
查看IIS web目录,其中%SystemDrive%表示系统盘符,通常是C盘
# 查看 IIS 网站配置
# %SystemDrive%\inetpub\wwwroot
Get-Website
创建uploads目录
mkdir C:\inetpub\wwwroot\uploads
uploads 继承自 wwwroot(已断继承且不含 Users),继承下来的即 SYSTEM:F / Administrators:F / AppPool:RX,此处只需把 AppPool 抬权为 Modify 使其可写入上传文件,无需再次断继承。
icacls C:\inetpub\wwwroot\uploads /grant "IIS APPPOOL\DefaultAppPool:(OI)(CI)M"
icacls C:\inetpub\wwwroot\uploads
phpinfo页面
notepad C:\inetpub\wwwroot\info.php
创建文件上传页面C:\inetpub\wwwroot\index.php
管理员权限下新建文件
notepad C:\inetpub\wwwroot\index.php
<?php
$uploadDir = dirname(__FILE__) . '/uploads/';
$files = array();
function cmpFileTime($a, $b) {
return strtotime($b['time']) - strtotime($a['time']);
}
if (is_dir($uploadDir)) {
$items = scandir($uploadDir);
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
if (is_file($uploadDir . $item)) {
$files[] = array(
'name' => $item,
'size' => filesize($uploadDir . $item),
'time' => date('Y-m-d H:i:s', filemtime($uploadDir . $item))
);
}
}
usort($files, 'cmpFileTime');
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>内部文件中转站</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;background:#0d1117;color:#c9d1d9;min-height:100vh;padding:40px 20px}
.container{max-width:800px;margin:0 auto}
.header{padding-bottom:20px;margin-bottom:30px;border-bottom:1px solid #30363d}
.header h1{font-size:22px;font-weight:600;color:#f0f6fc}
.header .subtitle{color:#8b949e;font-size:14px;margin-top:4px}
.upload-area{padding:24px 0;margin-bottom:30px;border-bottom:1px solid #30363d}
.upload-area h3{font-size:16px;font-weight:500;color:#f0f6fc;margin-bottom:4px}
.upload-area .desc{color:#8b949e;font-size:14px;margin-bottom:16px}
.upload-area form{display:flex;align-items:center;gap:10px}
.upload-area input[type="file"]{flex:1;min-width:0;color:#c9d1d9;font-size:14px;cursor:pointer;padding:6px 10px;border:1px solid #30363d;border-radius:4px;background:#0d1117}
.upload-area input[type="file"]::-webkit-file-upload-button{background:#21262d;color:#c9d1d9;border:1px solid #30363d;border-radius:4px;padding:5px 14px;cursor:pointer;margin-right:10px}
.upload-area input[type="submit"]{background:#238636;color:#fff;border:none;border-radius:4px;padding:7px 24px;font-size:14px;font-weight:500;cursor:pointer;white-space:nowrap}
.upload-area input[type="submit"]:hover{background:#2ea043}
.file-section{margin-bottom:30px}
.file-section h2{font-size:15px;color:#f0f6fc;font-weight:500;margin-bottom:10px}
.file-table{width:100%;border-collapse:collapse;font-size:14px;table-layout:fixed}
.file-table th{padding:6px 0;border-bottom:1px solid #30363d;color:#8b949e;font-weight:400;font-size:13px;text-align:left}
.file-table th:last-child,.file-table td.time{text-align:right}
.file-table th:nth-child(2),.file-table td.size{text-align:right}
.file-table td{padding:8px 0;border-bottom:1px solid #30363d;color:#c9d1d9;transition:background .15s}
.file-table tr:hover td{background:#1c2128}
.file-table .name{color:#f0f6fc;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:0}
.file-table .size{color:#8b949e;font-size:13px;width:80px}
.file-table .time{color:#8b949e;font-size:13px;width:150px;white-space:nowrap}
.file-empty{color:#8b949e;padding:30px 0;font-size:14px}
.footer{padding-top:16px;border-top:1px solid #30363d;text-align:center;font-size:13px;color:#8b949e}
.footer .brand{color:#58a6ff;font-weight:500}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>文件共享平台</h1>
<div class="subtitle">研发中心临时文件共享服务</div>
</div>
<div class="upload-area">
<h3>上传文件</h3>
<p class="desc">请选择需要共享的文件</p>
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="file" required>
<input type="submit" value="上传">
</form>
</div>
<div class="file-section">
<h2>共享文件(共 <?php echo count($files); ?> 个)</h2>
<?php if(empty($files)): ?>
<div class="file-empty">暂无文件</div>
<?php else: ?>
<table class="file-table">
<thead>
<tr>
<th>文件名</th>
<th>大小</th>
<th>上传时间</th>
</tr>
</thead>
<tbody>
<?php foreach($files as $file): ?>
<tr>
<td class="name"><?php echo htmlspecialchars($file['name']); ?></td>
<td class="size"><?php echo round($file['size']/1024,1); ?> KB</td>
<td class="time"><?php echo $file['time']; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<div class="footer">
<span class="brand">maze-sec</span>
</div>
</div>
</body>
</html>
处理页面C:\inetpub\wwwroot\upload.php
notepad C:\inetpub\wwwroot\upload.php
<?php
$uploadDir = dirname(__FILE__) . '/uploads/';
$ok = false;
$message = '';
$path = '';
$blacklist = array('php', 'php3', 'php4', 'php5', 'phtml', 'pht', 'phps');
$illegal = '/[\\\\\/\*\?"<>\|]/';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
$message = '请求方式错误';
} elseif (!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
$message = '未接收到文件或上传中断';
} else {
$name = $_FILES['file']['name'];
$tmp = $_FILES['file']['tmp_name'];
if (preg_match($illegal, $name)) {
$message = '文件名包含非法字符';
} elseif (in_array(pathinfo($name, PATHINFO_EXTENSION), $blacklist, true)) {
$message = '不允许的文件类型';
} elseif (!is_uploaded_file($tmp)) {
$message = '非法的上传来源';
} elseif (!move_uploaded_file($tmp, $uploadDir . $name)) {
$message = '文件保存失败,请检查目录权限';
} else {
$ok = true;
$path = '/uploads/' . $name;
}
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>上传结果</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;background:#0d1117;color:#c9d1d9;min-height:100vh;display:flex;align-items:center;justify-content:center;padding:40px 20px}
.box{max-width:520px;width:100%;background:#161b22;border:1px solid #30363d;border-radius:12px;padding:40px;text-align:center}
.icon{font-size:44px;display:block;margin-bottom:16px}
.title{font-size:18px;color:#f0f6fc;margin-bottom:8px}
.title.ok{color:#3fb950}
.title.err{color:#f85149}
.desc{color:#8b949e;font-size:14px;line-height:1.6}
.path{background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:12px;margin:18px 0;font-size:13px;color:#58a6ff;word-break:break-all}
.back{display:inline-block;margin-top:12px;background:#21262d;color:#c9d1d9;border:1px solid #30363d;border-radius:6px;padding:8px 22px;font-size:14px;text-decoration:none}
.back:hover{background:#30363d}
.footer{margin-top:24px;padding-top:16px;border-top:1px solid #30363d;font-size:13px;color:#8b949e}
.footer .brand{color:#58a6ff;font-weight:500;letter-spacing:.5px}
</style>
</head>
<body>
<div class="box">
<?php if ($ok): ?>
<span class="icon">✅</span>
<div class="title ok">上传成功</div>
<div class="desc">文件访问路径如下</div>
<div class="path"><?php echo htmlspecialchars($path); ?></div>
<?php else: ?>
<span class="icon">❌</span>
<div class="title err">上传失败</div>
<div class="desc"><?php echo htmlspecialchars($message); ?></div>
<?php endif; ?>
<a class="back" href="index.php">返回</a>
<div class="footer"><span class="brand">maze-sec</span></div>
</div>
</body>
</html>
notepad C:\inetpub\wwwroot\uploads\index.php
<?php
header('Content-Type: text/html; charset=utf-8');
?><!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件存储服务</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}body{font-family:-apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;background:#0d1117;color:#c9d1d9;min-height:100vh;display:flex;align-items:center;justify-content:center;padding:40px 20px}.box{max-width:500px;width:100%;background:#161b22;border:1px solid #30363d;border-radius:12px;padding:40px;text-align:center}.icon{font-size:48px;display:block;margin-bottom:16px}.title{font-size:18px;color:#f0f6fc;margin-bottom:8px}.desc{color:#8b949e;font-size:14px;line-height:1.6}.example{background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:12px;margin:16px 0;font-size:13px;color:#58a6ff;word-break:break-all}.footer{margin-top:24px;padding-top:16px;border-top:1px solid #30363d;font-size:13px;color:#8b949e}.footer .brand{color:#58a6ff;font-weight:500;letter-spacing:.5px}
</style>
</head>
<body>
<div class="box">
<span class="icon">📁</span>
<div class="title">文件存储服务</div>
<div class="desc">通过 URL 直接访问具体文件</div>
<div class="example">/uploads/文件名</div>
<div style="color:#8b949e;font-size:12px;margin-top:12px;">示例: <span style="color:#58a6ff;">/uploads/example.txt</span></div>
<div class="footer"><span class="brand">maze-sec</span></div>
</div>
</body>
</html>
验证 uploads 权限:应只有 IIS APPPOOL\DefaultAppPool 拥有 Modify, Users、Everyone 不应拥有 Modify/Full Control。
icacls C:\inetpub\wwwroot\uploads
把index.php添加到IIS默认文档列表中(IIS配置文件web.config)
# 添加 index.php 到默认文档列表
Add-WebConfiguration -Filter "/system.webServer/defaultDocument/files" `
-PSPath "IIS:\Sites\Default Web Site" `
-Value @{value="index.php"}
# 把它移到第一位(可选,但推荐)
Set-WebConfigurationProperty -Filter "/system.webServer/defaultDocument/files" `
-PSPath "IIS:\Sites\Default Web Site" `
-Name "collection" `
-Value @{add=@{value="index.php"}; remove=@{value="index.php"}}
至此 Apache 与 IIS 均已配置完成。由于两者共用 phpstudy 的 PHP 与临时目录,且涉及限制 kaada 写权限等安全加固,所有目录 ACL 统一放到下一节「权限检查」一次性定稿。
权限检查
涉及到的目录做权限检查
icacls C:\phpstudy_pro
icacls C:\phpstudy_pro\WWW
icacls C:\phpstudy_pro\Extensions\Apache2.4.39
icacls C:\phpstudy_pro\Extensions\php
icacls C:\phpstudy_pro\Extensions\php\php5.6.9nts
icacls C:\phpstudy_pro\Extensions\php\php5.6.9nts\php-cgi.exe
icacls C:\phpstudy_pro\Extensions\tmp
icacls C:\inetpub\wwwroot
icacls C:\inetpub\wwwroot\uploads
icacls C:\Share
检查会发现,默认安装的phpstudy权限宽松,允许普通用户直接在C:\phpstudy_pro\WWW目录下创建新文件或目录,导致选手可以直接上传WebShell的非预期解法,需进行权限加固。
普通用户:
可以:
创建新文件
创建目录
读取执行
不可以:
修改已有文件
删除已有文件
加固(唯一权威位置:以下为全部目录 ACL 的最终定稿,安装章节不再提前设置)
# —— phpstudy 目录树统一收紧 ——
# 顶层:仅系统/管理员完全控制,kaada 只读执行(防止 kaada 写入 WebShell)
icacls C:\phpstudy_pro /inheritance:r
icacls C:\phpstudy_pro /grant:r `
"SYSTEM:(OI)(CI)(F)" `
"Administrators:(OI)(CI)(F)" `
"kaada:(OI)(CI)(RX)"
# WWW:Apache 站点根,kaada 只读执行
icacls C:\phpstudy_pro\WWW /inheritance:r
icacls C:\phpstudy_pro\WWW /grant:r `
"SYSTEM:(OI)(CI)(F)" `
"Administrators:(OI)(CI)(F)" `
"kaada:(OI)(CI)(RX)"
# php 运行时:Apache(kaada) 与 IIS(DefaultAppPool) 共用 php-cgi.exe,两者都需 RX 才能执行 PHP
# 顶层 phpstudy_pro/Extensions 虽未显式授予 AppPool,但 Server 2019 默认将「绕过遍历检查」
# (SeChangeNotifyPrivilege) 授予 Everyone,令牌可直接遍历到此目录,故只需在此授 RX
icacls C:\phpstudy_pro\Extensions\php /inheritance:r
icacls C:\phpstudy_pro\Extensions\php /grant:r `
"SYSTEM:(OI)(CI)(F)" `
"Administrators:(OI)(CI)(F)" `
"kaada:(OI)(CI)(RX)" `
"IIS APPPOOL\DefaultAppPool:(OI)(CI)(RX)"
# Apache 日志:仅 Apache(kaada) 写入,IIS 不写此目录
icacls C:\phpstudy_pro\Extensions\Apache2.4.39\logs /inheritance:r
icacls C:\phpstudy_pro\Extensions\Apache2.4.39\logs /grant:r `
"SYSTEM:(OI)(CI)(F)" `
"Administrators:(OI)(CI)(F)" `
"kaada:(OI)(CI)(M)"
# PHP 临时目录:两个 PHP 使用方都要写,父目录未收紧此处直接追加即可,无需断继承
icacls C:\phpstudy_pro\Extensions\tmp /grant "kaada:(OI)(CI)(M)" "IIS APPPOOL\DefaultAppPool:(OI)(CI)(M)"
icacls C:\phpstudy_pro\Extensions\tmp\tmp /grant "kaada:(OI)(CI)(M)" "IIS APPPOOL\DefaultAppPool:(OI)(CI)(M)"
预期效果
phpstudy_pro
├── WWW
│ kaada RX (可读可执行)
│
├── Extensions
│ ├── Apache2.4.39
│ │ kaada RX (执行环境)
│ │ └── logs kaada M (可写日志)
│ │
│ ├── php
│ │ kaada RX / AppPool RX (php 执行环境,两个 PHP 使用方共用)
│ │
│ └── tmp (\tmp)
│ kaada M / AppPool M (PHP 临时目录,两者均需写)
自检:确认 IIS 运行账户对 php-cgi.exe 拥有可读可执行(否则 IIS 侧 PHP 会 500/无法启动)
icacls C:\phpstudy_pro\Extensions\php\php5.6.9nts\php-cgi.exe
# 期望输出中包含: IIS APPPOOL\DefaultAppPool:(RX) 和 kaada:(RX)
IIS 匿名认证身份改为应用池身份(解决 uploads 新文件 401.3)
默认情况下,一个匿名 PHP 请求其实牵涉两个身份: 环节 用的身份(默认) IIS 检查你能不能读这个文件(AuthenticateRequest / 文件授权) IUSR(匿名认证模拟的账户) 真正跑 PHP 的 FastCGI 工作进程 DefaultAppPool(应用池身份)
去掉匿名认证的默认身份 IUSR,改为应用池身份 DefaultAppPool,这样就不会出现 uploads 新文件 401.3 的问题。
$appcmd='C:\Windows\System32\inetsrv\appcmd.exe'
& $appcmd set config "Default Web Site" `
-section:system.webServer/security/authentication/anonymousAuthentication `
/userName:"" /commit:apphost
现在,重启后通过Administrator登录,检查服务的运行状态,同时写入flag文件,确保选手在提权后可以读取,最后将kaada从管理员组中移除作为普通用户。
放置flag
echo flag{root-58c1c19e8389524ba790c691541cb5b0} > C:\Users\Administrator\Desktop\root.txt
:: 验证
type C:\Users\Administrator\Desktop\root.txt
echo flag{user-51a7cf02f9dc6b536b2423057b864b3d} > C:\Users\kaada\Desktop\user.txt
:: 验证
type C:\Users\kaada\Desktop\user.txt
验证
重启后,确保各项服务正常运行
Get-Service WinRM
Get-Service LanmanServer
Get-Service Apache
Get-Service W3SVC
检查是否是开机自启
Get-Service WinRM, LanmanServer, Apache, W3SVC |
Select-Object Name, DisplayName, Status, StartType
查看端口开放情况,确保8080监听在0.0.0.0
netstat -ano -p tcp
80端口可能仍监听在0.0.0.0,单独查看IIS行为即可,监听在本地80则没有问题。
Get-WebBinding -Name "Default Web Site" -Protocol http
降权
安装所有补丁更新后,停止Windows Update服务,防止系统自动更新
sc stop wuauserv
sc config wuauserv start= disabled
将原管理员组的普通用户移出管理员组(vmware安装虚拟机时创建的用户,根据实际情况修改)
net localgroup Administrators kaada /delete
清空所有用户的历史命令记录
Get-ChildItem "C:\Users\*\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt" -Force -ErrorAction SilentlyContinue | Remove-Item -Force
压缩镜像
系统内清理:临时文件、更新缓存、回收站
cleanmgr /verylowdisk
零填充空闲空间
下载 sdelete 工具SDelete v2.06-microsoft并上传到靶机,使用以下命令零填充空闲空间
cd C:\temp
sdelete64.exe -accepteula -z C:
在宿主机vmware安装目录执行压缩命令,指定虚拟磁盘文件路径,压缩完成后,虚拟磁盘文件大小会明显减小
PS D:\VMware> .\vmware-vdiskmanager.exe -k "D:\VM_11s\11s.vmdk"
Shrink: 100% done.
Shrink completed successfully.
最终效果:22GB的虚拟机文件压缩到约7GB,方便分发。
最后,vmware导出虚拟机为OVF文件,再进行导入与测试,分发给选手。
测试
测试过程,需要确保以下环节符合预期
□ Apache 以 kaada 身份运行
□ WinRM 可登录
□ SMB 可认证
□ kaada 不属于 Administrators
□ kaada (WinRM) whoami /priv 无 SeImpersonatePrivilege
□ IIS AppPool (WebShell) whoami /priv 拥有 SeImpersonatePrivilege
□ Apache 根目录无 Users Modify
□ IIS 根目录无 AppPool Modify
□ uploads 目录仅 AppPool 可写
□ .git 可正常泄露用户名
□ Port Forward 可访问 127.0.0.1:80
□ 上传 WebShell 成功
□ sweetpotato 提权成功
□ root.txt 可读取
提权原理:IIS 应用池 SeImpersonatePrivilege 滥用(Potato 家族)
一、前提:IIS 工作进程身份自带模拟特权
WebShell 落在 IIS 上,执行身份是应用池账户 IIS APPPOOL\DefaultAppPool。
该账户虽为低权,但 Windows 默认授予它一项关键特权:
SeImpersonatePrivilege (模拟客户端令牌)
含义:当有其他进程/线程连接到本进程时,允许本进程"扮演(impersonate)"对方的 身份令牌。它不能凭空变 SYSTEM,只能在"别人连进来"时借用对方身份。服务型账户 (IIS 应用池、SQL Server 等)默认持有此特权,这正是这条提权链的根源。
二、利用原理:诱使一个 SYSTEM 进程来连我,借它的令牌
以 Named Pipe Impersonation(命名管道模拟,PrintSpooler variant)为例,四步:
-
建立命名管道服务端 以 DefaultAppPool 身份创建一个自己控制的命名管道(Named Pipe),等待连接。
-
诱导 SYSTEM 进程连接该管道 利用打印后台服务 Spooler(以 SYSTEM 运行)的接口特性,让它主动向攻击者 指定的命名管道发起连接。于是一个 SYSTEM 身份的连接被送上门。
-
模拟来访者令牌(关键一步) 连接建立后调用 ImpersonateNamedPipeClient(),把当前线程身份切换为连进来的 SYSTEM 令牌。正因为 DefaultAppPool 拥有 SeImpersonatePrivilege,此调用才被 系统允许——否则直接被拒,提权失败。
-
用 SYSTEM 令牌创建进程 借到 SYSTEM 令牌后,用它启动新进程/线程,即获得 NT AUTHORITY\SYSTEM。
一句话:Spooler 只是"被骗来送令牌的 SYSTEM 进程",真正让攻击者能"接住并使用" 该令牌的,是 IIS 应用池身份手里的 SeImpersonatePrivilege。
反思
仅靠Windows Update系统更新无法完整补全系统漏洞,仍然存在可利用CVE情况,后续尝试搭配火绒等杀软辅助修复系统自身漏洞。