해킹스터디

[Normaltic 웹해킹 입문] 9주차 문제풀이 XSS-5

herini0829 2025. 12. 31. 11:06

🕵️ XSS-5 문제 풀이: 응답 변조(Response Intercept)를 통한 보안 스크립트 무력화

XSS 시리즈의 대미를 장식할 5번 문제다. 이번 문제는 지금까지와는 차원이 달랐다. 단순히 문법을 맞추는 게 아니라, 브라우저가 나를 감시하려고 심어놓은 '보안 스크립트' 자체를 없애버려야 했기 때문이다. 역대급으로 어려웠던 만큼 해결했을 때의 쾌감도 컸다.


1. 탐색 단계: 공격 포인트 발견

평소처럼 여러 곳을 찔러보다가, 게시글을 '수정'하는 과정에서 발생하는 트래픽을 유심히 살펴봤다. 그러다 드디어 input 태그의 value 속성 안에서 내가 입력한 값이 그대로 반환되는 지점을 찾아냈다.

value="내가_넣은_값" 형태이므로, 따옴표(")로 속성을 닫고 이벤트 핸들러를 주입하면 될 것 같았다. 바로 공격 코드를 짜서 글을 올리고 관리자 봇에게 보냈다.


2. 첫 번째 위기: "관리자가 알아차렸습니다"

당연히 성공할 줄 알았는데, 예상치 못한 경고창이 떴다. "일정 수 이상의 alert는 의심스럽습니다"라며 관리자가 공격을 눈치챘다는 메시지였다.

"난 alert를 쓴 적이 없는데?" 여기서부터 멘붕이 시작됐다. 뭔가 내가 모르는 검문소가 중간에 있다는 뜻이었다. 다시 한번 코드를 샅샅이 분석해 보기로 했다.


3. 원인 파악: 클라이언트 사이드 필터링

다시 Response 패킷을 뜯어보니 범인이 보였다. 수정 페이지로 넘어갈 때 서버가 이상한 자바스크립트를 하나 끼워 보냈는데, 바로 checkContent라는 함수였다.

이 함수는 브라우저가 서버로 데이터를 다시 보낼 때 <>를 강제로 HTML Entity로 바꿔버리는 역할을 하고 있었다. 즉, 내가 아무리 잘 짜서 보내도 내 브라우저가 스스로 코드를 망가뜨려서 보내고 있었던 것이다. "서버가 시킨 대로 브라우저가 나를 검사하고 있었다니..."


4. 해결책: "검문소 자체를 삭제하라"

필터링이 브라우저에서 일어난다면, 브라우저가 그 필터링을 인지하지 못하게 하면 된다. Burp Suite의 'Do intercept-response' 기능을 써서 서버가 보낸 응답을 가로챈 뒤, 문제가 되는 보안 스크립트 부분을 통째로 지워버렸다.

필터가 사라진 상태에서 수정을 진행하니, 드디어 confirm() 창이 정상적으로 떴다. 이제 관리자의 쿠키를 탈취할 진짜 공격 코드를 주입할 차례였다.


5. 최종 공격 및 성공

동일한 방식으로 다시 글을 수정하고, Response를 가로채 필터를 지워주는 과정을 반복했다. 결과는 대성공! Beeceptor 로그에 관리자의 세션 쿠키가 찍히며 플래그를 손에 넣었다.(Stored XSS이므로 해당 글의 링크를 관리자봇에게 접속시키면 된다)


💡 보안 분석 및 소감

이번 실습의 핵심은 "보안 로직은 반드시 서버 사이드(Server-side)에 있어야 한다"는 것이다. 클라이언트(브라우저)에서 일어나는 모든 필터링은 공격자가 패킷을 가로채서 무력화할 수 있기 때문이다.

✅ 핵심 대응 방안
1. 서버 측 검증: 자바스크립트 필터에 의존하지 말고, 서버에서 수신한 모든 데이터를 최종적으로 다시 인코딩해야 한다.
2. HttpOnly 쿠키: 세션 탈취를 막기 위해 쿠키에 HttpOnly 속성을 부여한다.
3. CSP 도입: 인라인 스크립트 실행과 신뢰하지 않는 도메인으로의 전송을 차단하는 강력한 보안 정책을 수립한다.

막혔을 때 답답했지만, Response까지 변조하며 문제를 풀고 나니 웹 보안의 큰 그림이 조금 더 선명하게 보이는 것 같다. 😎