http://ctf.b01lers.com:5115/aW5kZXguaHRtbA==
첫 화면입니다.
URL 주소로 인코딩된 것 같습니다.
디코딩하자.
index.html이라고 한다.
아직 무슨 힌트인지 모르겠다.
개발자 도구를 사용하도록 설정합니다.
debug.html이 보입니다.
방금 index.html이 인코딩된 상태에서 url에 들어갔으니 마찬가지로 debug.html을 인코딩하고 넣자.
debug.html을 인코딩하여 넣은 것이다.
이번에는 app.py가 보입니다.
마찬가지로 인코딩하고 넣자.
결과다.
from base64 import b64decode
import flask
app = flask.Flask(__name__)
@app.route('/')
def index2(name):
name = b64decode(name)
if (validate(name)):
return "This file is blocked!
"
try: file = open(name, 'r').read()
except:
return "File Not Found"
return file
@app.route('/')
def index():
return flask.redirect('/aW5kZXguaHRtbA==')
def validate(data):
if data == b'flag.txt':
return True
return False
if __name__ == '__main__':
app.run()
보기 쉽게 들여쓰기한 결과다.
코드를 해석해 봅시다.
@app.route('/')
def index():
return flask.redirect('/aW5kZXguaHRtbA==')
파라미터를 받지 않는 index() 함수입니다.
index.html을 인코딩한 값을 넣고 다시 연결합니다.
이렇게 되면 어떻게 될까?
@app.route('/')
def index2(name):
name = b64decode(name)
if (validate(name)):
return "This file is blocked!
"
try: file = open(name, 'r').read()
except:
return "File Not Found"
return file
index2 함수는 name이라는 변수를 받습니다.
이 이름 변수를 디코드합니다.
이 디코딩된 이름 변수를 validate라는 함수에 넣습니다.
이 함수가 무엇인지 살펴 보겠습니다.
def validate(data):
if data == b'flag.txt':
return True
return False
아까 입력한 name 변수를 data 로 받는 모습이다.
이 data 가 flag.txt 또는 바이너리로 비교하고 있다.
@app.route('/')
def index2(name):
name = b64decode(name)
if (validate(name)):
return "This file is blocked!
"
try: file = open(name, 'r').read()
except:
return "File Not Found"
return file
다시 돌아왔다.
validate() 함수가 참이면 어떻게 됩니까? “This file is blocked!
”라는 단어가 반환됩니다.
false인 경우 name 변수의 값과 이름이 같은 파일을 열고 file 변수에 넣습니다.
파일이 아닌 경우 이를 반환합니다.
종합하려면 name은 flag.txt라는 이름을 가져야 합니다.
그러나 이것은 validate 함수가 flag.txt를 필터링합니다.
이것을 어떻게 우회해야합니까?
디렉토리 트레버셜 공격을 아십니까?
상대 경로로 ../../../로 이동하여 원하는 파일에 침투하는 공격이다.
이것을 활용하면 이 문제를 해결할 수 있다.
./flag.txt를 사용하면 flag.txt와 다르지만 flag.txt를 가져올 수 있습니다.
./flag.txt를 인코딩하고 url에 넣으십시오.
차잔