XSS : Cross Site Scripting
CSS에게 밀려 XSS가 된 Cross Site Scripting에 대해 알아보자.
XSS는 클라이언트 사이드 취약점의 대표적인 공격이다.
(클라이언트 사이트 취약점 : 웹페이지의 이용자를 대상으로 공격할 수 있는 취약점)
XSS는 공격자가 웹 리소스에 악성 스크립트를 삽입해 이용자의 웹 브라우저에서 해당 스크립트를 실행할 수 있다.
공격자는 해당 취약점을 통해 특정 계정의 세션정보를 탈취하고, 해당계정으로 임의의 기능을 수행할 수 있다.
해당 취약점은 SOP 보안 정책이 등장하면서 서로 다른 오리진에서는 정보를 읽는 행위가 이전에 비해 힘들어졌다.
그러나 이를 우회하는 다양한 기술이 소개되면서 XSS 공격은 지속되고 있다.
자바스크립트는 이용자와의 상호작용없이 이용자의 권한으로 정보를 조회하거나 변경할 수 있다. 쿠키와 세션이 저장되어있기 때문이다.
따라서 공격자는, 자바스크립트를 이용해 이용자에게 보여지는 웹페이지를 조작하고, 위치를 임의의주소로 변경할 수 있다.
쿠키 및 세션을 탈취한다던지, 페이지 변조 공격, 위치이동 공격 등이 있다.
Stored XSSs는 서버의 데이터베이스 또는 파일등의 형태로 저장된 악성스크립트를 조회할때 발생한다.
게시글, 댓글에 악성 스크립트를 포함해 업로드하는 방식이 있다.
Reflected XSS : 서버가 악성 스크립트가 담긴 요청을 출력할때 발생한다. 게시물 조회를 위한 검색창에 스크립트를 포함해 검색하는 방식이 있는데, 검색 문자열에 악성 스크립트가 포함되어 있으면 Reflected XSS가 발생할 수 있다.
워게임 XSS-1을 풀어보녀 쿠키 탈취를 실습해보자.
일단 서버를 열어 페이지를 열어보면
vuln페이지, memo페이지, flag페이지 3개가 있다.
문제의 app.py를 열어보면
이런 함수가 두개있다.
check_xss는 param와 cookie(딕셔너리)를 인자로 받고는다
url은 vuln페이지의 param을 설정하고있다.
그리고 url과 쿠키를 인자로 전달하며 호출한다.
read_url은 driver함수를 많이 사용하고 있는데,
driver.get은 url주소로 접속하게 해준다.
즉 접속한 뒤 쿠키를 넣어주고 아까 받은 인자의 url로 접속한다.
check_xss는
/flag에 들어가있는걸 볼 수 있다.
GET요청을 처리해줄때는 flag.html 템플릿을 렌더링하여 브라우저에 보여준다.
POST요청시에는 사용자가 보낸 param을 param변수에 넣어주고, check_xss에 넣어서 돌린다
그럼 위에서 본 check_xss함수가
url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"로 url을 만들고 read_url에 쿠키와 함께 보낸다.
이때의 쿠기의 value는 FLAG이다.
read_url 함수는 Selenium을 사용하여 크롬 브라우저를 헤드리스 모드로 실행하고, 특정 URL에 접근한 후, 쿠키를 설정하고 페이지를 로드한다. 웹 자동화를 통해 페이지에서 쿠키와 URL이 적용된 상황을 테스트한다.
마지막 페이지인 /memo를 살펴보면, 전역변수 memo_text를 사용하는걸 볼 수 있다.
text는 get으로 url에 /memo?memo=Hello처럼 요청하면 Hello가 memo_text변수에 한줄씩 띄워져서 누적되어 저장되는걸 알 수 있다.
여기서 memo는 검증없이 HTML로 랜더링되고 있다. 즉 여기에 악의적 자바스크립트 코드를 넣으면 XSS공격을 시도할 취약점이 되는것이다.
<script>alert(document.cookie)</script>
이 코드를 메모에 추가하게되면, 페이지가 렌더링될때 브라우저에서 자바스크립트 코드가 실행된다.
그리고 이 코드는 브라우저에 저장된 쿠키값을 반환한다.
위에 check_xss함수가 쿠키의 value값에 FLAG를 넣었으므로 check_xss함수를 실행한상태면 쿠키가 메모에 노출되게 된다.
조합해보면
vulln 페이지는 param값을 가져와 반환해주고, Flag페이지는 param 값을 받아온 뒤 check_xss로 param과 flag를 넘겨준다.
그럼 check_xss에서 param 값과 딕셔너리 형태의 쿠키를 인자로 받고, 파라미터를 url로 인코딩해준 뒤 get함수가 실행되어 param값이 포함된 URL로 접속한다.
http://127.0.0.1:8000/vuln?param={인코딩된 param} 형식으로, XSS 공격을 시도할 수 있는 페이지이다.
4취약한 /vuln 페이지는 param 값을 필터링 없이 그대로 반환하므로, 스크립트 코드가 실행될 수 있다.
즉 자바스크립트를 실행시키기 위해 메모에서 쿠키를 출력하는 자바스크립트 코드를 제출하면 되는것이다.
location.href="http://127.0.0.1:8000/memo?memo="+document.cookie
location.href="http://127.0.0.1:8000/memo?memo="+document.cookie
메모페이지로 들어간 이후 쿠키를 읽는명령어를 스크립트로 출력하게한다.