WEB hacking/드림핵(dreamhack)

드림핵 command-injection-1 Write Up

Roronoa 2023. 7. 15. 23:36
반응형

문제 설명

flag.py에 플래그가 존재하니 command 명령어를 통해 flag.py 파일을 읽으면 문제를 해결할 수 있다.

문제 풀이

[그림 1] ping 라우터 페이지

ping 페이지에 접속하면 host ip를 입력하는 페이지가 보여진다.

일단 8.8.8.8로 ping을 전송해보겠다.

 

[그림  2] ping 명령어 수행 결과

그림 2는 8.8.8.8로 ping을 보낸 결과이다.

3번 ping을 보내는 것을 보면 ping -c 3 {사용자 입력} 이런식으로 코드가 이루어져 있다고 예상이 된다.

일단 소스 코드를 한번 살펴 보겠다.

 

@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')

request.form.get으로 host의 값을 불러온 후 cmd 변수에다 집어 넣는다. 해당 과정에서 입력값 검증이 이루어지지 않고 있기 때문에 command injection 취약점이 발생한다.

output 변수를 보면 subprocess.check_output으로 command 명령어를 실행하고 있다.

/bin/sh을 실행하는데 -c 옵션으로 인자를 받는다 인자로 cmd 변수를 실행한다.

 

command injection에서 메타문자를 이용하여 다중 명령어를 실행할 수 있다.

;(세미콜론)을 사용하면 앞에 명령어의 결과와 상관없이 차례대로 명령어를 수행하기 때문에 세미콜론을 이용해서 문제를 해결하였다.

 

ping -c 3 "사용자 입력값" 에서 사용자 입력값을 변경한다.

payload : ping -c 3 "8.8.8.8"; ls ; echo ""

위의 payload를 이용하면 ping 명령어를 3번 수행하고 ls 명령어를 수행하고 echo 명령어를 수행한다. 여기에서 ls명령어로 현재 디렉터리에 어떤 파일들이 있는지 확인한다.

 

[그림 3] 오류 발생

요청한 형식과 일치 하지 않다고 해당 명령어가 수행되지 않고 있다.

페이지 소스보기를 통해 왜 오류가 발생하는지 살펴본다.

 

[그림 4] pattern 적용

페이지 소스보기를 한 결과 해당 input박스에는 pattern이 적용되어 있다. 숫자와 대소문자와 점으로 이루어져있어야하며 5~20글자 사이여야한다.

해당 패턴으로 메타문자 입력을 못하도록 보안조치가 되어있어서 command injection을 방어한다고 생각할 수 있지만, 이것은 클라이언트 쪽에서 필터링이 이루어져 있기 때문에 우회가 가능하다.

f12에서 pattern을 삭제하고 해당 payload를 입력하거나 burpsuite를 이용하여 우회가 가능하다.

 

[그림 5] ls 명령어 수행

필자는 burpsuite를 이용하였다.

host 매개 변수에 payload를 입력한 후 전송을하면 ls 명령어가 수행되는것을 볼 수 있다.

그 결과 flag.py 파일이 있음을 확인하였다.

 

[그림 6] flag.py 파일 읽기

해당 payload에서 ls를 cat flag.py로 변경하여 flag.py 파일을 읽도록 하였고 그 결과가 반환되었다.

 

Flag는 DH{pingpingppppppppping!!}이다.

반응형