Is there a work around for RHEL 5 concerning the Imagemagic Security vulnerability

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
trav
Posts: 5
Joined: 2016-05-04T23:34:14-07:00
Authentication code: 1151

Re: Is there a work around for RHEL 5 concerning the Imagemagic Security vulnerability

Post by trav » 2016-05-04T23:43:07-07:00

The remote command execution via 'HTTPS' appears to be able to be mitigated on RHEL/CentOS v5 by updating the delegates.xml

eg changing the following line in /usr/lib64/ImageMagick-6.2.8/config/delegates.xml (CentOS 5 path)
<delegate decode="https" command='"wget" -q -O "%o" "https:%M"' />

to something like
<delegate decode="https" command="/bin/false" />

at least in my testing. Of course it breaks anything trying to use the https feature, but so does disabling it in policy.

From my testing so far it also appears that v6.2.8 (as current for CentOS5) doesn't support 'EPHEMERAL' so is safe from the remote delete vulnerability.
I'm not sure about the others yet though.

User avatar
fmw42
Posts: 25423
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Is there a work around for RHEL 5 concerning the Imagemagic Security vulnerability

Post by fmw42 » 2016-05-04T23:59:32-07:00

I suspect 6.2.8 is too early for MSL. So probably the only issue is MVG files.

trav
Posts: 5
Joined: 2016-05-04T23:34:14-07:00
Authentication code: 1151

Re: Is there a work around for RHEL 5 concerning the Imagemagic Security vulnerability

Post by trav » 2016-05-05T00:35:23-07:00

Looks like MVG (and label) can be disabled on CentOSv5 by denying access to (or I guess removing / renaming) the coder plugin file(s):

chmod -v 000 /usr/lib*/ImageMagick-*/modules-*/coders/mvg.so

'label' and 'svg' can be disabled in the same way too.

trav
Posts: 5
Joined: 2016-05-04T23:34:14-07:00
Authentication code: 1151

Re: Is there a work around for RHEL 5 concerning the Imagemagic Security vulnerability

Post by trav » 2016-05-05T02:02:02-07:00

Based on the existence of an 'msl.so' on CentOS v5 it looks like MSL would be an issue too, for now I'm going to chmod 000 all of mvg.so, msl.so, url.so and label.so

nakadoma
Posts: 8
Joined: 2016-05-04T17:14:08-07:00
Authentication code: 1151

Re: Is there a work around for RHEL 5 concerning the Imagemagic Security vulnerability

Post by nakadoma » 2016-05-05T11:06:37-07:00

Thanks Trav, so do you think those changes are an acceptable workaround. Will this apply to both MSL and MVG. Thanks Your input is much appreciated but I'm going to keep seeking answers until I get something definitive.

nakadoma
Posts: 8
Joined: 2016-05-04T17:14:08-07:00
Authentication code: 1151

Re: Is there a work around for RHEL 5 concerning the Imagemagic Security vulnerability

Post by nakadoma » 2016-05-05T11:19:09-07:00

Redhat is suggesting this probably based on your input Trav. https://access.redhat.com/security/vuln ... 1#comments

frEEk
Posts: 8
Joined: 2016-05-04T18:14:10-07:00
Authentication code: 1151

Re: Is there a work around for RHEL 5 concerning the Imagemagic Security vulnerability

Post by frEEk » 2016-05-05T19:46:02-07:00

trav's mitigation worked for me with ImageMagick 6.2.
6.5 and 6.7 took the policy.xml mitigation.
6.0 does not appear to be susceptible to the MVG exploit per the test in the Redhat article above.

Obviously your mileage may vary, this is just my experience.

Thanks for the idea trav.

md.raja786786
Posts: 1
Joined: 2016-05-05T23:45:11-07:00
Authentication code: 1151

Re: Is there a work around for RHEL 5 concerning the Imagemagic Security vulnerability

Post by md.raja786786 » 2016-05-05T23:53:00-07:00

Red Hat Enterprise Linux 5 you can check your server vulnerability with below mentioned script.

way 1:-

Create a file called exploit.mvg with the following contents:
Then run the convert utility:
  • $ convert exploit.mvg out.png
If you see a local directory listing, your installation of ImageMagick is not sufficiently protected."

