기준

취약점 설명

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

 

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을 통해 알 수 있는 방식은 ..을 통해 접근하는 방식이지만 위의 방법을 통해 우회하여 접근할 수도 있습니다.

 

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

+ Recent posts