AIS3 Final CTF Web Writeup (Race Condition & one-byte off SQL Injection)

這次為了 AIS3 Final CTF 所出的一道題目,這題在這以初新者導向中的比賽中相對難,不過其中的觀念很有趣,在解題中什麼都給你了就是找不到洞但經人一解釋就會有豁然開朗覺得為什麼自己沒想到的感覺

在做 Web 攻擊、滲透滿多時候思路不能太正派、太直觀,要歪一點、要 “猥瑣” 一點XD

純粹 code review 直接上 code

(可以自己先嘗試一下找不找的到洞XD)

漏洞一 Race Condition

預設註冊的使用者都是會被放進 locks 表中鎖起來的,

但是只要在註冊中,帳號尚未被新增進 locks 表時(111 & 112 行) 馬上登入的話,

登入檢查是否被鎖住的限制就可以繞過了!

漏洞二 one-byte off SQL Injection

當成功登入後可以新增 note 並且可以看到自己新增的 note

漏洞發生在第 58 行,當 note 的標題太長為了畫面美觀會進行截斷的動作只限制前 32 個字顯示在畫面上

這時候因為對 SQL Injection 防護是使用 escape 的方式防護,單引號(‘)會被反斜線 escape 成 ('),這時候如果精心設計一個長度正確的 payload 就可以讓防護剛好被繞過造成後面的 SQL 語句跟前方連在一起

Payload

1
2
3
POST=
title=phddaaphddaaphddaaphddaaphddaa_\
&note=, (select pass from users where name=0x6f72616e6765)#

phddaaphddaaphddaaphddaaphddaa_\ (32 個字長)

會被 escape 成

phddaaphddaaphddaaphddaaphddaa\_\\ (33 個字長)

此時踩到超過 32 長的限制 (57 & 58 行),並進行截斷成

phddaaphddaaphddaaphddaaphddaa\_\

導致原本的防護被繞過,使得原本被括起來後面的單引號被 escape 原本的 SQL 語句就變成字串了

用這個方法就可以成功在 INSERT 語法中進行 SQL Injection 並在自己的 note 中看到資料,取得管理員密碼後即可變身成管理員

順道一提這個思路在 Discuz 7.2 去年還是前年被爆出的 SQL Injection 中有類似的思路

漏洞三 Local File Inclusion with PHP session

由於 include 前面不可控,所以不能使用 php://filter 或是 zip:// phar:// 等協議,而後面有 php 的後綴也不能使用 LFI with PHPINFO 的招數

不過在 PHP 中 SESSION 預設存在 /var/lib/php5/sess_* 中

例如 Cookie: PHPSESSID=123php 會產生 /var/lib/php5/sess_123php 的檔案

在可以偽造 $_SESSION 內容的時候其實就代表可以產生一個部分內容可控,部分檔名可控的檔案,這時候在使用 LFI 去包含他就可以產生一個 shell 了

Payload

1
2
/sqlpwn.php?mode=admin
&boom=../../../../var/lib/php5/sess_123

如此一來可以透過第一個漏洞註冊一個使用者名稱為 <?php eval($\_POST[ccc]);?> 的用戶,之後登入時指定 PHPSESSID 為 php 結尾,再利用所產生的 session file 進行 include 的動作。