본문으로 건너뛰기

© 2026 Molayo

HN분석2026. 06. 17. 11:34

재미와 투옥을 위한 IIS 서버 굴욕시키기

요약

IIS 웹 서버의 취약점을 탐색하고 버그 바운티를 수행하기 위한 기술적 접근법을 다룹니다. Shodan, Google Dorking, 능동적 핑거프린팅을 활용하여 타겟 서버를 식별하는 구체적인 방법론을 제시합니다.

핵심 포인트

  • Shodan 및 검색 엔진을 활용한 IIS 서버 식별 기술
  • Google Dorking을 통한 ASP.NET 및 IIS 관련 경로 탐색
  • 응답 헤더 분석을 통한 능동적 기술 핑거프린팅 방법
  • 버그 바운티 관점에서의 IIS 서버 접근 전략

재미와 투옥을 위한 IIS 서버 굴욕시키기

내 친구 중 한 명이 예전에 나에게 이렇게 말한 적이 있습니다:

"만약 IIS 블루 스크린을 발견한다면, 거기서 멈추지 마세요. 분명 무언가가 있을 겁니다."

네, 그의 말이 맞았습니다. 그 IIS 스플래시 페이지(splash page)는 막다른 길이 아닙니다. 그 파란 창 뒤에는 웹(www)에서 가장 지속적으로 잘못 설정되는 웹 서버 중 하나가 자리 잡고 있으며, 당신이 더 깊이 들여다보기를 간절히 바라고 있습니다.

그래서 제가 버그 바운티(bug bounty) 중에 IIS 타겟에 어떻게 접근하는지 안내해 드리겠습니다:

목차

  • 쉬잇, 쉬잇, IIS 서버들, 어디 있나요?
  • 좋아, IIS 서버를 찾았어. 이제 어떡하지?
  • pwn 타임
  • HPP를 통한 WAF 우회

쉬잇, 쉬잇, IIS 서버들, 어디 있나요?

다음은 제가 IIS 서버를 찾기 위해 사용하는 몇 가지 기술입니다.

Shodan

타겟에 손을 대기도 전에, Shodan이 이미 무엇을 알고 있는지 확인해 보세요:

ssl:"target.com" http.title:"IIS"
ssl.cert.subject.CN:"target.com" http.title:"IIS"
org:"target" http.title:"IIS"

이 샘플 쿼리들은 타겟의 조직(org) 또는 SSL 인증서와 연결된 IIS 장비들을 나열할 것입니다. 때때로 스테이징 서버(staging servers), 잊혀진 관리 패널, 그리고 인터넷에 노출되어 있다는 사실을 아무도 몰랐던 내부 도구들을 발견하게 될 것입니다.

Shodan을 fofa, Censys, Netlas, Odin 등과 같은 다른 플랫폼으로 교체하거나 조합하여 자유롭게 사용해 보세요. 이들은 모두 인터넷의 서로 다른 조각들을 인덱싱합니다. 🍕

Google Dorking

스캐너를 실행하기도 전에 Google이 당신을 위해 IIS 서버를 찾아줄 수 있습니다. 이 도크(dorks)들은 모두 범위(scope) 내에서 IIS 타겟을 찾는 것에 관한 것입니다:

site:target.com intitle:"IIS Windows Server"
site:target.com inurl:aspnet_client
site:target.com ext:aspx | ext:ashx | ext:asmx
...

aspnet_client 폴더와 _vti_bin (FrontPage 확장 기능)은 IIS를 나타내는 결정적인 증거입니다. Google이 이들을 인덱싱했다면, 당신은 타겟을 확보한 것입니다. ext:aspx 도크는 인덱싱된 모든 ASP.NET 페이지를 포착하며, 이는 그 밑에 IIS가 작동하고 있음을 의미합니다.

또한, 기본적인 열거(enumeration)가 놓치는 중첩된 서브도메인(subdomains)을 잡기 위해 스택형 와일드카드(stacked wildcards)를 사용하여 범위를 확장하세요:

