🖐️ 문제 🖐️
리눅스 명령어를 실행하는 웹 서비스가 작동하고 있습니다.
해당 웹 서비스의 코드가 첨부파일로 주어집니다.
flag.txt 파일을 찾아 출력하여 플래그를 획득하세요!
플래그 형식은 DH{...} 입니다.
baby-linux
Description 리눅스 명령어를 실행하는 웹 서비스가 작동하고 있습니다. 해당 웹 서비스의 코드가 첨부파일로 주어집니다. flag.txt 파일을 찾아 출력하여 플래그를 획득하세요! 플래그 형식은 DH{...}
dreamhack.io
☀️해결☀️
웹 해킹 문제 서버를 열어서 들어가면 해당 페이지가 나오는데 명령어를 작성하면 이어지는 것 같지는 않았다. cd 명령어를 쳐서 이동한다던가 이런게 불가능한 것 같다.

ls 명령어를 통해 존재하는 파일 및 디렉토리 목록을 확인해보니 다음과 같았다.

먼저 딱봐도 힌트가 들어있을 것 같은 hint.txt 파일을 확인해주었다. 그러자, flag의 위치가 나왔다

cat 명령어를 통해 해당 경로 아래에 있는 flag.txt 파일의 내용을 확인해보려고 하자 No!가 나왔다.
cat ./dream/hack/hello/flag.txt
이제는 첨부된 app.py 파일을 읽어봐야할 것 같은데
#!/usr/bin/env python3
import subprocess
from flask import Flask, request, render_template
APP = Flask(__name__)
@APP.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
user_input = request.form.get('user_input')
cmd = f'echo $({user_input})'
if 'flag' in cmd:
return render_template('index.html', result='No!')
try:
output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
return render_template('index.html', result=output.decode('utf-8'))
except subprocess.TimeoutExpired:
return render_template('index.html', result='Timeout')
except subprocess.CalledProcessError:
return render_template('index.html', result='Error')
return render_template('index.html')
if __name__ == '__main__':
APP.run(host='0.0.0.0', port=8000)
사실 파이썬 공부한지 엄청 오래되어서 다 까먹었다.. 하나 하나 뜯어보면
1. Shebang 및 라이브러리 임포트
python#!/usr/bin/env python3
import subprocess
from flask import Flask, request, render_template
외부 프로그램을 실행하고 그 결과를 얻기 위해 subprocess 모듈을 임포트하고 프레임워크에서 필요한 클래스를 임포트한다. Flask는 애플리케이션 객체를 생성하고, request는 클라이언트의 HTTP 요청을 처리하며, render_template는 HTML 템플릿을 렌더링하는 데 사용된다.
2. Flask 애플리케이션 객체 생성
pythonAPP = Flask(__name__)
APP: Flask 애플리케이션 객체를 생성한다. __name__은 현재 모듈의 이름을 나타내며, Flask가 애플리케이션의 위치를 찾는 데 사용된다
3. 라우트 정의
python@APP.route('/', methods=['GET', 'POST'])
def index():
@APP.route('/'): 루트 URL(예: http://localhost:8000/)에 대한 요청을 처리하는 함수를 정의한다.methods=['GET', 'POST']: 이 경로가 GET 및 POST 요청을 모두 처리할 수 있도록 설정한다
4. 요청 처리
pythonif request.method == 'POST':
user_input = request.form.get('user_input')
POST 요청이 들어오면, 사용자가 입력한 데이터를 user_input 변수에 저장한다. 이 데이터는 HTML 폼에서 전송된 값이다
5. 명령어 생성 및 검증
pythoncmd = f'echo $({user_input})'
if 'flag' in cmd:
return render_template('index.html', result='No!')
echo $() 구문은 입력된 내용을 쉘에서 실행하여 결과를 출력하려는 의도이다. 만약 사용자가 입력한 내용에 'flag'라는 단어가 포함되어 있다면, 보안상의 이유로 실행을 중단하고 'No!'라는 메시지를 표시한다
6. 명령어 실행 및 결과 처리
pythontry:
output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
return render_template('index.html', result=output.decode('utf-8'))
주어진 명령어를 실행하고 그 결과를 output 변수에 저장한다. 여기서는 /bin/sh -c를 사용하여 쉘 명령어를 실행한다. 명령어 실행이 5초 이상 걸리면 TimeoutExpired 예외가 발생하고 명령어 실행 후 결과는 UTF-8로 디코딩하여 HTML 템플릿에 전달한다.
7. 예외 처리
pythonexcept subprocess.TimeoutExpired:
return render_template('index.html', result='Timeout')
except subprocess.CalledProcessError:
return render_template('index.html', result='Error')
명령어 실행이 시간 초과되었을 경우 'Timeout' 메시지를 표시한다. 실행 중 오류가 발생했을 경우 'Error' 메시지를 표시한다.
8. 기본 GET 요청 처리
pythonreturn render_template('index.html')
GET 요청이 들어오면 기본 HTML 템플릿인 index.html을 렌더링한다
9. 애플리케이션 실행
pythonif __name__ == '__main__':
APP.run(host='0.0.0.0', port=8000)
이 코드 블록은 스크립트가 직접 실행될 때 Flask 애플리케이션을 시작한다. host='0.0.0.0'는 모든 네트워크 인터페이스에서 접근할 수 있도록 하고, port=8000은 애플리케이션이 8000번 포트에서 실행되도록 설정한다
참고한 부분!
cmd에 'flag'가 존재하는 경우 "No!"가 출력되도록 필터링이 되어 있는 것을 확인할 수 잇다. 정규 표현식을 이용하여 이를 우회해보자. 정규 표현식에서 *는 앞의 문자들이 0번 또는 그 이상 반복된다는 것을 의미한다. 따라서 다음과 같은 명령어를 이용하여 필터링을 우회해본다
cat ./dream/hack/hello/fl*g.txt

'WriteUp > DreamHeack Wargame' 카테고리의 다른 글
| [Beginner] file-download-1 (0) | 2024.08.29 |
|---|---|
| [Beginner] Cookie (0) | 2024.08.29 |
| [Beginner] 64se64 (0) | 2024.08.28 |