[WARGAME] DreamHack 웹해킹1 로드맵 / wargame command-injection-1 / 버프슈트 프록시

jckim22·2022년 10월 15일
0

[WEBHACKING] STUDY (WARGAME)

목록 보기
10/114
post-thumbnail

분석

아래는 서버 코드의 소스코드이다.
ping함수를 유심히 보자

#!/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='Timeout !')
        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)

host에 입력값을 받는 것을 볼 수 있는데 ping -c 3 "ip주소" 이런식으로 받는 것이 정상적인 작동이다.

하지만 우리는 Command Injection이라는 취약점을 사용해서 flag.py의 내용을 확인할 것이다.

이 역시 post 방식으로 받은 값을 필터링 없이 사용해서 생기는 Injection의 전형적인 취약점이다.

이전에 공부했던 것처럼 cat은 파일의 내용을 보여주는 명령어이고 연속적인 명령어를 실행하려면 ;, &&과 같은 메타문자를 사용해야한다.

그럼 ping -c 3 "ip주소" 이곳에 어떤 입력값을 넣어야할까
8.8.8.8 ; cat "flag.py" 이라는 커맨드를 주입하면 된다.

하지만 끈 따옴표가 자체적으로 있기 때문에 이 역시도 전에 했던 Injection처럼 따옴표를 따로 처리 해주면 된다.

그에 따라서 8.8.8.8" ; cat "flag.py 이러한 커맨드를 입력하게 되면

ping -c 3 "8.8.8.8" ; cat "flag.py"

이런 커맨드가 된다.

실습

그럼 직접 입력해보자
이 문제는 사실 입력폼에 설정되어 있는 패턴을 지워서 특수문자도 입력될 수 있게 하면 브라우저에서 직접 풀 수 있는 문제이다.

하지만 나는 버프슈트를 이용해서 프록시 서버에서 패킷을 가로채고 조작하여 서버에 요청해보겠다.

  1. 먼저 패킷을 잡기 위해 8.8.8.8 만 대입해서 서버에 요청해본다.

  2. 그리고 프록시 서버에서 그 패킷을 가로챈다.

  3. 이후 맨 밑 페이로드를 8.8.8.8" ; cat "flag.py로 바꾸어 주고 다시 forward로 서버에 요청하면

  4. 이렇게 flag.py 를 볼 수 있고 그 안에 flag를 얻을 수 있다.

profile
개발/보안

0개의 댓글