site:*.target.com intitle:"IIS"
site:*.*.target.com intitle:"IIS"

두 번째 쿼리는 저에게 여러 번 개발/스테이징 (dev/staging) 서버들을 찾아내 주었습니다.

능동적 기술 핑거프린팅 (active tech fingerprinting)

당신이 보고 있는 것이 IIS라는 것을 알 수 있는 가장 쉬운 방법은 응답 헤더 (response headers)를 확인하는 것입니다. 원시 요청 (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

하지만 아마도 당신은 이를 대규모로 (at scale) 수행하고 싶을 것입니다. 그렇다면 침착하게 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
...

해당 내부 IP와 X-FEServer 헤더는 Exchange 서버의 내부 호스트 이름을 알려준 것입니다. 이를 잘 기록해 두세요. 이는 다음 단계에서 활용할 수 있는 정보 노출 (information disclosure) 사례입니다.

공격 시간 (pwn time)

정찰은 이 정도면 충분하니, 이제 핵심적인 부분으로 넘어가 봅시다.

nuclei 템플릿: 지루한 작업 자동화하기

IIS 타겟 목록을 확보했다면, 관련 태그를 사용하여 nuclei로 공격을 퍼부으세요:

nuclei -l iis-targets.txt \
-tags microsoft,windows,asp,aspx,iis,azure,config,exposure -silent

저는 수동 정찰 (manual recon)을 수행하는 동안 이 작업을 백그라운드에서 실행하는 것을 좋아합니다.

막다른 길처럼 보이는 HTTPAPI 2.0

당신은 일반적인 HTTPAPI 2.0 404 에러로 응답하는 많은 IIS 서버들을 마주하게 될 것입니다. 대부분의 사람들은 이를 보고 "여긴 아무것도 없군"이라고 생각합니다. 틀렸습니다.

이것이 실제로 의미하는 바는 서버가 Host 헤더에서 올바른 도메인 이름(domain name)을 받지 못했다는 것입니다. IIS 인스턴스는 존재하며 무언가를 실행 중이지만, 특정 가상 호스트(virtual host)에 바인딩(bound)되어 있습니다. 여러분은 그중 어떤 것인지 알아내야 합니다.

두 가지 접근 방식이 있습니다:

  • SSL 인증서(SSL certificate)를 확인하십시오. Subject 또는 SAN 필드에 필요한 호스트 이름(hostname)이 포함되어 있는 경우가 많습니다. 브라우저로 접속하여 인증서를 검사하기만 하면 됩니다.
  • 인증서가 도움이 되지 않는다면, 가상 호스트를 브루트 포스(brute-force)하십시오. Host 헤더 워드리스트(wordlist)를 사용하는 ffuf와 같은 도구가 여기서 효과적입니다: ffuf -u https://TARGET_IP/ -H "Host: FUZZ.target.com" -w vhosts.txt -fs 0

올바른 호스트 이름에 도달하면, 서버는 갑자기 깨어나 무익한 404 에러 대신 실제 애플리케이션을 제공합니다.

IIS 틸데 열거(Tilde enumeration): 끊임없이 쏟아지는 선물

이것은 가장 과소평가된 기술 중 하나입니다. IIS는 오래된 DOS 8.3 파일 이름 규칙에서 상속된 레거시(legacy) 동작을 가지고 있습니다. 특별히 제작된 요청을 보냄으로써, 디렉토리 리스팅(directory listing)이 비활성화되어 있더라도 서버의 파일 및 디렉토리의 짧은 이름(short names)을 열거(enumerate)할 수 있습니다.

사용해야 할 도구는 shortscan입니다:

shortscan https://target.com/ -F -p 1

-F -p 1 파라미터는 shortscan에게 디렉토리(전체 URL)를 퍼징(fuzz)하고 짧은 이름들을 열거하도록 지시합니다 (-ppatience를 의미합니다).

사용할 수 있는 또 다른 도구는 Burp의 IIS Tilde Enumeration Scanner입니다.

이 도구는 다음과 같은 짧은 이름 조각들을 출력합니다:

File: WEB~1.CON
File: GLOBAL~1.ASA
File: SITEBA~1.ZIP
...

여기서 중요한 점은 다음과 같습니다: WEB~1.CON은 분명히 web.config입니다. 하지만 SITEBA~1.ZIP은 무엇일까요? sitebackup.zip일까요? sitebase.zip일까요? 아니면 sitebatch.zip일까요? 전체 이름을 추측할 수 있다면, 다운로드를 시도해 볼 수 있습니다.

워드리스트(wordlist) 생성을 위한 몇 가지 옵션을 살펴보겠습니다:

LLM 사용하기

다음과 같은 방식입니다:

줄바꿈으로 구분된 단어 목록만 반환하고, 그 외의 내용은 아무것도 포함하지 마세요. 단어에는 영문자와 숫자만 포함되어야 합니다.
이 스니펫(snippet)을 바탕으로 단어의 나머지 부분이 무엇일지에 대한 추측 목록을 만드세요. 스니펫이 추측한 단어의 부분 문자열(substring)이 되도록 하세요.
목록을 가능한 한 광범위하게 만드세요.
...

shortname을 해결하기 위한 GitHub dorks

GitHub의 코드 검색(code search)은 기본적으로 무료 파일명 데이터베이스와 같습니다. 수백만 개의 리포지토리(repos)는 여러분의 shortname 조각(fragment)과 패턴 매칭을 할 수 있는 수백만 개의 실제 파일명을 의미합니다. 이는 무작정 추측하는 것보다 훨씬 효과적입니다.

아이디어: shortname에서 처음 6글자( ~1 이전의 모든 것)를 가져와서, 해당 문자로 시작하고 올바른 확장자로 끝나는 파일명을 GitHub에서 검색하는 것입니다.

GitHub의 코드 검색 UI를 직접 사용하는 방법:

# GitHub 검색창에서 "Code"를 선택하고 path: 필터를 사용하세요
path:/.ds_st
path:/global*.asa
...

IIS Github dork

이를 유사 자동화(pseudo-automate)하려면 GSNW (GitHub Short Name Wordlist)를 확인해 보세요. shortname 조각을 입력하면 GitHub 코드 검색을 스크래핑하여 일치하는 파일명을 찾아줍니다:

python gsnw.py "siteba" output.txt

동일한 기능을 수행하며 깔끔한 워드리스트(wordlist)를 출력하는 GitHub-IIS-Shortname-Generator도 있습니다:

python scanner.py WEBDEV
Found matches:
--------------------------------------------------
- WebDev.md
...

또 다른 멋진 옵션은 shortnameguesser입니다. 이 도구는 shortname 스캐너의 출력값을 받아 여러 소스에 쿼리를 날려 조각들을 해결함으로써 타겟팅된 워드리스트를 생성합니다.

BigQuery를 사용하여 shortname 해결하기

여기서부터 흥미로워집니다. 이 기술은 IIS에서 숨겨진 파일을 찾기 위해 BigQuery를 사용하는 Assetnote의 연구에서 영감을 얻었습니다. 아이디어는 간단합니다. Google BigQuery의 공개 GitHub 데이터셋을 사용하여 전체 GitHub 코드베이스에서 여러분의 shortname 패턴과 일치하는 파일명을 검색하는 것입니다.

만약 shortname 스캔 결과가 SITEBA~1.ZIP으로 나왔다면, BigQuery에서 다음과 같이 실행합니다:

SELECT DISTINCT path
FROM `bigquery-public-data.github_repos.files`
WHERE REGEXP_CONTAINS(path, r'(?i)(/siteba[a-z0-9]+\.zip|^siteba[a-z0-9]+\.zip)')
...

그러면 sitebackup.zip, sitebase.zip 등 실제 프로젝트의 실제 파일 이름을 얻을 수 있습니다. 이제 무작정 추측하는 대신 집중된 워드리스트 (wordlist)를 갖게 되었습니다.

crunch를 이용한 나머지 부분 브루트포싱 (bruteforcing)

LLM, GitHub, BigQuery를 모두 동원해도 결과가 나오지 않을 때는, 때때로 단순히 무식하게 남은 문자들을 브루트포싱 (brute-force) 해야 할 때가 있습니다. crunch는 주어진 문자 길이에 대해 가능한 모든 조합의 워드리스트 (wordlist)를 생성합니다:

crunch 4 6 abcdefghijklmnopqrstuvwxyz -o wordlist.txt

이 명령은 4자에서 6자 길이의 모든 소문자 알파벳 문자열을 생성합니다. 8.3 shortname 방식은 처음 6글자를 보여주므로, 일반적으로 남은 부분만 추측하면 됩니다.

예를 들어 shortscan 결과가 DESKTO~1.ZIP으로 나왔다고 가정해 봅시다. 파일 이름이 deskto로 시작하고 .zip으로 끝난다는 것을 알고 있습니다. 이제 deskto 다음에 무엇이 오는지 알아내야 합니다. 파일 이름은 desktop.zip, desktopbackup.zip, desktop-files.zip 등이 될 수 있습니다. 패턴 기반 퍼징 (fuzzing)을 위해 ffuf를 사용하여 이러한 변형들을 탐색하세요:

ffuf -w wordlist.txt -u https://target.com/desktoFUZZ.zip -mc 200,301,302,403
ffuf -w wordlist.txt -u https://target.com/desktop-FUZZ.zip -mc 200,301,302,403
ffuf -w wordlist.txt -u https://target.com/desktop_FUZZ.zip -mc 200,301,302,403
...

하이픈 (-), 언더스코어 (_), URL 인코딩된 공백 (%20), 그리고 구분자가 아예 없는 경우 등 다양한 구분자에 주의하십시오. 개발자들은 명명 규칙 (naming conventions)이 일관되지 않으므로 모든 패턴을 다루어야 합니다. %20 변형은 누군가 파일 이름에 공백을 넣은 의외로 흔한 경우를 잡아냅니다. Windows는 이를 개의치 않으며, IIS는 이를 문제없이 서빙 (serve)할 것입니다.

이것은 스마트한 접근 방식이 실패했을 때 사용하는 브루트포싱 (brute-force) 대비책이며, 솔직히 말해서 예상보다 더 자주 효과가 있습니다.

퍼징 (fuzzing): IIS 전용 워드리스트 (wordlist)의 중요성

일반적인 서버에는 일반적인 워드리스트 (wordlist)로도 충분합니다. 하지만 IIS는 일반적이지 않습니다. IIS/.NET 생태계에만 존재하는 것들을 대상으로 퍼징 (fuzzing)해야 합니다.

퍼징하기에 가치가 높은 타겟들은 다음과 같습니다:

/web.config
/web.config.bak
/web.config.old
...

예를 들어, trace.axd

ASP.NET 트레이스 뷰어 (trace viewer)입니다. 만약 이것이 활성화되어 있다면, 헤더, 쿠키, 그리고 때로는 자격 증명 (credentials)을 포함한 전체 요청/응답 로그를 얻을 수 있습니다. elmah.axd

에러 로그 뷰어 (error log viewer)이며, 원리는 동일합니다. 이것들은 본질적으로 개발자들이 끄는 것을 잊어버린 디버그 엔드포인트 (debug endpoints)입니다. 🫣

그리고 항상 IIS 전용 확장자 (extensions)를 사용하여 퍼징하세요:

.asp,.aspx,.ashx,.asmx,.wsdl,.wadl,.config,.xml,.zip,.txt,.dll,.json

실용적인 ffuf 명령어 예시:

ffuf -u https://target.com/FUZZ -w iis-wordlist.txt \
-e .asp,.aspx,.ashx,.asmx,.config,.json,.xml,.zip,.bak,.txt \
-mc 200,301,302,403 -fs 0

제가 선호하는 몇 가지 IIS 전용 워드리스트 (wordlists)입니다:

  • secLists IIS.txt: 클래식한 리스트입니다. 기본 IIS 경로, 일반적인 핸들러 (handlers), 그리고 레거시 파일들을 다룹니다. 항목에 이미 확장자가 포함되어 있으므로 확장자를 추가하지 않고 그대로 사용하세요.
  • orwa’s iis.txt: Godfather Orwa(아래 참조 섹션의 “THE POWER OF RECON” 강연을 했던 바로 그 인물)가 큐레이션한 리스트입니다. 실제 버그 바운티 (bug bounty) 프로그램에서 검증되었습니다. 제가 가장 먼저 찾는 리스트입니다. 👑
  • orwa’s aspx.txt: 위 리스트의 동반자로, 특히 .aspx 엔드포인트에 집중되어 있습니다.
  • wfuzz iis.txt: 규모는 작지만 알려진 취약한 IIS 경로들에 집중되어 있습니다.
  • dirbuster-ng iis.txt: IIS 전용 약점을 타겟팅하는 또 다른 컴팩트한 리스트입니다.
  • Assetnote wordlists: 실제 세계의 크롤링 데이터로부터 자동 생성되며 매달 업데이트됩니다. ASP 및 ASPX 워드리스트를 가져오세요. 이들은 실제 운영 중인 애플리케이션에서 파생되었으므로, 일반적인 리스트보다 적중률 (hit rate)이 현저히 높습니다.
  • OneListForAll: “웹 퍼징계의 rockyou”입니다. 타겟팅된 실행에는 onelistforallshort.txt를 사용하고, 전체 리스트는 밤새도록 돌려두세요.

IIS는 대소문자를 구분하지 않습니다 (case-insensitive). 만약 사용 중인 워드리스트 (wordlist)가 대소문자가 섞여 있다면, 중복된 요청으로 시간을 낭비하게 됩니다. SecLists의 raft-medium-words-lowercase.txt와 같이 소문자로 된 워드리스트를 사용하거나,

tr '[:upper:]' '[:lower:]' | sort -u 명령어를 통해 커스텀 리스트를 파이프 (pipe) 처리하여 중복을 제거한 뒤,

ffuf에 입력하세요.

web.config: 왕국의 열쇠

경로 탐색 (path traversal), 잘못 설정된 백업 파일, 또는 짧은 이름 (shortname) 기반의 탐색을 통해 web.config 파일을 읽을 수 있다면, 해당 침투 테스트 (engagement) 전체를 승리로 이끌 가능성이 높습니다.

그 이유는 다음과 같습니다: IIS의 web.config 파일에는 종종 머신 키 (machine keys)가 포함되어 있습니다. 이는 ViewState를 서명하고 암호화하는 데 사용되는 암호화 키 (cryptographic keys)입니다. 머신 키를 확보하면 악성 직렬화된 (serialized) ViewState 페이로드 (payload)를 위조할 수 있으며, 역직렬화 (deserialization)를 통해 원격 코드 실행 (RCE)을 달성할 수 있습니다.

이는 현존하는 가장 신뢰할 수 있는 IIS RCE 체인 중 하나입니다. 키를 확보한 후에는 ysoserial.net과 같은 도구가 페이로드를 생성해 줄 것입니다. 🔑

web.config로의 경로 탐색 (path traversal)

어떠한 종류의 파일 다운로드 또는 파일 읽기 파라미터 (parameter)를 발견한다면, 다음과 같은 시도를 해보세요:

GET /download?id=../../web.config
GET /download?id=..%2f..%2fweb.config

AI 자동 생성 콘텐츠

본 콘텐츠는 HN AI Posts의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0