사자자리

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

웹해킹/bWAPP

[bWAPP] Cross-Site Scripting – Stored (Change Secret)

renne 2022. 8. 9. 03:49

[난이도 low]

Quest. Change Secret 페이지에서 XSS 공격 후 SQL Injection (Login From/User) 페이지에서 확인할 수 있습니다. 다음 화면을 출력해보세요.(bee/bug)

 

 


New secret: <script>alert('success')</script>

 

SQL Injection (Login From/User) 페이지로 이동

 

Login: bee

Password: bug

 

성공

 


[난이도 low]

Quest. secret을 사용자의 쿠키 정보로 바꿔봅시다.

 

 


New secret: <script>alert(document.cookie)</script>

위와 마찬가지로 SQL Injection (Login From/User) 페이지로 이동하고 로그인(bee/bug)

 

성공

 


[난이도 high]

Quest. 공격할 수 없습니다. Secret은 두 개의 함수를 이용해 방어하고 있습니다. 함수의 이름을 적어주세요.

 

New secret: <script>alert('success')</script>

위와 마찬가지로 SQL Injection (Login From/User) 페이지로 이동하고 로그인(bee/bug)

 

입력한 XSS 공격문이 문자 그대로 출력된다.

 

    <h1>XSS - Stored (Change Secret)</h1>
    <p>Change your secret.</p>
    <form action="/bWAPP/xss_stored_3.php" method="POST">
        <p><label for="secret">New secret:</label><br />
        <input type="text" id="secret" name="secret"></p>
        <input type="hidden" id="token" name="token" value="d9afd65ee31260211022df26690e8f8ade1c90e8">
        <button type="submit" name="action" value="change">Change</button>
    </form>

Cross-Site Scripting – Stored (Change Secret) 사이트의 Page Source를 보면, 입력한 데이터는 secret이라는 이름으로 /bWAPP/xss_stored_3.php에 전송된다.

 

//xss_stored_3.php
<?php
if(isset($_POST["action"]))
{
    if(isset($_REQUEST["secret"]))
    {
        $secret = $_REQUEST["secret"];
        
        if($secret == "")
        {
            $message = "<font color=\"red\">Please enter a new secret...</font>";       
        }
        
        else
        { 
            // If the security level is not MEDIUM or HIGH
            if($_COOKIE["security_level"] != "1" && $_COOKIE["security_level"] != "2") 
            {
            //생략
            }

            else
            {
                // If the security level is MEDIUM or HIGH
                if(!isset($_REQUEST["token"]) or !isset($_SESSION["token"]) or $_REQUEST["token"] != $_SESSION["token"])
                {
                    $message = "<font color=\"red\">Invalid token!</font>";            
                }

                else
                {
                    $secret = mysqli_real_escape_string($link, $secret);
                    $secret = htmlspecialchars($secret, ENT_QUOTES, "UTF-8");

                    $sql = "UPDATE users SET secret = '" . $secret . "' WHERE login = '" . $login . "'";

                    // Debugging
                    // echo $sql;      
                    $recordset = $link->query($sql);
                    if(!$recordset)
                    {
                        die("Connect Error: " . $link->error);
                    }
                    $message = "<font color=\"green\">The secret has been changed!</font>";
                } 
            }
        }
    }
    else
    {
        $message = "<font color=\"red\">Invalid secret!</font>";
    }   
}

// A random token is generated when the security level is MEDIUM or HIGH
if($_COOKIE["security_level"] == "1" or $_COOKIE["security_level"] == "2")
{
    $token = sha1(uniqid(mt_rand(0,100000)));
    $_SESSION["token"] = $token;
}
?>

security level이 MEDIUM 이나 HIGH이고 token에 문제가 없을 때,

$secret은 mysqli_real_escape_string 함수htmlspecialchars 함수의 인자에 입력되고 난 다음에 저장된다.

Comments