way 2:-

create a file abc.sh , insert below mentined lines in that file.

Code: Select all

#!/bin/bash
# Version: 1.0

YELLOW='\033[1;33m'
RED='\033[1;31m'
RESET='\033[0m'

VULNERABLE_VERSIONS=(

    # RHEL5
    'ImageMagick-6.2.8.0-4.el5_1.1'   
    'ImageMagick-6.2.8.0-4.el5_5.2'   
    'ImageMagick-6.2.8.0-4.el5_5.3'   
    'ImageMagick-6.2.8.0-3.el5.4'     
    'ImageMagick-6.2.8.0-12.el5'      
    'ImageMagick-6.2.8.0-15.el5_8'    

    # RHEL6
    'ImageMagick-6.5.4.7-5.el6'       
    'ImageMagick-6.5.4.7-6.el6_2'     
    'ImageMagick-6.5.4.7-7.el6_5'     
    'ImageMagick-6.7.2.7-2.el6'       

    # RHEL7
    'ImageMagick-6.7.8.9-10.aa7a'     
    'ImageMagick-6.7.8.9-10.ael7b'    
    'ImageMagick-6.7.8.9-10.el7'      
    'ImageMagick-6.7.8.9-12.el7_2'    

)


# look for last item in the set of previous items
function contains() {
    # number of arguments
    local n=$#
    # the last positional argument (using indirect reference)
    local value=${!n}
    for ((i=1;i < $#;i++)) {
        # comparing the i-th positional argument with the last one
        if [ "${!i}" == "${value}" ]; then
            return 0
        fi
    }
    return 1
}


result=0

# Get versions of installed ImageMagick and check them against the list of known vulnerable versions
for package in `rpm -qa --qf '%{name}-%{version}-%{release}\n' ImageMagick | sort` ; do
    if $(contains "${VULNERABLE_VERSIONS[@]}" "$package"); then
        result=1
    fi
done


# Check for mitigation in place
in_policymap=0
EPHEMERAL=0
URL=0
HTTPS=0
MVG=0
MSL=0

# Recommended mitigation:
#  <policymap>
#    <policy domain="coder" rights="none" pattern="EPHEMERAL" />
#    <policy domain="coder" rights="none" pattern="URL" />
#    <policy domain="coder" rights="none" pattern="HTTPS" />
#    <policy domain="coder" rights="none" pattern="MVG" />
#    <policy domain="coder" rights="none" pattern="MSL" />
#  </policymap>

if [ $result -eq 1 ]; then
    while read line; do
        if [[ $line =~ .*\<policymap\>.* ]]; then
            in_policymap=1
        elif [[ $line =~ .*\</policymap\>.* ]]; then
            in_policymap=0
        else
            if [ $in_policymap -eq 1 ]; then
                # best-effort matching for the recommended mitigation lines; full XML parsing is not done
                if [[ $line =~ ^[[:space:]]*\<policy[[:space:]]+domain=[\"\']coder[\"\'][[:space:]]+rights=[\"\']none[\"\'][[:space:]]+pattern=[\"\']EPHEMERAL[\"\'][[:space:]]*/\> ]]; then
                    EPHEMERAL=1
                fi
                if [[ $line =~ ^[[:space:]]*\<policy[[:space:]]+domain=[\"\']coder[\"\'][[:space:]]+rights=[\"\']none[\"\'][[:space:]]+pattern=[\"\']URL[\"\'][[:space:]]*/\> ]]; then
                    URL=1
                fi
                if [[ $line =~ ^[[:space:]]*\<policy[[:space:]]+domain=[\"\']coder[\"\'][[:space:]]+rights=[\"\']none[\"\'][[:space:]]+pattern=[\"\']HTTPS[\"\'][[:space:]]*/\> ]]; then
                    HTTPS=1
                fi
                if [[ $line =~ ^[[:space:]]*\<policy[[:space:]]+domain=[\"\']coder[\"\'][[:space:]]+rights=[\"\']none[\"\'][[:space:]]+pattern=[\"\']MVG[\"\'][[:space:]]*/\> ]]; then
                    MVG=1
                fi
                if [[ $line =~ ^[[:space:]]*\<policy[[:space:]]+domain=[\"\']coder[\"\'][[:space:]]+rights=[\"\']none[\"\'][[:space:]]+pattern=[\"\']MSL[\"\'][[:space:]]*/\> ]]; then
                    MSL=1
                fi
            fi
        fi
    done < /etc/ImageMagick/policy.xml
fi

if [ $result -eq 1 ]; then
    if [ $EPHEMERAL -eq 1 ] && [ $URL -eq 1 ] && [ $HTTPS -eq 1 ] && [ $MVG -eq 1 ] && [ $MSL -eq 1 ] ; then
        result=2
    fi
fi

# Result 0 - no vulnerable package found
# Result 1 - vulnerable package found and no mitigation
# Result 2 - vulnerable package found but mitigation

if [ $result -eq 1 ]; then
    echo -e $RED"WARNING"$RESET": The installed version of ImageMagick ($package) is vulnerable to ImageMagick Filtering Vulnerability - CVE-2016-3714."
    echo "Apply the mitigation described at https://access.redhat.com/security/vulnerabilities/2296071"
elif [ $result -eq 2 ]; then
    echo -e $YELLOW"WARNING"$RESET": The installed version of ImageMagick ($package) is vulnerable to ImageMagick Filtering Vulnerability - CVE-2016-3714."
    echo "The machine is NOT vulnerable, as the recommended mitigation is in place."
else
    echo "No vulnerability to CVE-2016-3714 (ImageMagick) detected."
fi
echo "See https://access.redhat.com/security/vulnerabilities/2296071 for more information."

# Return an exit code usable for automated testing
exit $result
Give permission chmod +x abc.sh then execute this script ./abc.sh.


remedy :-

In the following folders:
  • /usr/lib64/ImageMagick-6.2.8/modules-Q16/coders/ (64bit package)
    or
    /usr/lib/ImageMagick-6.2.8/modules-Q16/coders/ (32bit package)

Rename the following files, mvg.so, msl.so, label.so. Example:
  • $ mv mvg.so mvg.so.bak
    $ mv msl.so msl.so.bak
    $ mv label.so label.so.bak

regards,

Md Raja
md.raja786786@gmail.com

trav
Posts: 5
Joined: 2016-05-04T23:34:14-07:00
Authentication code: 1151

Re: Is there a work around for RHEL 5 concerning the Imagemagic Security vulnerability

Post by trav » 2016-05-07T03:58:44-07:00

Just by way of an update, I was able to replicate all the exploits listed on https://imagetragick.com/ on CentOS7, and all with the exception of the epehmeral:/ delete on RHEL5 & CentOS5 and have deployed the mitigations below to all my systems with no issues, other than the loss of SVG thumbnailing in applications using convert.

At present my mitigation (which blocked all the examples on https://imagetragick.com/) is as follows for both OS versions:
  • If a policy.xml can be located then:
  • If a delegates.xml can be located then:
    • Set command=/bin/false for the HTTPS delegate
  • If any of the following .so files are found in the coders directory set their permissions to 000
    • label.so, mvg.so, svg.so, msl.so, url.so
If you do choose to use the script/rpms below please ensure you understand what they are doing and how to undo it, as there is currently no uninstall support and uninstalling the rpm will not undo the changes!


The following python script (requires libxml2-python to be installed) will do all of this on RHEL or CentOS 5 & 7 (it will probably work on v6 too, but I haven't tested there). Note that the script will blindly apply all the mitigations regardless of ImageMagick version etc to any of the configs / modules it can find, if changes are made to xml config files a .cvebak backup will be created first.

My script is linked here fixpolicy.py and listed inline below

Code: Select all

#!/usr/bin/python
#
# A simple script to update policy.xml and/or delegates.xml to help mitigate
# the "ImageTragic" family of vulnerabilities, this script is intended for
# CentOS v5 an v7 but will probably work on v6 and may also work on other
# distos
#
# (C) Noggin Pty Ltd 2016
#
# This script is distributed under the GPLv2+ license
#
import os
import glob
import libxml2
import shutil

# Which policies to disable (set rights=none)
policiesToDisable = {
  'coder': ['EPHEMERAL', 'HTTPS', 'HTTP', 'URL', 'FTP', 'MVG', 'MSL', 'TEXT'],
  'path':  ['@*']
}

# Delegate command overrides
delegatesToOverride = {
    'https': "/bin/false"
}

# Where to look for policy.xml files
policyFiles = [
    '/etc/ImageMagick*/policy.xml',
    '/usr/local/etc/ImageMagick-*/policy.xml'
]

# Where to look for delegates.xml files
delegateFiles = [
    '/etc/ImageMagick*/delegates.xml',
    '/usr/lib*/ImageMagick-*/config/delegates.xml'
]

# Files to deny access to (prevent coders from running)
denyFiles = {
    '/usr/lib*/ImageMagick-*/modules-*/coders/': ['label.so', 'mvg.so', 'svg.so', 'msl.so', 'url.so']
}

    
# set a delegate command
def setDelegateCommands(filename, delegateCommands):
    changed = 0
    
    doc = libxml2.parseFile(filename)
    for delegate in delegateCommands:
        nodes = doc.xpathEval("/delegatemap/delegate[@decode='" + delegate + "']")
        for dn in nodes:
            if (dn.prop('command') != delegateCommands[delegate]):
                dn.setProp('command', delegateCommands[delegate])
                changed = changed + 1
            
    if (changed):
        shutil.copy2(filename, filename + '.cvebak')
        doc.saveFile(filename)
        

# Disable ImageMagick policies (rights=none)
def disablePolicies(filename, policies):

    inserted = None
    changed = 0

    doc = libxml2.parseFile(filename)

    policymap = doc.xpathEval('/policymap')[0]

    for domain in policies.keys():
        for pattern in policies[domain]:
            policy = doc.xpathEval("/policymap/policy[@domain='coder' and @pattern='" + pattern + "']")
            for pn in policy:
                if (pn.prop('rights') != 'none'):
                    pn.setProp('rights', 'none')
                    changed = changed + 1
            if not policy:
                pn = policymap.newChild(None, 'policy', None)
                pn.setProp('domain', domain)
                pn.setProp('pattern', pattern)
                pn.setProp('rights', 'none')
                ws = libxml2.newText('\n  ')
                pn.addNextSibling(ws)
                if (not inserted):
                    ws = libxml2.newText('\n  ')
                    pn.addPrevSibling(ws)
                inserted = pn
                
    if (inserted):
      inserted.next.setContent('\n\n')

    if (inserted or changed):
        shutil.copy2(filename, filename + '.cvebak')
        doc.saveFile(filename)

for pattern in policyFiles:
    for filename in glob.glob(pattern):
        if (os.path.isfile(filename)):
            disablePolicies(filename, policiesToDisable)

for pattern in delegateFiles:
    for filename in glob.glob(pattern):
        if (os.path.isfile(filename)):
            setDelegateCommands(filename, delegatesToOverride)
            
for pattern in denyFiles.keys():
        for directory in glob.glob(pattern):
            if (os.path.isdir(directory)):
                for filename in denyFiles[pattern]:
                    if (os.path.isfile(directory + '/' + filename)):
                            os.chmod(directory + '/' + filename, 0)
I do also have rpms for el5 & el7 (the only difference is the signatures), which apply the script and re-apply it on any ImageMagick updates (via an rpm trigger) which is what I deployed to my systems, note that neither the script or the rpms actually check for the vulnability, they just apply all the mitigations and will totally disable MVG/MSL/SVG/LABEL features, also if you chose to use the rpm note that uninstalling it does not revert the changes!

Source RPM cve-2016-3714-1.0.0-2.ng.src.rpm
RHEL/CentOS 5 RPM cve-2016-3714-1.0.0-2.el5.ng.noarch.rpm
RHEL/CentOS 7 RPM cve-2016-3714-1.0.0-2.el7.ng.noarch.rpm

The RPMS are signed with the following GPG key

Code: Select all

pub  4096R/7B8E4A54 2016-02-23 Noggin IT (RPM Signing Key - release repos) <sysadmin@noggin.com.au>
      Key fingerprint = 7860 C910 D239 A3EE 9121  6F4B C1D1 FD90 7B8E 4A54

Post Reply