(해당 취약점은 이전에 설명한 취약점에서 공격 방법이 충분히 유추가 가능하므로 기준과 취약점 설명만 하도록 하겠습니다.)

기준

취약점 설명

관리자 페이지가 노출되어 공격의 대상이 되거나 알려진 계정, URL일 경우 해당하는 취약점입니다.

 

관리자 페이지가 하부 URL로 설정되어 있는 경우 쉽게 유추할 수 있는 URL은 공격자에 의해 침해당할 가능성이 매우 높습니다.

 

위와 마찬가지로 계정이 흔히 알려진 계정(admin, administrator, manager, public 등)으로 생성되어 있는 경우 공격자가 칭해할 수 있는 가능성이 존재합니다.

 

포트를 나누어 설정한 경우도 추측하기 쉬운 포트로 설정되어 있거나 nmap을 활용하여 공격하면 쉽게 알 수 있기 때문에 공격 대상이 될 수 있습니다.

 

해당 취약점에 의해 관리자 계정이 탈취당할 경우 서비스가 장악될 수 있으며 관리자 페이지 노출로 인해 공격자의 접근으로 권한 탈취를 시도할 수도 있는 취약점입니다.

기준

취약점 설명

서비스 내에 파일을 다운로드할 수 있는 구역이 존재하면 파일을 다운로드할 때 경로를 조작하여 서버 내부 파일을 다운로드하여 중요정보를 탈취하는 취약점입니다.

 

URL을 조작하여 서버의 내부 파일을 획득하기도 하지만 파라미터 값을 조작하여 내부의 파일에 접근하여 획득하기도 합니다.

 

주로 /etc/passwd, /winnt/win.ini, boot.ini를 획득하여 서버 사용자 정보나 내부 정보를 획득하는 방식으로 공격합니다.

 

내부 사용자 정보를 알아내고 내부정보를 탈취할 수 있는 매우 위험한 취약점입니다. 

 

공격 방법

(Dreamhack fil-download-1을 활용하여 실습하도록 하겠습니다.)

#!/usr/bin/env python3
import os
import shutil

from flask import Flask, request, render_template, redirect

from flag import FLAG

APP = Flask(__name__)

UPLOAD_DIR = 'uploads'


@APP.route('/')
def index():
    files = os.listdir(UPLOAD_DIR)
    return render_template('index.html', files=files)


@APP.route('/upload', methods=['GET', 'POST'])
def upload_memo():
    if request.method == 'POST':
        filename = request.form.get('filename')
        content = request.form.get('content').encode('utf-8')

        if filename.find('..') != -1:
            return render_template('upload_result.html', data='bad characters,,')

        with open(f'{UPLOAD_DIR}/{filename}', 'wb') as f:
            f.write(content)

        return redirect('/')

    return render_template('upload.html')


@APP.route('/read')
def read_memo():
    error = False
    data = b''

    filename = request.args.get('name', '')

    try:
        with open(f'{UPLOAD_DIR}/{filename}', 'rb') as f:
            data = f.read()
    except (IsADirectoryError, FileNotFoundError):
        error = True


    return render_template('read.html',
                           filename=filename,
                           content=data.decode('utf-8'),
                           error=error)


if __name__ == '__main__':
    if os.path.exists(UPLOAD_DIR):
        shutil.rmtree(UPLOAD_DIR)

    os.mkdir(UPLOAD_DIR)

    APP.run(host='0.0.0.0', port=8000)

페이지의 형태는 메모를 드록하고 홈에 등록된 메모가 저장되어 클릭 시 조회되는 형식의 페이지였습니다.

소스코드를 확인해보면 upload페이지에 파일 이름에 상위 디렉터리에 접근하도록 명령어가 포함되면 bad characters를 반환하도록 되어있습니다.

하지만 read페이지에는 아무런 보안 조치가 없는 것을 확인할 수 있습니다.

우선 쓰레기값으로 채운 메모를 업로드해보도록 하겠습니다.

우선 홈에서 asd를 호출할 때 flag.py를 호출해보도록 하겠습니다.

