메뉴
HN
Hacker News 42일 전

재미와 감옥행을 위한 IIS 서버 모의해킹

IMP
8/10
핵심 요약

이 글은 버그 바운티(모의해킹) 참여자들을 위해 마이크로소프트 IIS 서버를 탐지하고 취약점을 찾는 실용적인 해킹 기법들을 상세히 다루고 있습니다. 단순한 정보 수집부터 내부 IP 노출 확인, 틸드(Tilde) 열거, web.config 파일 접근 및 웹 방화벽 우회까지 실제 공격에서 자주 쓰이는 기술들을 설명합니다. 네트워크 및 웹 보안 실무자들에게 IIS 서버의 주요 취약점과 이를 방어하기 위한 해커들의 접근 방식을 이해하는 데 매우 유용한 자료입니다.

번역된 본문

재미와 감옥행을 위한 IIS 서버 모의해킹 2026년 3월 18일 · 약 13분 분량

내 친구 중 한 명이 이렇게 말한 적이 있습니다: "혹시 IIS 블루 스크린(에러 페이지)을 발견하게 되면, 거기서 멈추지 마. 분명 뭔가가 숨어 있을 거야." 맞습니다. 그 말이 맞았습니다. 그 IIS 스플래시 페이지는 막다른 길이 아닙니다. 그 파란 창 뒤에는 웹상에서 가장 지속적으로 잘못 구성되어 있는 웹 서버 중 하나가 자리 잡고 있으며, 더 깊이 파고들기를 간절히 원하고 있습니다. 그러니 버그 바운티 활동 중 IIS 대상을 어떻게 접근하는지 제 방식을 단계별로 안내해 드리겠습니다.

목차

  • 여보세요, IIS 서버들아, 너희들 어디 있니? (샤오단, 구글 도킹, 능동적 기술 핑거프린팅)
  • 좋아, IIS 서버를 찾았어. 이제 뭘 해야 할까? (내부 IP 노출)
  • 해킹(해킹) 타임 (Nuclei 템플릿, HTTPAPI 2.0, 틸드(Tilde) 열거, LLM 사용, 빅쿼리, 무차별 대입 공격)
  • 퍼징: IIS 전용 워드리스트가 중요하다
  • web.config: 왕국의 열쇠 (경로 순회, 쿠키리스 세션을 통한 BIN 디렉터리 DLL 노출)
  • 리버스 프록시 경로 혼란 (NTFS 해킹을 통한 인증 우회)
  • 파일 업로드 속임수 (HPP를 통한 WAF 우회)

여보세요, IIS 서버들아, 너희들 어디 있니? 제가 IIS 서버를 찾을 때 사용하는 몇 가지 기술은 다음과 같습니다.

샤오단 (Shodan) 대상에 본격적으로 손대기 전에 샤오단이 이미 무엇을 알고 있는지 먼저 확인해 보세요. ssl:"target.com" http.title:"IIS" ssl.cert.subject.CN:"target.com" http.title:"IIS" org:"target" http.title:"IIS" 이러한 예제 쿼리는 대상 조직이나 SSL 인증서와 연결된 IIS 장치들을 나열해 줍니다. 종종 스테이징 서버, 잊혀진 관리자 패널, 누구도 인터넷에 노출되어 있다는 것을 인지하지 못했던 내부 도구들을 발견할 수 있습니다. 자유롭게 샤오단을 Fofa, Censys, Netlas, Odin 등 다른 플랫폼으로 대체하거나 결합하여 사용해 보세요. 이들은 모두 인터넷의 서로 다른 부분들을 인덱싱하고 있습니다. 🍕

구글 도킹 (Google Dorking) 스캐너를 실행하기도 전에 구글은 여러분을 위해 IIS 서버를 찾아줄 수 있습니다. 이 도킹(Dorking) 기법들은 주어진 범위 내에서 IIS 대상을 찾는 데 초점이 맞춰져 있습니다. site:target.com intitle:"IIS Windows Server" site:target.com inurl:aspnet_client site:target.com ext:aspx | ext:ashx | ext:asmx site:target.com intext:"Microsoft-IIS" | intext:"X-Powered-By: ASP.NET" site:target.com inurl:_vti_bin site:target.com intitle:"Microsoft Internet Information Services" aspnet_client 폴더와 _vti_bin(프론트페이지 확장 프로그램)은 IIS라는 것을 단번에 알려주는 명백한 증거입니다. 구글이 이것들을 인덱싱했다면 여러분은 확실한 대상을 얻은 것입니다. 또한, ext:aspx 도크는 인덱싱된 모든 ASP.NET 페이지를 잡아내며, 이는 그 아래에 IIS가 있다는 것을 의미합니다. 뿐만 아니라, 와일드카드를 겹겹이 쌓아 기본 열거 과정에서 놓칠 수 있는 중첩된 하위 도메인을 잡아내도록 범위를 확장해 보세요. site:.target.com intitle:"IIS" site:.*.target.com intitle:"IIS" 위 목록 중 두 번째 쿼리는 제게 개발 및 스테이징 서버를 여러 번 찾아주었습니다.

