Didier Stevens

Saturday 17 January 2009

Playing With Authenticode and MD5 Collisions

Filed under: Encryption,Hacking — Didier Stevens @ 15:11

Back when I researched Microsoft’s code signing mechanism (Authenticode), I noticed it still supported MD5, but that the signtool uses SHA1 by default.

You can extract the signature from one program and inject it in another, but that signature will not be valid for the second program. The cryptographic hash of the parts of the program signed by Authenticode is different for both programs, so the signature is invalid. By default, Microsoft’s codesigning uses SHA1 to hash the program. And that’s too difficult to find a collision for. But Authenticode also supports MD5, and generating collisions for MD5 has become feasible under the right circumstances.
illustration-ab

If both programs have the same MD5 Authenticode hash, the signature can be copied from program A to program B and it will remain valid. Here is the procedure I followed to achieve this.

I start to work with the goodevil program used on this MD5 Collision site. goodevil is a schizophrenic program. It contains both good and evil in it, and it decides to execute the good part or the evil part depending on some data it caries. This data is different for both programs, and also makes that both programs have the same MD5 hash.

The MD5 collision procedure explained on Peter Selinger’s page will generate 2 different programs, good and evil, with the same MD5 hash. But this is not what I need. I need 2 different programs that generate the same MD5 hash for the byte sequences taken into account by the Authenticode signature. For a simple PE file, the PE Checksum (4 bytes) and the pointer to the digital signature (8 bytes) are not taken into account (complete details here). That shouldn’t be a surprise, because signing a PE file changes these values.

So let’s remove these bytes from PE file goodevil.exe, and call it goodevil.exe.stripped. The hash for goodevil.exe.stripped is the same as the Authenticode hash for goodevil.exe.

20090116-235321

20090116-235400

Now I can compute an MD5 collision for goodevil.exe.stripped, as explained on Peter Selinger’s page. (I could also have modified the MD5 collision programs to skip these fields, but because this is just a one shot demo, I decided not to).

After about an hour, I have 2 new files, good.exe.stripped and evil.exe.stripped, both with the same MD5 hash. I transform them back to standard-compliant PE files by adding the checksum and pointer bytes I removed (giving me good.exe and evil.exe). Now the MD5 hashes are different again, but not the Authenticode MD5 hashes (Authenticode disregards the PE checksum and the signature pointer when calculating the hash).

OK, now I sign good.exe with my own cert. But there’s a little change in the code signing procedure I explained in this other post.

One difference is that I select custom signing:

20090116-232242

This allows me to select MD5 hashing in stead of the default SHA1:

20090116-232318

OK, now good.signed.exe is signed:

20090117-000846

20090117-001029

The signature is valid, and of course, the program still works:

20090117-001333

Let’s summarize what we have. Two programs with different behavior (good.exe and evil.exe), both with the same MD5 Authenticode hash, one with a valid Authenticode signature (good.signed.exe), the other without signature.

Now I extract the signature of good.signed.exe and add it to evil.exe, saving it with the name evil.signed.exe. I use my digital signature tool disitool for this:

disitool.py copy good.signed.exe evil.exe evil.signed.exe

illustration-aa

This transfers the signature from program good.signed.exe (A) to evil.signed.exe (A’). Under normal circumstances, the signature transferred to the second program will be invalid because the second program is different and has a different hash. But this is an exceptional situation, both programs have the same Authenticode hash. Hence the signature for program evil.signed.exe (A’) is also valid:

20090117-001029

evil.signed.exe executes without problem, but does something else than good.signed.exe:

20090117-004549

This demonstrates that MD5 is also broken for Authenticode code signing, and that you shouldn’t use it. But that’s not a real problem, because Authenticode uses SHA1 by default (I had to use the signtool in wizard mode and explicitly select MD5 hashing). In command-line mode (for batching or makefiles), the signtool provides no option to select the hashing algorithm, it’s always SHA1. And yes, SHA1 is also showing some cracks, but for Authenticode, you have no other choice.

You can download the demo programs and code signing cert here.

