# picoCTF2024 writeups
JMGSH y1w3n
||有空打打而已沒啥分,後續也有空會補齊||

## Web Exploitation
### WebDecode
#### 題目說明

http://titan.picoctf.net:58480/
#### solve
進去進到about,按``F12``查看網頁原始碼
看到notify_true那邊有cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfMDdiOTFjNzl9

from base64

#### answer
``picoCTF{web_succ3ssfully_d3c0ded_07b91c79}``
#### note
### Bookmarklet
#### 題目說明

http://titan.picoctf.net:51073/
#### solve

點一下框框內的程式碼,結果他說程式已複製到剪貼簿
:::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"
反正直接執行程式
:::

[網站](https://jsfiddle.net/)
#### answer
``picoCTF{p@g3_turn3r_0c0d211f}``
### IntroToBurp
#### 題目說明

http://titan.picoctf.net:50233/
#### slove
> tools: Burp Suite

隨便輸入點東西後按Register,然後burpsuite 中按forward 把資料送出去

發現之後是要輸入OTP (一次性密碼)
隨邊輸入點東西(我這裡都是輸入'a') 後按Submit,同樣在burpsuite 中按forward 把資料送出去

出現Invalid OTP,由此可見這題是要bypass OTP

回到上一個步驟,看到當我forward 之前第16行有```otp=a```
把這行刪掉後forward出去

#### answer
``picoCTF{#0TP_Bypvss_SuCc3$S_6bffad21}``
## Cryptography
### interencdec
#### 題目說明

* 一個文字檔:enc_flag

#### solve
* 看到兩個'=' : base64特徵

* 得到的結果再base64一次(去掉b前綴)

* 現在逐漸有flag的樣子了,但字母不對,所以用凱薩去解密,因為凱薩加密是字母位移的加密方式

位移19得到flag

[網站](https://cryptii.com/)
#### answer
``picoCTF{caesar_d3cr9pt3d_f0212758}``
## Reverse Engineering
### WinAntiDbg0x100
#### 題目說明

>hint: Hints will be displayed to the Debug console. Good luck!

* 執行下來發現他叫我using a debugger
#### slove
* 進到IDA中看看哪裡會輸出flag
* 發現這裡是判斷會不會輸出flag的地方

* 在``` jz short loc_C6161B```設中斷點
* 使用Debugger功能執行
* 會發現直接執行後輸出:

* 也就是說沒嘗試bypass不會跳到輸出flag的地方
* 回去看看上面跳轉的條件

* ```call ds:IsDebuggerPresent```: 偵測有沒有debugger存在,沒有的話就return 0
* ```test eax, eax```: 概念和AND eax,eax差不多,不一樣的是test不會改變eax。==現在我們有使用debugger所以值不為0==

* ```jz```: 如果為0則跳轉到輸出flag的地方
* 把eax值改成0

* 成功跳轉,得到答案

#### Answer
``picoCTF{d3bug_f0r_th3_Win_0x100_cc0ff664}``
### WinAntiDbg0x200
#### 題目說明

> hints: Hints will be displayed to the Debug console. Good luck!
* 使用管理員權限執行

* 跟前一題一樣要用debugger
#### slove
* 一開始有先判斷是否為管理員權限執行

* 先看看哪裡的執行步驟會前往不輸出flag的路線

* ```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```輸出錯誤==

* 修改其值,成功前往下一步

* 繼續往下看發現還有檢查是否在Debugger執行

* ```call ds:IsDebuggerPresent```: 回傳值0(如果沒有Debugger)或 1(如果有Debugger)
* 現在eax值為1
* ``jz short loc_F11847``: 如果為0則跳轉到輸出flag的地方
* 跟前一題一樣,修改eax暫存器值

* 得到答案

#### Answer
``picoCTF{0x200_debug_f0r_Win_c6db2768}``
## Forensics
### Scan Surprise
#### 題目說明
給一個壓縮過的challenge.zip裡面有一個QRcode的圖
或者ssh也是得到一樣的東西


#### solve
用它給的圖上網找QRcode掃描器去看,得到flag

#### answer
``picoCTF{p33k_@_b00_0194a007}``
### CanYouSee
#### 題目說明

題目給了一張圖片: ukn_reality

#### solve
使用``nano``文字編輯器打開看圖片詳細的內容

看到裡面長這樣:

有一串base64的內容,拿去解碼

得到flag
#### answer
``picoCTF{ME74D47A_HIDD3N_b32040b8}``
### Secret of the Polyglot
#### 題目說明

給一個pdf檔: flag2of2-final.pdf

只有一半的flag
#### solve
* ``nano flag2of2-final.pdf`` : 用文字編輯器打開

看到它其實是個PNG檔
* 把副檔名改成.png
* 得到前半段的flag

* 合併兩段
#### answer
``picoCTF{f1u3n7_1n_pn9_&_pdf_724b1287}``
## General Skills
### Super SSH
#### 題目說明

#### solve
照題目說的做就得到flag了

#### answer
``picoCTF{s3cur3_c0nn3ct10n_07a987ac}``
#### note
* 輸入密碼的時候它不會顯示出來你打什麼
### Time Machine
#### 題目說明

* challenge
* message.txt
#### solve
* ``git log`` : 查看提交歷史

得到flag
#### answer
``picoCTF{t1m3m@ch1n3_8defe16a}``
#### note
### Commitment Issues
#### 題目說明

* 一個壓縮的資料夾: challenge.zip
#### solve
他說他刪掉了flag所以我用``git log``查看提交歷史

看到``picoCTF <ops@picoctf.com>``他在3/12創建了flag後又刪掉了
因此用``git show``,顯示指定提交的詳細訊息

#### answer
``picoCTF{s@n1t1z3_cf09a485}``
#### note
* ``git``: 版本控制
[常用指令](https://hellojs-tw.github.io/git-101/cheat-sheet.html)
### Verify
#### 題目說明

* challenge
* files(資料夾,裡面放了一堆要比對的文件)
* decrypt. sh
* checksum.txt

#### solve
要找到跟checksum.txt裡面hash值一樣的檔案
* 使用``sha256sum files/* | grep 3ad37ed6c5ab81d31e4c94ae611e0adf2e9e3e6bee55804ebc7f386283e366a4
3ad37ed6c5ab81d31e4c94ae611e0adf2e9e3e6bee55804ebc7f386283e366a4 files/e018b574
``

看到files裡e018b574的文件符合條件
接著用它給的decrypt. sh解密

#### answer
``picoCTF{trust_but_verify_e018b574}``
#### note
* ``sha256sum`` : 驗證文件
1. 計算文件的校驗和
2. 跟預期值做比較
* ``file/*`` : file資料夾中所有檔案
### Blame Game
#### 題目說明

給一個壓縮過的challenge.zip裡面有一個message. py
#### solve
* ``git blame <file>`` : 顯示檔案的每一行是在哪個提交中被修改的,並顯示修改者的資訊

得到flag
#### answer
``picoCTF{@sk_th3_1nt3rn_cfca95b2}``
### Collaborative Development
#### 題目說明

給了一個flag. py ,裡面只有一行:``print("Printing the flag...")``就沒了

#### solve
* ``git branch -a``:看可用的分支

看到我現在在``main``,然後還有``feature/part-1``、``feature/part-2``、``feature/part-3``這幾個分支
* ``git merge feature/part-1``

flag.py中有未提交的更改,而合併操作會覆蓋這些更改。
* 如何解決?
* ``git checkout -- flag.py`` : 撤銷修改
* 然後再執行一次``git merge feature/part-1``就好了,現在flag.py長這樣:

* ``git merge feature/part-2``

無法確定身份資訊(作者和提交者)
* 如何解決?
* 登入就好www(直接拿人家的XD)

* 然後再執行一次``git merge feature/part-2``就好了,現在flag.py長這樣:

* ``git merge feature/part-3``

嘗試合併feature/part-3分支時發生了衝突,導致合併無法進行
* 如何解決?
* 打開flag. py,看到衝突標記,``<<<<<<< HEAD``、``=======``和``>>>>>>> feature/part-2``表示目前分支(main分支)和要合併的分支(feature/part-2分支)之間有衝突

* 手動把衝突標記刪掉

* ``git add flag.py`` : 提交
* ``git merge --continue`` : 繼續
* 再執行一次``git merge feature/part-3``就好了,現在flag.py長這樣:

* 已經有flag了但如果想做到完美就把這邊的合併衝突也手動解決掉

* 執行

#### answer
``picoCTF{t3@mw0rk_m@k3s_th3_dr3@m_w0rk_7ae8dd33}``
#### note
分支是獨立的。使得團隊成員能夠在不互相干擾的情況下並行開發和合作。
### binhexa
#### 題目說明

進去之後長這樣

就是它給了兩個二進制數字接著出題要我們答,共六題,我無聊玩了三次,每次出題那兩個數字是隨機的
#### solve
* Question 1/6:
* ">> 1" 右循環1 bits: 把每個右移1 bits,最後一個補到最前面

* Question 2/6:
* '+'加法運算

* Question 3/6:
* '*' 乘法運算

* Question 4/6:
* "<< 1" 左循環1 bits: 把每個左移1 bits,第一個捕到最後面

* Question 5/6:
* AND運算: 2個都是1才會輸出1

* Question 6/6:
* OR運算: 其中一個是1結果就是1

* 最後要我給最後一題答案的16進制
* 11111111 -> ff

最後得到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
#### 題目說明


一個終極密碼的遊戲,有10次機會給你猜,答案的數字是隨機的
#### solve
:::success
使用二分搜尋法即可解題
猜的數字=(最小範圍+最大範圍)/2,我的話小數4捨5入
:::

#### answer
``picoCTF{g00d_gu355_2e90d29b}``
## Binary Exploitation
### heap 0
#### 題目說明

* 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
:::
* 執行

#### answer
``picoCTF{my_first_heap_overflow_c3935a08}``