능동적 기술 핑거프린팅 (Active tech fingerprinting) 여러분이 보고 있는 서버가 IIS인지 확인하는 가장 쉬운 방법은 응답 헤더를 확인하는 것입니다. 다음과 같은 순수 요청(Raw request)을 서버에 보내보세요. nc -v target.com 80 또는 TLS 통신이라면 다음과 같이 하세요. openssl s_client -connect target.com:443 응답 헤더에서 다음과 같은 형식을 찾으면 됩니다. Server: Microsoft-IIS/10.0 X-Powered-By: ASP.NET 하지만 아마도 여러분은 이 작업을 대규모로 수행하고 싶을 것입니다. 그럴 때는 침착하게 httpx(또는 nuclei)를 사용하면 됩니다. httpx -l targets.txt -td | grep IIS | tee iis-targets.txt

좋아, IIS 서버를 찾았어. 이제 뭘 해야 할까? 우선, 우리가 다루고 있는 대상이 무엇인지 확인하고 서버가 공짜로 줄 수 있는 한 많은 정보를 얻어냅시다.

내부 IP 노출 (Internal IP disclosure) 대부분의 사람들이 놓치는 공짜 정보 하나 소개합니다. 특정 IIS 설정(특히 Exchange 또는 OWA 프론트)에 HTTP/1.0 요청을 보내면 서버가 때때로 Location 헤더에 내부 IP를 그대로 넘겨줍니다. curl -v --http1.0 http://example.com 다음과 같은 결과를 받을 수도 있습니다. HTTP/1.1 302 Moved Temporarily Location: https://192.168.5.237/owa/ Server: Microsoft-IIS/10.0 X-FEServer: NHEXCHANGE2016 저 내부 IP와 X-FEServer 헤더는 방금 여러분에게 Exchange 서버의 내부 호스트 이름을 알려준 것입니다. 이를 잘 기록해 두세요. 이것은 정보 노출(Information disclosure)로, 다음 단계에서 우리가 활용할 수 있는 것입니다.

해킹(Pwn) 타임 정찰은 충분히 했으니, 이제 재미있는 부분으로 넘어가 봅시다. Nucle...