19 Comments »

  1. […] malicious software whose signature matches that of an Authenticode-signed binary. Researcher Didier Stevens has shown that the technique described by Peter Selinger for generating pairs of executables with the same MD5 hash can be used […]

    Pingback by Zero Day mobile edition — Saturday 17 January 2009 @ 18:06

  2. About the ZDNet article referenced in comment 1:

    1) Copying a signature from a Microsoft signed executable will not work, they use SHA1, not MD5.
    2) Even if they did use MD5, then this would require a “chosen hash attack”, not the MD5 collision algorithm I used

    Comment by Didier Stevens — Sunday 18 January 2009 @ 10:36

  3. […] Forscher Didier Stevens ist es in einer Studie gelungen Dateien zu generieren deren Signatur identisch  mit einer Authenticode-signierten […]

    Pingback by Forscher erstellt Dateien mit “Fake” Microsoft Authenticode™ « Netzhappen — Monday 19 January 2009 @ 10:44

  4. […] is at it again. Good thing he is on our side :0 Playing With Authenticode and MD5 Collisions << Didier Stevens Tags: ( md5 malware […]

    Pingback by Interesting Information Security Bits for 01/19/2009 at Infosec Ramblings — Monday 19 January 2009 @ 21:08

  5. SHA-1 is showing cracks. AES does not yet have an accepted/standardized hashing algorithm. In your opinion, currently, what is the next best hashing standard if a developer is concerned about performance (and not limited to microsoft’s signing tools)?

    Comment by k — Tuesday 20 January 2009 @ 18:16

  6. Great work Didier, thanks for investing time to explain it step by step.

    Comment by Thierry Zoller — Tuesday 20 January 2009 @ 23:39

  7. Thanks Thierry!

    Comment by Didier Stevens — Wednesday 21 January 2009 @ 7:37

  8. In general, for a new development, design your system for “easy” swap-out of the hashing function. Take one of the SHA2 functions, and in a couple of years, switch to the new SHA3 standard.

    Can you give more details of your performance requirements?

    Comment by Didier Stevens — Wednesday 21 January 2009 @ 7:42

  9. […] asta nu a fost tot. Didier Stevens s-a gandit sa treaca la nivelul urmator. Asa ca s-a folosit de scula celor de la Microsoft (special […]

    Pingback by Criza algoritmilor de criptare? « 0×30 0×20 0×61 0×6e 0×64 0×20 0×31 — Saturday 31 January 2009 @ 9:34

  10. […] Stevens used the evilize program (below) to create two different programs with the same Authenticode digital signature. Authenticode is Microsoft’s code signing mechanism, and although it uses SHA1 by default, it […]

    Pingback by 3medya Blog » Blog Archive » MD5 Collision Demo — Monday 2 November 2009 @ 10:10

  11. Hi guys,
    Great post by the day!
    For some of you looking for an online encoder, check this online md5 converter
    Pretty Cool!
    David

    Comment by David — Saturday 20 February 2010 @ 10:20

  12. Skąd pochodzi podpisany kod…

    W zamierzchłych czasach pojawiły się pierwsze informacje o malware, który był cyfrowo podpisany. Zdziwienie związane z tym faktem skomentowałem we wpisie Kapcie z nóg… czyli po co podpisywać programy. Pisałem wówczas, że podpisy cyfrowe określają źró…

    Trackback by Wampiryczny blog — Thursday 26 August 2010 @ 6:48

  13. MD5 has been cryptographically weak for a long time, thats why i built my online md5 cracker – hashhack.com to put pressure on the industry to stop using it all together. Its just not secure anymore.

    Great blog – keep up the good work

    Comment by Adam — Monday 29 November 2010 @ 10:49

  14. […] With Authenticode and MD5 Collisions | Didier Stevenshttps://blog.didierstevens.com/2009/01/17/playing-with-authenticode-and-md5-collisions/Share this:TwitterFacebookLike this:LikeBe the first to like this post. […]

    Pingback by Playing With Authenticode and MD5 Collisions | Didier Stevens « Petroaudios's Blog — Sunday 20 November 2011 @ 13:15

  15. […] Stevens used the evilize program (below) to create two different programs with the same Authenticode digital signature. Authenticode is Microsoft’s code signing mechanism, and although it uses SHA1 by default, it […]

    Pingback by Speed Hashing | GeekFreak — Friday 6 April 2012 @ 11:02

  16. […] in the next office along has just pointed me in the direction of this known “exploit” but this method can’t be used to sign random […]

    Pingback by Myrtus and Guava, Episode 2 - Securelist — Thursday 16 July 2015 @ 12:59

  17. […] robustez. Uno de los algoritmo más conocidos vulnerable a colisiones es MD5 y podemos encontrar pruebas de concepto que demuestran esto y librerías como […]

    Pingback by Descubierta la primera colisión de SHA-1 - ConectaBell — Sunday 26 February 2017 @ 10:09

  18. […] кабинета мне подсказывают, что известен один «эксплоит», но он не позволяет подписывать произвольные […]

    Pingback by Мирт и гуава: Эпизод 2 — Securelist — Всё об интернет-безопасности — Wednesday 20 September 2017 @ 11:01


RSS feed for comments on this post. TrackBack URI

Leave a Reply (comments are moderated)

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.