| @@ -0,0 +1,105 @@ | ||
| begin | ||
| require 'snortor' | ||
| rescue | ||
| raise "can not find snortor gem. Please gem install snortor" | ||
| end | ||
| #require 'evasion-db/vendor/bitfield' | ||
| require File.join(FIDIUS::EvasionDB::GEM_BASE, 'evasion-db', 'vendor', 'bitfield') | ||
|
|
||
| module FIDIUS | ||
| module EvasionDB | ||
| module SnortRuleFetcher | ||
| @@rule_path = nil | ||
|
|
||
|
|
||
| @@ssh_host = nil | ||
| @@ssh_pw = nil | ||
| @@ssh_remote_path = nil | ||
| @@ssh_user = nil | ||
| @@fetch_remote = false | ||
| @@ssh_options = {} | ||
|
|
||
| def import_rules_to_snortor | ||
| raise "no rulepath given" unless @@rule_path | ||
| if @@fetch_remote | ||
| a = {:host=>@@ssh_host,:user=>@@ssh_user,:password=>@@ssh_pw,:remote_path=>@@ssh_remote_path,:options=>@@ssh_options} | ||
| puts "Snortor.import_rules(#{a.inspect})" | ||
| Snortor.import_rules(a) | ||
| else | ||
| Snortor.import_rules(@@rule_path) | ||
| end | ||
| end | ||
| # generate a bitvector based on activated rules | ||
| # and assign this bisvector to the given attack_module | ||
| def fetch_rules(attack_module) | ||
| import_rules_to_snortor | ||
|
|
||
| raise "this attack_module has an ruleset bitvector" if attack_module.enabled_rules | ||
|
|
||
| start_time = Time.now | ||
| rules_enabled = BitField.new(Snortor.rules.size) | ||
| i = 0 | ||
| Snortor.rules.each do |rule| | ||
| if rule.message | ||
| rules_enabled[i] = (rule.active == true)? 1 : 0 | ||
| i += 1 | ||
| end | ||
| end | ||
| end_time = Time.now | ||
|
|
||
| ruleset = FIDIUS::EvasionDB::Knowledge::EnabledRules.create(:bitstring=>rules_enabled.to_s) | ||
| ruleset.attack_module = attack_module | ||
| ruleset.save | ||
| end | ||
|
|
||
| # fetches rules with snortor | ||
| # and stores them all into db | ||
| def import_rules | ||
| raise "rules imported already" if FIDIUS::EvasionDB::Knowledge::IdsRule.all.size > 0 | ||
| import_rules_to_snortor | ||
|
|
||
| start_time = Time.now | ||
| puts "rules exported save to db now" | ||
|
|
||
| i = 0 | ||
| insert_query = [] | ||
| Snortor.rules.each do |rule| | ||
| if rule.message | ||
| insert_query << FIDIUS::EvasionDB::Knowledge::IdsRule.sub_query_for_insert(rule.message,i) | ||
| i += 1 | ||
| end | ||
| end | ||
| begin | ||
| FIDIUS::EvasionDB::Knowledge::IdsRule.connection.execute("INSERT IGNORE INTO ids_rules (rule_text,rule_hash,sort) VALUES #{insert_query.join(',')};") | ||
| rescue | ||
| begin | ||
| # try without IGNORE statement | ||
| FIDIUS::EvasionDB::Knowledge::IdsRule.connection.execute("INSERT INTO ids_rules (rule_text,rule_hash,sort) VALUES #{insert_query.join(',')};") | ||
| rescue | ||
| puts $!.message+":"+$!.backtrace.to_s | ||
| end | ||
| end | ||
| end_time = Time.now | ||
| puts "Import needed #{end_time-start_time} seconds" | ||
| end | ||
|
|
||
| def config(conf) | ||
| return unless conf | ||
| conf = conf["snort-fetcher"] | ||
| return unless conf.class == Hash | ||
|
|
||
| @@rule_path = conf["rule_path"]#"/home/bernd/fidius/snort/rules/fetched" | ||
|
|
||
| @@ssh_host = conf["ssh_host"] #"10.10.10.254" | ||
| @@ssh_pw = conf["ssh_pw"]#"fidius09" | ||
| @@ssh_remote_path = conf["ssh_remote_path"] #"/etc/snort/rules/" | ||
| @@ssh_user = conf["ssh_user"] #"fidius" | ||
| @@fetch_remote = @@ssh_host != nil | ||
| end | ||
|
|
||
| def self.ssh_options=(a) | ||
| @@ssh_options = a | ||
| end | ||
| end | ||
| end | ||
| end |
| @@ -0,0 +1,7 @@ | ||
| puts "loading snort_fetcher" | ||
| FIDIUS::EvasionDB.rule_fetcher "Snortrule-Fetcher" do | ||
| install do | ||
| require (File.join File.dirname(__FILE__), 'lib', 'snort.rb') | ||
| self.extend FIDIUS::EvasionDB::SnortRuleFetcher | ||
| end | ||
| end |
| @@ -0,0 +1,66 @@ | ||
| # NAME: BitField | ||
| # AUTHOR: Peter Cooper | ||
| # LICENSE: MIT ( http://www.opensource.org/licenses/mit-license.php ) | ||
| # COPYRIGHT: (c) 2007 Peter Cooper (http://www.petercooper.co.uk/) | ||
| # VERSION: v4 | ||
| # HISTORY: v4 (fixed bug where setting 0 bits to 0 caused a set to 1) | ||
| # v3 (supports dynamic bitwidths for array elements.. now doing 32 bit widths default) | ||
| # v2 (now uses 1 << y, rather than 2 ** y .. it's 21.8 times faster!) | ||
| # v1 (first release) | ||
| # | ||
| # DESCRIPTION: Basic, pure Ruby bit field. Pretty fast (for what it is) and memory efficient. | ||
| # I've written a pretty intensive test suite for it and it passes great. | ||
| # Works well for Bloom filters (the reason I wrote it). | ||
| # | ||
| # Create a bit field 1000 bits wide | ||
| # bf = BitField.new(1000) | ||
| # | ||
| # Setting and reading bits | ||
| # bf[100] = 1 | ||
| # bf[100] .. => 1 | ||
| # bf[100] = 0 | ||
| # | ||
| # More | ||
| # bf.to_s = "10101000101010101" (example) | ||
| # bf.total_set .. => 10 (example - 10 bits are set to "1") | ||
| class BitField | ||
| attr_reader :size | ||
| include Enumerable | ||
|
|
||
| ELEMENT_WIDTH = 32 | ||
|
|
||
| def initialize(size) | ||
| @size = size | ||
| @field = Array.new(((size - 1) / ELEMENT_WIDTH) + 1, 0) | ||
| end | ||
|
|
||
| # Set a bit (1/0) | ||
| def []=(position, value) | ||
| if value == 1 | ||
| @field[position / ELEMENT_WIDTH] |= 1 << (position % ELEMENT_WIDTH) | ||
| elsif (@field[position / ELEMENT_WIDTH]) & (1 << (position % ELEMENT_WIDTH)) != 0 | ||
| @field[position / ELEMENT_WIDTH] ^= 1 << (position % ELEMENT_WIDTH) | ||
| end | ||
| end | ||
|
|
||
| # Read a bit (1/0) | ||
| def [](position) | ||
| @field[position / ELEMENT_WIDTH] & 1 << (position % ELEMENT_WIDTH) > 0 ? 1 : 0 | ||
| end | ||
|
|
||
| # Iterate over each bit | ||
| def each(&block) | ||
| @size.times { |position| yield self[position] } | ||
| end | ||
|
|
||
| # Returns the field as a string like "0101010100111100," etc. | ||
| def to_s | ||
| inject("") { |a, b| a + b.to_s } | ||
| end | ||
|
|
||
| # Returns the total number of bits that are set | ||
| # (The technique used here is about 6 times faster than using each or inject direct on the bitfield) | ||
| def total_set | ||
| @field.inject(0) { |a, byte| a += byte & 1 and byte >>= 1 until byte == 0; a } | ||
| end | ||
| end |
| @@ -1,5 +1,5 @@ | ||
| module FIDIUS | ||
| module EvasionDB | ||
| VERSION = "0.0.2" | ||
| end | ||
| end |
| @@ -0,0 +1,3 @@ | ||
| alert tcp $EXTERNAL_NET any <> $HOME_NET 0 (msg:"BAD-TRAFFIC tcp port 0 traffic"; flow:stateless; classtype:misc-activity; sid:524; rev:8;) | ||
| alert udp $EXTERNAL_NET any <> $HOME_NET 0 (msg:"BAD-TRAFFIC udp port 0 traffic"; reference:bugtraq,576; reference:cve,1999-0675; reference:nessus,10074; classtype:misc-activity; sid:525; rev:9;) | ||
|
|
| @@ -0,0 +1,17 @@ | ||
| require 'helper' | ||
|
|
||
| class TestRuleFetchers < Test::Unit::TestCase | ||
| def test_rule_fetcher | ||
| FIDIUS::EvasionDB::Knowledge::EnabledRules.destroy_all | ||
| FIDIUS::EvasionDB::Knowledge::IdsRule.destroy_all | ||
|
|
||
| FIDIUS::EvasionDB.use_rule_fetcher "Snortrule-Fetcher" | ||
| FIDIUS::EvasionDB::current_rule_fetcher.fetch_rules(FIDIUS::EvasionDB::Knowledge::AttackModule.new) | ||
|
|
||
| # cant provide this for sqlite | ||
| #assert_equal 2, FIDIUS::EvasionDB::Knowledge::IdsRule.all.size | ||
| assert_equal 1, FIDIUS::EvasionDB::Knowledge::EnabledRules.all.size | ||
| enabled_rules = FIDIUS::EvasionDB::Knowledge::EnabledRules.first | ||
| assert_equal "11", enabled_rules.bitstring | ||
| end | ||
| end |