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 +0 -0
- data/README.rdoc +25 -11
- data/VERSION +1 -1
- data/bin/yaratool +23 -0
- data/lib/yara-normalize/yara-normalize.rb +94 -70
- data/ruby_results.txt +24 -0
- data/test/test_yara-normalize.rb +47 -107
- data/yara-normalize.gemspec +6 -2
- metadata +8 -6
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/README.rdoc
CHANGED
@@ -16,20 +16,34 @@ See test cases.
|
|
16
16
|
require 'yara-normalize'
|
17
17
|
sig =<<EOS
|
18
18
|
rule DataConversion__wide : IntegerParsing DataConversion {
|
19
|
-
|
20
|
-
weight =
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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 =
|
31
|
-
|
32
|
-
puts
|
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.
|
1
|
+
0.1.0
|
data/bin/yaratool
ADDED
@@ -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/
|
2
|
-
|
3
|
-
module
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
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
|
61
|
-
def
|
62
|
-
|
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
|
data/ruby_results.txt
ADDED
@@ -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]
[0-9];/%/[a-zA-Z][0-9];/%/[a-zA-Z][012];/%/[a-zA-Z]	[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
|
data/test/test_yara-normalize.rb
CHANGED
@@ -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 = "
|
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 =
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
"
|
36
|
-
"
|
37
|
-
"strings
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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 = "
|
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 =
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
"
|
90
|
-
"
|
91
|
-
"
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
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
|
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 =
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
"
|
162
|
-
"
|
163
|
-
|
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
|
|
data/yara-normalize.gemspec
CHANGED
@@ -5,14 +5,16 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{yara-normalize}
|
8
|
-
s.version = "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-
|
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
|
-
|
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-
|
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
|