사자자리

[bWAPP] Cross-Site Scripting - Reflected (GET) 본문

웹해킹/bWAPP

[bWAPP] Cross-Site Scripting - Reflected (GET)

renne 2022. 8. 3. 01:07

Quest. XSS 취약점이 있는지 알아봅시다. 다음 화면을 띄워보세요.


경고창을 누른 후 화면 (Welcome success 출력)

 


 

[난이도 low]

저렇게 입력하니, Welcome Hello Hi가 출력됐다. Welcome success를 출력하려면 success만 입력하면 된다.

 

일단 난이도 low를 믿고 가장 기본적인 XSS 공격을 실행했다.

 

경고창이 떴다. 경고창의 OK 버튼을 누르니 success도 출력됐다.

성공

 



[난이도 medium]

난이도 low일 때와의 차이를 알기 위해 똑같이 입력했다.

 

XSS 공격이 아니었던, Last name의 success만 출력이 됐다.

 

<form action="/bWAPP/xss_get.php" method="GET">
    <p><label for="firstname">First name:</label><br />
    <input type="text" id="firstname" name="firstname"></p>
    
    <p><label for="lastname">Last name:</label><br />
    <input type="text" id="lastname" name="lastname"></p>
    
    <button type="submit" name="form" value="submit">Go</button>  
</form>

    <br />
    Welcome <script>alert(\"XSS\")</script> success

우클릭 후 View Page Source로 Page Source를 살펴봤다. input에 입력한 데이터들은 /bWAPP/xss_get.php로 간다.

 

/var/www/bWAPP로 이동하고 xss_get.php 파일을 찾았다.

 

//xss_get.php
<?php
    if(isset($_GET["firstname"]) && isset($_GET["lastname"]))
    {   
        $firstname = $_GET["firstname"];
        $lastname = $_GET["lastname"];    

        if($firstname == "" or $lastname == "")
        {
            echo "<font color=\"red\">Please enter both fields...</font>";       
        }
        else            
        { 
            echo "Welcome " . xss($firstname) . " " . xss($lastname);   
        }
    }
?>

Ctrl + F로 firstname을 검색하고 살펴봤다. if문을 보니, firstname과 lastname의 값이 둘 다 들어오면, xss라는 함수의 인자로 들어가고, xss 함수의 return값이 출력된다.

 

//xss_get.php
<?php
function xss($data)
{      
    switch($_COOKIE["security_level"])
    {      
        case "0" :       
            $data = no_check($data);            
            break;       
        case "1" :            
            $data = xss_check_4($data);
            break;        
        case "2" :
            $data = xss_check_3($data);            
            break;        
        default :           
            $data = no_check($data);            
            break;   
    }       
    return $data;
}
?>

xss 함수로 들어온 인자는 security_level에 따라 각각 다른 함수의 인자로 들어간다.

 

<div id="security_level">
    <form action="/bWAPP/xss_get.php" method="POST">
        <label>Set your security level:</label><br />
        
        <select name="security_level">   
            <option value="0">low</option>
            <option value="1">medium</option>
            <option value="2">high</option>   
        </select>
        
        <button type="submit" name="form_security_level" value="submit">Set</button>
        <font size="4">Current: <b>medium</b></font>
    </form>   
</div>

해킹을 시도하고 있던 웹페이지의 Page Source에서 security_level을 검색했다. 난이도 medium은 값이 1이다.

즉, xss_check_4 함수로 인자가 들어간다.

 

////xss_get.php
include("security.php");
include("security_level_check.php");
include("functions_external.php");
include("selections.php");

xss_get.php 파일의 상단을 보니, 4개의 php 파일을 include 했다. 각각의 파일들에 들어가서 xss_check_4를 검색해보자.

 

//functions_external.php
function xss_check_4($data)
{
    // addslashes - returns a string with backslashes before characters that need to be quoted in database queries etc.
    // These characters are single quote ('), double quote ("), backslash (\) and NUL (the NUL byte).
    // Do NOT use this for XSS or HTML validations!!!

    return addslashes($data);
}

functions_external.php 파일에 있었다. xss_check_4는 addslashes 함수에 인자를 넣고 return한다.

addslashes는 작은 따옴표('), 큰 따옴표("), 백슬래쉬(\), NUL 값이 들어오면, 그 앞에 백슬래쉬(\)를 추가해서 return한다.

 

Welcome <script>alert(\"XSS\")</script> success

Page Source에서 큰 따옴표 앞에 백슬래쉬(\)가 붙은 이유가 addslashes 함수 때문이었다.

 

https://www.w3schools.com/jsref/jsref_fromcharcode.asp

 

JavaScript String fromCharCode() Method

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

String.fromCharCode 함수

 - ASCII 코드에서 문자로 변환하는 함수

 

https://www.alpharithms.com/ascii-table-512119/

X는 88, S는 83이다.

 

<script>alert(String.fromCharCode(88, 88, 83))</script> 입력

 

성공

 


 

 

[난이도 high]

필터링을 우회해서 공격해보세요. 그러나 공격이 통하지 않습니다. 그 이유를 정리해주세요.

난이도 medium에서 한 공격을 해봤지만, 입력한 문자 그대로 출력됐다.

 

<div id="security_level">
    <form action="/bWAPP/xss_get.php" method="POST">
        <label>Set your security level:</label><br />
        
        <select name="security_level">   
            <option value="0">low</option>
            <option value="1">medium</option>
            <option value="2">high</option>   
        </select>
        
        <button type="submit" name="form_security_level" value="submit">Set</button>
        <font size="4">Current: <b>medium</b></font>
    </form>   
</div>

난이도 high의 값은 2이다.

 

//xss_get.php
<?php
function xss($data)
{      
    switch($_COOKIE["security_level"])
    {      
        case "0" :       
            $data = no_check($data);            
            break;       
        case "1" :            
            $data = xss_check_4($data);
            break;        
        case "2" :
            $data = xss_check_3($data);            
            break;        
        default :           
            $data = no_check($data);            
            break;   
    }       
    return $data;
}
?>

따라서 입력한 데이터는 xss_check_3 함수에 들어간다.

 

function xss_check_3($data, $encoding = "UTF-8")
{
    // htmlspecialchars - converts special characters to HTML entities    
    // '&' (ampersand) becomes '&amp;' 
    // '"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set
    // "'" (single quote) becomes '&#039;' (or &apos;) only when ENT_QUOTES is set
    // '<' (less than) becomes '&lt;'
    // '>' (greater than) becomes '&gt;'
    
    return htmlspecialchars($data, ENT_QUOTES, $encoding);
}

htmlspecialchars 함수는 우회가 거의 불가능한, XSS을 정말 잘 막아주는 함수이다.

따라서 난이도 high에서의 공격은 실패.

Comments