Fix for imagemagick vulnerability

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Fix for imagemagick vulnerability

Jolle Carlestam-2
Hello!

Ke made a Gitter lasso chat room alert about an exploit possibility recently found in ImageMagick.

https://imagetragick.com/

The recommended protection that we should all take is summarized as:

• Verify that all image files begin with the expected "magic bytes" corresponding to the image file types you support before sending them to ImageMagick for processing.
• Use a policy file to disable the vulnerable ImageMagick coders. The global policy for ImageMagick is usually found in “/etc/ImageMagick”.

The second item is something that all server admins should do ASAP directly on their server.

The first item is for us Lasso developers to take care of in our code. Basically, before you send any kind of image data to ImageMagick make sure that it’s a proper image and not an exploit attempt.
Note, a simple call to image(some_binary_data) is all that’s needed! That will invoke ImageMagick and open up for exploit.

Some iteration between Ke and myself gave this possible solution. First, create a method that will sniff for proper ”magic bytes”.

define image_sniff(bytedata::bytes) => {

        local(data = #bytedata -> sub(1, 30) -> encodehex -> asstring)

        match(true) => {
                case(#data -> substring(1, 8) == "00000100") return (: "ico")
                case(#data -> substring(1, 12) == "474946383761") return (: "gif")
                case(#data -> substring(1, 12) == "474946383961") return (: "gif")
                case(#data -> substring(1, 8) == "49492A00") return (: "tif","tiff")
                case(#data -> substring(1, 8) == "4D4D002A") return (: "tif","tiff")

                case((#data -> substring(1, 8) + #data -> substring(13, 4)) == 'FFD8FFE04A46') return (: "jpg","jpeg")
                case((#data -> substring(1, 8) + #data -> substring(13, 4)) == 'FFD8FFE14578') return (: "jpg","jpeg")
                case(#data -> substring(1, 8) == "69660000") return (: "jpg","jpeg")
                case(#data -> substring(1, 16) == "89504E470D0A1A0A") return (: "png")

                case(#data -> substring(1, 8) == "25215053") return (: "ps")
                case(#data -> substring(1, 8) == "25504446") return (: "pdf")
                case(#data -> substring(1, 8) == "38425053") return (: "psd")
                case(#data -> substring(1, 4) == "424D") return (: "bmp","dib")
        }

        return (: #data)
}

You can call this with some image bytes

local(filedata = file(’path/to/myimage.jpg') -> readbytes)
image_sniff(#filedata)

This will return a staticarray with file suffixes, if any of the image formats where found. In this case
(: "jpg","jpeg”)

It is then up to you to match that with the expectations you have for each place where you want the bytes sent to the image type.
For example, I have a method that can be used to compare arrays with arrays.

define array -> exists_in(m) => {

        if(#m -> isa(::array) or #m -> isa(::staticarray)) => {
                with v in #m do {
                        self >> (#v -> isa(::pair) ? #v -> value | #v) ? return true
                }
        else(#m -> isa(::map))
                with v in #m do {
                        self >> string(#v) ? return true
                }
        else
                fail(-1, 'Input of wrong type. Expected a map, staticarray or array')
        }
        return false
}

Combining the two methods can be done like so:

array('pdf', 'jpg', 'gif', 'tif') -> exists_in(image_sniff(file('path/to/myimage.jpg') -> read bytes))
array('pdf', 'jpg', 'gif', 'tif') -> exists_in(image_sniff(file('path/to/mytext.txt') -> read bytes))

This will return
true
false

Thanks Ke for the warning!

HDB
Jolle

#############################################################

This message is sent to you because you are subscribed to
  the mailing list Lasso [hidden email]
Official list archives available at http://www.lassotalk.com
To unsubscribe, E-mail to: <[hidden email]>
Send administrative queries to  <[hidden email]>
Reply | Threaded
Open this post in threaded view
|

Re: Fix for imagemagick vulnerability

stevepiercy
'file' uses 'magic' to sniff the file type.

$ file -b --mime-type moosehair.png
image/png

More options.
http://linux.die.net/man/1/file

One could use Lasso's os_process or sys_process to invoke the command.

Also policy.xml might not be in /etc/ImageMagick/.  Use 'find'
to locate it, then view its contents to make sure it's the right file.

     # dude, where's my policy.xml?
     find / -name 'policy.xml'
     cat /usr/lib64/ImageMagick-6.5.4/config/policy.xml

--steve


On 5/5/16 at 2:41 PM, [hidden email] (Jolle Carlestam) pronounced:

>Hello!
>
>Ke made a Gitter lasso chat room alert about an exploit
>possibility recently found in ImageMagick.
>
>https://imagetragick.com/
>
>The recommended protection that we should all take is summarized as:
>
>• Verify that all image files begin with the expected "magic
>bytes" corresponding to the image file types you support before
>sending them to ImageMagick for processing.
>• Use a policy file to disable the vulnerable ImageMagick
>coders. The global policy for ImageMagick is usually found in “/etc/ImageMagick”.
>
>The second item is something that all server admins should do
>ASAP directly on their server.
>
>The first item is for us Lasso developers to take care of in
>our code. Basically, before you send any kind of image data to
>ImageMagick make sure that it’s a proper image and not an
>exploit attempt.
>Note, a simple call to image(some_binary_data) is all that’s
>needed! That will invoke ImageMagick and open up for exploit.
>
>Some iteration between Ke and myself gave this possible
>solution. First, create a method that will sniff for proper
>”magic bytes”.
>
>define image_sniff(bytedata::bytes) => {
>
>local(data = #bytedata -> sub(1, 30) -> encodehex -> asstring)
>
>match(true) => {
>case(#data -> substring(1, 8) == "00000100") return (: "ico")
>case(#data -> substring(1, 12) == "474946383761") return (: "gif")
>case(#data -> substring(1, 12) == "474946383961") return (: "gif")
>case(#data -> substring(1, 8) == "49492A00") return (: "tif","tiff")
>case(#data -> substring(1, 8) == "4D4D002A") return (: "tif","tiff")
>
>case((#data -> substring(1, 8) + #data -> substring(13, 4)) ==
>'FFD8FFE04A46') return (: "jpg","jpeg")
>case((#data -> substring(1, 8) + #data -> substring(13, 4)) ==
>'FFD8FFE14578') return (: "jpg","jpeg")
>case(#data -> substring(1, 8) == "69660000") return (: "jpg","jpeg")
>case(#data -> substring(1, 16) == "89504E470D0A1A0A") return (: "png")
>
>case(#data -> substring(1, 8) == "25215053") return (: "ps")
>case(#data -> substring(1, 8) == "25504446") return (: "pdf")
>case(#data -> substring(1, 8) == "38425053") return (: "psd")
>case(#data -> substring(1, 4) == "424D") return (: "bmp","dib")
>}
>
>return (: #data)
>}
>
>You can call this with some image bytes
>
>local(filedata = file(’path/to/myimage.jpg') -> readbytes)
>image_sniff(#filedata)
>
>This will return a staticarray with file suffixes, if any of
>the image formats where found. In this case
>(: "jpg","jpeg”)
>
>It is then up to you to match that with the expectations you
>have for each place where you want the bytes sent to the image type.
>For example, I have a method that can be used to compare arrays with arrays.
>
>define array -> exists_in(m) => {
>
>if(#m -> isa(::array) or #m -> isa(::staticarray)) => {
>with v in #m do {
>self >> (#v -> isa(::pair) ? #v -> value | #v) ? return true
>}
>else(#m -> isa(::map))
>with v in #m do {
>self >> string(#v) ? return true
>}
>else
>fail(-1, 'Input of wrong type. Expected a map, staticarray or array')
>}
>return false
>}
>
>Combining the two methods can be done like so:
>
>array('pdf', 'jpg', 'gif', 'tif') ->
>exists_in(image_sniff(file('path/to/myimage.jpg') -> read bytes))
>array('pdf', 'jpg', 'gif', 'tif') ->
>exists_in(image_sniff(file('path/to/mytext.txt') -> read bytes))
>
>This will return
>true
>false
>
>Thanks Ke for the warning!
>
>HDB
>Jolle
>
>#############################################################
>
>This message is sent to you because you are subscribed to
>the mailing list Lasso [hidden email]
>Official list archives available at http://www.lassotalk.com
>To unsubscribe, E-mail to: <[hidden email]>
>Send administrative queries to  <[hidden email]>

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Steve Piercy              Website Builder              Soquel, CA
<[hidden email]>               <http://www.stevepiercy.com/>


#############################################################

This message is sent to you because you are subscribed to
  the mailing list Lasso [hidden email]
Official list archives available at http://www.lassotalk.com
To unsubscribe, E-mail to: <[hidden email]>
Send administrative queries to  <[hidden email]>
Reply | Threaded
Open this post in threaded view
|

Re: Fix for imagemagick vulnerability

John May-2
Is this an issue with a stock Lasso 8.5 install?  Or does one have to
explicitly install imagemagick?  I dont see a policy.xml file on my systems.

        - John



On 5/12/16 2:09 PM, Steve Piercy - Website Builder wrote:

> 'file' uses 'magic' to sniff the file type.
>
> $ file -b --mime-type moosehair.png
> image/png
>
> More options.
> http://linux.die.net/man/1/file
>
> One could use Lasso's os_process or sys_process to invoke the command.
>
> Also policy.xml might not be in /etc/ImageMagick/.  Use 'find' to locate
> it, then view its contents to make sure it's the right file.
>
>      # dude, where's my policy.xml?
>      find / -name 'policy.xml'
>      cat /usr/lib64/ImageMagick-6.5.4/config/policy.xml
>
> --steve
>
>
> On 5/5/16 at 2:41 PM, [hidden email] (Jolle Carlestam) pronounced:
>
>> Hello!
>>
>> Ke made a Gitter lasso chat room alert about an exploit possibility
>> recently found in ImageMagick.
>>
>> https://imagetragick.com/
>>
>> The recommended protection that we should all take is summarized as:
>>
>> • Verify that all image files begin with the expected "magic bytes"
>> corresponding to the image file types you support before sending them
>> to ImageMagick for processing.
>> • Use a policy file to disable the vulnerable ImageMagick coders. The
>> global policy for ImageMagick is usually found in “/etc/ImageMagick”.
>>
>> The second item is something that all server admins should do ASAP
>> directly on their server.
>>
>> The first item is for us Lasso developers to take care of in our code.
>> Basically, before you send any kind of image data to ImageMagick make
>> sure that it’s a proper image and not an exploit attempt.
>> Note, a simple call to image(some_binary_data) is all that’s needed!
>> That will invoke ImageMagick and open up for exploit.
>>
>> Some iteration between Ke and myself gave this possible solution.
>> First, create a method that will sniff for proper ”magic bytes”.
>>
>> define image_sniff(bytedata::bytes) => {
>>
>> local(data = #bytedata -> sub(1, 30) -> encodehex -> asstring)
>>
>> match(true) => {
>> case(#data -> substring(1, 8) == "00000100") return (: "ico")
>> case(#data -> substring(1, 12) == "474946383761") return (: "gif")
>> case(#data -> substring(1, 12) == "474946383961") return (: "gif")
>> case(#data -> substring(1, 8) == "49492A00") return (: "tif","tiff")
>> case(#data -> substring(1, 8) == "4D4D002A") return (: "tif","tiff")
>>
>> case((#data -> substring(1, 8) + #data -> substring(13, 4)) ==
>> 'FFD8FFE04A46') return (: "jpg","jpeg")
>> case((#data -> substring(1, 8) + #data -> substring(13, 4)) ==
>> 'FFD8FFE14578') return (: "jpg","jpeg")
>> case(#data -> substring(1, 8) == "69660000") return (: "jpg","jpeg")
>> case(#data -> substring(1, 16) == "89504E470D0A1A0A") return (: "png")
>>
>> case(#data -> substring(1, 8) == "25215053") return (: "ps")
>> case(#data -> substring(1, 8) == "25504446") return (: "pdf")
>> case(#data -> substring(1, 8) == "38425053") return (: "psd")
>> case(#data -> substring(1, 4) == "424D") return (: "bmp","dib")
>> }
>>
>> return (: #data)
>> }
>>
>> You can call this with some image bytes
>>
>> local(filedata = file(’path/to/myimage.jpg') -> readbytes)
>> image_sniff(#filedata)
>>
>> This will return a staticarray with file suffixes, if any of the image
>> formats where found. In this case
>> (: "jpg","jpeg”)
>>
>> It is then up to you to match that with the expectations you have for
>> each place where you want the bytes sent to the image type.
>> For example, I have a method that can be used to compare arrays with
>> arrays.
>>
>> define array -> exists_in(m) => {
>>
>> if(#m -> isa(::array) or #m -> isa(::staticarray)) => {
>> with v in #m do {
>> self >> (#v -> isa(::pair) ? #v -> value | #v) ? return true
>> }
>> else(#m -> isa(::map))
>> with v in #m do {
>> self >> string(#v) ? return true
>> }
>> else
>> fail(-1, 'Input of wrong type. Expected a map, staticarray or array')
>> }
>> return false
>> }
>>
>> Combining the two methods can be done like so:
>>
>> array('pdf', 'jpg', 'gif', 'tif') ->
>> exists_in(image_sniff(file('path/to/myimage.jpg') -> read bytes))
>> array('pdf', 'jpg', 'gif', 'tif') ->
>> exists_in(image_sniff(file('path/to/mytext.txt') -> read bytes))
>>
>> This will return
>> true
>> false
>>
>> Thanks Ke for the warning!
>>
>> HDB
>> Jolle
>>
--

-------------------------------------------------------------------
John May : President                   http://www.pointinspace.com/
Point In Space Internet Solutions         800.664.8610 919.338.8198

         Professional FileMaker Pro, MySQL, PHP & Lasso Hosting
           on shared, virtual and hardware dedicated servers


#############################################################

This message is sent to you because you are subscribed to
  the mailing list Lasso [hidden email]
Official list archives available at http://www.lassotalk.com
To unsubscribe, E-mail to: <[hidden email]>
Send administrative queries to  <[hidden email]>
Reply | Threaded
Open this post in threaded view
|

Re: Fix for imagemagick vulnerability

Jolle Carlestam-2
Until Lassosoft chimes in with a definitive answer I would say yes, the threat is still there.
Since Lasso calls imageMagick and imageMagick is vulnerable for these types of attacks. Would think especially since the version of imageMagick that comes wit hLassos installation probably not is of latest version and thus not patched.

HDB
Jolle


> 12 maj 2016 kl. 21:28 skrev John May <[hidden email]>:
>
> Is this an issue with a stock Lasso 8.5 install?  Or does one have to explicitly install imagemagick? I dont see a policy.xml file on my systems.
>
> - John


#############################################################

This message is sent to you because you are subscribed to
  the mailing list Lasso [hidden email]
Official list archives available at http://www.lassotalk.com
To unsubscribe, E-mail to: <[hidden email]>
Send administrative queries to  <[hidden email]>
Reply | Threaded
Open this post in threaded view
|

Re: Fix for imagemagick vulnerability

stevepiercy
In reply to this post by John May-2
I recommend checking for any vulnerabilities of your version of
IM before taking any action.
https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-3714

     ImageMagick before 6.9.3-10 and 7.x before 7.0.1-1

The vulnerability is with IM's core.  The issues can be
mitigated with:

* upgrading your IM install
* a policy.xml file with security configuration
* using 'file' to first sniff the MIME type of the file before
sending it to IM

AFAIK, none of those mitigations are possible with the stock
install of Lasso IM, thus requiring either a separate
installation or LassoSoft to provide an update.

Although this process is for CentOS/RHEL, a similar process
could be followed using brew or macports (I prefer brew) to
install IM on Mac OS X, assuming that's your host OS.
http://www.lassosoft.com/Upgrading-ImageMagick-on-CentOS-5

--steve


On 5/12/16 at 3:28 PM, [hidden email] (John May) pronounced:

>Is this an issue with a stock Lasso 8.5 install?  Or does one
>have to explicitly install imagemagick?  I dont see a
>policy.xml file on my systems.
>
>- John
>
>
>
>On 5/12/16 2:09 PM, Steve Piercy - Website Builder wrote:
>>'file' uses 'magic' to sniff the file type.
>>
>>$ file -b --mime-type moosehair.png
>>image/png
>>
>>More options.
>>http://linux.die.net/man/1/file
>>
>>One could use Lasso's os_process or sys_process to invoke the command.
>>
>>Also policy.xml might not be in /etc/ImageMagick/.  Use 'find' to locate
>>it, then view its contents to make sure it's the right file.
>>
>># dude, where's my policy.xml?
>>find / -name 'policy.xml'
>>cat /usr/lib64/ImageMagick-6.5.4/config/policy.xml
>>
>>--steve
>>
>>
>>On 5/5/16 at 2:41 PM, [hidden email] (Jolle Carlestam) pronounced:
>>
>>> Hello!
>>>
>>> Ke made a Gitter lasso chat room alert about an exploit possibility
>>> recently found in ImageMagick.
>>>
>>> https://imagetragick.com/
>>>
>>> The recommended protection that we should all take is summarized as:
>>>
>>> • Verify that all image files begin with the expected "magic bytes"
>>> corresponding to the image file types you support before sending them
>>> to ImageMagick for processing.
>>> • Use a policy file to disable the vulnerable ImageMagick coders. The
>>> global policy for ImageMagick is usually found in “/etc/ImageMagick”.
>>>
>>> The second item is something that all server admins should do ASAP
>>> directly on their server.
>>>
>>> The first item is for us Lasso developers to take care of in our code.
>>> Basically, before you send any kind of image data to ImageMagick make
>>> sure that it’s a proper image and not an exploit attempt.
>>> Note, a simple call to image(some_binary_data) is all that’s needed!
>>> That will invoke ImageMagick and open up for exploit.
>>>
>>> Some iteration between Ke and myself gave this possible solution.
>>> First, create a method that will sniff for proper ”magic bytes”.
>>>
>>> define image_sniff(bytedata::bytes) => {
>>>
>>> local(data = #bytedata -> sub(1, 30) -> encodehex -> asstring)
>>>
>>> match(true) => {
>>> case(#data -> substring(1, 8) == "00000100") return (: "ico")
>>> case(#data -> substring(1, 12) == "474946383761") return (: "gif")
>>> case(#data -> substring(1, 12) == "474946383961") return (: "gif")
>>> case(#data -> substring(1, 8) == "49492A00") return (: "tif","tiff")
>>> case(#data -> substring(1, 8) == "4D4D002A") return (: "tif","tiff")
>>>
>>> case((#data -> substring(1, 8) + #data -> substring(13, 4)) ==
>>> 'FFD8FFE04A46') return (: "jpg","jpeg")
>>> case((#data -> substring(1, 8) + #data -> substring(13, 4)) ==
>>> 'FFD8FFE14578') return (: "jpg","jpeg")
>>> case(#data -> substring(1, 8) == "69660000") return (: "jpg","jpeg")
>>> case(#data -> substring(1, 16) == "89504E470D0A1A0A") return (: "png")
>>>
>>> case(#data -> substring(1, 8) == "25215053") return (: "ps")
>>> case(#data -> substring(1, 8) == "25504446") return (: "pdf")
>>> case(#data -> substring(1, 8) == "38425053") return (: "psd")
>>> case(#data -> substring(1, 4) == "424D") return (: "bmp","dib")
>>> }
>>>
>>> return (: #data)
>>> }
>>>
>>> You can call this with some image bytes
>>>
>>> local(filedata = file(’path/to/myimage.jpg') -> readbytes)
>>> image_sniff(#filedata)
>>>
>>> This will return a staticarray with file suffixes, if any of the image
>>> formats where found. In this case
>>> (: "jpg","jpeg”)
>>>
>>> It is then up to you to match that with the expectations you have for
>>> each place where you want the bytes sent to the image type.
>>> For example, I have a method that can be used to compare arrays with
>>> arrays.
>>>
>>> define array -> exists_in(m) => {
>>>
>>> if(#m -> isa(::array) or #m -> isa(::staticarray)) => {
>>> with v in #m do {
>>> self >> (#v -> isa(::pair) ? #v -> value | #v) ? return true
>>> }
>>> else(#m -> isa(::map))
>>> with v in #m do {
>>> self >> string(#v) ? return true
>>> }
>>> else
>>> fail(-1, 'Input of wrong type. Expected a map, staticarray or array')
>>> }
>>> return false
>>> }
>>>
>>> Combining the two methods can be done like so:
>>>
>>> array('pdf', 'jpg', 'gif', 'tif') ->
>>> exists_in(image_sniff(file('path/to/myimage.jpg') -> read bytes))
>>> array('pdf', 'jpg', 'gif', 'tif') ->
>>> exists_in(image_sniff(file('path/to/mytext.txt') -> read bytes))
>>>
>>> This will return
>>> true
>>> false
>>>
>>> Thanks Ke for the warning!
>>>
>>> HDB
>>> Jolle
>>>

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Steve Piercy              Website Builder              Soquel, CA
<[hidden email]>               <http://www.stevepiercy.com/>


#############################################################

This message is sent to you because you are subscribed to
  the mailing list Lasso [hidden email]
Official list archives available at http://www.lassotalk.com
To unsubscribe, E-mail to: <[hidden email]>
Send administrative queries to  <[hidden email]>
Reply | Threaded
Open this post in threaded view
|

Re: Fix for imagemagick vulnerability

Bil Corry-3
Even if an vulnerable Imagemagick is installed, to exploit it,
attacker-controlled images have to be sent to it.  If Imagemagick isn't
used, then there isn't any risk.

If you are using Imagemagick, then upgrading to the latest version helps,
but note there are many more flaws that could also lead to RCE, DoS, etc.
This blog is from a respected security researcher at Google, it has
suggestions on how to use Imagemagick safely:

https://lcamtuf.blogspot.lu/2016/05/clearing-up-some-misconceptions-around.html


- Bil

On Fri, May 13, 2016 at 2:00 AM, Steve Piercy - Website Builder <
[hidden email]> wrote:

> I recommend checking for any vulnerabilities of your version of IM before
> taking any action.
> https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-3714
>
>     ImageMagick before 6.9.3-10 and 7.x before 7.0.1-1
>
> The vulnerability is with IM's core.  The issues can be mitigated with:
>
> * upgrading your IM install
> * a policy.xml file with security configuration
> * using 'file' to first sniff the MIME type of the file before sending it
> to IM
>
> AFAIK, none of those mitigations are possible with the stock install of
> Lasso IM, thus requiring either a separate installation or LassoSoft to
> provide an update.
>
> Although this process is for CentOS/RHEL, a similar process could be
> followed using brew or macports (I prefer brew) to install IM on Mac OS X,
> assuming that's your host OS.
> http://www.lassosoft.com/Upgrading-ImageMagick-on-CentOS-5
>
> --steve
>
>
> On 5/12/16 at 3:28 PM, [hidden email] (John May) pronounced:
>
>
> Is this an issue with a stock Lasso 8.5 install?  Or does one have to
>> explicitly install imagemagick?  I dont see a policy.xml file on my systems.
>>
>> - John
>>
>>
>>
>> On 5/12/16 2:09 PM, Steve Piercy - Website Builder wrote:
>>
>>> 'file' uses 'magic' to sniff the file type.
>>>
>>> $ file -b --mime-type moosehair.png
>>> image/png
>>>
>>> More options.
>>> http://linux.die.net/man/1/file
>>>
>>> One could use Lasso's os_process or sys_process to invoke the command.
>>>
>>> Also policy.xml might not be in /etc/ImageMagick/.  Use 'find' to locate
>>> it, then view its contents to make sure it's the right file.
>>>
>>> # dude, where's my policy.xml?
>>> find / -name 'policy.xml'
>>> cat /usr/lib64/ImageMagick-6.5.4/config/policy.xml
>>>
>>> --steve
>>>
>>>
>>> On 5/5/16 at 2:41 PM, [hidden email] (Jolle Carlestam) pronounced:
>>>
>>> Hello!
>>>>
>>>> Ke made a Gitter lasso chat room alert about an exploit possibility
>>>> recently found in ImageMagick.
>>>>
>>>> https://imagetragick.com/
>>>>
>>>> The recommended protection that we should all take is summarized as:
>>>>
>>>> • Verify that all image files begin with the expected "magic bytes"
>>>> corresponding to the image file types you support before sending them
>>>> to ImageMagick for processing.
>>>> • Use a policy file to disable the vulnerable ImageMagick coders. The
>>>> global policy for ImageMagick is usually found in “/etc/ImageMagick”.
>>>>
>>>> The second item is something that all server admins should do ASAP
>>>> directly on their server.
>>>>
>>>> The first item is for us Lasso developers to take care of in our code.
>>>> Basically, before you send any kind of image data to ImageMagick make
>>>> sure that it’s a proper image and not an exploit attempt.
>>>> Note, a simple call to image(some_binary_data) is all that’s needed!
>>>> That will invoke ImageMagick and open up for exploit.
>>>>
>>>> Some iteration between Ke and myself gave this possible solution.
>>>> First, create a method that will sniff for proper ”magic bytes”.
>>>>
>>>> define image_sniff(bytedata::bytes) => {
>>>>
>>>> local(data = #bytedata -> sub(1, 30) -> encodehex -> asstring)
>>>>
>>>> match(true) => {
>>>> case(#data -> substring(1, 8) == "00000100") return (: "ico")
>>>> case(#data -> substring(1, 12) == "474946383761") return (: "gif")
>>>> case(#data -> substring(1, 12) == "474946383961") return (: "gif")
>>>> case(#data -> substring(1, 8) == "49492A00") return (: "tif","tiff")
>>>> case(#data -> substring(1, 8) == "4D4D002A") return (: "tif","tiff")
>>>>
>>>> case((#data -> substring(1, 8) + #data -> substring(13, 4)) ==
>>>> 'FFD8FFE04A46') return (: "jpg","jpeg")
>>>> case((#data -> substring(1, 8) + #data -> substring(13, 4)) ==
>>>> 'FFD8FFE14578') return (: "jpg","jpeg")
>>>> case(#data -> substring(1, 8) == "69660000") return (: "jpg","jpeg")
>>>> case(#data -> substring(1, 16) == "89504E470D0A1A0A") return (: "png")
>>>>
>>>> case(#data -> substring(1, 8) == "25215053") return (: "ps")
>>>> case(#data -> substring(1, 8) == "25504446") return (: "pdf")
>>>> case(#data -> substring(1, 8) == "38425053") return (: "psd")
>>>> case(#data -> substring(1, 4) == "424D") return (: "bmp","dib")
>>>> }
>>>>
>>>> return (: #data)
>>>> }
>>>>
>>>> You can call this with some image bytes
>>>>
>>>> local(filedata = file(’path/to/myimage.jpg') -> readbytes)
>>>> image_sniff(#filedata)
>>>>
>>>> This will return a staticarray with file suffixes, if any of the image
>>>> formats where found. In this case
>>>> (: "jpg","jpeg”)
>>>>
>>>> It is then up to you to match that with the expectations you have for
>>>> each place where you want the bytes sent to the image type.
>>>> For example, I have a method that can be used to compare arrays with
>>>> arrays.
>>>>
>>>> define array -> exists_in(m) => {
>>>>
>>>> if(#m -> isa(::array) or #m -> isa(::staticarray)) => {
>>>> with v in #m do {
>>>> self >> (#v -> isa(::pair) ? #v -> value | #v) ? return true
>>>> }
>>>> else(#m -> isa(::map))
>>>> with v in #m do {
>>>> self >> string(#v) ? return true
>>>> }
>>>> else
>>>> fail(-1, 'Input of wrong type. Expected a map, staticarray or array')
>>>> }
>>>> return false
>>>> }
>>>>
>>>> Combining the two methods can be done like so:
>>>>
>>>> array('pdf', 'jpg', 'gif', 'tif') ->
>>>> exists_in(image_sniff(file('path/to/myimage.jpg') -> read bytes))
>>>> array('pdf', 'jpg', 'gif', 'tif') ->
>>>> exists_in(image_sniff(file('path/to/mytext.txt') -> read bytes))
>>>>
>>>> This will return
>>>> true
>>>> false
>>>>
>>>> Thanks Ke for the warning!
>>>>
>>>> HDB
>>>> Jolle
>>>>
>>>>
> -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> Steve Piercy              Website Builder              Soquel, CA
> <[hidden email]>               <http://www.stevepiercy.com/>
>
>
> #############################################################
>
> This message is sent to you because you are subscribed to
>  the mailing list Lasso [hidden email]
> Official list archives available at http://www.lassotalk.com
> To unsubscribe, E-mail to: <[hidden email]>
> Send administrative queries to  <[hidden email]>
>

#############################################################

This message is sent to you because you are subscribed to
  the mailing list Lasso [hidden email]
Official list archives available at http://www.lassotalk.com
To unsubscribe, E-mail to: <[hidden email]>
Send administrative queries to  <[hidden email]>
Reply | Threaded
Open this post in threaded view
|

Re: Fix for imagemagick vulnerability

Mason Miller
In reply to this post by Jolle Carlestam-2
I am using exiftool to try to sniff out the file:

                'myProcess' = (OS_Process: '/usr/bin/exiftool', (array:((File_Uploads)->(Get:(Loop_Count))->(Find:'upload.name'))) );
                var:
                'simpleInfo' = $myProcess->ReadString;
                if:$simpleInfo >> 'Unknown file type';
                        log: '/exif.log';(output:$simpleInfo + '\r\r');/log;
                        abort;
                /if;

Does this seem like a decent approach?

Mason

> On May 5, 2016, at 8:41 AM, Jolle Carlestam <[hidden email]> wrote:
>
> Hello!
>
> Ke made a Gitter lasso chat room alert about an exploit possibility recently found in ImageMagick.
>
> https://imagetragick.com/
>
> The recommended protection that we should all take is summarized as:
>
> • Verify that all image files begin with the expected "magic bytes" corresponding to the image file types you support before sending them to ImageMagick for processing.
> • Use a policy file to disable the vulnerable ImageMagick coders. The global policy for ImageMagick is usually found in “/etc/ImageMagick”.
>
> The second item is something that all server admins should do ASAP directly on their server.
>
> The first item is for us Lasso developers to take care of in our code. Basically, before you send any kind of image data to ImageMagick make sure that it’s a proper image and not an exploit attempt.
> Note, a simple call to image(some_binary_data) is all that’s needed! That will invoke ImageMagick and open up for exploit.
>
> Some iteration between Ke and myself gave this possible solution. First, create a method that will sniff for proper ”magic bytes”.
>
> define image_sniff(bytedata::bytes) => {
>
> local(data = #bytedata -> sub(1, 30) -> encodehex -> asstring)
>
> match(true) => {
> case(#data -> substring(1, 8) == "00000100") return (: "ico")
> case(#data -> substring(1, 12) == "474946383761") return (: "gif")
> case(#data -> substring(1, 12) == "474946383961") return (: "gif")
> case(#data -> substring(1, 8) == "49492A00") return (: "tif","tiff")
> case(#data -> substring(1, 8) == "4D4D002A") return (: "tif","tiff")
>
> case((#data -> substring(1, 8) + #data -> substring(13, 4)) == 'FFD8FFE04A46') return (: "jpg","jpeg")
> case((#data -> substring(1, 8) + #data -> substring(13, 4)) == 'FFD8FFE14578') return (: "jpg","jpeg")
> case(#data -> substring(1, 8) == "69660000") return (: "jpg","jpeg")
> case(#data -> substring(1, 16) == "89504E470D0A1A0A") return (: "png")
>
> case(#data -> substring(1, 8) == "25215053") return (: "ps")
> case(#data -> substring(1, 8) == "25504446") return (: "pdf")
> case(#data -> substring(1, 8) == "38425053") return (: "psd")
> case(#data -> substring(1, 4) == "424D") return (: "bmp","dib")
> }
>
> return (: #data)
> }
>
> You can call this with some image bytes
>
> local(filedata = file(’path/to/myimage.jpg') -> readbytes)
> image_sniff(#filedata)
>
> This will return a staticarray with file suffixes, if any of the image formats where found. In this case
> (: "jpg","jpeg”)
>
> It is then up to you to match that with the expectations you have for each place where you want the bytes sent to the image type.
> For example, I have a method that can be used to compare arrays with arrays.
>
> define array -> exists_in(m) => {
>
> if(#m -> isa(::array) or #m -> isa(::staticarray)) => {
> with v in #m do {
> self >> (#v -> isa(::pair) ? #v -> value | #v) ? return true
> }
> else(#m -> isa(::map))
> with v in #m do {
> self >> string(#v) ? return true
> }
> else
> fail(-1, 'Input of wrong type. Expected a map, staticarray or array')
> }
> return false
> }
>
> Combining the two methods can be done like so:
>
> array('pdf', 'jpg', 'gif', 'tif') -> exists_in(image_sniff(file('path/to/myimage.jpg') -> read bytes))
> array('pdf', 'jpg', 'gif', 'tif') -> exists_in(image_sniff(file('path/to/mytext.txt') -> read bytes))
>
> This will return
> true
> false
>
> Thanks Ke for the warning!
>
> HDB
> Jolle
>
> #############################################################
>
> This message is sent to you because you are subscribed to
>  the mailing list Lasso [hidden email]
> Official list archives available at http://www.lassotalk.com
> To unsubscribe, E-mail to: <[hidden email]>
> Send administrative queries to  <[hidden email]>



#############################################################

This message is sent to you because you are subscribed to
  the mailing list Lasso [hidden email]
Official list archives available at http://www.lassotalk.com
To unsubscribe, E-mail to: <[hidden email]>
Send administrative queries to  <[hidden email]>
Reply | Threaded
Open this post in threaded view
|

Re: Fix for imagemagick vulnerability

Marc Vos-3
Well, Exiftool is actually a tool for managing metadata inside images.
See for example my SetEXIFData (http://marc.vos.net/downloads/setexifdata/) tool which uses Phil's exiftool.

Personally I like Steve's 'file -b --mime-type moosehair.png' very much. Easy and simple.
To check if it works ok, I renamed the extension of a .zip file to .tif, but that luckily didn't fool the tool ...

$ file -b --mime-type WhatsApp.zip
application/zip
$ file -b --mime-type WhatsApp.tif
application/zip

- -
Regards,
Marc

> On 13 mei 2016, at 17:43, Mason Miller <[hidden email]> wrote:
>
> I am using exiftool to try to sniff out the file:
>
> 'myProcess' = (OS_Process: '/usr/bin/exiftool', (array:((File_Uploads)->(Get:(Loop_Count))->(Find:'upload.name'))) );
> var:
> 'simpleInfo' = $myProcess->ReadString;
> if:$simpleInfo >> 'Unknown file type';
> log: '/exif.log';(output:$simpleInfo + '\r\r');/log;
> abort;
> /if;
>
> Does this seem like a decent approach?
>
> Mason
>
>> On May 5, 2016, at 8:41 AM, Jolle Carlestam <[hidden email]> wrote:
>>
>> Hello!
>>
>> Ke made a Gitter lasso chat room alert about an exploit possibility recently found in ImageMagick.
>>
>> https://imagetragick.com/
>>
>> The recommended protection that we should all take is summarized as:
>>
>> • Verify that all image files begin with the expected "magic bytes" corresponding to the image file types you support before sending them to ImageMagick for processing.
>> • Use a policy file to disable the vulnerable ImageMagick coders. The global policy for ImageMagick is usually found in “/etc/ImageMagick”.
>>
>> The second item is something that all server admins should do ASAP directly on their server.
>>
>> The first item is for us Lasso developers to take care of in our code. Basically, before you send any kind of image data to ImageMagick make sure that it’s a proper image and not an exploit attempt.
>> Note, a simple call to image(some_binary_data) is all that’s needed! That will invoke ImageMagick and open up for exploit.
>>
>> Some iteration between Ke and myself gave this possible solution. First, create a method that will sniff for proper ”magic bytes”.
>>
>> define image_sniff(bytedata::bytes) => {
>>
>> local(data = #bytedata -> sub(1, 30) -> encodehex -> asstring)
>>
>> match(true) => {
>> case(#data -> substring(1, 8) == "00000100") return (: "ico")
>> case(#data -> substring(1, 12) == "474946383761") return (: "gif")
>> case(#data -> substring(1, 12) == "474946383961") return (: "gif")
>> case(#data -> substring(1, 8) == "49492A00") return (: "tif","tiff")
>> case(#data -> substring(1, 8) == "4D4D002A") return (: "tif","tiff")
>>
>> case((#data -> substring(1, 8) + #data -> substring(13, 4)) == 'FFD8FFE04A46') return (: "jpg","jpeg")
>> case((#data -> substring(1, 8) + #data -> substring(13, 4)) == 'FFD8FFE14578') return (: "jpg","jpeg")
>> case(#data -> substring(1, 8) == "69660000") return (: "jpg","jpeg")
>> case(#data -> substring(1, 16) == "89504E470D0A1A0A") return (: "png")
>>
>> case(#data -> substring(1, 8) == "25215053") return (: "ps")
>> case(#data -> substring(1, 8) == "25504446") return (: "pdf")
>> case(#data -> substring(1, 8) == "38425053") return (: "psd")
>> case(#data -> substring(1, 4) == "424D") return (: "bmp","dib")
>> }
>>
>> return (: #data)
>> }
>>
>> You can call this with some image bytes
>>
>> local(filedata = file(’path/to/myimage.jpg') -> readbytes)
>> image_sniff(#filedata)
>>
>> This will return a staticarray with file suffixes, if any of the image formats where found. In this case
>> (: "jpg","jpeg”)
>>
>> It is then up to you to match that with the expectations you have for each place where you want the bytes sent to the image type.
>> For example, I have a method that can be used to compare arrays with arrays.
>>
>> define array -> exists_in(m) => {
>>
>> if(#m -> isa(::array) or #m -> isa(::staticarray)) => {
>> with v in #m do {
>> self >> (#v -> isa(::pair) ? #v -> value | #v) ? return true
>> }
>> else(#m -> isa(::map))
>> with v in #m do {
>> self >> string(#v) ? return true
>> }
>> else
>> fail(-1, 'Input of wrong type. Expected a map, staticarray or array')
>> }
>> return false
>> }
>>
>> Combining the two methods can be done like so:
>>
>> array('pdf', 'jpg', 'gif', 'tif') -> exists_in(image_sniff(file('path/to/myimage.jpg') -> read bytes))
>> array('pdf', 'jpg', 'gif', 'tif') -> exists_in(image_sniff(file('path/to/mytext.txt') -> read bytes))
>>
>> This will return
>> true
>> false
>>
>> Thanks Ke for the warning!
>>
>> HDB
>> Jolle
>>
>> #############################################################
>>
>> This message is sent to you because you are subscribed to
>> the mailing list Lasso [hidden email]
>> Official list archives available at http://www.lassotalk.com
>> To unsubscribe, E-mail to: <[hidden email]>
>> Send administrative queries to  <[hidden email]>
>
>
>
> #############################################################
>
> This message is sent to you because you are subscribed to
>  the mailing list Lasso [hidden email]
> Official list archives available at http://www.lassotalk.com
> To unsubscribe, E-mail to: <[hidden email]>
> Send administrative queries to  <[hidden email]>


#############################################################

This message is sent to you because you are subscribed to
  the mailing list Lasso [hidden email]
Official list archives available at http://www.lassotalk.com
To unsubscribe, E-mail to: <[hidden email]>
Send administrative queries to  <[hidden email]>
Reply | Threaded
Open this post in threaded view
|

Re: Fix for imagemagick vulnerability

Steffan A. Cline
Try compromising a file the same way the article describes and see if "file" catches it.


Thanks,
Steffan Cline
[hidden email]
602-793-0014

> On May 13, 2016, at 9:26 AM, Marc Vos <[hidden email]> wrote:
>
> Well, Exiftool is actually a tool for managing metadata inside images.
> See for example my SetEXIFData (http://marc.vos.net/downloads/setexifdata/) tool which uses Phil's exiftool.
>
> Personally I like Steve's 'file -b --mime-type moosehair.png' very much. Easy and simple.
> To check if it works ok, I renamed the extension of a .zip file to .tif, but that luckily didn't fool the tool ...
>
> $ file -b --mime-type WhatsApp.zip
> application/zip
> $ file -b --mime-type WhatsApp.tif
> application/zip
>
> - -
> Regards,
> Marc
>
>> On 13 mei 2016, at 17:43, Mason Miller <[hidden email]> wrote:
>>
>> I am using exiftool to try to sniff out the file:
>>
>>        'myProcess' = (OS_Process: '/usr/bin/exiftool', (array:((File_Uploads)->(Get:(Loop_Count))->(Find:'upload.name'))) );
>>        var:
>>        'simpleInfo' = $myProcess->ReadString;
>>        if:$simpleInfo >> 'Unknown file type';
>>            log: '/exif.log';(output:$simpleInfo + '\r\r');/log;    
>>            abort;
>>        /if;
>>
>> Does this seem like a decent approach?
>>
>> Mason
>>
>>> On May 5, 2016, at 8:41 AM, Jolle Carlestam <[hidden email]> wrote:
>>>
>>> Hello!
>>>
>>> Ke made a Gitter lasso chat room alert about an exploit possibility recently found in ImageMagick.
>>>
>>> https://imagetragick.com/
>>>
>>> The recommended protection that we should all take is summarized as:
>>>
>>> • Verify that all image files begin with the expected "magic bytes" corresponding to the image file types you support before sending them to ImageMagick for processing.
>>> • Use a policy file to disable the vulnerable ImageMagick coders. The global policy for ImageMagick is usually found in “/etc/ImageMagick”.
>>>
>>> The second item is something that all server admins should do ASAP directly on their server.
>>>
>>> The first item is for us Lasso developers to take care of in our code. Basically, before you send any kind of image data to ImageMagick make sure that it’s a proper image and not an exploit attempt.
>>> Note, a simple call to image(some_binary_data) is all that’s needed! That will invoke ImageMagick and open up for exploit.
>>>
>>> Some iteration between Ke and myself gave this possible solution. First, create a method that will sniff for proper ”magic bytes”.
>>>
>>> define image_sniff(bytedata::bytes) => {
>>>
>>>    local(data = #bytedata -> sub(1, 30) -> encodehex -> asstring)
>>>
>>>    match(true) => {
>>>        case(#data -> substring(1, 8) == "00000100") return (: "ico")
>>>        case(#data -> substring(1, 12) == "474946383761") return (: "gif")
>>>        case(#data -> substring(1, 12) == "474946383961") return (: "gif")
>>>        case(#data -> substring(1, 8) == "49492A00") return (: "tif","tiff")
>>>        case(#data -> substring(1, 8) == "4D4D002A") return (: "tif","tiff")
>>>
>>>        case((#data -> substring(1, 8) + #data -> substring(13, 4)) == 'FFD8FFE04A46') return (: "jpg","jpeg")
>>>        case((#data -> substring(1, 8) + #data -> substring(13, 4)) == 'FFD8FFE14578') return (: "jpg","jpeg")
>>>        case(#data -> substring(1, 8) == "69660000") return (: "jpg","jpeg")
>>>        case(#data -> substring(1, 16) == "89504E470D0A1A0A") return (: "png")
>>>
>>>        case(#data -> substring(1, 8) == "25215053") return (: "ps")
>>>        case(#data -> substring(1, 8) == "25504446") return (: "pdf")
>>>        case(#data -> substring(1, 8) == "38425053") return (: "psd")
>>>        case(#data -> substring(1, 4) == "424D") return (: "bmp","dib")
>>>    }
>>>
>>>    return (: #data)
>>> }
>>>
>>> You can call this with some image bytes
>>>
>>> local(filedata = file(’path/to/myimage.jpg') -> readbytes)
>>> image_sniff(#filedata)
>>>
>>> This will return a staticarray with file suffixes, if any of the image formats where found. In this case
>>> (: "jpg","jpeg”)
>>>
>>> It is then up to you to match that with the expectations you have for each place where you want the bytes sent to the image type.
>>> For example, I have a method that can be used to compare arrays with arrays.
>>>
>>> define array -> exists_in(m) => {
>>>
>>>    if(#m -> isa(::array) or #m -> isa(::staticarray)) => {
>>>        with v in #m do {
>>>            self >> (#v -> isa(::pair) ? #v -> value | #v) ? return true
>>>        }
>>>    else(#m -> isa(::map))
>>>        with v in #m do {
>>>            self >> string(#v) ? return true
>>>        }
>>>    else
>>>        fail(-1, 'Input of wrong type. Expected a map, staticarray or array')
>>>    }
>>>    return false
>>> }
>>>
>>> Combining the two methods can be done like so:
>>>
>>> array('pdf', 'jpg', 'gif', 'tif') -> exists_in(image_sniff(file('path/to/myimage.jpg') -> read bytes))
>>> array('pdf', 'jpg', 'gif', 'tif') -> exists_in(image_sniff(file('path/to/mytext.txt') -> read bytes))
>>>
>>> This will return
>>> true
>>> false
>>>
>>> Thanks Ke for the warning!
>>>
>>> HDB
>>> Jolle
>>>
>>> #############################################################
>>>
>>> This message is sent to you because you are subscribed to
>>> the mailing list Lasso [hidden email]
>>> Official list archives available at http://www.lassotalk.com
>>> To unsubscribe, E-mail to: <[hidden email]>
>>> Send administrative queries to  <[hidden email]>
>>
>>
>>
>> #############################################################
>>
>> This message is sent to you because you are subscribed to
>> the mailing list Lasso [hidden email]
>> Official list archives available at http://www.lassotalk.com
>> To unsubscribe, E-mail to: <[hidden email]>
>> Send administrative queries to  <[hidden email]>
>
>
> #############################################################
>
> This message is sent to you because you are subscribed to
>  the mailing list Lasso [hidden email]
> Official list archives available at http://www.lassotalk.com
> To unsubscribe, E-mail to: <[hidden email]>
> Send administrative queries to  <[hidden email]>


#############################################################

This message is sent to you because you are subscribed to
  the mailing list Lasso [hidden email]
Official list archives available at http://www.lassotalk.com
To unsubscribe, E-mail to: <[hidden email]>
Send administrative queries to  <[hidden email]>