Kevin Seo 2025. 1. 1. 01:53

이 문제의 경우 알맞은 KEY 값을 입력하여 FLAG를 획득하는 문제이다.

 

[문제 해결]

1. 문제 서버 접속

 

KEY값을 입력하는 부분을 확인 가능하다.

 

어떤 방식으로 동작하는지 확인하기 위해 문제 파일 분석을 진행한다.

 

2. 문제 파일 분석

코드의 경우 두가지의 중요 포인트로 나누어진다.

 

첫번째 중요 포인트인 필터링 부분이다.

 

 

분석할 시 아래와 같다.

우선 소문자(a-z), ' ', 숫자(0~9)를 alphabet 변수에 리스트로 저장한다.

 

또한 command_list에 특정 명령들을 리스트로 저장한다

 

이 후 반복문과 조건문을 이용해 True값을 반환한다.

이 조건문을 해석할 경우 만일 입력받은 cmd 즉 명령이 command_list에 존재하는 명령이거나 alphabet에 존재하지 않는 값일 경우 True 값을 반환한다.

 

즉 이 필터링에서 False 값을 받아야 통과인 것이다.

 

 

메인 코드인 부분으로 조건문들을 분석할 경우 아래와 같다.

if cmd == '' and key == KEY:
            return render_template('flag.html', txt=FLAG)

 

cmd가 빈 곳이고 key가 KEY(FLAG를 인코딩하고 해시화한 값)일 경우 FLAG를 리턴

 

elif cmd == '' and key == guest_key:
            return render_template('guest.html', txt=f"guest key: {guest_key}")

 

cmd가 빈 곳이고 key가 gueste_key일 경우 guest.html 리턴

 

if cmd != '' or key == KEY:
            if not filter_cmd(cmd):
                try:
                    output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
                    return render_template('flag.html', txt=output.decode('utf-8'))

 

cmd가 빈 곳이 아니거나 key가 KEY일 경우에 if not filter_cmd, 즉 필터링에서 True값을 리턴 받지 않을 경우 해당 명령을 쉘로 실행한다.

 

대략적인 코드의 동작 방식은 이해를 했기에 이제 우회법을 찾아야 한다.

 

FLAG가 저장된 곳은 ./flag.txt다.

보통의 경우라면 cat 명령어를 사용하여 쉽게 읽을 수 있겠지만 cat, flag의 경우 필터링 리스트에 등록되어 있다.

 

하지만 코드를 자세히 볼 경우 우회를 할 필요가 없다는 것을 알 수 있다.

 

output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)

 

명령에 대한 timeout 시간이 5초로 설정되어 있는 것을 알 수 있다.

 

이때 아래의 except 조건을 살펴보자.

 

except subprocess.TimeoutExpired:
                    return render_template('flag.html', txt=f'Timeout! Your key: {KEY}')

 

timeout을 초과할 경우 KEY를 리턴하는 것을 알 수 있다.

 

이를 이용하여 FLAG 획득을 진행한다.

 

3. Exploit

우선 guest_key값을 입력하여 테스트를 진행해본다.

 

 

 

elif cmd == '' and key == guest_key:
            return render_template('guest.html', txt=f"guest key: {guest_key}")

 

해당 조건문이 충족되어 guest.html이 리턴된 것을 확인 할 수 있다.

 

if cmd != '' or key == KEY:
            if not filter_cmd(cmd):

 

위의 조건문을 충족시키기 위해 ls 명령어를 입력한다.

 

 

여기서 중요한 것은 해당 POST 요청을 burp를 이용하여 캡쳐해 key를 cmd_input으로 변경해 cmd에 ls 값이 저장되도록 해야한다.

 

 

 

 

명령이 실행되어 결과가 리턴된 것을 확인 가능하다.

 

except subprocess.TimeoutExpired:
                    return render_template('flag.html', txt=f'Timeout! Your key: {KEY}')

 

해당 코드를 발생시키기 위해 timeout 야기한다.

 

 

 

KEY값을 획득하였다.

 

 

해당 KEY값을 입력 후 요청을 전송하고 burp를 이용해 이를 캡쳐한 후 이전과는 반대로 cmd_input을 key로 변경한다.

 

 

 

FLAG를 획득하였다.