Spookyctf 2024의 write-up이다.
문제에 제공되는 파일은 존재하지 않는다. 하지만 로그인 페이지가 존재하기에 SQL injection을 시도했다.
admin ' OR '1' == '1'
id에 해당 값을 넣고, password에 아무 값이나 넣어주었다.
"/creatures.php" 경로로 이동하며, 아래의 사진과 같이 flag를 획득할 수 있는 문제이다.
NICC{1N_PuRSu1T_0F_4LL13S}
해당 사이트에 들어가면 cryptid의 사진과 그에 따른 설명들이 나열해 있다.
밑으로 내리다 보면 URL을 입력하는 부분이 나온다.
@app.route('/flag')
def flag():
if request.remote_addr == '::ffff:127.0.0.1' or request.remote_addr == '::1':
return render_template('flag.html', FLAG=os.environ.get("FLAG"))
else:
return render_template('alarm.html'), 403
해당 코드를 보는 것과 같이 로컬일 때, flag를 획득할 수 있다.
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
url = request.form['url']
try:
result = verifyBlog(url) # 키워드 체크
if not result:
return render_template('index.html', error=f"Please submit a blog!")
except:
return render_template('index.html', error=f"Please submit a blog!")
r = requests.get(url)
return render_template('index.html', result=r.text)
return render_template('index.html')
위의 코드를 통해 URL을 검사하는 부분이 취약해서 SSRF가 터질 것이라고 가정했다.
def verifyBlog(url):
blog_list = ["blog","cryptid","real","666",".org"]
for word in blog_list:
if word not in url:
return False
return True
하지만 위와 같이 코드를 보면 blog_list의 리스트 값들이 URL에 들어가야 한다.
위의 조건을 모두 충족하는 URL을 만들어서 입력하여 flag를 획득할 수 있었다.
NICC{tHe_crYptIds_aRe_waIting_t0_sTrike}