# 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) :::