사자자리

[bWAPP] Cross-Site Scripting – Stored (Blog) 본문

웹해킹/bWAPP

[bWAPP] Cross-Site Scripting – Stored (Blog)

renne 2022. 8. 9. 03:22

[난이도 low]

Quest. 다음 화면과 같이 경고창을 띄워봅시다.

 


<script>alert('success')</script> 입력 후 Submit

 

성공

 


[난이도 low]

Quest. 사용자의 쿠키 값을 경고창에 띄워봅시다.

 


<script>alert(document.cookie)</script> 입력 후 Submit

 

alert 창이 먼저 떴다.

 

성공

 


[난이도 low]

Quest. (게시판에 등록된 내용을 삭제하지 않았다면) XSS 공격을 시도할 때마다 경고창이 여러 개가 뜨는 것을 확인했습니다. 왜 그럴까요? 이유를 작성해주세요.

 

https://www.imperva.com/learn/application-security/cross-site-scripting-xss-attacks/

 

Reflected XSS Stored XSS
1회용 공격 지속적으로 활용될 수 있는 공격
웹 서버 및 데이터베이스에 악성 코드 저장 X 웹 서버 및 데이터베이스에 악성 코드 저장 O

 

<table id="table_yellow">
        <tr height="30" bgcolor="#ffb717" align="center">
            <td width="20">#</td>
            <td width="100"><b>Owner</b></td>
            <td width="100"><b>Date</b></td>
            <td width="445"><b>Entry</b></td>
        </tr> 

        <tr height="40">
            <td align="center">7</td>
            <td>bee</td>
            <td>2022-08-08 16:42:21</td>
            <td><script>alert('success')</script></td>
        </tr>

        <tr height="40">
            <td align="center">8</td>
            <td>bee</td>
            <td>2022-08-08 16:42:32</td>
            <td><script>alert(document.cookie)</script></td>
       </tr>
</table>

Page Source를 보면, 이전에 입력했던 해킹 코드가 저장되어(Stored) 있다.

 


[난이도 high]

Quest. 공격할 수 없습니다. 이유를 적어주세요.

    <form action="/bWAPP/xss_stored_1.php" method="POST">
	<table>
            <tr>
                <td colspan="6"><p><textarea name="entry" id="entry" cols="80" rows="3"></textarea></p></td>
            </tr>

            <tr>
                <td width="79" align="left">
                    <button type="submit" name="blog" value="submit">Submit</button>
                </td>

                <td width="85" align="center">
                    <label for="entry_add">Add:</label>
                    <input type="checkbox" id="entry_add" name="entry_add" value="" checked="on">
                </td>

                <td width="100" align="center">
                    <label for="entry_all">Show all:</label>
                    <input type="checkbox" id="entry_all" name="entry_all" value="">
                </td>

                <td width="106" align="center">
                    <label for="entry_delete">Delete:</label>
                    <input type="checkbox" id="entry_delete" name="entry_delete" value="">
                </td>

                <td width="7"></td>
                <td align="left"></td>
            </tr>
	</table>
    </form>

Page Source를 보면, textarea에 입력한 데이터는 entry라는 이름으로 /bWAPP/xss_stored_1.php에 전송된다.

 

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

 

<?php
if(isset($_POST["entry_add"]))
{
    $entry = xss($_POST["entry"]);
    $owner = $_SESSION["login"];
    if($entry == "")
    {
        $message =  "<font color=\"red\">Please enter some text...</font>";
    }

    else            
    { 
        $sql = "INSERT INTO blog (date, entry, owner) VALUES (now(),'" . $entry . "','" . $owner . "')";
        $recordset = $link->query($sql);
        if(!$recordset)
        {
            die("Error: " . $link->error . "<br /><br />");
        }
        // Debugging
        // echo $sql;
        $message = "<font color=\"green\">Your entry was added to our blog!</font>";
    }
}
?>

xss_stored_1.php 파일의 내용을 보면, entry_add가 있을 때(웹페이지에서 Add에 체크되어있을 때), entry는 xss함수의 인자로 들어가고 $entry 변수에 저장된다. $entry는 sql문을 통해 데이터베이스에 저장된다.

 

<?php
function xss($data)
{
    include("connect_i.php");
    switch($_COOKIE["security_level"])
    {
        case "0" : 
            $data = sqli_check_3($link, $data);
            break;

        case "1" :
            $data = sqli_check_3($link, $data);
            // $data = xss_check_4($data);
            break;

        case "2" :
            $data = sqli_check_3($link, $data);
            // $data = xss_check_3($data);
            break;

        default :
            $data = sqli_check_3($link, $data);
            break;
    }
    return $data;
}
?>

(생략)

        <select name="security_level">
            <option value="0">low</option>
            <option value="1">medium</option>
            <option value="2">high</option>
        </select>

xss 함수의 인자는 security_level에 따라 다른 함수의 인자로 들어간다. 난이도 high는 2이므로, sqli_check_3 함수이다.

 

<?php
function sqli_check_3($link, $data)
{
    return mysqli_real_escape_string($link, $data);
}
?>

외부 함수 파일(functions_external.php)에서 보면, sqli_check_3 함수는 인자를 mysqli_real_escape_string 함수에 넣고 return한다.

 

mysqli_real_escape_string( )

 - 인자로 들어온 데이터 중에서 SQL을 주입하는 공격과 관련된 기호들을 문자로 바꾸는 API
 - 즉, SQL Injection을 막을 수 있다.

 

따라서 공격이 실패했다.

Comments