읽기 안내
Dreamhack의 개인 문제 풀이 기록입니다. 원문에 남아 있는 실습 주소·플래그와 실패·미완료 결과를 그대로 보존했습니다.
웹 서비스 분석
엔드포인트: /ping
다음 코드는 /ping 페이지를 구성하는 코드다.
@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')
코드를 살펴보면 요청에서 host라는 이름의 폼 데이터를 가져온다. 가져온 host 값을 사용하여 ping 명령어를 실행한다. subprocess.check_output 함수를 사용하여 /bin/sh에서 cmd 명령어를 실행하고, 결과 출력 변수 output에 저장한다.
- 명령어 실행 중 예외가 발생하지 않으면, 결과 출력을 UTF-8로 디코딩한 후
ping_result.html템플릿과 함께 렌더링하여 반환한다. - 만약 명령어 실행 시간이 5초를 초과하면
subprocess.TimeoutExpired예외가 발생하며,Timeout!메시지와 함께ping_result.html템플릿을 렌더링하여 반환한다. - 명령어 실행 중 오류가 발생하면
subprocess.CalledProcessError예외가 발생하며, 해당 오류 메시지와 함께ping_result.html템플릿을 렌더링하여 반환한다.
subprocess.check_output 함수(Information)
서브 프로세스를 실행하고 출력 문자열을 파이썬 로직에서 변수에 담아 사용하고 싶은 경우 사용하는 함수다. 비정상 종료되면 CalledProcessError 예외를 발생시킨다.
취약점 분석
cmd 변수는 사용자로부터 입력받은 host 값을 포함하고 있다. 하지만 **사용자 입력을 그대로 명령어로 실행하기 때문에, 사용자가 악의적인 공격 코드를 주입할 수 있다. **이를 Command Injection 공격 이라고 부른다.
예를 들어, host 에 의도대로 "8.8.8.8" 이 들어간다면 ping -c 3 "8.8.8.8"이 올바르게 실행되겠지만, " 문자를 임의로 삽입하여 문자열에서 빠져나온다면 원하는 명령어를 이어서 실행할 수 있다.
host = '8.8.8.8"; ls #'일 경우, cmd = 'ping -c 3 "8.8.8.8"; ls #"'의 문자열을 가지게 된다.
이를 /bin/sh로 실행시킨 결과는 의도된 핑 뿐만 아니라 ls라는 명령어의 결과를 추가적으로 확인할 수 있게 된다.
익스플로잇
익스플로잇
필터링 검사

명령어 구분자 ;를 이용하여 익스플로잇을 시도했을 시 형식에 대한 조건이 있음을 확인할 수 있다.
개발자 도구를 통해 input태그의 pattern속성이 설정되어 있음을 확인할 수 있다. pattern속성이란 폼 제출 시 <input>요소의 값을 검사할 때 사용될 정규 표현식(regular expression)을 명시하며, 허용된 정규 표현식은 영어, 숫자, ".", 글자 수 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 속성을 제거하여 허용된 정규표현식에 대한 조건을 우회할 수 있다. pattern속성이 제거된 코드와 개발자 도구에서의 모습을 확인할 수 있다.
패턴 속성이 제거된 코드
<input type="text" class="form-control" id="Host" placeholder="8.8.8.8" name="host" required="">
payload
8.8.8.8"; cat flag.py #

작성 기록과 문제 출처
원문과 출처
풀이와 설명: MadEyE / 이선용의 개인 Notion 기록.
문제에서 제공한 코드·서비스 화면과 외부 참고자료의 권리는 해당 작성자와 플랫폼에 있습니다.
원문 본문·코드·실습 증적을 보존했으며, 원문에 포함된 외부 글은 참고 링크로 안내합니다.
다음 글