원문 보기
원문 보기 (영어)
humiliating iis servers for fun and jail time March 18, 2026 · 13 minutes read A friend of mine once told me: If you ever spot an IIS blue screen, don’t stop there; there must be something. Yep, he was right. That IIS splash page is not a dead end. Behind that blue window sits one of the most consistently misconfigured web servers on the www, and it’s begging you to look deeper. So let me walk you through how I approach IIS targets during bug bounty: table of contents psst, psst, IIS servers, where are you? shodan google dorking active tech fingerprinting ok, I found an IIS server. now what? internal IP disclosure pwn time nuclei templates: automate the boring stuff the HTTPAPI 2.0 dead end that isn’t IIS tilde enumeration: the gift that keeps giving using LLMs github dorks to resolve shortnames using BigQuery to resolve shortnames bruteforcing the rest with crunch fuzzing: the IIS-specific wordlist matters web.config: the keys to the kingdom path traversal to web.config bin directory DLL exposure via cookieless sessions reverse proxy path confusion authentication bypass via NTFS hacks file upload tricks bypassing WAFs via HPP psst, psst, IIS servers, where are you? Here are some techniques I use to find IIS servers. shodan Before you even touch a target, go see what Shodan already knows: ssl:"target.com" http.title:"IIS" ssl.cert.subject.CN:"target.com" http.title:"IIS" org:"target" http.title:"IIS" These sample queries will list IIS boxes tied to the target’s org or SSL certificates. You’ll sometimes find staging servers, forgotten admin panels, and internal tools that nobody realized were internet-facing. Feel free to replace or combine shodan with other platforms like fofa, censys, netlas, odin, etc. They all index different slices of the internet. 🍕 google dorking Google can find IIS servers for you before you even fire up a scanner. These dorks are all about locating IIS targets within a scope: site:target.com intitle:"IIS Windows Server" site:target.com inurl:aspnet_client site:target.com ext:aspx | ext:ashx | ext:asmx site:target.com intext:"Microsoft-IIS" | intext:"X-Powered-By: ASP.NET" site:target.com inurl:_vti_bin site:target.com intitle:"Microsoft Internet Information Services" The aspnet_client folder and _vti_bin (FrontPage extensions) are dead giveaways for IIS; if Google has indexed them, you’ve got a target. The ext:aspx dork catches any indexed ASP.NET pages, which means IIS is underneath. Also, expand your scope with stacked wildcards to catch nested subdomains that basic enumeration misses: site:*.target.com intitle:"IIS" site:*.*.target.com intitle:"IIS" That second one has surfaced dev/staging boxes for me more than once. active tech fingerprinting The easiest way to know you’re staring at IIS is the response headers. Hit it with a raw request: nc -v target.com 80 Or if it’s TLS: openssl s_client -connect target.com:443 What you’re looking for something like this in the response headers: Server: Microsoft-IIS/10.0 X-Powered-By: ASP.NET But probably you want to do this at scale . Then just keep calm and use httpx (or nuclei ): httpx -l targets.txt -td | grep IIS | tee iis-targets.txt ok, I found an IIS server. now what? First off, let’s confirm what we’re dealing with and grab as much information as the server is willing to give away for free. internal IP disclosure Here’s a freebie most people miss. Send an HTTP/1.0 request to certain IIS setups (especially Exchange or OWA fronts) and the server will sometimes hand you an internal IP in the Location header: curl -v --http1.0 http://example.com You might get back something like: HTTP/1.1 302 Moved Temporarily Location: https://192.168.5.237/owa/ Server: Microsoft-IIS/10.0 X-FEServer: NHEXCHANGE2016 That internal IP and that X-FEServer header just told you the internal hostname of the Exchange server. File that away. It’s information disclosure that we could leverage in the following steps. pwn time Enough recon by now, let’s get to the juicy parts. nuclei templates: automate the boring stuff Once you’ve got your list of IIS targets, blast them with nuclei using relevant tags: nuclei -l iis-targets.txt \ -tags microsoft,windows,asp,aspx,iis,azure,config,exposure -silent I like to fire this in the background while I’m doing manual recon. the HTTPAPI 2.0 dead end that isn’t You’ll hit a lot of IIS boxes that respond with a generic HTTPAPI 2.0 404 error. Most people see this and think “nothing here.” Wrong. What this actually means is the server didn’t receive the right domain name in the Host header. The IIS instance is there, it’s running something, but it’s bound to a specific virtual host. You need to figure out which one. Two approaches: check the SSL certificate. The subject or SAN field often contains the hostname you need. Just hit it in a browser and inspect the cert. if the cert doesn’t help, you brute-force virtual hosts. Tools like ffuf with a Host header wordlist work well here: ffuf -u https://TARGET_IP/ -H "Host: FUZZ.target.com" -w vhosts.txt -fs 0 When you land on the right hostname, the server suddenly wakes up and serves you a real application instead of that useless 404. IIS tilde enumeration: the gift that keeps giving This is, one of the most underrated techniques. IIS has a legacy behavior inherited from the old DOS 8.3 filename convention. By sending specially crafted requests, you can enumerate the short names of files and directories on the server even if directory listing is disabled. The tool you want is shortscan : shortscan https://target.com/ -F -p 1 Note -F -p 1 parameters tell shortscan to fuzz the directories (full urls) and enumerate the shortnames ( -p stands for patience ). Another tool you can use is burp’s IIS Tilde Enumeration Scanner . This will spit out shortname fragments like: File: WEB~1.CON File: GLOBAL~1.ASA File: SITEBA~1.ZIP Dir: ADMIN~1 Now here’s the thing: WEB~1.CON is obviously web.config . But what’s SITEBA~1.ZIP ? Is it sitebackup.zip ? sitebase.zip ? sitebatch.zip ? If we can guess the full name, we can try to download it. Let’s explore some options for wordlist generation: using LLMs Something like: Return only a list of words, separated by newlines, and nothing else. Ensure that the words contain only alphanumeric characters. Make a list of guesses, for what the rest of the word could be from this snippet. Ensure that the snippet is a substring of your guess. Make the list as extensive as possible. Snippet: {shortname} github dorks to resolve shortnames GitHub’s code search is basically a free filename database. Millions of repos means millions of real-world filenames you can pattern-match against your shortname fragments. Way more effective than guessing blindly. The idea: take the first 6 characters from your shortname (everything before ~1 ) and search GitHub for filenames that start with those characters and end with the right extension. Using GitHub’s code search UI directly: # In GitHub's search bar, select "Code" and use path: filters path:/.ds_st path:/global*.asa path:/connec*.config To pseudo-automate this, check out GSNW (GitHub Short Name Wordlist). You feed it your shortname fragments and it scrapes GitHub code search for matching filenames: python gsnw.py "siteba" output.txt There’s also GitHub-IIS-Shortname-Generator which does the same thing and outputs a clean wordlist: python scanner.py WEBDEV Found matches: -------------------------------------------------- - WebDev.md - WebDeveloper.java - webdev.txt - webdevicons.lua -------------------------------------------------- Total unique matches: 86 Another cool option is shortnameguesser , which takes shortname scanner output and generates targeted wordlists by querying multiple sources to resolve the fragments. using BigQuery to resolve shortnames This is where it gets interesting. This technique is inspired by Assetnote’s research on using BigQuery to find hidden files on IIS . The idea is simple: use Google BigQuery’s public GitHub dataset to search the e