아래는 서버 코드이다.
import os, subprocess
from functools import wraps
from flask import Flask, request
app = Flask(__name__)
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 Denined !'
return wrapped_view
@app.route('/', methods=['GET'])
def index():
return 'API Index'
@app.route('/file', methods=['GET'])
def file():
path = request.args.get('path', None)
if path:
data = open('./files/' + path).read()
return data
return 'Error !'
@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 !'
if __name__ == '__main__':
app.run(host='0.0.0.0')
코드를 보면
1./file 페이지에서는 파일을 읽어서 보여준다 파일 다운로드 취약점이 있는 것이다.
2./admin 페이지에서는 cmd를 get으로 받아서 실행시켜준다 하지만 API-KEY를 요구한다.
내가 해야할 것은
/file페이지에서 시스템의 메인 디렉토리를 찾은 후 그 곳에서 환경변수 설정파일에 들어갈 것이다.
API-KEY는 보통 환경변수파일에 있다고 하기 때문이다.
그 후 얻은 API-KEY로 /admin에서 cmd와 같이 get요청을 보낸다.
flag는 파일 형태이므로 실행시켜야 하기 때문에 cmd에 /flag를 입력하면 될 것이다.
먼저 아래를 보자.
/etc/passwd를 앞에 ../를 입력해보며 어디가 메인 디렉토리인지 찾아냈다.
../../ 로 가면된다.
그 후 아래처럼 환경변수 파일로 들어가준다.
그 곳에서는 API-KEY를 찾을 수 있었다.
이제 아래와 같이 admin에서 param에 API-KEY와 cmd요청으로 flag 파일을 열어달라고 요청하면
아래처럼 flag를 얻을 수 있다.