[Web Hacking] DH Command-Injection-1

KyungH·2024년 3월 10일

Web Hacking War Game

목록 보기
10/17
post-thumbnail

📝Problem - Command-Injection-1

이 문제는 서버 내부에 있는 flag.py 파일 내의 FLAG를 획득하는 것이다. /ping 페이지에서는 시스템 명령어를 통해 특정 Host에 ping 패킷을 보내는 기능을 제공하고 있다.


📌Approach

@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 저장한다. 추가로 오류가 발생할 경우 오류 메세지와 함께 템플릿을 렌더링하여 반환한다.

cmd 변수는 사용자로부터 입력받은 host 값을 포함하며, 사용자의 입력을 그대로 명령어로 실행하기 때문에, 사용자가 악의적인 공격 코드를 주입할 수 있다.


📌Solution

공격 코드를 작성하기 전,
메타문자를 사용함에 있어서 입력 형식에 대한 조건이 있어 입력할 수 없다.

개발자 도구를 통해 확인해보면, input 태그의 pattern 속성이 설정되어 있음을 확인할 수 있다. pattern 속성이란 폼 제출 시 <input> 요소의 값을 검사할 때 사용될 정규 표현식을 명시하며, 허용된 정규 표현식은 영어, 숫자, ".", 글자 수 5~20자 이다.

위 검증은 서버 단에서 일어나는 검증이 아닌, 클라이언트 단에서 검증이 일어나기 때문에 필터링 우회가 가능하다. pattern 속성을 제거하여 허용된 정규표현식에 대한 조건을 우회할 수 있다.

이제 FLAG 획득을 위한 공격 코드를 삽입할 수 있다.
FLAG는 flag.py에 있으며 먼저 ls 명령어를 통해 현재 디렉터리에 존재하는 파일 리스트를 확인해본다.

입력은 ping 명령어로 시작하므로 8.8.8.8" 을 입력하여 첫 번째 문자열을 탈출하고, 메타문자 ;를 통해 다음 명령어인 ls를 실행하며, 두 번째 문자열 탈출을 위해 뒷부분은 #을 통해 주석처리 해준다.

flag.py가 현재 디렉터리에 존재하는 것을 확인할 수 있으므로, cat 명령어를 사용하여 flag.py를 읽으면 플래그를 다음과 획득할 수 있다.


References

DreamHack 강의 - Exercise: Command Injection

0개의 댓글