read페이지에 보안 조치가 없기 때문에 name필드를 하위 디렉터리에 접근하도록 '../flag.py'를 삽입하면 하위 디렉터리에 포함된 flag를 획득할 수 있습니다.

 

----------------------------------------------------------------------------------------------------------------------------------

위 사진에서 확인할 수 있는 것은 상위 디렉터에 접근하는 방식을 여러가지로 표현한 것입니다.

 

Dreamhack을 통해 알 수 있는 방식은 ..을 통해 접근하는 방식이지만 위의 방법을 통해 우회하여 접근할 수도 있습니다.

 

(이외에 다른 방식으로 실습할 수 있는 방식이 있다면 알려주세요ㅠㅠ)

기준

취약점 설명

파일 업로드 기능이 존재하는 페이지에 서버의 웹 언어와 같은 확장자의 파일을 업로드하여 서버 내에서 업로드된 파일이 실행 가능할 경우 발생되는 취약점입니다.

 

허용되지 않아야 하는 확장자(.asp, .jsp, .php, .cgi 등)가 업로드되는 것도 안되지만 가장 위험한 것은 Server Side Script가 작성된 파일이 업로드되어 실행되는 것이 가장 위험한 부분입니다.

 

Server Side Script가 업로드되어 실행되면 공격자가 의도하는 대로 서버 내부에서 악성코드를 실행시킬 수 있는 공격(Remote Code Execution, RCE)도 가능하며 다양한 방식의 공격이 가능합니다.

 

서버 내에서 명령어를 실행시켜 정보를 확인하거나 서버의 내부 파일을 업/다운로드하는 방식으로 중요 정보가 포함된 파일을 탈취하거나 서버를 장악하는 방식으로 공격이 가능합니다.

 

공격 방법

(해당 취약점은 DVWA를 활용하여 실습해보도록 하겠습니다.)

1. Low Level

페이지의 형태는 파일을 업로드를 할 수 있도록 구성되어 있습니다.

소스 코드를 확인해보면 보안 조치가 되어있지 않은 것을 알 수 있습니다.

업로드한 파일이 'hackable/uploads/'에 업로드되는 것을 확인할 수 있습니다.

우선 업로드할 파일을 작성해보도록 하겠습니다.

업로드가 될 경우 command변수에 명령어를 삽입하여 실행시킬 수 있는 웹쉘입니다.

따로 구현된 필터링이 없기 때문에 정상적으로 등록되는 것을 알 수 있습니다.

업로드를 진행해보도록 하겠습니다.

정상적으로 업로드되고 파일이 업로드된 경로까지 노출되는 것을 확인할 수 있습니다.

해당 URL로 접근해보도록 하겠습니다.

업로드된 경로로 접근하여 command를 입력해보니 정상적으로 실행되는 것을 확인할 수 있습니다.

명령어를 입력하여 /etc/passwd 정보를 획득할 수도 있습니다.

 

