yara-normalize 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data.tar.gz.sig CHANGED
Binary file
@@ -16,20 +16,34 @@ See test cases.
16
16
  require 'yara-normalize'
17
17
  sig =<<EOS
18
18
  rule DataConversion__wide : IntegerParsing DataConversion {
19
- meta:
20
- weight = 1
21
- strings:
22
- $ = "wtoi" nocase
23
- $ = "wtol" nocase
24
- $ = "wtof" nocase
25
- $ = "wtodb" nocase
26
- condition:
19
+ meta:
20
+ weight =1
21
+ strings:
22
+ $="wtoi" nocase
23
+ $ ="wtol" nocase
24
+ $= "wtof" nocase
25
+ $ = "wtodb" nocase
26
+ condition:
27
27
  any of them
28
28
  }
29
29
  EOS
30
- yn = Yara::Normalizer.new
31
- nrm = yn.normalize(sig)
32
- puts nrm.hash_code # => dacfb7f79e2ad96cb66c4784323d91e09e8ad2f8c214c8ea0a52e3a3bda71e6612f02361609e0f7a
30
+ yn = YaraTools::YaraRule.new(sig)
31
+ puts yn.hash # => yn01:488085c947cb22ed:d936fceffe
32
+ puts yn.normalize # =>
33
+ rule DataConversion__wide : IntegerParsing DataConversion {
34
+ meta:
35
+ weight = 1
36
+ strings:
37
+ $ = "wtoi" nocase
38
+ $ = "wtol" nocase
39
+ $ = "wtof" nocase
40
+ $ = "wtodb" nocase
41
+ condition:
42
+ any of them
43
+ }
44
+ puts yn.name # => DataConversion__wide
45
+ pp yn.tags # => ["IntegerParsing","DataConversion"]
46
+
33
47
 
34
48
  == Contributing to yara-normalize
35
49
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.1.0
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'yara-normalize'
4
+
5
+ if __FILE__ == $0
6
+ count = duplicates = 0
7
+ hashes = {}
8
+ ARGV.each do |file|
9
+ buf = open(file).read
10
+ YaraTools::Splitter.split(buf).each do |rule|
11
+ count += 1
12
+ #puts rule.normalize
13
+ hash = rule.hash
14
+ puts "#{rule.name} #{hash} #{rule.normalized_strings.join("%")}"
15
+ if hashes[hash]
16
+ duplicate += 1
17
+ end
18
+ hashes[hash] = rule
19
+ end
20
+ end
21
+ puts "Count: #{count}, Duplicates: #{duplicates}"
22
+ end
23
+
@@ -1,84 +1,108 @@
1
- require 'digest/sha1'
2
-
3
- module Yara
4
- class Rule < Struct.new(:name, :tags, :meta, :strings, :condition)
5
- def hash_code
6
- normalized_strings = strings.map{|x| x.gsub(/^\s*\$\w+\s*=\s*/,'')}.sort.join("%")
7
- strings_hash = Digest::SHA1.hexdigest(normalized_strings)
8
- condition_hash = Digest::SHA1.hexdigest(normalized_condition)
9
- #pp normalized_strings
10
- #pp normalized_condition
11
- "#{strings_hash}#{condition_hash}"
12
- end
13
-
14
- def condition_var_replace(condition)
15
- vars = {}
16
- nextvar = 'a'
17
- condition.gsub(/\$\w+/) do |x|
18
- unless vars[x]
19
- vars[x] = "\$#{nextvar}"
20
- nextvar = (nextvar[0] + 1).chr
1
+ require 'digest/md5'
2
+ require 'pp'
3
+ module YaraTools
4
+ VERSION = "01"
5
+ class YaraRule
6
+ attr_reader :original, :name, :tags, :meta, :strings, :condition, :normalized_strings
7
+ def initialize(ruletext)
8
+ ruletext = ruletext.gsub(/[\r\n]+/,"\n").gsub(/^\s*\/\/.*$/,'')
9
+ @original = ruletext
10
+ @lookup_table = {}
11
+ @next_replacement = 'a'
12
+
13
+ if ruletext =~ /rule\s+([\w\_\-]+)(\s*:\s*(\w[\w\s]+\w))?\s*\{\s*(meta:\s*(.*?))?strings:\s*(.*?)\s*condition:\s*(.*?)\s*\}/m
14
+ name,_,tags,ifmeta,meta,strings,condition = $~.captures
15
+ @name = name
16
+ @tags = tags.strip.split(/[,\s]+/) if tags
17
+ @meta = {}
18
+ meta.split(/\n/).each do |m|
19
+ k,v = m.strip.split(/\s*=\s*/,2)
20
+ if v
21
+ @meta[k] = v
22
+ end
21
23
  end
