這次是我第二次參考澳門人舉辦的 CTF 賽事,雖然小弟不才,能解到的題目不多,但題目難度相較去年感覺出有明顯的提昇,也表示澳門其實不論是舉辦方還是參加者,在技術和質量都有明顯進步。也說明了我再不努力就要跟不上了
這次的題目有不少都超出自己的知識範圍,尤其我不擅長的 PWN 一題都做不出來,不過同時能看到自己可以進步的地方,畢業後才後發現原來自己很享受獲取知識的這個過程。
Mics
take it II (100 points)
did you take it last year? ssh mocsctf@34.136.108.210 -p 30001 (password:mocsctf) author: RB916120
題目就是用 ssh 連線至遠端 server,連線後就會出現眼花繚亂的畫面
Solution
按照去年的套路,先嘗試按 Ctrl + D
去中止這個 process,可惜無效果
經過一番 Google 找到這篇文章,發現了 Ctrl + S
去可暫停 process,而 Ctrl + Z
可以把 process 放到背景去(這裡的效果是減少出現的字),反覆試了一番就會看到這樣的畫面:
由於我照著打了多次不正確,所以這題我是沒有分得的(手殘惹的禍)
後來 kit 給出了解題方法:
ssh mocsctf@34.136.108.210 -p 30001 | grep -oP 'MOCSCTF{.*?}'
等十秒後按 Ctrl + C
中止,可以把 ssh 連線後的字串變成 stdout 出來(也就是可以用複製貼上)
效果如下:
如果對 grep 和 正規表達式不熟,還有一個更簡單的方法:
ssh mocsctf@34.136.108.210 -p 30001 > output.txt
等十秒後按 Ctrl + C
中止,再找出 output.txt 裡含有 }
的字串。
location code (100 points)
where is the code? Author:bluebear
附件 : location_code.png
location_code.png
知識點 : Exif
題目相當有今年的澳門特色,今年在疫情情間我們出入公共場所都需要掃描場所二維碼。
如果單純掃描這個 QR Code,只會出現一行 this is location code 的一行字,沒有其他特別。當然這不也是真的場所二維碼,就算用澳門健康碼掃描也只會出現錯誤。
Solution 1
提示是 where is the code,我們知道一張圖裡,會含有一些資訊例如拍攝時間、圖片尺寸、副標題等 Metadata 訊息。
然後我找到這個網站,它很方便的幫助我們找出圖片的詳細訊息。
Solution 2
$ cat location_code.png | grep -aoP "MOCSCTF{.*?}"
MOCSCTF{stay_home_stay_safe_play_CTF}
倒轉地球 (120 points)
來吧 倒轉地球 噓~ http://34.136.108.210:30003 author: RB916120
知識點 : Burp Suite
打開網站後:
等待大約 5 秒後就會 redirect 到 youtube。
Solution
由於這題會重導向,所以利用了 Burp Suite 這個工具,去看一看 request 和 response。
這裡看到一個 css 文件 deead76a0b4ae11caa2945c9a9fe6709.css
放到網址路徑後方打開看看:
html {
display: flex;
height:100vh;
overflow: hidden;
justify-content: center;
align-items: center;
flex-direction:column;
background: rgb(80, 79, 79);
}
body::before{
font-weight: bold;
font-size: 55px;
color: #38df8b;
}
head {
display: block;
background-image: url(https://media.giphy.com/media/HT1l9RaUUcHQMYwWy9/giphy.gif);
height: 251px;
width:447px;
background-repeat: no-repeat;
background-size: cover;
border: 5px solid rgb(209, 149, 228);
border-radius: 10px;
border-style: dashed;
/* MOCSCTF{YoY0YoYo0ooO0_1nv151bl3_57yl3_5h337??} */
}
body::before {
display: inline-block;
padding-top: 3rem;
content: "來吧! 倒轉地球~";
}
flag 就藏在裡面。
Crypto
super secure algorithm (120 points)
sssssuper secure!!
author:RB916120
附件 : output.txt , ssa.py
output.txt
LjdžIJǂIJLJıƚƢŻŻŻŻǶŢŧƢƤƢƢƢƢǶǑŻƽǶŮǓżƢƘ
ssa.py
#!/bin/python3
def encrypt(flag):
f = lambda x : x^2 + 2*x + 233
return ''.join(chr(f(c)) for c in flag)
FLAG = open('./flag.txt', 'rb').read().strip()
enc = encrypt(FLAG)
print(enc)
Analysis
首先,花一點時間弄明白這個 ssa.py
運行原理,然後去驗證,譬如 flag 都是從 MOCSCTF{
開始的。
用第一個字母 M
去搞明白當中是如何變換 :
M
-> 77
-> 456
-> Lj
然後,弄明白之後,解答就是從上述過程的逆向過程,不過當中最困難就是解出 x^2 + 2*x + 233
這裡的 x。也就是從 456
回到 77
的步驟。
這一步我相信大神們有很多辦法,譬如 z3 求解器,可是小弟不才,這一步驟使用了暴力窮舉法,話雖如此,我還是把 x 值的窮舉範圍收窄在 ASCII 有效字母 33 ~ 126 之間
solution
#!/bin/python3
result = ""
c = open('./output.txt', 'r').read().strip()
for a in c:
y = ord(a)
for x in range(33,126):
if(x^2 + 2*x + 233 == y):
result += (chr(x))
print(result)
$ python3 solve.py
MOCSCTF{s0000_34syssss_f0r_7h1s}
Forensic
baby wireshark (100 points)
Baby shark, doo, doo, doo, doo, doo, doo. Author: bluebear
附件 : baby_wireshark.pcap
知識點: Wireshark
Solution
其實看到副檔名是 .pcap
就可以確定要用到 wiresharkf 這個知名的封包分析工具
對其中一個 TCP 的封包點右鍵 -> follow -> TCP Stream
翻幾頁就能看到 flag 了
Web
git me (100 points)
https://github.com/MOCSCTF/capture-the-flag Author: bluebear
知識點 : git & github
Solution
由於 git 具有文件回溯的功能,因此可以很好的隠藏已刪除的東西,而且這題還隠藏在分支底下:
face (100 points)
emoji (-_.-) http://34.136.219.163:31004 Author: BoardWare
Solution
這一題有幾個連續的線索去進行解題
1.查看原始碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Face</title>
</head>
<body>
<!--source.php-->
<br><h1>You can't find the flag!</h1><br><img src="asmallface.png" /></body>
</html>
獲得線索 source.php
2.查看 34.136.219.163:31004/source.php
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it!";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><h1>You can't find the flag!</h1><br><img src=\"abigface.png\" />";
}
?>
獲得線索 hint.php
3.查看 http://34.136.219.163:31004/hint.php
flag is not here, try to find it in ffflllaaaggg
獲得線索 ffflllaaaggg
4.查看 http://34.136.219.163:31004/ffflllaaaggg
flag is not here, try to find it in a big face
獲得線索是叫我們在 big face 裡面找,這裡開始本來有點卡住,但回頭看最一開始的原始碼,它的 emoji 圖名稱叫 asmallface.png
5.查看 34.136.219.163:31004/source.php 的原始碼
...略...
</code>
<br>
<h1>You can't find the flag!</h1>
<br>
<img src="abigface.png"/>
獲得線索 abigface.png,其實就是要把圖片下載下來,找找看這張圖裡有什麼古怪東西。
6. 用 binwalk 查看圖片
我下載
abigface.png
後的名稱叫index.png
binwalk index.png
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 PNG image, 640 x 640, 8-bit/color RGBA, non-interlaced
341 0x155 Zlib compressed data, best compression
90846 0x162DE Zip archive data, at least v2.0 to extract, compressed size: 91, uncompressed size: 167, name: flag
91057 0x163B1 End of Zip archive, footer length: 22
果然看到有東西藏在圖片裡,獲得線索 flag
7.用 binwalk 解壓並查看 flag
binwalk -e index.png
cd _index.png.extracted/
cat flag
4d 4f 43 53 43 54 46 7b 6e 76 63 78 37 65 77 6a 73 64 6b 6a 38 77 34 6a 64 73 38 39 65 77 6e 38 39 66 32 65 74 38 5f 54 68 61 6e 6b 73 5f 42 6f 61 72 64 57 61 72 65 7d
獲得線索,一串 16 進位的編碼
8.把 16 進位轉成 ASCII
獲得 flag
Reverse
string reverse (100 points)
reverse and reverse string… Author: bluebear
附件 : reverseStr.class
Analysis
一開始看到副檔名叫 .class
,發現無法直接閱讀,就先 google 一下 class decompiler online 網找到了一個線上網站 Java decompiler online,把檔案上傳並翻譯成能閱讀的 java 檔案
import java.io.PrintStream;
import java.util.Scanner;
class reverseStr
{
reverseStr()
{
}
public static void main(String args[])
{
reverseStr reversestr = new reverseStr();
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the flag: ");
String s = scanner.next();
String s1 = s.substring("MOCSCTF{".length(), s.length() - 1);
if(reversestr.checkFlag(s1))
System.out.print("Correct!");
else
System.out.print("Wrong!");
}
public boolean checkFlag(String s)
{
if(s.length() != 22)
return false;
StringBuilder stringbuilder = new StringBuilder();
String as[] = s.split("_");
for(int i = 0; i < 3; i++)
{
char ac[] = as[i].toCharArray();
for(int j = ac.length - 1; j >= 0; j--)
stringbuilder.append(ac[j]);
stringbuilder.append("_");
}
String s1 = stringbuilder.toString();
return s1.equals("Esr3v3R_eSReVer_9n1rt3_");
}
}
即使對 Java 不熟悉,但仔細閱讀也能看出個大概:
String as[] = s.split("_");
1.對字串以 _
來分割
for(int i = 0; i < 3; i++)
2.一共做 3 次
for(int j = ac.length - 1; j >= 0; j--)
stringbuilder.append(ac[j]);
3.字串從尾排到頭,也就是 reverse string
stringbuilder.append("_");
4.每排好一次,加上底線 _
return s1.equals("Esr3v3R_eSReVer_9n1rt3_");
5.做完上面的事情,回傳的字串剛好等於 Esr3v3R_eSReVer_9n1rt3_
Solution
Q.現在問一開始的字串是什麼樣子?
A.其實就是 3 段分別的 reverse
如果會用 java 去還原更佳
解前:Esr3v3R_eSReVer_9n1rt3_
解後:R3v3rsE_reVeRSe_3tr1n9
(記得最後的底線不用加)
構成 flag MOCSCTF{R3v3rsE_reVeRSe_3tr1n9}