블랙박스 웹 취약점 테스트 (Nikto, SQL Injection, XSS)
Source: Dev.to
범위 및 윤리
이 문서는 의도적으로 취약하게 만든 Kali Linux 클래스 실험실 내부에서 오직 수행된 테스트를 문서화합니다. 모든 활동은 교육 목적을 위해 통제된 환경에서 승인받아 실행되었습니다.
추가 세부 사항이 포함된 GitHub 저장소:
Black‑Box Web Vulnerability Testing
목차
- 왜 이 실험실이 중요한가
- 실험실 환경 및 범위
- 방법론 (블랙‑박스 접근법)
- 1단계: 네트워크 및 호스트 탐색
- 2단계: 서비스 열거
- 3단계: Nikto를 이용한 취약점 스캔
- 4단계: SQL 인젝션 테스트
- 5단계: 교차 사이트 스크립팅 (XSS)
- 결과 요약
- 완화 방안 및 보안 설계 시사점
- 초보자 흔히 저지르는 실수
- 결론
왜 이 실험실이 중요한가
Web 취약점은 바로 익스플로잇 단계로 뛰어들어 찾는 경우는 드뭅니다. 실제로 테스터들은 발견(discovery) 단계부터 시작해 가정들을 검증하고 긍정적 결과와 부정적 결과를 모두 문서화합니다. 이 실험실은 세 가지 기본 카테고리를 사용해 엔드‑투‑엔드 워크플로우를 보여줍니다:
| 카테고리 | 초점 |
|---|---|
| Nikto | 서버 잘못된 구성 및 위생 |
| SQL Injection (SQLi) | 백엔드 신뢰 및 입력 처리 실패 |
| Cross‑Site Scripting (XSS) | 클라이언트 측 신뢰 및 출력 인코딩 실패 |
목표는 이해와 문서화이며, 무기화가 아닙니다.
실험실 환경 및 범위
| 항목 | 세부 정보 |
|---|---|
| 운영 체제 | Kali Linux (class OVA) |
| 권한 | 실험실 네트워크 내 의도적으로 취약하게 만든 서비스에 대한 테스트만 제한됨 |
| 발견된 대상 (내부 네트워크) | • DVWA (Damn Vulnerable Web Application) • WebGoat • 추가 의도적으로 취약하게 만든 앱 |
초보자 주의: 실제 평가에서는 어떤 것이 취약한지 모르는 경우가 많습니다. 첫 번째 승리는 단순히 존재하는 것을 발견하는 것입니다.
방법론 (블랙‑Box 접근법)
A black‑box 테스트는 애플리케이션 내부에 대한 사전 지식이 없다고 가정합니다. 사용된 워크플로우:
- 도달 가능한 네트워크와 호스트 식별.
- 열린 서비스와 버전 열거.
- 잘못된 구성 스캔.
- 애플리케이션 동작 테스트.
무엇이 변경되었는지와 왜 중요한지를 문서화하십시오. 부정적인 결과도 성공적인 발견과 동일한 엄격함으로 기록됩니다.
Phase 1: 네트워크 및 호스트 탐색
목표: 내부 실험실 네트워크에서 활성 호스트를 식별합니다.
- 로컬 IP와 라우트를 확인했습니다.
- 내부 브리지 네트워크에서 호스트 탐색을 수행했습니다(예:
nmap -sn 10.0.0.0/24). - 호스트명으로 여러 의도적으로 취약한 서비스를 식별했습니다.
초보자 참고: 호스트 탐색은 불필요한 노력을 방지합니다. 잘못된 IP를 테스트하는 것은 흔한 초기 실수입니다.
Phase 2: 서비스 열거
목표: 각 호스트가 무엇을 실행하고 있는지, 어디에 집중해야 하는지 파악.
- 발견된 호스트의 열린 포트를 열거함 (예:
nmap -sV -p-). - HTTP 서비스와 지원 구성 요소(웹 서버, 데이터베이스)를 식별함.
- 각 취약점 유형에 가장 적합한 애플리케이션을 확인함.
핵심 요점: 열거는 어디서 테스트할지를 알려주며, 어떻게 악용할지는 알려주지 않는다.
Source: …
3단계: Nikto를 이용한 취약점 스캔
| 항목 | 세부 정보 |
|---|---|
| 대상 | DVWA 웹 서비스 |
| 도구 | nikto -h http:///dvwa |
| Nikto가 확인하는 내용 | • 구식 서버 소프트웨어 • 누락된 보안 헤더 • 노출된 디렉터리 및 기본 파일 |
주요 결과
- 구식 Apache 버전.
- 누락된 보안 헤더:
X‑Frame‑Options,X‑Content‑Type‑Options. - 세션 쿠키에
HttpOnly가 없음. - 디렉터리 인덱싱이 활성화됨.
- 인증 엔드포인트 확인됨.
왜 중요한가: 이러한 결과는 “해킹”을 의미하지는 않지만, 위험을 극적으로 증가시키며 종종 더 깊은 취약점으로 직접 연결됩니다.
4단계: SQL 인젝션 테스트
초기 테스트 (부정 결과)
로그인 페이지는 입력과 관계없이 일반적인 “Login failed” 메시지를 반환했습니다.
- 눈에 보이는 SQL 오류 없음.
- 동작 편차 없음.
왜 문서화하나요? 일관된 오류 처리는 방어적 제어입니다. 모든 엔드포인트가 취약한 것은 아닙니다.
더 나은 대상으로 전환
열거 결과를 활용하여, SQL‑Injection 테스트를 전용 SQLi 모듈(예: DVWA의 “SQL Injection” 페이지)로 이동했으며, 이는 안전하지 않은 입력 처리를 시연하도록 설계되었습니다.
관찰된 동작
- 사용자가 제공한 입력이 백엔드 쿼리에 직접 영향을 미쳤습니다.
- 하나가 예상되던 곳에 여러 레코드가 반환되었습니다.
- 사용자 데이터 및 데이터베이스 메타데이터에 대한 무단 접근.
입증된 영향
- 사용자 레코드 노출.
- 데이터베이스 스키마 및 버전 공개.
- 비밀번호 해시 획득.
초보자 주의: 취약점은 “데이터를 보는 것”이 아니라 신뢰할 수 없는 입력이 데이터베이스 로직을 제어한다는 것입니다.
추가 위험 증거
대표적인 무소금 MD5 해시가 공개 조회 서비스를 이용해 쉽게 복원 가능한 것으로 확인되었으며, 이는 약한 해싱이 SQLi 위험을 복합적으로 증가시킴을 보여줍니다.
Phase 5: 교차 사이트 스크립팅 (XSS)
Reflected XSS (DVWA)
Baseline test:
- 평문 입력이 응답에 직접 반영됩니다.
- HTML 출력 인코딩이 관찰되지 않았습니다.
Conclusion: 사용자 입력이 그대로 반영되어, 낮은 보안 설정에서 Reflected XSS condition임을 확인했습니다.
Beginner note: 팝업은 XSS를 증명하기 위해 필요하지 않습니다. 안전하지 않은 반영만으로도 충분합니다.
Stored XSS (DVWA)
Baseline storage test:
- 사용자 댓글이 백엔드에 영구 저장됩니다.
- 콘텐츠가 모든 사용자에게 렌더링됩니다.
- 페이지 새로 고침 후에도 항목이 유지됩니다.
Why this is critical: Stored XSS는 페이지를 보는 모든 사용자에게 영향을 미치며, 공격자만 해당되지 않습니다.
Root Cause (from Source Review)
입력은 SQL 사용을 위해 이스케이프되었지만 HTML 출력에 대해 인코딩되지 않았습니다.
Key lesson: SQL 이스케이프 ≠ XSS 방어. 출력은 브라우저 컨텍스트에 맞게 인코딩되어야 합니다.
조사 요약
| Category | Result |
|---|---|
| Nikto | 다수의 잘못된 구성 확인 (구버전 Apache, 보안 헤더 누락, 디렉터리 인덱싱, 보안이 취약한 쿠키) |
| SQL Injection | 데이터 유출, 스키마 노출 및 비밀번호 해시 획득을 가능하게 하는 안전하지 않은 쿼리 구성 |
| Cross‑Site Scripting | 반사형 및 저장형 XSS 확인; HTML 출력 인코딩 부재 |
| Overall Risk | 잘못된 구성이 SQLi와 XSS의 영향을 증폭시키며, 약한 해싱이 보안 상태를 더욱 낮춤 |
완화 방안 및 보안 설계 시사점
- 패치 및 업데이트 – 웹 서버, 프레임워크, 라이브러리를 최신 상태로 유지합니다.
- 보안 헤더 –
X‑Frame‑Options,X‑Content‑Type‑Options,Content‑Security‑Policy,Strict‑Transport‑Security를 적용합니다. - 쿠키 하드닝 – 세션 쿠키에
HttpOnly와Secure플래그를 설정합니다. - 입력 검증 및 출력 인코딩 –
- 허용된 문자 화이트리스트에 따라 입력을 검증합니다.
- 컨텍스트(HTML, JavaScript, URL 등)에 따라 출력을 인코딩합니다.
- 파라미터화된 쿼리 / 준비된 문 – 문자열을 연결한 SQL을 제거합니다.
- 강력한 비밀번호 저장 – 솔트가 적용된 적응형 해시 알고리즘(예: bcrypt, Argon2)을 사용합니다.
- 최소 권한 원칙 – 데이터베이스 계정에 필요한 권한만 부여합니다.
초보자 흔히 빠지는 함정
| 함정 | 문제점 |
|---|---|
| “오류 없음” 페이지가 앱이 안전하다고 가정하기 | 조용한 실패는 의도적인 방어 제어일 수 있습니다. |
| SQLi(SQL 인젝션) 테스트를 로그인 페이지에만 국한하기 | 취약한 파라미터는 검색, 댓글 입력란 등 다른 곳에도 존재하는 경우가 많습니다. |
| XSS를 증명하기 위해 팝업 알림에 의존하기 | 반사만으로도 충분하며, 그 영향은 데이터 탈취나 세션 하이재킹이 될 수 있습니다. |
| SQL 이스케이프와 HTML 인코딩을 혼동하기 | 각 컨텍스트마다 고유한 정화/인코딩 전략이 필요합니다. |
| 서버 측 설정 오류를 무시하기 | 민감한 파일, 관리자 인터페이스를 노출하거나 다른 공격을 촉진할 수 있습니다. |
결론
이 실험은 안전하고 허가된 환경에서 웹 애플리케이션 취약점을 발견하고 문서화하는 체계적인 블랙‑박스 접근 방식을 단계별로 안내합니다. 네트워크 탐색으로 시작해 서비스 열거를 진행하고, 이후 집중 도구(Nikto, 수동 SQLi 테스트, XSS 검사)를 적용함으로써 체계적인 방법론이 윤리적이고 교육적인 범위 내에서 신뢰할 수 있는 결과를 도출하는 방식을 보여줍니다.
이 결과는 잘못된 설정, 약한 해시, 적절한 출력 인코딩 부재가 종종 고전적인 코드 수준 버그만큼 위험하다는 점을 강조합니다. 따라서 복구 조치는 보안 구성과 보안 코딩 관행을 모두 다루어 견고한 웹 애플리케이션을 구축해야 합니다.
# QL Injection
**Backend query manipulation confirmed**
# Reflected XSS
**Unsafe reflection detected**
# Stored XSS
**Persistent unsafe rendering confirmed**
---
완화 방안 및 보안 설계 시사점
- 파라미터화된 쿼리 사용 (PDO / MySQLi)
- 컨텍스트 인식 출력 인코딩 적용 (
htmlspecialchars) - 보안 헤더 설정 (
HttpOnly,X‑Frame‑Options, CSP) - 약하거나 솔트가 없는 비밀번호 해시 사용 금지
- 입력을 검증하고 출력을 인코딩
다중 방어(Defense‑in‑depth)가 중요: 단일 제어만으로는 충분하지 않다.
Common Beginner Pitfalls
- 모든 입력이 취약할 것이라고 기대함
- 열거를 건너뛰고 목표를 추측함
- SQL 이스케이프와 XSS 방지를 혼동함
- 부정적인 결과를 문서화하지 않음
Learning to say “this did not change behavior” is a skill.
결론
이 실험은 구조화된 블랙‑박스 접근 방식이 어떻게 체계적으로 취약점을 발견하고, 마법처럼가 아니라는 것을 보여주었습니다. 탐색, 스캔, 행동 테스트 및 문서화를 결합함으로써, what이 취약한지뿐만 아니라 why it matters도 설명할 수 있습니다.
가장 중요한 교훈:
보안 테스트는 페이로드를 외우는 것이 아니라 신뢰 경계를 이해하는 것입니다.
연결
이 글을 즐겁게 읽으셨거나 DevOps, Linux, 보안, 혹은 클라우드 자동화를 배우고 계시다면, 저는 여러분과 연결하고 아이디어를 공유하며 배우고 싶습니다.
💬 언제든지 연락 주시거나 👉 LinkedIn에서 제 여정을 팔로우해 주세요.