문제를 보면 아이피를 입력할 수 있는 창이 있고
입력하면 해당 아이피로 핑을 보낸 결과를 보여준다.
만약 아이피 형식이 아닌 다른 값을 입력하면 명령어는 실행이 되지 않는다.
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')
문제 소스코드를 보면 입력값에 대한 검사 없이 명령어를 실행하고 있다.
따라서 입력값에 대한 검증은 html이나 js에서 수행되는 것을 알 수 있다.
크롬 개발자도구에서 확인해보니 input창에서 검사하고 있다.
따라서 검증 부분을 지워주면 검증을 우회할 수 있다.
이후 다음과 같이 command-injection을 시도하면 flag를 얻을 수 있다.