---
# System prepended metadata

title: picoCTF - Web Exploitation write-up
tags: [write up]

---

# picoCTF - Web Exploitation write-up
未寫:
* Easy
    * n0s4n1ty 
* Medium
    * More SQLi
    * byp4ss3d
    * Pachinko
    * SSTI2
    * SOAP
    * MatchTheRegex
    * findme
    * Super Serial
    * More Cookies
    * It is my Birthday






# Easy
## WebDecode
:::spoiler 解法
打開網頁之後按按看三個頁面，可以看到在About那邊它叫我們try inspecting the page，打開F12可以看到notify_true=後面接被base64編碼過的flag
![image](https://hackmd.io/_uploads/HJeUm9gxWe.png)

解碼就獲得flag了
![image](https://hackmd.io/_uploads/H1sU79lgZe.png)

:::
## Crack the Gate 1

:::spoiler 解法
題目描述寫到the developer left a secret way in. 聯想到有一種常見漏洞是工程師在程式碼裡直接留下測試帳密，所以先F12看一下~
好欸果然有留下東西，但看起來被位移過了，所以先還原一下，會得到temporary bypass: use header "X-Dev-Access: yes"
![image](https://hackmd.io/_uploads/SyHrm53JZg.png)

接著就是打開我們的BurpSuite，輸入帳號之後密碼亂打然後攔截我們的HTTP Request，加上X-Dev-Access: yes
![image](https://hackmd.io/_uploads/B1MIQ93kbl.png)

成功繞過驗證獲得flag
![image](https://hackmd.io/_uploads/BkcUmqny-e.png)

:::
## SSTI1
> SSTI

:::spoiler 解法
一開始先輸入`{{7*7}}`確認他有SSTI漏洞
然後用 `{{ ''.__class__.__mro__[1].__subclasses__() }}` 列出所有class
我們要找的是 subprocess.Popen，最後找到在356
用 `{{ ''.__class__.__mro__[1].__subclasses__()[356]('ls /',shell=True,stdout=-1).communicate() }}`
列出所有目錄，看到有一個是challenge
然後再列出challenge底下有甚麼(把'ls /'改成'ls /challenge'就好)
有一個檔名叫flag
最後用`{{ ''.__class__.__mro__[1].__subclasses__()[356]('cat /challenge/flag',shell=True,stdout=-1).communicate() }}`成功印出flag

:::

## Unminify
> F12

:::spoiler 解法
按下挑戰會有個網址
進去有一段文字
他說瀏覽器成功收到旗幟
網頁沒啥可以按的
打開F12
滑一下原始碼就有了
:::

## Cookie Monster Secret Recipe
> cookie
:::spoiler 解法
打開是登入畫面，隨便輸入帳號密碼
然後可以看到他叫我們確認cookie
![image](https://hackmd.io/_uploads/rk-8cypyWl.png)

打開看到cookie的值像是被base64編碼過
解碼就是flag
![image](https://hackmd.io/_uploads/B1iLqyT1-e.png)

:::

## IntroToBurp
> burp suite

:::spoiler 解法
題目給了一個網站
按進去會有一個註冊的畫面，不知道他要幹嘛，隨便輸入點東西
然後她會叫你輸入OTP
一樣隨便輸入，然後就顯示Invalid OTP
聯想到題目打開burp suite進行攔截
![image](https://hackmd.io/_uploads/rJduhhpy-e.png)

看到提示說要把請求弄壞
想不到有甚麼好弄壞的就把參數傳遞刪了，然後就對了
![image](https://hackmd.io/_uploads/B1fY3hpJ-x.png)

:::
## Bookmarklet
:::spoiler 解法
今天解picoCTF的Bookmarklet
進到網頁，會看到他給了一串js程式
程式內容看起來是在解碼一串加密過的flag最後print出這個flag
那應該只要運行程式就好了!
想到F12的Console可以直接運行，直接貼上他會顯示警告，打allow pasting就好了
貼上程式就取得flag了
![image](https://hackmd.io/_uploads/r1Lu6hakZe.png)

:::
## Local Authority
:::spoiler 解法
題目的網站一開始會看到一個登入畫面，翻遍網頁也找不到flag或登入提示，就先用admin，admin登入看看
毫不意外的登入失敗，再亂翻一下，發現多了一個js檔案，裡面寫了密碼登入的判斷，得知了帳號跟密碼
![image](https://hackmd.io/_uploads/HkTKWapyZe.png)

登入之後就是flag
:::

## Inspect HTML
:::spoiler 解法
F12就看的到了
![image](https://hackmd.io/_uploads/S1uFfTp1Zx.png)

:::
## Includes
:::spoiler 解法
按進網頁戳一下say hello 會跳出一個視窗跟你說"This code is in a separate file!"
要找獨立的文件
所以按到Sources
只有兩個檔案 一個js一個css
裡面各有一段flag
![image](https://hackmd.io/_uploads/r1v0z6T1Wg.png)
![image](https://hackmd.io/_uploads/SkH1QTpJbg.png)

組合起來就好了
:::
## Cookies
> cookie

:::spoiler 解法
打開cookie，會看到name原本是-1，依序往上加數字，加到18就有flag了
![image](https://hackmd.io/_uploads/B1mzX0BOlg.png)
:::
## Scavenger Hunt
:::spoiler 解法
一樣先F12
可以在HTML跟CSS找到兩部分
![image](https://hackmd.io/_uploads/rJWz4a61-g.png)
![image](https://hackmd.io/_uploads/Sy2zVpaJ-e.png)

JS檔裡說"How can I keep Google from indexing my website?"
所以想到要看robots.txt ， 在網址後加上/robots.txt 得到第三部分跟新提示"I think this is an apache server… can you Access the next flag?"
![image](https://hackmd.io/_uploads/B17EVpakZx.png)

他提到這是apache server ， 所以應該要找.htaccess ， 獲得第四部份跟新提示" I love making websites on my Mac, I can Store a lot of information there."
![image](https://hackmd.io/_uploads/H1PrEaTy-e.png)

提到Mac跟store information 所以要找.DS_Store
![image](https://hackmd.io/_uploads/H168NTaJ-g.png)

全部接起來就是flag了
:::
## GET aHEAD
:::spoiler 解法
觀察一下可以發現按下RED的method是GET，BLUE的是POST
結合題目去看可以猜出是要用HEAD
一樣用burp suite攔截後按右鍵選「send to repeater」
然後把POST改成HEAD按send就有了
![image](https://hackmd.io/_uploads/H1_QBRBOxg.png)
:::
## logon
> cookie

:::spoiler 解法
先隨便登一組帳密
按到cookie可以發現有一個cookie名稱叫admin，然後值目前是False
把他改成True，刷新頁面就成功了
![image](https://hackmd.io/_uploads/B1CQwa61bx.png)

:::
## Insp3ct0r
:::spoiler 解法
按how 他會跟你說
`I used these to make this site: HTML CSS JS (JavaScript)`
按F12找出這三個的檔案，裡面就有三段flag
![image](https://hackmd.io/_uploads/SkWdPpTJ-e.png)
![image](https://hackmd.io/_uploads/BJHKDTT1We.png)
![image](https://hackmd.io/_uploads/ryd5D6aJZe.png)

組合起來就是了
:::

## where are the robots
:::spoiler
依robots的名字聯想到要找robots.txt
robots.txt檔案裡寫了一個禁止的路徑
把他加到網址後面，找到flag了
![image](https://hackmd.io/_uploads/rkff_aa1be.png)

:::

# Medium
## Crack the Gate 2
:::spoiler 解法
這題給了一個密碼表跟一個登入頁面，但他說會卡IP限速
看完題目之後有種沃感覺就要用burp suite 的 intruder
大概就是加上X-forwarded-For之後選取IP跟密碼的位子
IP可以上網找20個可用IP
![image](https://hackmd.io/_uploads/HkRPV0pyWg.png)

然後按start attack之後他就會去跑每一個密碼，找到回應有flag的就是正確密碼
![image](https://hackmd.io/_uploads/B1_u4CaJZx.png)

:::

## 3v@l
> RCE

:::spoiler 解法
這題題目直接說了是RCE
提示說了flag的位子在/flag.txt，而且可能要用編碼方式來繞過黑名單
cat 被禁止了所以我用open以及ASCII編碼來繞過黑名單
![image](https://hackmd.io/_uploads/SymB_RTJZe.png)
![image](https://hackmd.io/_uploads/r1aHdCa1We.png)

:::
## Trickster
:::spoiler 解法
這題打開有一個可以上傳檔案的地方
他說只能傳png，猜到應該是要傳php但要繞過他的條件
看一下robots.txt寫了兩個禁止的路徑
![image](https://hackmd.io/_uploads/Hyh6uRa1Wx.png)

先去instructions.txt看一下，這邊寫了她的過濾規則，檔名要有.png跟開頭要有png
![image](https://hackmd.io/_uploads/rydAORpkbl.png)

/uploads/顯示沒有權限，但推測上傳後的檔案會在這
知道規則之後就用burp suite修改我們送出的請求，把png的內容改成一句話木馬，send之後顯示successfully就成功了
![image](https://hackmd.io/_uploads/H1vyY0a1-x.png)

在網址後面加/uploads/檔名?cmd=指令 就可以自由打指令了!
用find找出所有txt，看到一個像是flag的 `/var/www/html/HFQWKODGMIYTO.txt`
用cat 把他抓出來，成功獲得flag
![image](https://hackmd.io/_uploads/S1FetCTkWe.png)

:::
## No Sql Injection
:::spoiler 解法
這題有給它的source code，所以我們可以先看看它的js檔
在伺服器啟動時，程式會自動建立一個使用者，token 欄位沒有特別設定，因此會使用預設值 {{Flag}}
它的查找使用者的地方有一個no sql的漏洞，我們可以自己傳入一個 MongoDB 查詢語法，像是 { "$ne": null }（意思是「不等於 null」）來繞過驗證，找到第一個 email 與 password 都不是 null 的使用者
用 curl模擬 POST 請求送出這組 payload後就可以成功獲得initialUser的所有內容
其中token的值就是被編碼過的flag，解碼後就是flag了
![image](https://hackmd.io/_uploads/HJLL5Aakbe.png)

:::
## SQL Direct
> SQL

:::spoiler 解法
這題要連線到PostgreSQL server在上面找到flag
連進去先用`help \?`看一下有甚麼指令
找到`\dt`可以顯示所有tables
![image](https://hackmd.io/_uploads/By4Fp0Tk-x.png)

執行之後可以看到一個叫flags的table
![image](https://hackmd.io/_uploads/BkntTRakbl.png)

使用 SELECT * FROM flags; 查看flags的所有內容，找到其中一欄就是這題的 flag
![image](https://hackmd.io/_uploads/SkIq6R6yZl.png)

:::

## Secrets
> path 

:::spoiler 解法
先F12去到Sources可以看到除了現在的(index)還有另一個叫secret的檔案，嘗試修改網址為 /../secret/ 進入該路徑
![image](https://hackmd.io/_uploads/HybeA061Wx.png)
成功了!這次一樣有一個叫hidden的資料夾，同樣方式修改網址繼續深入

![image](https://hackmd.io/_uploads/Bk0W0Rp1Wx.png)

又有一層，再次修改路徑就找到flag了
![image](https://hackmd.io/_uploads/SySWRCTk-x.png)

:::
## Search source
:::spoiler 解法
這題要從他給的網站中找到flag，因為裡面檔案很多一個一個找有點困難，所以上網搜有沒有指令，發現wget可以用
等他全部下載完後，在那個資料夾裡用grep就能很快地找到flag了 
![image](https://hackmd.io/_uploads/r1kUCC61Ze.png)

:::
## SQLiLite
> SQLi

:::spoiler 解法
先隨便打個帳密登入後會看到他後端的SQL語法
![image](https://hackmd.io/_uploads/H1vF_t1x-x.png)

要把AND password='admin'註解掉
所以回到登入畫面
在Username打admin'--
Password隨便
進去之後會看到Logged in! But can you see the flag, it is in plainsight.
F12就看的到flag了 
![image](https://hackmd.io/_uploads/BJequK1x-e.png)

:::
## Roboto Sans
> robots.txt

:::spoiler 解法
看到這個標題想到可能跟robots.txt有關
查看後可以看到有兩個路徑跟三行看起來被編碼過的文字
![image](https://hackmd.io/_uploads/H1OO4cgx-e.png)
兩個路徑都顯示404，所以推測應該跟那三行有關
分別拿去做base64解碼，第一個顯示404
第二個成功找到flag
![image](https://hackmd.io/_uploads/r195E5gl-x.png)

:::
## Power Cookie
:::spoiler 解法
這題進去只有一個按鈕可以按，直接按會顯示no guest services
回到上一頁F12找按鈕按下後發生了什麼，可以找到一個js檔，按下後會跑到/check.php還有cookie的isAdmin = 0
![image](https://hackmd.io/_uploads/Hys1rqgxZl.png)

我們把js裡的改成isAdmin = 1，再按按鈕，成功獲得flag
![image](https://hackmd.io/_uploads/BkUlrclx-x.png)

:::
## Forbidden Paths
> Path Traversal

:::spoiler 解法
題目說不能用絕對路徑，所以要用相對
已知目前的網頁檔案在 /usr/share/nginx/html/
我們要找的flag在/flag.txt
所以輸入../../../../flag.txt 成功讀取到flag.txt 
![image](https://hackmd.io/_uploads/B1JzOXGeZe.png)

:::
## JAuth
:::spoiler
這題可以用給的帳號登入後，在 cookie 中看到一個 JWT token
![image](https://hackmd.io/_uploads/HklHO7flZe.png)

解密 token 後可以看到 role 為 user，因此可以推測目標是把它改成 admin
我們可以透過把 header 的 alg 改成 none，告訴伺服器不驗證簽名，這樣就能自由修改 payload

要注意的是最後得到的 JWT token要有兩個. 
![image](https://hackmd.io/_uploads/rkQ8uQMl-e.png)
:::
## caas
> command injection

:::spoiler 解法
先看看題目給的js程式碼
重點在`exec(`/usr/games/cowsay ${req.params.message}`)`
他會把我們輸入的內容直接丟進去shell 指令字串中，而且exec其實會開一個 shell 環境來跑你傳入的指令，所以只要用 ;串接更多指令，就能執行多個指令
所以我們就可以用ls來看看他有甚麼檔案，可以看到有一個是falg.txt
![image](https://hackmd.io/_uploads/Hkmjd7Mebe.png)

猜測應該就是flag，修改網址為cat%20falg.txt就能得到flag
![image](https://hackmd.io/_uploads/BJ9jdQflZl.png)

:::
## login
:::spoiler 解法
這題有個登入畫面，隨便輸入個admin跟123，顯示密碼錯誤
F12打開想說會不會有個js可以看，結果真的有
可以看到一段看起來被base64編碼過的字串
![image](https://hackmd.io/_uploads/BJEyYXMgWe.png)

拿去做解密就是flag

:::
## Most Cookies
:::spoiler 解法
先打開server.py，可以看到他有一個cookie_names的陣列，他會隨機其中一個作為secret_key
我們可以用flask-unsign加上字典爆破 secret_key
先將所有cookie name存成cookies.txt
然後用`flask-unsign --unsign --cookie "eyJ2ZXJ5X2F1dGgiOiJibGFuayJ9.aERZWw.Ug7VkbJpGqy9HolQLhkERolrL5A" --wordlist cookies.txt`
他會爆破出目前使用的secret_key
![image](https://hackmd.io/_uploads/SyaXYmzxbx.png)

然後我們就可以用這個key去做出一個假的cookie
![image](https://hackmd.io/_uploads/SyBNtQMgWg.png)

將原本網頁的cookie改成我們做的cookie，然後重整頁面就能獲得flag
![image](https://hackmd.io/_uploads/HyxBYmze-e.png)

:::
## Web Gauntlet 2
> SQLi

:::spoiler 解法
這題不能使用`or and true false union like = > < ; -- /* */ admin`
所以可以用||串聯admin
密碼輸入`1' is not '2`讓他恆等於true
![image](https://hackmd.io/_uploads/S1qTfuQx-l.png)

:::
## Some Assembly Required 1
:::spoiler 解法
這題打開網頁後會有一個輸入框要填入flag，不知道要填甚麼打開F12看看有沒有甚麼提示
找到一個js檔案，但他被混淆過，找個反混淆工具反混淆後觀察他的邏輯
![image](https://hackmd.io/_uploads/S1OfXOQgbg.png)

他會把我們輸入的丟去wasm進行字串比對
所以我們去看看wasm裡寫了什麼，往最下面滑就看到flag了
![image](https://hackmd.io/_uploads/S1lQm_QeWx.png)

:::
## Who are you?
:::spoiler 解法
一開始會說只有PicoBrowser，所以把`User-Agent`改成PicoBrowser
然後是不相信從別的地方來的 所以加個`Referer`
然後是只在2018年運作 加個`Date`
然後是不相信可以被追蹤的 加`DNT: 1`
只能來自Sweden，所以就上網查然後用`X-Forwarded-For`
最後是在瑞典但不會說瑞典語，查sweden accept-language第一個就是sv-SE，加`Accept-Language: sv-SE`
![image](https://hackmd.io/_uploads/H1TdQ_Xlbx.png)

:::
## Some Assembly Required 2
:::spoiler
感覺跟1很像直接去看看wasm寫了什麼
在 copy_char 裡，可以看到程式會把輸入的每個字元和 8 做 xor，再存到記憶體
在 check_flag 裡，呼叫了 strcmp(1024, 1072)，也就是把data 段裡的字串和我們 XOR 過的輸入做比對
因此，data 段那串字串其實就是flag xor 8 之後的結果
所以只要把 data 段的字串取出來，xor 回去，就能還原出真正的 flag
![image](https://hackmd.io/_uploads/BJd3muXgWx.png)

:::
## Web Gauntlet 3
:::spoiler 解法
這題一樣是SQLite Injection，但他限制了很多黑名單
username可以用||來串聯兩個字串
password因為沒辦法用;或任何註解方法註解掉，所以要讓他恆為true
我輸入`1' is not '2`，這樣就登入成功
![image](https://hackmd.io/_uploads/SJFvBO7lZx.png)

:::
## Web Gauntlet
:::spoiler 解法
這題是SQLite Injection，有五層要破，每層filter都不同
Round1: or : `admin' --`
Round2: or and like = -- : `admin' /*`
Round3: or and = like > < -- : `admin';`
Round4: or and = like > < -- admin : `ad'||'min';`
Round5: or and = like > < -- union admin : `ad'||'min';`
然後刷新一下filter.php就可以看到flag了
:::
## Irish-Name-Repo 1
> SQL injection

:::spoiler 解法
這題按左上的橫線之後可以按到Admin Login
在登入畫面看不出什麼，用burp suite攔截觀察一下
可以看到他有傳送一個debug=0，把她改成1試試看
可以看到他顯示了一個SQL語句，很明顯這題是SQL injection
![image](https://hackmd.io/_uploads/HJ3uFO7lZl.png)
在帳號填入admin';密碼隨便填，就能成功以admin登入獲得flag了
![image](https://hackmd.io/_uploads/H115tOXg-x.png)


:::
## Client-side-again
:::spoiler 解法
觀察一下他的原始碼，發現藏了一串js，看到一堆0x開頭變數第一直覺就是要解混淆
丟個線上工具 https://raz1ner.com/Online-Tools/JavaScript-Deobfuscator.html 看看，發現解成功ㄌ
這樣邏輯就很清楚了，按照他檢查密碼的順序就能排出flag了
![image](https://hackmd.io/_uploads/rJSk9_mxZl.png)

:::
## dont-use-client-side
:::spoiler 解法
這題叫我們輸入valid credentials，但沒給其他提示
F12看一下原始碼，可以看到他直接寫在裡面了
按照順序排好就是flag了

![image](https://hackmd.io/_uploads/rkcSnM4lbg.png)

:::

## Irish-Name-Repo 2
> SQL injection


:::spoiler 解法
這題跟他的1其實應該差不多
用burp suite攔截把debug改成1可以看到他的SQL語句
然後就是SQL injection，很簡單用`'--`就能登入成功
![image](https://hackmd.io/_uploads/rkoeH-9x-x.png)

:::

## logon

:::spoiler 解法
這題說要以Joe的身分登入，但不知道密碼
隨便輸入一個帳號密碼，意外發現可以直接登入
看一下cookie有甚麼內容
有一個寫admin，原本是False，改成True之後刷新就獲得flag了
![image](https://hackmd.io/_uploads/H1XIoWceZx.png)
:::
## picobrowser
:::spoiler 解法
這題給了一個連結，打開可以看到一個按鈕上面寫著flag
![image](https://hackmd.io/_uploads/H1_4KQ_bbl.png)

直接按他會跟你說你不是picobrowser
所以就用burp，把User-Agent改成picobrowser
![image](https://hackmd.io/_uploads/Bk2tqmuWbl.png)

按forward，成功獲得flag
![image](https://hackmd.io/_uploads/SyQ59Q_bZl.png)

:::
## Irish-Name-Repo 3
:::spoiler 解法
這題按到admin login後只有一個輸入密碼的地方
我們用burp suite觀察一下我們送出的HTTP請求，發現最下面傳遞參數的後面接了一個debug=0，嘗試把它改成1之後多了一行SQL query
![image](https://hackmd.io/_uploads/H1qa5mO-bx.png)

可以發現我們輸入的密碼會被做ROT13之後填入SQL查詢語句中
![image](https://hackmd.io/_uploads/r1XCcQdWWx.png)

我們可以透過輸入' BE '1'='1 (' OR '1'='1 做ROT13) 讓 where 條件式恆成立
送出之後就獲得flag了!
![image](https://hackmd.io/_uploads/BkT05XdZ-g.png)

:::
