dreamhack

[Dreamhack] command-injection-1

부산영롱 2024. 1. 10. 21:59

위 화면에 보이는 페이지에서 command injection을 통해 flag를 획득해야 한다.

아래는 웹서버 코드이다.

#!/usr/bin/env python3
import subprocess

from flask import Flask, request, render_template, redirect

from flag import FLAG

APP = Flask(__name__)


@APP.route('/')
def index():
    return render_template('index.html')


@APP.route('/ping', methods=['GET', 'POST'])
def ping():
    if request.method == 'POST':
        host = request.form.get('host')
        cmd = f'ping -c 3 "{host}"'
        try:
            output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
            return render_template('ping_result.html', data=output.decode('utf-8'))
        except subprocess.TimeoutExpired:
            return render_template('ping_result.html', data='Timeo ut !')
        except subprocess.CalledProcessError:
            return render_template('ping_result.html', data=f'an error occurred while executing the command. -> {cmd}')

    return render_template('ping.html')


if __name__ == '__main__':
    APP.run(host='0.0.0.0', port=8000)

코드를 살펴보면 페이지에 입력한 값을 'ping -c 3' 뒤에 붙여서 쉘 명령어로 실행된다.

command injection이 잘 실행되는지 'id' 명령어를 실행해 보기로 했다.

웹서버 코드에서 입력값 형식을 제한하는 부분이 없었는데 에러가 발생했다.

개발자도구로 웹소스를 확인해보니 아래와 같이 pattern을 통해 영문 대소문자, 숫자, 온점(.)으로 이루어진 5~20자 문자열만 입력 가능하도록 제한되어 있었다.

<input type="text" class="form-control" id="Host" placeholder="8.8.8.8" name="host"
pattern="[A-Za-z0-9.]{5,20}" required="">

pattern 부분을 삭제하고 입력하면 '요청한 형식과 일치시키세요.' 라는 에러 메시지는 더이상 발생하지 않는다.

하지만 아래와 같은 에러메시지와 또 마주했다.

메시지를 보면 우리가 입력한 8.8.8.8; id; 양쪽으로 " "가 들어가서 쉘 명령어로 인식되지 못했다.

8.8.8.8"; id;# 를 입력하니 정상적으로 쉘 명령어가 실행된 것을 볼 수 있었다. 

이제 id 대신 cat flag.py 를 입력해서 플래그를 얻을 수 있다.

'dreamhack' 카테고리의 다른 글

[Dreamhack] file-download-1  (1) 2024.01.14
[Dreamhack] image-storage  (0) 2024.01.11
[Dreamhack] Mango  (0) 2024.01.10
[Dreamhack] simple_sqli  (1) 2024.01.09
[Dreamhack] CSRF-1 / 2  (0) 2024.01.01