yara-normalize 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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