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

Stored XSS

공격 원리

공격자가 악성 스크립트를 취약한 서버에 게시글 형태로 등록시킨 후 사용자가 해당 게시물에 접근 시 스크립트가 실행되어 피해를 발생시키는 공격 기법이다.

Stored XSS는 다음의 과정으로 이루어진다.

1. 공격자는 게시판에 Stored XSS 취약점이 있는 것을 확인합니다.

2. 공격자는 사용자 쿠키 정보를 탈취하는 스크립트를 포함한 게시물을 작성합니다.

3. 희생자는 해당 열람 쿠키 정보가 공격자에게 전송됩니다.

4. 공격자는 희생자의 쿠키 정보를 이용해 계정을 탈취합니다.

공격 실습

No.

실습 위치

비고

1

localhost/freeboard/write

게시판 게시글 추가 기능

취약 페이지 구현

<div class="col-sm-12 col-md-9 col-lg-10 p-2">
    <div class="content">
        <form
        method="post"
        class="was-validated"
        action="write.php"
        enctype="multipart/form-data">

            <div class="mb-3">
            <label for="validationTextarea">제목</label>
            <textarea
            class="form-control is-invalid"
            id="validationTextarea"
            name="title"
            placeholder="제목을 입력해주세요"
            required="required"></textarea>
                <div class="invalid-feedback">
                    제목은 필수 입력 항목입니다!
                </div>
            </div>
            <div class="form-group">
                <label for="exampleFormControlTextarea1">본문</label>
                <textarea
                class="form-control"
                name="content"
                id="exampleFormControlTextarea1"
                rows="10"></textarea>
            </div>
            <div class="input-group">
            <label class="input-group-btn">
            <span class="btn btn-primary">
            Browse&hellip;
            <input
                id="my-file-selecter"
                type="file"
                name="b_file"
                style="display: none;"
                onchange="$('#upload-file-info').val($(this).val());"
                multiple="multiple"></span>
            </label>
            <input
                type="text"
                class="form-control"
                id="upload-file-info"
                readonly="readonly"></div>
            <!-- 파일 업로드 경로 /freeboard/upload -->
            <span class="help-block">
                파일 용량 제한은 50MB입니다. 허용된 확장자는 jpg, jpeg, gif, png입니다.
            </span>
            <div class="col-auto my-1">
                <button
                    type="submit"
                    class="btn btn-primary"
                    onclick='chkex(my-file-selecter.value);'>Submit</button>
            </div>



        </div>
    </form>
    </div>
</div>

/freeboard/write.html 중 일부

<?php
    $connect = mysqli_connect("localhost", "myuser1", "if8QV06jvIs8!@", "myuser1") or die("fail");
    $id = $_SESSION['username'];
    $title = $_POST['title'];
    $tmpfile =  $_FILES['b_file']['tmp_name'];
    $o_name = $_FILES['b_file']['name'];
    $filename = iconv("UTF-8", "EUC-KR",$_FILES['b_file']['name']);
    $folder = "upload/".$filename;
    move_uploaded_file($tmpfile,$folder);
    $content = $_POST['content'];             

    $URL = "index";

    if($id && $title && $content){
        $mqq = mq("alter table freeboard auto_increment =1");
        $sql = mq(    "insert into freeboard(name, title, content, date, hit, recom, file) values('".$id."','".$title."','".$content."',now(), 0,0, '".$o_name."')");
        echo "<script>
    alert('글쓰기 완료되었습니다.');
    location.href='/freeboard/index';</script>";
}else{
    echo "<script>
    alert('글쓰기에 실패했습니다.');
    history.back();</script>";
}
?>

/freeboard/write.php 중 일부

공격 실습

Step1: 게시판 글쓰기 기능에 악의적인 기능을 하는 스크립트를 포함한 글을 게시합니다.

해당 구문은 사용자의 쿠키를 파라미터로 포함하여 악성 페이지로 리다이렉트 하도록 하는 스크립트 구문입니다.

악성 스크립트 등록을 통한 Stored XSS 시도

Step2: 게시글 클릭 시 스크립트가 동작하여 세션 값이 공격자의 도메인으로 전송됩니다.

세션 값 전송

Step3:공격자의 웹서버 로그에서 전송된 세션 값을 확인할 수 있습니다.

세션 값 확인

Step4:공격자는 획득한 세션 값으로 변조하여 세션을 탈취합니다.

세션 값 변경 및 계정 권한 탈취

대응방안

사용자 입력 값 검증을 반드시 서버단에서 실시합니다.

사용자 입력 문자열에서 HTML 코드로 인식될 수 있는 특수문자를 일반문자로 치환하여 처리합니다.

HTML 특수문자

HTML Entity

HTML 특수문자

HTML Entity

<, >

&lt;, &gt;

"

&quot;

(, )

&#x28;, &#x29;

'

&#x27;

&

&amp;

#

&#x23;

/

&#x2F

 

 

게시판 등에서 HTML 태그를 허용 해야하는 경우 HTML 태그 화이트리스트를 선정 후, 해당 태그만 허용하는 방식을 적용합니다.

반응형