首先來看到題目,題目要求我們從網站上找到 flag,並且從題名知道這題跟 SQLi 有關,提示也告訴了我們這題跟 SQLiLite 有關。
hint 1:SQLiLite
SQLi ( SQL injection ),是一種通過操縱 SQL 查詢語句來訪問或破壞資料庫的攻擊方法,主要分成三種:
更多有關於 SQLi 的資訊,可參考:秒懂 SQL Injection
回到解題,點進網址,會出現一個登入的畫面。
在 username 和 password 中,我都填入 '123’,並按下 log in,會出現以下畫面。
從這裡,我們能夠知道 SQL 查詢的邏輯式:SELECT id FROM users WHERE password = ‘123’ AND username = ‘123’
。所以我們能夠知道,在查詢時會先查詢 password ,然後再查 username。
於是,我們在 password 中,填入 'OR 1=1 --
,username 中填 '123'
,便可以進入到以下畫面了。
其中 'OR 1=1 --
是一種 SQLi,正常查詢下,將 username 和 password 都填入 '123’ 時,SQL 查詢如下:
SELECT * FROM users WHERE password = '123' AND username = '123';
但若將 password 填入 'OR 1=1 --
做 SQLi,則會變成以下:
SELECT * FROM users WHERE password = '' OR 1=1 -- ' AND username = '123';
在這個攻擊中,'
單引號的作用是結束原本應該是 password 的字串。例如,在上面的注入中,原本查詢中的 password (這裡是 '123' ) 變成了一個空字串 ( ’ ‘ )。
然後插入了 OR 1=1
,使這個 SQL 查詢永遠為 True, --
之後的部分將被註解掉,不再執行 。
接著,我們在搜尋欄中隨便輸入一個城市 ( Pretoria ),確認可以使用城市名查詢。
於是我們在搜尋欄中再以 SQLi 的方法做攻擊,希望能夠得到 flag 的資訊。
在這裡,我們輸入 Pretoria ' UNION SELECT name, sql,"" FROM sqlite_master WHERE type='table' --
,便會出現以下資訊,從這裡能看到 flag 的資訊在 more_table 的表格裡。
其中 Pretoria ' UNION SELECT name, sql,"" FROM sqlite_master WHERE type='table' --
意思如下,Pretoria '
:目的是結束原本的 SQL 語句。UNION SELECT name, sql,""
:顯示 name 和 sql 的資訊。""
是因為,在這個查詢裡應該要有 3 個欄位,但是因為我們只有輸入兩個欄位 ( name 和 sql ),所以要再加入一個空字串,作為第 3 欄 ( 當然您也可以隨便輸入一個字串 )。FROM sqlite_master WHERE type='table'
:從 sqlite_master 中的表格做查找。其中,sqlite_master 是 SQLite 資料庫中的一個特殊表,這個表可以查詢資料庫的結構資訊。--
:忽略原查詢中剩餘的部分,避免語法錯誤。
仿造剛剛的攻擊,輸入 Pretoria ' UNION SELECT flag, "","" FROM more_table--
,於是我們可以從 more_table 中得到 flag 的資訊。
補充:
若您輸入以下,則會將 users 這個表格中的 name, password, id 顯示出來。
Pretoria ' UNION SELECT name, password,id FROM users--
這時若您要再重新登入,也能使用這組帳號密碼登入。
username = admin
password = moreRandOMN3ss'--
小結:
了解並且實作 SQLi。