본문 바로가기

Security

[Webhacking] path traversal

반응형

URL에서 해석되는 구분문자

/ Path identifier
.. Parent directory
* /tmp/test/../1234 => /tmp/1234
? Query identifier
* ? 뒤는 query로 해석
# Fragment identifier
* # 뒤의 값은 Server로 전달되지 않음
& Parameter separator
* key1=value&key2=value... 형식으로 사용

 

내부 API가 Path variable로 입력 데이터를 받는 형태로 구현되어 URL의 Path로 데이터가 입력되는 경우도 존재.

dream이라는 user의 정보를 가져오기 위해 

http://internal.dreamhack.io/api/user/dream

이렇게 입력이 들어가기도 함.

 

URL 구분문자 사용에 대한 필터링이나 인코딩이 없을 경우 ../ 과 같은 구분 문자를 통해 의도한 경로가 아닌 상위 경로에 접근해 다른 API를 호출할 수 있음.

 

URL은 인코딩을 통해 사용자의 입력 데이터에 포함된 구분 문자를 인식하지 않도록 할 수 있음.


External Server에서 사용자 입력 데이터를 받아 Internal Server로 URL Path variable 형식으로 전달하는 경우에서

guest의 level을 관리자로 만들기.

 

External

# https://external.dreamhack.io/
...
def api_get(url):
    return requests.get('https://internal.dreamhack.io/'+url).text
@app.route('/get_info', methods=['POST', 'GET'])
def get_info():
    result = ''
    if request.method == 'POST':
        username = request.form['username']
        result = api_get('/api/user/' + username)
    return render_template('get_info.html', result=result)

Internal

# https://internal.dreamhack.io/
...
@app.route('/')
def index(): return 'index page'
@app.route('/api/')
def api(): return route_info();
@app.route("/api/admin/make_admin/<str:username>")
def make_admin(username):
    users[username].level = 'admin'
    return username + '의 레벨을 관리자로 설정';
@app.route("/api/user/<str:username>")
def user(username):
    return json.dumps(users[username])

관리자로 만드는 api는 /api/admin/make_admin/"username"

input 창에 입력시에는 /api/user/"username" 으로 경로 이동됨.

따라서 api 하위에 있는 admin에 접근하기 위해 ../를 통해 상위 path로 이동

../admin/make_admin/guest 입력

 

반응형