home *** CD-ROM | disk | FTP | other *** search
/ Cuteskunk BBS / cuteskunk.zip / cuteskunk / Virus / Virus-Magazines / Vlad / vlad#4.zip / ARTICLE.2_4 < prev    next >
Text File  |  1995-04-27  |  8KB  |  186 lines

  1.  
  2. Detecting oh, roughly every polymorphic engine out there.
  3.         By Rhincewind [Vlad]
  4.  
  5.  
  6. This article assumes that the reader has basic knowledge of polymorphic
  7. engines, mathematical reasoning and logics. I suggest to those who lack
  8. the first to read Dark Angel's fine two-part 'polymorphism primer',
  9. published in issues 11 and 12 of the Phalcon/Skism publication 40hex.
  10.  
  11. ---- Definitions and terminology, and some general bits.
  12.  
  13. The ideal polymorphic engine is popularly defined as a program that can
  14. transform a given block of code into another block of code that will have the
  15. exact same functionality and that any number of transformed blocks, all
  16. different instances of the same original code, share no predictable patterns
  17. as the presence of such patterns can be used to deduce the presence of
  18. encrypted code the engine is meant to hide.
  19.  
  20. The most commonly used method by far to approximate this ideal is to apply an
  21. encryption loop on the given code, and prepend a program to the
  22. encrypted block of code that will decrypt it, and then pass on execution
  23. as if the program hadn't been encrypted at all.
  24.  
  25. To get anywhere close to the ideal defined above, the prepended program
  26. most of course also vary, and this is where the real benefit of this
  27. approach comes in. Instead of having to vary a large block of code,
  28. only a decryption loop needs to be varied, typically having a size of
  29. just a little over 10 bytes. The advantages should be obvious.
  30.  
  31. The disadvantages are a little less obvious and they are the main topic
  32. of this article. The decryption algorithm is kept as simple
  33. as possible as the complexity of the decryptor has a direct relation to the
  34. complexity of the code needed to succesfully vary it. Result? Encryption
  35. schemes even Caesar would've been ashamed of using: usually one round of
  36. operation, transforming each data unit U to it's crypttext equivalent U'.
  37. Yes transforming, it really isn't that much like encryption at all but alas,
  38. terminology is easier when this is regarded as encryption.
  39.  
  40. As said, unit per unit, typically byte- or word-length, code is transformed.
  41. The detransformation procedure merely performs the reciprocal operation,
  42. et voila. Typical transformational operations are ADD, SUB, XOR and bit 
  43. rotations. All these are binary operators, and, viewed as 
  44. encryption can be said to use a key K. U' = U + K, or U' = U - K or
  45. U' = U XOR K. 
  46.  
  47. ---- How to detect? And a small bit o' maths.
  48.  
  49. An engine would be undetectable if 1) the decryptor is indistinguishable from
  50. programs without a decrypting function and 2) the encrypted code is
  51. indistinguishable from random data. Of course it would help if the decryptor
  52. were like random data but alas, the restrictions imposed on programs by
  53. the processor's instruction set do not permit this.
  54.  
  55. Decryptor attacks come in a few flavors but are basically all the same.
  56. They see if a fragment of code could have been generated by the engine
  57. the attack is looking for. This is obviously a flawed attack as parts
  58. of a legitimate program may very well have been generated by an engine.
  59. Hiding polymorphically generated code in the middle of a legitimate
  60. program makes flawless detection of this type virtually impossible, 
  61. see Commander Bomber.
  62.  
  63. The most foolish of decryptor attacks traces the decrypting code, looking
  64. for processor opcodes the engine searched for can't generate. Prepending
  65. one or two instructions foreign to the engine will throw off this attack.
  66. Quite a few of the lesser anti-virus programs can be fooled by this.
  67.  
  68. A more sophisticated, but related attack involves statistical analysis. 
  69. Perhaps it's worth a description in another issue. Votes please!
  70.  
  71. No, the real attacks of the moment are different. They focus on the encrypted
  72. code. There may not be a predictable unit sequence, but the units have 
  73. distinct mathematical relations to eachother as all were transformed using 
  74. the same operation. Exploiting this is not hard at all if the reciprocal
  75. operator is known.
  76.  
  77. It is possible to transform corresponding parts of crypt- and plaintext
  78. independently into a common form. To use this for detection you assume a 
  79. string of units to be an encrypted version of a string of plaintext, 
  80. compute what should be their common form, once from the plaintext, once
  81. from the crypttext, and see if it's a match.  The manipulations needed to
  82. get to this common form are different for each encryption type, but are for
  83. single loops easily obtained as follows:
  84.  
  85. A' = A OP K and 
  86. B' = B OP K where A and B are plaintext (unencrypted) data units, 
  87.             and A' and B' form their crypttext. 
  88.  
  89. Now we can derive:
  90.  
  91. A' NegOP B'             == 
  92. (A OP K) NegOP (B OP K) == 
  93. A OP K NegOP B NegOP K  == 
  94. A NegOP B.
  95.  
  96. Yes, A' NegOP B' == A NegOP B!
  97.  
  98. To illustrate this: A' XOR B' = A XOR B if the code was encrypted with 
  99. a XOR loop. You XOR consecutive unitpairs of crypttext, and of your 
  100. plaintext signature and check the results. Pairs meaning
  101. D[n] and D[n+1], followed by D[n+1] and D[n+2], with D as a unit-length array
  102. of data.
  103.  
  104. Of course this also works for a bit more complex loops, such as an addition
  105. loop where K is increased by one every iteration, and one unit is transformed
  106. per iteration.
  107.  
  108. A' = A + K 
  109. B' = B + K + 1
  110.  
  111. A' - B'               == 
  112. (A + K) - (B + K + 1) == 
  113. A + K - B - K - 1     == 
  114. A - B - 1.
  115.  
  116. A' - B' == A - B - 1
  117.  
  118. Now you compute A' - B' and A - B - 1 and compare the results. As you can
  119. see, the operations needed to transform crypt- and plaintext to a common
  120. form need not be equal, as long as both results are.
  121.  
  122. This attack is called cryptanalysis; you check if a string of units
  123. could be an encrypted version of a plaintext string. False positive error
  124. chance drops rapidly as signaturelength increases following 
  125. 1/2^(unit_bitlen*unit_siglen).
  126.  
  127. Now try another one. A XOR loop where the loop counter 
  128. (=units left to transform) is added to the key K each iteration.
  129.  
  130. A' = A XOR K
  131. B' = A XOR (K + C)
  132.  
  133. A' XOR B'                   == 
  134. (A XOR K) XOR (A XOR (K+C)) == 
  135. ??? We can't eliminate K!
  136.  
  137. If you can't eliminate K, then a common form cannot be computed from A and B.
  138. The solution is to recover K using a cryptological known plaintext attack.
  139. This kind of attack happens to be ridiculously easy on 'ciphers' (sic) like
  140. these.
  141.  
  142. K     = A' XOR A
  143. K + C = B' XOR B
  144.  
  145. Now we have K. This is need not be the K of the first byte encrypted, just
  146. start somewhere in the middle of call it THE K, like the pioneers who
  147. coincidentally found some land and decided to call it theirs. If it were
  148. an easier loop we could take K and decrypt all of the code, but alas, 
  149. now we must first recover the counter C.
  150.  
  151. K + C - K = C  ==  B' XOR B - A' XOR A = C
  152.  
  153. Now we can decrypt the Nth unit, A being unit 0,
  154. by U=U' XOR (K+N*C) and comparing U against the unit in our plaintext
  155. signature. 
  156.  
  157. This attack is usually also referred to as being cryptanalytic, but
  158. technically it falls in the domain of cryptology as you actually decrypt
  159. what is encrypted. For this type it is vital that you operate on
  160. pairs of consecutive units only. With most cryptanalytic attacks, 
  161. you may just as well muddle about.
  162.  
  163. ---- The limit of these attacks.
  164.  
  165. Nearly all polymorphic engines to date can be caught using these simple, what
  166. I like to call 'crypto-sweeps'. Things get a bit more complex when multiple
  167. layer encryption is used. Let's take an engine that encrypts each unit
  168. using an ADD and a XOR:
  169.  
  170. A' = (A+K1) + K2
  171. B' = (B+K1) + K2
  172.  
  173. Looks easy:
  174.  
  175. A' XOR B' == (A+K1) XOR (B+K1)
  176.  
  177. But now you need to recover or eliminate K1 which is not at all easy with the
  178. XOR in the middle. With even more layers, it becomes practically impossible
  179. to decrypt and the weight is pushed back to the complexity of the decryptor.
  180.  
  181. All in all I'd say that what we've seen so far is just the start of
  182. polymorphism. Territory to be conquered, things unthought of to be thought
  183. of, and so on.
  184.  
  185. Rhince.
  186.