# picoCTF2024 writeups JMGSH y1w3n ||有空打打而已沒啥分,後續也有空會補齊|| ![image](https://hackmd.io/_uploads/HkTppH3RT.png) ## Web Exploitation ### WebDecode #### 題目說明 ![image](https://hackmd.io/_uploads/HJmh07lRp.png) http://titan.picoctf.net:58480/ #### solve 進去進到about,按``F12``查看網頁原始碼 看到notify_true那邊有cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfMDdiOTFjNzl9 ![image](https://hackmd.io/_uploads/ByOQ1VlR6.png) from base64 ![image](https://hackmd.io/_uploads/S1lgOwl0p.png) #### answer ``picoCTF{web_succ3ssfully_d3c0ded_07b91c79}`` #### note ### Bookmarklet #### 題目說明 ![image](https://hackmd.io/_uploads/S1ZCOwg06.png) http://titan.picoctf.net:51073/ #### solve ![image](https://hackmd.io/_uploads/rJ1VKve0p.png) 點一下框框內的程式碼,結果他說程式已複製到剪貼簿 :::spoiler 程式 ```javascript= javascript:(function() { var encryptedFlag = "àÒÆÞ¦È¬ë٣֖ÓÚåÛÑ¢ÕӖәǡ”¥Ìí"; var key = "picoctf"; var decryptedFlag = ""; for (var i = 0; i < encryptedFlag.length; i++) { decryptedFlag += String.fromCharCode((encryptedFlag.charCodeAt(i) - key.charCodeAt(i % key.length) + 256) % 256); } alert(decryptedFlag); })(); ``` ::: :::success flag就是``àÒÆÞ¦È¬ë٣֖ÓÚåÛÑ¢ÕӖәǡ”¥Ì``加密後的內容 key是"picoctf" 反正直接執行程式 ::: ![image](https://hackmd.io/_uploads/Sk6_owxRp.png) [網站](https://jsfiddle.net/) #### answer ``picoCTF{p@g3_turn3r_0c0d211f}`` ### IntroToBurp #### 題目說明 ![image](https://hackmd.io/_uploads/SJNUcxbF1x.png) http://titan.picoctf.net:50233/ #### slove > tools: Burp Suite ![image](https://hackmd.io/_uploads/rJNAeMbKkx.png) 隨便輸入點東西後按Register,然後burpsuite 中按forward 把資料送出去 ![image](https://hackmd.io/_uploads/SJ0OZG-Ykx.png) 發現之後是要輸入OTP (一次性密碼) 隨邊輸入點東西(我這裡都是輸入'a') 後按Submit,同樣在burpsuite 中按forward 把資料送出去 ![image](https://hackmd.io/_uploads/BkMZfzbtyg.png) 出現Invalid OTP,由此可見這題是要bypass OTP ![image](https://hackmd.io/_uploads/B17wQzbKyg.png) 回到上一個步驟,看到當我forward 之前第16行有```otp=a``` 把這行刪掉後forward出去 ![image](https://hackmd.io/_uploads/HJhBIGZFkl.png) #### answer ``picoCTF{#0TP_Bypvss_SuCc3$S_6bffad21}`` ## Cryptography ### interencdec #### 題目說明 ![image](https://hackmd.io/_uploads/HkGgq_gC6.png) * 一個文字檔:enc_flag ![image](https://hackmd.io/_uploads/ryPt3PgR6.png) #### solve * 看到兩個'=' : base64特徵 ![image](https://hackmd.io/_uploads/rkDE6wgAa.png) * 得到的結果再base64一次(去掉b前綴) ![image](https://hackmd.io/_uploads/rytcTvxAT.png) * 現在逐漸有flag的樣子了,但字母不對,所以用凱薩去解密,因為凱薩加密是字母位移的加密方式 ![image](https://hackmd.io/_uploads/Hk980Dl0p.png) 位移19得到flag ![image](https://hackmd.io/_uploads/Hkk5CDgRp.png) [網站](https://cryptii.com/) #### answer ``picoCTF{caesar_d3cr9pt3d_f0212758}`` ## Reverse Engineering ### WinAntiDbg0x100 #### 題目說明 ![image](https://hackmd.io/_uploads/rJdz9CkTC.png) >hint: Hints will be displayed to the Debug console. Good luck! ![image](https://hackmd.io/_uploads/rJEDoDA3A.png) * 執行下來發現他叫我using a debugger #### slove * 進到IDA中看看哪裡會輸出flag * 發現這裡是判斷會不會輸出flag的地方 ![image](https://hackmd.io/_uploads/Byo4WIyaA.png) * 在``` jz short loc_C6161B```設中斷點 * 使用Debugger功能執行 * 會發現直接執行後輸出: ![image](https://hackmd.io/_uploads/HJBoArJaC.png) * 也就是說沒嘗試bypass不會跳到輸出flag的地方 * 回去看看上面跳轉的條件 ![image](https://hackmd.io/_uploads/HJEByLJpA.png) * ```call ds:IsDebuggerPresent```: 偵測有沒有debugger存在,沒有的話就return 0 * ```test eax, eax```: 概念和AND eax,eax差不多,不一樣的是test不會改變eax。==現在我們有使用debugger所以值不為0== ![image](https://hackmd.io/_uploads/SJMWQ816C.png) * ```jz```: 如果為0則跳轉到輸出flag的地方 * 把eax值改成0 ![image](https://hackmd.io/_uploads/BkPPX8yaA.png) * 成功跳轉,得到答案 ![image](https://hackmd.io/_uploads/BkvbNLJa0.png) #### Answer ``picoCTF{d3bug_f0r_th3_Win_0x100_cc0ff664}`` ### WinAntiDbg0x200 #### 題目說明 ![image](https://hackmd.io/_uploads/BkByIIJpR.png) > hints: Hints will be displayed to the Debug console. Good luck! * 使用管理員權限執行 ![image](https://hackmd.io/_uploads/HkecsU1pR.png) * 跟前一題一樣要用debugger #### slove * 一開始有先判斷是否為管理員權限執行 ![image](https://hackmd.io/_uploads/By04Vak60.png) * 先看看哪裡的執行步驟會前往不輸出flag的路線 ![image](https://hackmd.io/_uploads/rJ6oVp1pA.png) * ```test edx, edx```:測試 edx 是否為零 * ```jnz short loc_F11832```:如果結果為==非零==,則跳轉到```loc_F11832``` * ```loc_F11832```: 輸出### Oops! The debugger was detected. Try to bypass * ==現在edx為1,1!=0,會前往```loc_F11832```輸出錯誤== ![image](https://hackmd.io/_uploads/HykCvaya0.png) * 修改其值,成功前往下一步 ![image](https://hackmd.io/_uploads/r1hSuaJTA.png) * 繼續往下看發現還有檢查是否在Debugger執行 ![image](https://hackmd.io/_uploads/H1hTupk60.png) * ```call ds:IsDebuggerPresent```: 回傳值0(如果沒有Debugger)或 1(如果有Debugger) * 現在eax值為1 * ``jz short loc_F11847``: 如果為0則跳轉到輸出flag的地方 * 跟前一題一樣,修改eax暫存器值 ![image](https://hackmd.io/_uploads/ByZ-ZAka0.png) * 得到答案 ![image](https://hackmd.io/_uploads/SyQBbCkpA.png) #### Answer ``picoCTF{0x200_debug_f0r_Win_c6db2768}`` ## Forensics ### Scan Surprise #### 題目說明 給一個壓縮過的challenge.zip裡面有一個QRcode的圖 或者ssh也是得到一樣的東西 ![image](https://hackmd.io/_uploads/HJ2Lgue0a.png) ![image](https://hackmd.io/_uploads/BJDjlOxAa.png) #### solve 用它給的圖上網找QRcode掃描器去看,得到flag ![image](https://hackmd.io/_uploads/Sysk-_eAT.png) #### answer ``picoCTF{p33k_@_b00_0194a007}`` ### CanYouSee #### 題目說明 ![image](https://hackmd.io/_uploads/H1eO5dz06.png) 題目給了一張圖片: ukn_reality ![image](https://hackmd.io/_uploads/HJyc2_f0a.png) #### solve 使用``nano``文字編輯器打開看圖片詳細的內容 ![image](https://hackmd.io/_uploads/ByvzTdM0p.png) 看到裡面長這樣: ![image](https://hackmd.io/_uploads/S1J8pOMR6.png) 有一串base64的內容,拿去解碼 ![image](https://hackmd.io/_uploads/BkGqadMC6.png) 得到flag #### answer ``picoCTF{ME74D47A_HIDD3N_b32040b8}`` ### Secret of the Polyglot #### 題目說明 ![image](https://hackmd.io/_uploads/BJBDX1I0a.png) 給一個pdf檔: flag2of2-final.pdf ![image](https://hackmd.io/_uploads/r10p71LC6.png) 只有一半的flag #### solve * ``nano flag2of2-final.pdf`` : 用文字編輯器打開 ![image](https://hackmd.io/_uploads/S1784JIAT.png) 看到它其實是個PNG檔 * 把副檔名改成.png * 得到前半段的flag ![image](https://hackmd.io/_uploads/ryyXSy8Ap.png) * 合併兩段 #### answer ``picoCTF{f1u3n7_1n_pn9_&_pdf_724b1287}`` ## General Skills ### Super SSH #### 題目說明 ![image](https://hackmd.io/_uploads/BJX3Oul06.png) #### solve 照題目說的做就得到flag了 ![image](https://hackmd.io/_uploads/H1XMtugRp.png) #### answer ``picoCTF{s3cur3_c0nn3ct10n_07a987ac}`` #### note * 輸入密碼的時候它不會顯示出來你打什麼 ### Time Machine #### 題目說明 ![image](https://hackmd.io/_uploads/B1TX1ogCp.png) * challenge * message.txt #### solve * ``git log`` : 查看提交歷史 ![image](https://hackmd.io/_uploads/SkPtyigCT.png) 得到flag #### answer ``picoCTF{t1m3m@ch1n3_8defe16a}`` #### note ### Commitment Issues #### 題目說明 ![image](https://hackmd.io/_uploads/H1ksG_lCT.png) * 一個壓縮的資料夾: challenge.zip #### solve 他說他刪掉了flag所以我用``git log``查看提交歷史 ![image](https://hackmd.io/_uploads/BywIrue0a.png) 看到``picoCTF <ops@picoctf.com>``他在3/12創建了flag後又刪掉了 因此用``git show``,顯示指定提交的詳細訊息 ![image](https://hackmd.io/_uploads/B1XaI_e0a.png) #### answer ``picoCTF{s@n1t1z3_cf09a485}`` #### note * ``git``: 版本控制 [常用指令](https://hellojs-tw.github.io/git-101/cheat-sheet.html) ### Verify #### 題目說明 ![image](https://hackmd.io/_uploads/SJlA4ceCa.png) * challenge * files(資料夾,裡面放了一堆要比對的文件) * decrypt. sh * checksum.txt ![image](https://hackmd.io/_uploads/HyIlI9gC6.png) #### solve 要找到跟checksum.txt裡面hash值一樣的檔案 * 使用``sha256sum files/* | grep 3ad37ed6c5ab81d31e4c94ae611e0adf2e9e3e6bee55804ebc7f386283e366a4 3ad37ed6c5ab81d31e4c94ae611e0adf2e9e3e6bee55804ebc7f386283e366a4 files/e018b574 `` ![image](https://hackmd.io/_uploads/SyR2w5lAp.png) 看到files裡e018b574的文件符合條件 接著用它給的decrypt. sh解密 ![image](https://hackmd.io/_uploads/H1MlOcg0T.png) #### answer ``picoCTF{trust_but_verify_e018b574}`` #### note * ``sha256sum`` : 驗證文件 1. 計算文件的校驗和 2. 跟預期值做比較 * ``file/*`` : file資料夾中所有檔案 ### Blame Game #### 題目說明 ![image](https://hackmd.io/_uploads/ry2ylqgAp.png) 給一個壓縮過的challenge.zip裡面有一個message. py #### solve * ``git blame <file>`` : 顯示檔案的每一行是在哪個提交中被修改的,並顯示修改者的資訊 ![image](https://hackmd.io/_uploads/BkUdW9lAp.png) 得到flag #### answer ``picoCTF{@sk_th3_1nt3rn_cfca95b2}`` ### Collaborative Development #### 題目說明 ![image](https://hackmd.io/_uploads/BkGrJsVR6.png) 給了一個flag. py ,裡面只有一行:``print("Printing the flag...")``就沒了 ![image](https://hackmd.io/_uploads/rkZe_mHCT.png) #### solve * ``git branch -a``:看可用的分支 ![image](https://hackmd.io/_uploads/BylEd7rAT.png) 看到我現在在``main``,然後還有``feature/part-1``、``feature/part-2``、``feature/part-3``這幾個分支 * ``git merge feature/part-1`` ![image](https://hackmd.io/_uploads/rkq0ZNrCp.png) flag.py中有未提交的更改,而合併操作會覆蓋這些更改。 * 如何解決? * ``git checkout -- flag.py`` : 撤銷修改 * 然後再執行一次``git merge feature/part-1``就好了,現在flag.py長這樣: ![image](https://hackmd.io/_uploads/SJ4qmVrCa.png) * ``git merge feature/part-2`` ![image](https://hackmd.io/_uploads/BkZVU4SR6.png) 無法確定身份資訊(作者和提交者) * 如何解決? * 登入就好www(直接拿人家的XD) ![image](https://hackmd.io/_uploads/By6aU4rRa.png) * 然後再執行一次``git merge feature/part-2``就好了,現在flag.py長這樣: ![image](https://hackmd.io/_uploads/ByDQPVBRa.png) * ``git merge feature/part-3`` ![image](https://hackmd.io/_uploads/r1cnv4SR6.png) 嘗試合併feature/part-3分支時發生了衝突,導致合併無法進行 * 如何解決? * 打開flag. py,看到衝突標記,``<<<<<<< HEAD``、``=======``和``>>>>>>> feature/part-2``表示目前分支(main分支)和要合併的分支(feature/part-2分支)之間有衝突 ![image](https://hackmd.io/_uploads/Skrzi4S0T.png) * 手動把衝突標記刪掉 ![image](https://hackmd.io/_uploads/r1KKiESRa.png) * ``git add flag.py`` : 提交 * ``git merge --continue`` : 繼續 * 再執行一次``git merge feature/part-3``就好了,現在flag.py長這樣: ![image](https://hackmd.io/_uploads/Bkiz3NBRT.png) * 已經有flag了但如果想做到完美就把這邊的合併衝突也手動解決掉 ![image](https://hackmd.io/_uploads/Bylxc3EHRT.png) * 執行 ![image](https://hackmd.io/_uploads/rJlCnESC6.png) #### answer ``picoCTF{t3@mw0rk_m@k3s_th3_dr3@m_w0rk_7ae8dd33}`` #### note 分支是獨立的。使得團隊成員能夠在不互相干擾的情況下並行開發和合作。 ### binhexa #### 題目說明 ![image](https://hackmd.io/_uploads/rybcGxMCa.png) 進去之後長這樣 ![image](https://hackmd.io/_uploads/rJtIBgfRT.png) 就是它給了兩個二進制數字接著出題要我們答,共六題,我無聊玩了三次,每次出題那兩個數字是隨機的 #### solve * Question 1/6: * ">> 1" 右循環1 bits: 把每個右移1 bits,最後一個補到最前面 ![image](https://hackmd.io/_uploads/HyiOBeMCT.png) * Question 2/6: * '+'加法運算 ![image](https://hackmd.io/_uploads/B1cZUxMC6.png) * Question 3/6: * '*' 乘法運算 ![image](https://hackmd.io/_uploads/S14BLlMCp.png) * Question 4/6: * "<< 1" 左循環1 bits: 把每個左移1 bits,第一個捕到最後面 ![image](https://hackmd.io/_uploads/HyfOIez0p.png) * Question 5/6: * AND運算: 2個都是1才會輸出1 ![image](https://hackmd.io/_uploads/SkJUvlfR6.png) * Question 6/6: * OR運算: 其中一個是1結果就是1 ![image](https://hackmd.io/_uploads/BJSpPgfA6.png) * 最後要我給最後一題答案的16進制 * 11111111 -> ff ![image](https://hackmd.io/_uploads/By3PuxGAa.png) 最後得到flag #### answer ``picoCTF{b1tw^3se_0p3eR@tI0n_su33essFuL_d9a7ddd2}`` #### note [運算式運算子概念](https://ithelp.ithome.com.tw/articles/10214404) [二進制計算機](https://miniwebtool.com/zh-tw/binary-calculator/?number1=01110111&operate=3&number2=10011110) [進制轉換網站](https://www.kwuntung.net/hkunit/base/base.php) ### Binary Search #### 題目說明 ![image](https://hackmd.io/_uploads/H1PiwuG0p.png) ![image](https://hackmd.io/_uploads/Sy_4_OMC6.png) 一個終極密碼的遊戲,有10次機會給你猜,答案的數字是隨機的 #### solve :::success 使用二分搜尋法即可解題 猜的數字=(最小範圍+最大範圍)/2,我的話小數4捨5入 ::: ![image](https://hackmd.io/_uploads/HyHPFdG0a.png) #### answer ``picoCTF{g00d_gu355_2e90d29b}`` ## Binary Exploitation ### heap 0 #### 題目說明 ![image](https://hackmd.io/_uploads/HySeqmxRa.png) * linux 執行檔 : chall * 跟它的原始檔 : chall.c #### solve 先看chall.c ::: spoiler chall.c ```gcc= #include <stdio.h> #include <stdlib.h> #include <string.h> #define FLAGSIZE_MAX 64 // amount of memory allocated for input_data #define INPUT_DATA_SIZE 5 // amount of memory allocated for safe_var #define SAFE_VAR_SIZE 5 int num_allocs; char *safe_var; char *input_data; void check_win() { if (strcmp(safe_var, "bico") != 0) { printf("\nYOU WIN\n"); // Print flag char buf[FLAGSIZE_MAX]; FILE *fd = fopen("flag.txt", "r"); fgets(buf, FLAGSIZE_MAX, fd); printf("%s\n", buf); fflush(stdout); exit(0); } else { printf("Looks like everything is still secure!\n"); printf("\nNo flage for you :(\n"); fflush(stdout); } } void print_menu() { printf("\n1. Print Heap:\t\t(print the current state of the heap)" "\n2. Write to buffer:\t(write to your own personal block of data " "on the heap)" "\n3. Print safe_var:\t(I'll even let you look at my variable on " "the heap, " "I'm confident it can't be modified)" "\n4. Print Flag:\t\t(Try to print the flag, good luck)" "\n5. Exit\n\nEnter your choice: "); fflush(stdout); } void init() { printf("\nWelcome to heap0!\n"); printf( "I put my data on the heap so it should be safe from any tampering.\n"); printf("Since my data isn't on the stack I'll even let you write whatever " "info you want to the heap, I already took care of using malloc for " "you.\n\n"); fflush(stdout); input_data = malloc(INPUT_DATA_SIZE); strncpy(input_data, "pico", INPUT_DATA_SIZE); safe_var = malloc(SAFE_VAR_SIZE); strncpy(safe_var, "bico", SAFE_VAR_SIZE); } void write_buffer() { printf("Data for buffer: "); fflush(stdout); scanf("%s", input_data); } void print_heap() { printf("Heap State:\n"); printf("+-------------+----------------+\n"); printf("[*] Address -> Heap Data \n"); printf("+-------------+----------------+\n"); printf("[*] %p -> %s\n", input_data, input_data); printf("+-------------+----------------+\n"); printf("[*] %p -> %s\n", safe_var, safe_var); printf("+-------------+----------------+\n"); fflush(stdout); } int main(void) { // Setup init(); print_heap(); int choice; while (1) { print_menu(); int rval = scanf("%d", &choice); if (rval == EOF){ exit(0); } if (rval != 1) { //printf("Invalid input. Please enter a valid choice.\n"); //fflush(stdout); // Clear input buffer //while (getchar() != '\n'); //continue; exit(0); } switch (choice) { case 1: // print heap print_heap(); break; case 2: write_buffer(); break; case 3: // print safe_var printf("\n\nTake a look at my variable: safe_var = %s\n\n", safe_var); fflush(stdout); break; case 4: // Check for win condition check_win(); break; case 5: // exit return 0; default: printf("Invalid choice\n"); fflush(stdout); } } } ``` ::: * ``input_data``和``safe_var``的記憶體分配都是5字節,因此溢出時的空間有限。 * 程式使用了strncpy來防止緩衝區溢出,但strncpy在沒有添加null 終止符的情況下可能導致字串不完整。 * 在選單中選擇4(Print Flag)將觸發``check_win``函數,該函數透過比較``safe_var``和 "bico" 來決定是否輸出flag :::success buffer overflow 得到 flag,需要輸入超過5個字元的內容,覆蓋到safe_var記憶體區域,讓它的內容不再是"bico"。最後選4(Print Flag)進入check_win函數並輸出flag.txt ::: * 執行 ![image](https://hackmd.io/_uploads/BkUVhXgR6.png) #### answer ``picoCTF{my_first_heap_overflow_c3935a08}``