| Add the new signature structure - warvox - VoIP based wardialing tool, forked f… | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit 6d4ec6d54551bc27269e9202e8ed3ebfb62b952d | |
| parent a919a76a13611af8105aff7c96fad4a714e3c6c7 | |
| Author: HD Moore <[email protected]> | |
| Date: Tue, 19 May 2009 02:30:46 +0000 | |
| Add the new signature structure | |
| Diffstat: | |
| A etc/sigs/01.default.rb | 96 +++++++++++++++++++++++++++++… | |
| A etc/sigs/99.default.rb | 10 ++++++++++ | |
| M etc/warvox.conf | 5 +++++ | |
| M lib/warvox/config.rb | 23 +++++++++++++++++++++++ | |
| M lib/warvox/jobs/analysis.rb | 66 ++++++-----------------------… | |
| 5 files changed, 146 insertions(+), 54 deletions(-) | |
| --- | |
| diff --git a/etc/sigs/01.default.rb b/etc/sigs/01.default.rb | |
| @@ -0,0 +1,96 @@ | |
| +# | |
| +# WarVOX Default Signatures | |
| +# | |
| + | |
| +# | |
| +# Variables: | |
| +# pks = peak frequencies | |
| +# ppz = top 10 frequencies per sample | |
| +# flow = flow signature | |
| +# | |
| + | |
| +# | |
| +# These signatures are used first and catch the majority of common | |
| +# systems. If you want to force a different type of detection, add | |
| +# your signatures to a file starting with "00." and place it in | |
| +# this directory. Signature files are processed numerically from | |
| +# lowest to highest (like RC scripts) | |
| +# | |
| + | |
| + | |
| +# | |
| +# Look for silence by checking for any significant noise | |
| +# | |
| +if(flow.split(/\s+/).grep(/^H,/).length == 0) | |
| + line_type = 'silence' | |
| + break | |
| +end | |
| + | |
| + | |
| +# | |
| +# Look for modems by detecting a peak 2250hz tone | |
| +# | |
| +f_2250 = 0 | |
| +pks.each{|f| f_2250 += 1 if(f[0] > 2240 and f[0] < 2260) } | |
| +if(f_2250 > 2) | |
| + line_type = 'modem' | |
| + break | |
| +end | |
| + | |
| + | |
| +# | |
| +# Most faxes have at least two of the following tones | |
| +# This can false positive if the modem signature above | |
| +# is removed. | |
| +# | |
| +f_1625 = f_1660 = f_1825 = f_2100 = false | |
| +pks.each do |f| | |
| + f_1625 = true if(f[0] > 1620 and f[0] < 1630) | |
| + f_1660 = true if(f[0] > 1655 and f[0] < 1665) | |
| + f_1825 = true if(f[0] > 1820 and f[0] < 1830) | |
| + f_2100 = true if(f[0] > 2090 and f[0] < 2110) … | |
| +end | |
| +if([ f_1625, f_1660, f_1825, f_2100 ].grep(true).length >= 2) | |
| + line_type = 'fax' | |
| + break | |
| +end | |
| + | |
| + | |
| +# | |
| +# Dial tone detection (more precise to use pkz over pks) | |
| +# Look for a combination of 440hz + 350hz signals | |
| +# | |
| +f_440 = 0 | |
| +f_350 = 0 | |
| +pkz.each do |fb| | |
| + fb.each do |f| | |
| + f_440 += 0.1 if (f[0] > 437 and f[0] < 444) | |
| + f_350 += 0.1 if (f[0] > 345 and f[0] < 355) | |
| + end | |
| +end | |
| +if(f_440 > 1.0 and f_350 > 1.0) | |
| + line_type = 'dialtone' | |
| + break | |
| +end | |
| + | |
| + | |
| +# | |
| +# Look for voice mail by detecting the 1000hz BEEP | |
| +# If the call length was too short to catch the beep, | |
| +# this signature can fail. For non-US numbers, the beep | |
| +# is often a different frequency entirely. | |
| +# | |
| +f_1000 = 0 | |
| +pks.each{|f| f_1000 += 1 if(f[0] > 990 and f[0] < 1010) } | |
| +if(f_1000 > 0) | |
| + line_type = 'voicemail' | |
| + break | |
| +end | |
| + | |
| + | |
| +# | |
| +# To use additional signatures, add new scripts to this directory | |
| +# named XX.myscript.rb, where XX is a two digit number less than | |
| +# 99 and greater than 01. | |
| +# | |
| +# | |
| diff --git a/etc/sigs/99.default.rb b/etc/sigs/99.default.rb | |
| @@ -0,0 +1,10 @@ | |
| +# | |
| +# WarVOX Fallback Signatures | |
| +# | |
| + | |
| +# | |
| +# Fall back to 'voice' if nothing else has been matched | |
| +# This should be last signature file processed | |
| +# | |
| + | |
| +line_type = 'voice' | |
| diff --git a/etc/warvox.conf b/etc/warvox.conf | |
| @@ -38,3 +38,8 @@ analysis_threads: 2 | |
| # Configure the dial blacklist location | |
| # | |
| blacklist: %BASE%/etc/blacklist.txt | |
| + | |
| +# | |
| +# Configure the signature directory | |
| +# | |
| +signatures: %BASE%/etc/sigs | |
| diff --git a/lib/warvox/config.rb b/lib/warvox/config.rb | |
| @@ -73,6 +73,29 @@ module Config | |
| end | |
| + def self.signatures_path | |
| + info = YAML.load_file(WarVOX::Conf) | |
| + return nil if not info | |
| + return nil if not info['signatures'] | |
| + File.expand_path(info['signatures'].gsub('%BASE%', WarVOX::Bas… | |
| + end | |
| + | |
| + def self.signatures_load | |
| + path = signatures_path | |
| + sigs = [] | |
| + return sigs if not path | |
| + | |
| + Dir.new(path).entries.sort{ |a,b| | |
| + a.to_i <=> b.to_i | |
| + }.map{ |ent| | |
| + File.join(path, ent) | |
| + }.each do |ent| | |
| + sigs << ent if File.file?(ent) | |
| + end | |
| + | |
| + sigs | |
| + end | |
| + | |
| # This method searches the PATH environment variable for | |
| # a fully qualified path to the supplied file name. | |
| # Stolen from Rex | |
| diff --git a/lib/warvox/jobs/analysis.rb b/lib/warvox/jobs/analysis.rb | |
| @@ -170,8 +170,10 @@ class Analysis < Base | |
| # Calculate average frequency and peaks over time | |
| avg = {} | |
| pks = [] | |
| + pkz = [] | |
| fft.each do |slot| | |
| pks << slot.sort{|a,b| a[1] <=> b[1] }.reverse[0] | |
| + pkz << slot.sort{|a,b| a[1] <=> b[1] }.reverse[0..9] | |
| slot.each do |freq| | |
| avg[ freq[0] ] ||= 0 | |
| avg[ freq[0] ] += freq[1] | |
| @@ -188,64 +190,20 @@ class Analysis < Base | |
| end | |
| frefile.flush | |
| - # | |
| - # XXX: store significant frequencies somewhere (tones) | |
| - # | |
| - | |
| # Make a guess as to what kind of phone number we found | |
| line_type = nil | |
| - while(not line_type) | |
| - | |
| - # Look for silence | |
| - if(flow.split(/\s+/).grep(/^H,/).length == 0) | |
| - line_type = 'silence' | |
| - break | |
| - end | |
| - | |
| - # Look for modems by detecting 2250hz tones | |
| - f_2250 = 0 | |
| - pks.each{|f| f_2250 += 1 if(f[0] > 2240 and f[0] < 226… | |
| - if(f_2250 > 2) | |
| - line_type = 'modem' | |
| - break | |
| - end | |
| - # Look for the 1000hz voicemail BEEP | |
| - if(res[:peak_freq] > 990 and res[:peak_freq] < 1010) | |
| - line_type = 'voicemail' | |
| - break | |
| - end | |
| - | |
| - # Most faxes have at least two of the following tones | |
| - f_1625 = f_1660 = f_1825 = f_2100 = false | |
| - pks.each do |f| | |
| - # $stderr.puts "#{r.number} #{f.inspect}" | |
| - f_1625 = true if(f[0] > 1620 and f[0] < 1630) | |
| - f_1660 = true if(f[0] > 1655 and f[0] < 1665) | |
| - f_1825 = true if(f[0] > 1820 and f[0] < 1830) | |
| - f_2100 = true if(f[0] > 2090 and f[0] < 2110) … | |
| - end | |
| - if([ f_1625, f_1660, f_1825, f_2100 ].grep(true).lengt… | |
| - line_type = 'fax' | |
| - break | |
| - end | |
| - | |
| - # Dial tone detection | |
| - f_440 = false | |
| - f_350 = false | |
| - pks.each do |f| | |
| - f_440 = true if(f[0] > 435 and f[0] < 445) | |
| - f_345 = true if(f[0] > 345 and f[0] < 355) | |
| - end | |
| - if(f_440 and f_350) | |
| - line_type = 'dialtone' | |
| - break | |
| + WarVOX::Config.signatures_load.each do |sigfile| | |
| + begin | |
| + str = File.read(sigfile, File.size(sigfile)) | |
| + while(true) | |
| + eval(str, binding) | |
| + break | |
| + end | |
| + rescue ::Exception => e | |
| + $stderr.puts "DEBUG: Caught exception in #{sig… | |
| end | |
| - | |
| - # Detect humans based on long pauses | |
| - | |
| - # Default to voice | |
| - line_type = 'voice' | |
| + break if line_type | |
| end | |
| # Save the guessed line type |