2. Medium Level

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];

    // Is it an image?
    if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
        ( $uploaded_size < 100000 ) ) {

        // Can we move the file to the upload folder?
        if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // Yes!
            echo "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?>

페이지의 형태는 전과 동일합니다.

소스 코드를 확인해보면 Low Level과는 달리 이미지파일만 업로드할 수 있는 것을 알 수 있습니다.

Low Level과 같은 방식으로 업로드해보면 업로드가 되지 않는 것을 확인할 수 있습니다.

확장자를 바꿔 업로드 과정 중 확장자를 바꾸는 방식으로 시도해보도록 하겠습니다.

Low Level에서 사용한 웹쉘 파일의 확장자를 바꿔 업로드를 시도하는 중 파라미터를 변조하는 방식으로 진행해보려 합니다.

위의 사진처럼 업로드되는 과정 중에 파일의 확장자를 php로 바꿔주었습니다.

정상적으로 업로드되는 것을 확인할 수 있습니다.

업로드된 파일의 확장자가 php로 보이지만 접근하여 바꿔준 확장자로 업로드됐는지 확인해보도록 하겠습니다.

파라미터를 변조하여 업로드한 파일의 업로드 시간이 서버의 시간과 같은 것을 확인할 수 있습니다.

 

3. High Level

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];

    // Is it an image?
    if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
        ( $uploaded_size < 100000 ) &&
        getimagesize( $uploaded_tmp ) ) {

        // Can we move the file to the upload folder?
        if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // Yes!
            echo "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?>

페이지의 형태는 전과 동일한 것을 확인할 수 있습니다.

소스 코드를 확인해보면 전과 달리 보안 조치가 조금더 추가된 것을 확인할 수 있는데 허용된 파일은 jpg, jpeg, png이며 파일이 이미지 파일인 것을 확인하여 업로드하는 것을 알 수 있습니다.

전과 동일한 방식으로 업로드해봤지만 안되는 것을 확인할 수 있습니다.

파일 업로드 시에 파일의 확장자를 바꿔 업로드해야하는데 getimagesize()로 이미지 헤더를 검증하므로 GIF헤더(GIF89a)를 추가하여 검증을 우회하여 주었습니다.

또한 파일 업로드 시에 우회하는 방법을 사용해보았으나 우회가 되지 않아 마지막에 png를 넣어주어 업로드 시도하였습니다.

이에 덧붙여 High Level에서 되지는 않지만 종종 사용되는 확장자 우회방법을 몇가지말해보도록 하겠습니다.

 

확장자 우회 방법

1) 대소문자 치환 : jsp -> .Jsp, .jSp, .jsP, .JsP 등등

2) Null Byte : [파일이름].php%00.jpg, [파일이름].php%zz.jpg

(%00, %zz 뒤의 확장자가 null 처리되어 앞에 입력한 확장자로 업로드됩니다.)

3) 확장자 대체

asp -> cer, cdx, asa

jsp -> war, jspx, jsv, jsw

php -> php3, htm, html

 

본론으로 돌아와서 업로드된 파일을 확인해보도록 하겠습니다.

파일이 정상적으로 업로드된 것을 확인할 수 있습니다.

업로드된 파일에 명령어를 삽입해봤지만 업로드된 파일을 이미지 파일로 인식하여 명령어가 실행되지 않습니다.

이를 우회하여 실행하기 위해 File Inclusion 취약점을 활용하여 파일을 실행시켜보도록 하겠습니다.

 File Inclusion 취약점이 존재하면 확장자가 php, jsp, asp가 아니더라도 실행할 수 있습니다.

확장자가 다르게 업로드되었지만 정상적으로 파일이 실행되어 명령어를 실행시킬 수 있습니다.

단, 입력 시에 'page=file/../../../hackable/uploads/rokefoke1.php.png&cmd=cat%20/etc/passwd'와 같이 &를 가운데에 삽입하여 명령어를 입력해주면 실행시킬 수 있습니다.

기준

취약점 설명

공격하고자 하는 페이지에 접근하여 URL에 서버의 디렉터리 구성이 노출되거나 파라미터 변조를 통해 서버의 디렉터리를 알 수 있는 경우 인증 후 접근할 수 있는데 하위 URL에 URL 변조 만을 통해 접근 가능한 경우 해당 취약점으로 판단합니다.

 

해당 취약점을 통해 서버에 권한이 없거나 인가되지 않은 기능을 도용할 가능성이 존재하는 취약점입니다.

 

공격 방법

접근하려는 인가되지 않은 URL의 직접적으로 입력하여 접근하여 공격합니다.

 

예)

URL : http://www.test.com/ 

공격 : http://www.test.com/admin/

 

위의 URL처럼 공격 URL을 접근하여 별도의 인증과정 없이 admin 페이지에 접근이 가능하다면 프로세스 검증 누락 취약점으로 판단합니다.

 

----------------------------------------------------------------------------------------------------------------------------------

 

해당 취약점은 불충분한 인증/ 인가와 비슷한 부분이 있지만 인증 / 인가 검증 과정이 존재한다 하더라도 URL 입력만을 통해 접근이 가능하다면 해당 취약점으로 판단하는 부분이 차이점입니다.

+ Recent posts