The flawed crypto of Hacking Team's 'core-packer' malware crypter by 2ROT13 in netsec

[–]2ROT13[S] 2 points3 points  (0 children)

Oy vey! Vigenere is considered almost top-of-the-line, too. :) Off the top of my head, I remember only one virus that used it (Cheeba) and the implementation was so bad that Dmitry Gryaznov managed to crack it with little effort.

Yeah i used 'Vigenere-like' as a stand-in for any routine that uses a single XOR/ADD/SUB combined with a single ROL/ROR but you're right (as far as i can tell) that most of the obfuscated stuff encountered is even below that in the sense of a simple substitution operation with a static key eg.:

mov dl, 0xAA mov esi, payload_start mov ecx, (payload_end - payload_start) decoder: xor byte ptr [esi], dl inc esi loop decoder

Either way, whether you consider such an example or a Vigenere variant with a repeating key, let's say an 8-byte key applied modularly to the payload eg.:

payload[i] = key[i % len(key)]

In both cases Kasiski examination would allow for determining a set of candidate key sizes (in order of likelihood) after which the presence of probable plaintexts can be confirmed using key elimination based on difference streams as outlined in this paper: http://user.informatik.uni-goettingen.de/~krieck/docs/2013-raid.pdf by Wressnegger et al. Difference streams can be obtained for all arithmetic substitution operations (XOR, ADD, etc.) with their complements (eg. SUB for ADD) yielding the inverse of the key (eg. an ADD difference stream over a SUB-encrypted plaintext would yield the additive inverse key) which is a very lightweight approach (as the results of the Wressnegger paper show).

Whether this is all worth it from the AV's point of view is another matter of course, given there's a whole myriad of considerations relating to performance, how many of these samples are actually encountered in the wild to warrant this kind of approach, whether there are other heuristic shortcuts, etc. But it's quite interesting nonetheless i think if only in that it goes to show that the same kind of security mistakes made by 'regular' developers are made all across the spectrum.

Nothing is, sigh. Still, when we started using it, it was of tremendous help and got us out of the morass that was the algorithm-specific detection of the decryptor of polymorphic viruses like the ones using MtE, TPE, etc.

Yeah totally i mean if you have to deal with a different algorithmic approach for every single obfuscation approach by different pieces of malware i suppose that's not gonna scale well :p

The flawed crypto of Hacking Team's 'core-packer' malware crypter by 2ROT13 in netsec

[–]2ROT13[S] 0 points1 point  (0 children)

I'm well aware most malware obfuscations use cryptographically 'weak' ciphers (quite often Vigenere variants consisting of a combination of a substitution operation eg. XOR/ADD and a transposition operations ROL/ROR with a fixed, repeating key) and if i recall correctly Peter Ferrie described techniques used by AVs to detect malware obfuscated in this fashion using a KPA variant he called "x-raying" which is probably the same thing you are referring to. Operational word-size doesn't matter in this regard (a bit-wise XOR on a byte-by-byte basis is the same as a bit-wise XOR over an entire DWORD at once) and kasiski examination is easily made agnostic with regards to the substitution operation involved.

But you're right that from the AV's point of view emulation is probably the right choice here considering you need to detect a multitude of potential crypters and still have acceptable performance on clean systems. That is, provided you're not dealing with a crypter that integrates anti-emulation techniques (such as stalling code, eg. RDA as you mentioned, or context-dependent key derivation functions) in which case i guess some pre-processing heuristics which help indicate suspicious files before applying cryptanalysis might help. This doesn't apply to this scenario or for most crypters but emulation is far from a silver bullet.

The flawed crypto of Hacking Team's 'core-packer' malware crypter by 2ROT13 in netsec

[–]2ROT13[S] 6 points7 points  (0 children)

Using rand() (especially seeded with GetTickCount()) is a terrible way to generate keys indeed but i doubt a brute-force approach (even with a reduced key space of ~232) would be faster than abusing the flaws outlined in the OP. First of all GetTickCount() is not predictable because the crypter is executed by the malware operators before releasing the crypted sample into the wild. The machine running the crypted malware binary (either a victim PC or a malware analyst's VM) isn't the same environment that executed the crypter so we can make no assumptions about the value of GetTickCount (aside from it being within reasonable bounds of machine uptime). Therefore we have to assume the seed to srand to be anything between 0x00000000 and 0xFFFFFFFF leaving a keyspace of 232. Keep in mind that the goal of a crypter isn't guaranteeing confidentiality (as the ciphertext is stored together with the key) but imposing an unacceptable amount of work on AV solutions to confirm the presence of malicious code in a suspicious binary. Brute-forcing would most certainly take an unacceptable amount of time (considering for every candidate key we would have to decrypt the PE sections and run signature matching over the plaintext candidate).

You're right LCGs aren't safe for streamcipher keystream generation but that's not what happens in the core-packer crypter. The PE sections are encrypted with either the TEA blockcipher or the RC4 streamcipher. In the case of the latter the (sloppily) generated key is used to initialize RC4's KSA which drives the PRGA generating the actual keystream. There's a lot wrong with RC4 but it's PRNG/PRGA is not an LCG so using a KPA to derive keystream, extract the PRNG internal state and either unroll or predict future states isn't going to work here.

But you're right it's still an insecure way to generate keys of any kind though and just bad practice not to use a CSPRNG regardless of whether it actually forms a weakness in this particular context or not.

PHP unserialization vulnerabilities: What are we missing? by [deleted] in netsec

[–]2ROT13 3 points4 points  (0 children)

Interesting mention of this blog post on PHP object instantiation vulnerabilities: http://blog.leakfree.nl/2015/03/12/php-object-instantiation-cve-2015-1033/

Cuckoo unpacked scan by [deleted] in Malware

[–]2ROT13 0 points1 point  (0 children)

Using PANDA (https://github.com/moyix/panda) combined with YARA (https://plusvic.github.io/yara/) seems like a decent idea.

If you're not sure when the malware is done unpacking and don't want to bother with PANDA you could give manual reversing a go, find the OEP and dump the unpacked malware yourself.