22
- vars[x]
24
+ @normalized_strings = []
25
+ @strings = strings.split(/\n/).map do |s|
26
+ # strip off the spaces from the edges and then replace the first = with ' = '.
27
+ s = s.strip
28
+ if s[/\s*=\s*/,0]
29
+ s[/\s*=\s*/,0] = " = "
30
+ end
31
+ if s =~ /= \{([0-9a-fA-F\s]+)\}/
32
+ # normalize the hex string
33
+ hexstr = $1.gsub(/\s+/,'').downcase.scan(/../).join(" ")
34
+ s = s.gsub(/= \{([0-9a-fA-F\s]+)\}/, "= { #{hexstr} }")
35
+ end
36
+ key, val = s.split(/ = /,2)
37
+ if val
38
+ @normalized_strings << val
39
+ else
40
+ @normalized_strings << s
41
+ end
42
+ s
43
+ end
44
+ @normalized_strings.sort!
45
+ @condition = condition.split(/\n/).map{|x| x.strip}
46
+ @normalized_condition = @condition.map{|x| _normalize_condition(x)}
23
47
  end
24
48
  end
25
49
 
26
- # ($a and $b) or ($c and $d and ($e or $f)) => (($e or $f) and $c and $d) or ($a and $b)
27
- # [['$a','and','$b'],'or',['$c','and','$d','and',['$e','or','$f']]]
28
- def normalized_condition
29
- return condition if condition =~ /(any of them|all of them|any \d+ of them)/i
30
- condition_var_replace(condition_rearrange(condition_var_replace(self.condition)).join(","))
31
- end
32
-
33
- def condition_rearrange(condition)
34
- c = condition.gsub(/\(/,'[').gsub(/\)/,'],').gsub(/((\$\w+|and|or|not))/) do |x| "'#{x}',"; end.gsub(/,\]/,']').gsub(/,\s*$/,'')
35
- arr = eval("[#{c}]")
36
- condition_rearrange2(arr)
50
+ def _normalize_condition(condition)
51
+ condition.gsub(/[\$\#]\w+/) do |x|
52
+ key = x[1,1000]
53
+ if not @lookup_table[key]
54
+ @lookup_table[key] = @next_replacement
55
+ @next_replacement = (@next_replacement[0] + 1).chr
56
+ end
57
+ x[0].chr+@lookup_table[key]
58
+ end
37
59
  end
38
60
 
39
- def condition_rearrange2(subpart)
40
- if subpart.is_a? Array
41
- subpart.sort {|a,b|
42
- if a.is_a? Array and b.is_a? Array
43
- b.flatten.length <=> a.flatten.length
44
- elsif a.is_a? Array
45
- -1
46
- elsif b.is_a? Array
47
- 1
48
- else
49
- b.length <=> a.length
61
+ def normalize
62
+ text = "rule #{@name} "
63
+ if @tags and @tags.length > 0
64
+ text += ": #{@tags.join(' ')} "
65
+ end
66
+ text += "{\n"
67
+ if @meta and @meta.length > 0
68
+ text += " meta:\n"
69
+ @meta.each do |k,v|
70
+ text += " #{k} = #{v}\n"
71
+ end
72
+ end
73
+ if @strings and @strings.length > 0
74
+ text += " strings:\n"
75
+ @strings.each do |s|
76
+ if s =~ /\w/
77
+ text += " #{s}\n"
78
+ end
79
+ end
80
+ end
81
+ if @condition and @condition.length > 0
82
+ text += " condition:\n"
83
+ @condition.each do |c|
84
+ if c =~ /\w/
85
+ text += " #{c}\n"
50
86
  end
51
- }.map{ |sp|
52
- condition_rearrange2(sp)
53
- }
54
- else
55
- subpart
87
+ end
56
88
  end
89
+ text + "}"
90
+ end
91
+
92
+ def hash
93
+ normalized_strings = @normalized_strings.join("%")
94
+ normalized_condition = @normalized_condition.join("%")
95
+ strings_hash = Digest::MD5.hexdigest(normalized_strings)
96
+ condition_hash = Digest::MD5.hexdigest(normalized_condition)
97
+ "yn#{VERSION}:#{strings_hash[-16,16]}:#{condition_hash[-10,10]}"
57
98
  end
58
99
  end
59
100
 
60
- class Normalizer
61
- def initialize
62
- end
63
-
64
- def normalize(rule)
65
- raise "Invalid rule: rules must begin with the word 'rule'" unless rule =~ /^\s*rule\s/
66
- raise "Invalid rule: rules must end with a closing bracket, }" unless rule =~ /\}\s*$/
67
- if rule =~ /^\s*rule\s+(\w+)(\s*:\s*(\w[\w\s]+\w))?\s*\{\s*meta:\s*(.*?)\s*strings:\s*(.*?)\s*condition:\s*(.*?)\s*\}\s*$/m
68
- #pp $~.captures
69
- name,_,tags,meta,strings,condition = $~.captures
70
- tags = tags.split(/\s+/) if tags
71
- metatags = {}
72
- meta.split(/\n+/).each do |x|
73
- a,b = x.split(/\s*=\s*/)
74
- metatags[a.strip] = b.strip
75
- end
76
- strings = strings.split(/\n+/).map{|x| x.strip}
77
- condition = condition.strip
78
- Rule.new(name,tags,metatags,strings,condition)
79
- else
80
- nil
101
+ class Splitter
102
+ def Splitter.split(ruleset)
103
+ rules = ruleset.gsub(/[\r\n]+/,"\n").gsub(/^\s*\/\/.*$/,'').scan(/(rule\s+([\w\_\-]+)(\s*:\s*(\w[\w\s]+\w))?\s*\{\s*(meta:\s*(.*?))?strings:\s*(.*?)\s*condition:\s*(.*?)\s*\})/m).map do |rule|
104
+ YaraRule.new(rule[0])
81
105
  end
82
106
  end
83
107
  end
84
- end
108
+ end
@@ -0,0 +1,24 @@
1
+ CF_DOC_CVE_2012_1535_original yn01:06420b6c243181e8:a7e7b4fe3a { 45 78 61 6d 70 6c 65 0b 63 72 65 61 74 65 4c 69 6e 65 73 09 68 65 61 70 53 70 72 61 79 08 68 65 78 54 6f 42 69 6e 07 6d 78 2e 63 6f 72 65 0a 49 46 6c 65 78 41 73 73 65 74 09 46 6f 6e 74 41 73 73 65 74 0a 66 6c 61 73 68 2e 74 65 78 74 } /*Example.createLines.heapSpray.hexToBin.mx.core.IFlexAsset.FontAsset.flash.text*/%{ 4d 61 69 6e 2f 70 72 69 76 61 74 65 3a } /*Main/private:*/%{ 53 00 69 00 6d 00 53 00 75 00 6e 00 } /*S.i.m.S.u.n*/%{ 57 6f 72 64 2e 44 6f 63 75 6d 65 6e 74 2e 38 } /*Word.Document.8*/%{ 66 6c 61 73 68 2e 64 69 73 70 6c 61 79 06 53 70 72 69 74 65 06 4f 62 6a 65 63 74 0f 45 76 65 6e 74 44 69 73 70 61 74 63 68 65 72 0d 44 69 73 70 6c 61 79 4f 62 6a 65 63 74 } /*flash.display.Sprite.Object.EventDispatcher.DisplayObject*/%{ 68 69 6a 6b 6c 6d 6e 6f } /*hijklmno strings */
2
+ CF_DOC_CVE_2012_1535_shellcode yn01:aed85d99267c6173:4be571de0b "9090909090E947010000C28F36D8A0DF16D5B5F0DE78D00589E91B28BF56BEF71ED697165FFAA1665256D0541988A5D913E98E3A172B9BB28253A2E362577E574F52444C2E746D7000"
3
+ CVE_2012_1535_SWF yn01:d0b0e41fbb90ee63:0c2737ef53 "Edit the world in hex"%"FontAsset"%"PSpop"%"createTextLine"%"heapSpray"%"hexToBin"%{ 46 57 53 }
4
+ cf_exe_dropper_sfx yn01:32c758a1635b4d6e:9534ef77f9 ";The comment below contains SFX script commands"%"Setup=" ascii wide%"Silent=1" ascii wide%"WinRAR" ascii wide
5
+ cf_hlp_malicious_help_file yn01:22be215570105ad6:2edd241969 "CreateThread" nocase%/RR\(.KERNEL32.DLL.,/ nocase%{ 3f 5f 03 00 }%{ 4c 4e 02 00 }
6
+ cf_html_IE8_CVE_2012_4969 yn01:18d1ab9564026f79:a7e7b4fe3a "YMjf\\u0c08\\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH"%"document.execCommand(\\"
7
+ cf_ie_cve_2012_1526 yn01:791760cc1bb44202:fa3fd96df1 /\.getElements?By/ nocase%/\.removeChild\(/ nocase%/document\..*?= ?null/ nocase%/mailto\:.{2000,}/ nocase fullword
8
+ CF_JAVA_system_cmds yn01:9369881e5d91ae88:23497b0a75 "/bin/sh"%"Math.random"%"chmod"%"cmd.exe"%"indexOf" //usually used to get result of $fingerprint2%/(os.name|java.io.tmpdir)/%/* Payload */%/* System commands */%/get(Property|env)/%{ ca fe ba be }
9
+ CF_JAVA_network_connectivity yn01:7c4e5171925f60dc:4ffbde1efc "ServerSocket"%"URLConnection" //URL class can also be used to access files in the local file system%"getMbeanServer" //used with MarshallObject%"host"%"lport"%"openConnection"%/* Network indicators */%/get(Input|Output)Stream/%/socket(lhost, lport)/%{ ca fe ba be }
10
+ CF_JAVA_changing_security yn01:cf8a3ae054b77a6d:f6b1a6926b %"AccessController.doPrivileged"%"AllPermission"%"PrivilegedActionException"%"ProtectionDomain"%"file://"%/* Modifying local security : a class that allows applications to implement a security policy */%/[sg]etSecurityManager/%{ ca fe ba be }
11
+ CF_JAVA_execute_write yn01:47d6a8c1cd7ca988:595f5c08f4 %%%"ArrayOfByte"%"Exception.printStackTrace"%"FileOutputStream" /*contains a byte stream with the serialized representation of an object given to its constructor*/%"HexDecode"%"InputStream"%"MarshalledObject"%"ObjectInputStream"%"OutputStreamWriter"%"Runtime.getRuntime"%"StringtoBytes"%"exec"%"getResourceAsStream"%"toByteArray"%"writeObject"%/* Exploit */%/* Loader indicators */%/* Local execution */%/arrayOf(Byte|String)/%/l(port|host)/%{ ca fe ba be }
12
+ CF_JAVA_possible_exploit yn01:b58561333df5354e:e51d8cdbd7 %"ByteArrayInputStream"%"Character.digit"%"ProtectionDomain"%"String.charAt"%"StringBuilder"%"arrayOfByte"%"localPermissions"%"printStackTrace"%{ ca fe ba be }
13
+ CF_PDF_CVE_2007_5659 yn01:ada07a590bb9b5b8:a7e7b4fe3a { 25 50 44 46 2d }%{ 65 70 61 63 73 65 6e 75 }%{ 6e 6f 69 74 63 6e 75 66 }%{ 79 61 72 70 73 }%{ 79 61 72 72 41 }
14
+ CF_PDF_obfuscated_alphabetic_char_blackhole yn01:78654b53f1b3a0d3:c453df481f "%PDF-"%/[a-zA-Z]&#10[0-9];/%/[a-zA-Z]&#11[0-9];/%/[a-zA-Z]&#12[012];/%/[a-zA-Z]&#9[789];/
15
+ CF_PDF_suspicious_js yn01:360cd6b36773334c:e0bbde6bd2 "%PDF-"%/(\(|\[)(.{1,4}(,|-)){64}/
16
+ CF_RTF_ACTOR_CVE_2012_0158_tnauthor_John_Doe yn01:e82aa6a75f86469c:78c8a3f51c { 07 74 6e 61 75 74 68 6f 72 20 4a 6f 68 6e 20 44 6f 65 7d } /* tnauthor John Doe}*/
17
+ CF_RTF_CVE_2012_1856 yn01:0bffc7a0c3656c46:aea71fc2f5 "0CF11E0A1B" nocase%"4d53436f6d63746c4c69622e546162537472697" nocase%"9665fb1e7c85d111b16a00c0f0283628" nocase%"D0CF11E0A1B11AE1" nocase%"D\x0a0\x0aC\x0aF" nocase%"MSComctlLib.TabStrip"%"{\\rt"%"}0105000002000000"%/objdata[[:space:].]{1,20}01.{0,1}05.{0,1}00.{0,1}00.{0,1}02.{0,1}00.{0,1}00.{0,1}00/
18
+ CF_RTF_CVE_2010_3333 yn01:5d18fb7b42dfd5c0:3873ea4382 "\\shp " nocase%"\\shp\\" nocase%"\\sp \\" nocase%"\\sp\\" nocase%"pFragments" nocase%"{\\rt" /* RTF specs */ nocase
19
+ CF_RTF_CVE_2010_3333_rare_ge_type yn01:5bbb6168467e0386:3873ea4382 "\\shp " nocase%"\\shp\\" nocase%"\\sp \\" nocase%"\\sp\\" nocase%"pFragments" nocase%"{\\ge" /* RTF specs */ nocase
20
+ CF_RTF_CVE_2012_0158_var1_objocx yn01:dd9b4fb8c95de7f6:c32f773f84 "\\object" nocase%"\\objemb" nocase%"\\objocx" nocase%"{\\rt" /* RTF specs */ nocase%{ d0 cf 11 e0 a1 b1 1a e1 }
21
+ CF_RTF_CVE_2012_0158_var2_MSComctlLib yn01:cbf14eb4327aae3e:19df01f1b8 "4C697374566965774374726C" nocase%"4D53436F6D63746C4C69622E" nocase%"54726565566965774374726C" nocase
22
+ CF_RTF_CVE_2012_0158_var3_fchars yn01:5a65c8be3acd5373:a7e7b4fe3a /(\\\'[a-f0-9]{2}){30}/%{ 5c 2a 5c 66 63 68 61 72 73 }%{ 7b 5c 72 74 }
23
+ CF_XDP_embedded_PDF yn01:d3a748381610c2e1:bd721f6929 "%PDF"%"</pdf>"%"<chunk>"%"<pdf xmlns="%"JVBERi0"
24
+ Count: 23, Duplicates: 0
@@ -1,11 +1,13 @@
1
1
  require 'helper'
2
+ require 'pp'
3
+
2
4
  class TestYaraNormalize < Test::Unit::TestCase
3
5
  should "normalize a simple signature" do
4
6
  sig =<<EOS
5
7
  rule newIE0daymshtmlExec
6
8
  {
7
9
  meta:
8
- author = "adnan.shukor@gmail.com"
10
+ author = "redacted @ gmail.com"
9
11
  ref = "http://blog.vulnhunt.com/index.php/2012/09/17/ie-execcommand-fuction-use-after-free-vulnerability-0day_en/"
10
12
  description = "Internet Explorer CMshtmlEd::Exec() 0day"
11
13
  cve = "CVE-2012-XXXX"
@@ -24,42 +26,27 @@ rule newIE0daymshtmlExec
24
26
  ($mshtmlExec_1 and $mshtmlExec_2 and $mshtmlExec_3) or ($mshtmlExec_4 and $mshtmlExec_5 and ($mshtmlExec_6 or $mshtmlExec_7))
25
27
  }
26
28
  EOS
27
- yn = Yara::Normalizer.new
28
- nrm = yn.normalize(sig)
29
- hash = {}
30
- nrm.members.sort.each do |member|
31
- hash[member] = nrm[member]
32
- end
33
- assert_equal({"condition"=>
34
- "($mshtmlExec_1 and $mshtmlExec_2 and $mshtmlExec_3) or ($mshtmlExec_4 and $mshtmlExec_5 and ($mshtmlExec_6 or $mshtmlExec_7))",
35
- "tags"=>nil,
36
- "name"=>"newIE0daymshtmlExec",
37
- "strings"=>
38
- ["$mshtmlExec_1 = /document.execCommand(['\"]selectAll['\"])/ nocase fullword",
39
- "$mshtmlExec_2 = /YMjf\\u0c08\\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH/ nocase fullword",
40
- "$mshtmlExec_3 = /<body on(load|select)=['\"]w*?();['\"] on(load|select)=['\"]w*?()['\"]/ nocase",
41
- "$mshtmlExec_4 = /var w{1,} = new Array()/ nocase",
42
- "$mshtmlExec_5 = /window.document.createElement(['\"]img['\"])/ nocase",
43
- "$mshtmlExec_6 = /w{1,}[0][['\"]src['\"]] = ['\"]w{1,}['\"]/ nocase",
44
- "$mshtmlExec_7 = /<iframe src=['\"].*?['\"]/ nocase"],
45
- "meta"=>
46
- {"author"=>"\"adnan.shukor@gmail.com\"",
47
- "description"=>"\"Internet Explorer CMshtmlEd::Exec() 0day\"",
48
- "ref"=>
49
- "\"http://blog.vulnhunt.com/index.php/2012/09/17/ie-execcommand-fuction-use-after-free-vulnerability-0day_en/\"",
50
- "impact"=>"4",
51
- "hide"=>"false",
52
- "cve"=>"\"CVE-2012-XXXX\"",
53
- "version"=>"\"1\""}}, hash)
54
- assert_equal("ee2e32d623a0debca271cada22b35b3b904d6abd678cf2a48a87b43cd6302e73f67510c19ffe2f1a", nrm.hash_code)
55
- end
56
-
57
- should "normalize a simple signature with tags and spaces instead of tabs" do
29
+ yn = YaraTools::YaraRule.new(sig)
30
+ assert_equal("yn01:3c0de1ad64681376:3ff75e9945", yn.hash)
31
+ assert_equal("newIE0daymshtmlExec", yn.name)
32
+ assert_equal("\"redacted @ gmail.com\"", yn.meta['author'])
33
+ assert_equal(["$mshtmlExec_1 = /document.execCommand(['\"]selectAll['\"])/ nocase fullword",
34
+ "$mshtmlExec_2 = /YMjf\\u0c08\\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH/ nocase fullword",
35
+ "$mshtmlExec_3 = /<body on(load|select)=['\"]w*?();['\"] on(load|select)=['\"]w*?()['\"]/ nocase",
36
+ "$mshtmlExec_4 = /var w{1,} = new Array()/ nocase",
37
+ "$mshtmlExec_5 = /window.document.createElement(['\"]img['\"])/ nocase",
38
+ "$mshtmlExec_6 = /w{1,}[0][['\"]src['\"]] = ['\"]w{1,}['\"]/ nocase",
39
+ "$mshtmlExec_7 = /<iframe src=['\"].*?['\"]/ nocase"], yn.strings)
40
+ assert_equal(
41
+ ["($mshtmlExec_1 and $mshtmlExec_2 and $mshtmlExec_3) or ($mshtmlExec_4 and $mshtmlExec_5 and ($mshtmlExec_6 or $mshtmlExec_7))"],
42
+ yn.condition
43
+ )
44
+ hash1 = yn.hash
58
45
  sig =<<EOS
59
46
  rule newIE0daymshtmlExec : tag1 tag2 tag3
60
47
  {
61
48
  meta:
62
- author = "adnan.shukor@gmail.com"
49
+ author = "redacted @ gmail.com"
63
50
  ref = "http://blog.vulnhunt.com/index.php/2012/09/17/ie-execcommand-fuction-use-after-free-vulnerability-0day_en/"
64
51
  description = "Internet Explorer CMshtmlEd::Exec() 0day"
65
52
  cve = "CVE-2012-XXXX"
@@ -78,66 +65,25 @@ rule newIE0daymshtmlExec : tag1 tag2 tag3
78
65
  ($mshtmlExec_1 and $mshtmlExec_2 and $mshtmlExec_3) or ($mshtmlExec_4 and $mshtmlExec_5 and ($mshtmlExec_6 or $mshtmlExec_7))
79
66
  }
80
67
  EOS
81
- yn = Yara::Normalizer.new
82
- nrm = yn.normalize(sig)
83
- hash = {}
84
- nrm.members.sort.each do |member|
85
- hash[member] = nrm[member]
86
- end
87
- assert_equal({"condition"=>
88
- "($mshtmlExec_1 and $mshtmlExec_2 and $mshtmlExec_3) or ($mshtmlExec_4 and $mshtmlExec_5 and ($mshtmlExec_6 or $mshtmlExec_7))",
89
- "tags"=>["tag1","tag2","tag3"],
90
- "name"=>"newIE0daymshtmlExec",
91
- "strings"=>
92
- ["$mshtmlExec_1 = /document.execCommand(['\"]selectAll['\"])/ nocase fullword",
93
- "$mshtmlExec_2 = /YMjf\\u0c08\\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH/ nocase fullword",
94
- "$mshtmlExec_3 = /<body on(load|select)=['\"]w*?();['\"] on(load|select)=['\"]w*?()['\"]/ nocase",
95
- "$mshtmlExec_4 = /var w{1,} = new Array()/ nocase",
96
- "$mshtmlExec_5 = /window.document.createElement(['\"]img['\"])/ nocase",
97
- "$mshtmlExec_6 = /w{1,}[0][['\"]src['\"]] = ['\"]w{1,}['\"]/ nocase",
98
- "$mshtmlExec_7 = /<iframe src=['\"].*?['\"]/ nocase"],
99
- "meta"=>
100
- {"author"=>"\"adnan.shukor@gmail.com\"",
101
- "description"=>"\"Internet Explorer CMshtmlEd::Exec() 0day\"",
102
- "ref"=>
103
- "\"http://blog.vulnhunt.com/index.php/2012/09/17/ie-execcommand-fuction-use-after-free-vulnerability-0day_en/\"",
104
- "impact"=>"4",
105
- "hide"=>"false",
106
- "cve"=>"\"CVE-2012-XXXX\"",
107
- "version"=>"\"1\""}}, hash)
108
- assert_equal("ee2e32d623a0debca271cada22b35b3b904d6abd678cf2a48a87b43cd6302e73f67510c19ffe2f1a", nrm.hash_code)
109
- end
110
-
111
- should "normalize a simple signature that has been rearranged" do
112
- sig =<<EOS
113
- rule newIE0daymshtmlExec
114
- {
115
- meta:
116
- author = "adnan.shukor@gmail.com"
117
- ref = "http://blog.vulnhunt.com/index.php/2012/09/17/ie-execcommand-fuction-use-after-free-vulnerability-0day_en/"
118
- description = "Internet Explorer CMshtmlEd::Exec() 0day"
119
- cve = "CVE-2012-XXXX"
120
- version = "1"
121
- impact = 4
122
- hide = false
123
- strings:
124
- $mshtmlExec_3 = /\<body\son(load|select)=['"]\w*?\(\)\;['"]\son(load|select)=['"]\w*?\(\)['"]/ nocase
125
- $mshtmlExec_5 = /window\.document\.createElement\(['"]img['"]\)/ nocase
126
- $mshtmlExec_6 = /\w{1,}\[0\]\[['"]src['"]\]\s\=\s['"]\w{1,}['"]/ nocase
127
- $mshtmlExec_4 = /var\s\w{1,}\s=\snew\sArray\(\)/ nocase
128
- $mshtmlExec_1 = /document\.execCommand\(['"]selectAll['"]\)/ nocase fullword
129
- $mshtmlExec_7 = /\<iframe\ssrc=['"].*?['"]/ nocase
130
- $mshtmlExec_2 = /YMjf\\u0c08\\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH/ nocase fullword
131
- condition:
132
- ($mshtmlExec_4 and ($mshtmlExec_6 or $mshtmlExec_7) and $mshtmlExec_5) or ($mshtmlExec_1 and $mshtmlExec_2 and $mshtmlExec_3)
133
- }
134
- EOS
135
- yn = Yara::Normalizer.new
136
- nrm = yn.normalize(sig)
137
- assert_equal("ee2e32d623a0debca271cada22b35b3b904d6abd678cf2a48a87b43cd6302e73f67510c19ffe2f1a", nrm.hash_code)
68
+ yn = YaraTools::YaraRule.new(sig)
69
+ assert_equal(hash1, yn.hash)
70
+ assert_equal("newIE0daymshtmlExec", yn.name)
71
+ assert_equal(["tag1","tag2","tag3"], yn.tags)
72
+ assert_equal("\"redacted @ gmail.com\"", yn.meta['author'])
73
+ assert_equal(["$mshtmlExec_1 = /document.execCommand(['\"]selectAll['\"])/ nocase fullword",
74
+ "$mshtmlExec_2 = /YMjf\\u0c08\\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH/ nocase fullword",
75
+ "$mshtmlExec_3 = /<body on(load|select)=['\"]w*?();['\"] on(load|select)=['\"]w*?()['\"]/ nocase",
76
+ "$mshtmlExec_4 = /var w{1,} = new Array()/ nocase",
77
+ "$mshtmlExec_5 = /window.document.createElement(['\"]img['\"])/ nocase",
78
+ "$mshtmlExec_6 = /w{1,}[0][['\"]src['\"]] = ['\"]w{1,}['\"]/ nocase",
79
+ "$mshtmlExec_7 = /<iframe src=['\"].*?['\"]/ nocase"], yn.strings)
80
+ assert_equal(
81
+ ["($mshtmlExec_1 and $mshtmlExec_2 and $mshtmlExec_3) or ($mshtmlExec_4 and $mshtmlExec_5 and ($mshtmlExec_6 or $mshtmlExec_7))"],
82
+ yn.condition
83
+ )
138
84
  end
139
85
 
140
- should "normalize a simple signature that has been rearranged" do
86
+ should "normalize a simple signature that has a condition of 'any of them'" do
141
87
  sig =<<EOS
142
88
  rule DataConversion__wide : IntegerParsing DataConversion {
143
89
  meta:
@@ -151,22 +97,16 @@ rule DataConversion__wide : IntegerParsing DataConversion {
151
97
  any of them
152
98
  }
153
99
  EOS
154
- yn = Yara::Normalizer.new
155
- nrm = yn.normalize(sig)
156
- hash = {}
157
- nrm.members.sort.each do |member|
158
- hash[member] = nrm[member]
159
- end
160
- assert_equal({"tags"=>["IntegerParsing", "DataConversion"],
161
- "name"=>"DataConversion__wide",
162
- "condition"=>"any of them",
163
- "strings"=>
164
- ["$ = \"wtoi\" nocase",
165
- "$ = \"wtol\" nocase",
166
- "$ = \"wtof\" nocase",
167
- "$ = \"wtodb\" nocase"],
168
- "meta"=>{"weight"=>"1"}},hash)
169
- assert_equal("dacfb7f79e2ad96cb66c4784323d91e09e8ad2f8c214c8ea0a52e3a3bda71e6612f02361609e0f7a", nrm.hash_code)
100
+ yn = YaraTools::YaraRule.new(sig)
101
+ assert_equal("yn01:488085c947cb22ed:d936fceffe", yn.hash)
102
+ assert_equal("1", yn.meta['weight'])
103
+ assert_equal("DataConversion__wide", yn.name)
104
+ assert_equal(["IntegerParsing", "DataConversion"], yn.tags)
105
+ assert_equal(["$ = \"wtoi\" nocase",
106
+ "$ = \"wtol\" nocase",
107
+ "$ = \"wtof\" nocase",
108
+ "$ = \"wtodb\" nocase"], yn.strings)
109
+ assert_equal(["any of them"], yn.condition)
170
110
  end
171
111
  end
172
112
 
@@ -5,14 +5,16 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{yara-normalize}
8
- s.version = "0.0.0"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["chrislee35"]
12
12
  s.cert_chain = ["/Users/chris/Documents/projects/rubygems/yara-normalize/../gem-public_cert.pem"]
13
- s.date = %q{2012-09-30}
13
+ s.date = %q{2012-10-29}
14
+ s.default_executable = %q{yaratool}
14
15
  s.description = %q{To enable consistent comparisons between yara rules (signature), a uniform hashing standard was needed.}
15
16
  s.email = %q{rubygems@chrislee.dhs.org}
17
+ s.executables = ["yaratool"]
16
18
  s.extra_rdoc_files = [
17
19
  "LICENSE.txt",
18
20
  "README.rdoc"
@@ -25,8 +27,10 @@ Gem::Specification.new do |s|
25
27
  "README.rdoc",
26
28
  "Rakefile",
27
29
  "VERSION",
30
+ "bin/yaratool",
28
31
  "lib/yara-normalize.rb",
29
32
  "lib/yara-normalize/yara-normalize.rb",
33
+ "ruby_results.txt",
30
34
  "test/helper.rb",
31
35
  "test/test_yara-normalize.rb",
32
36
  "yara-normalize.gemspec"
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 1
7
8
  - 0
8
- - 0
9
- version: 0.0.0
9
+ version: 0.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - chrislee35
@@ -36,8 +36,8 @@ cert_chain:
36
36
  6yhklP75
37
37
  -----END CERTIFICATE-----
38
38
 
39
- date: 2012-09-30 00:00:00 -04:00
40
- default_executable:
39
+ date: 2012-10-29 00:00:00 -04:00
40
+ default_executable: yaratool
41
41
  dependencies:
42
42
  - !ruby/object:Gem::Dependency
43
43
  prerelease: false
@@ -106,8 +106,8 @@ dependencies:
106
106
  requirement: *id005
107
107
  description: To enable consistent comparisons between yara rules (signature), a uniform hashing standard was needed.
108
108
  email: rubygems@chrislee.dhs.org
109
- executables: []
110
-
109
+ executables:
110
+ - yaratool
111
111
  extensions: []
112
112
 
113
113
  extra_rdoc_files:
@@ -121,8 +121,10 @@ files:
121
121
  - README.rdoc
122
122
  - Rakefile
123
123
  - VERSION
124
+ - bin/yaratool
124
125
  - lib/yara-normalize.rb
125
126
  - lib/yara-normalize/yara-normalize.rb
127
+ - ruby_results.txt
126
128
  - test/helper.rb
127
129
  - test/test_yara-normalize.rb
128
130
  - yara-normalize.gemspec
metadata.gz.sig CHANGED
Binary file