Store various call info into the database, determine whether the call is fax/modem/vmb/voice/dialtone, add a type pie chart - warvox - VoIP based wardialing tool, forked from rapid7/warvox.
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit 6389d305a83d6a5384d3332e5ca69cf6d35a8abf
(DIR) parent 76fc65ae7c8b0a944971cfcdbdf4dae3bb1cd3ec
(HTM) Author: HD Moore <hd_moore@rapid7.com>
Date: Wed, 4 Mar 2009 03:57:08 +0000
Store various call info into the database, determine whether the call is fax/modem/vmb/voice/dialtone, add a type pie chart
Diffstat:
M lib/warvox/jobs/analysis.rb | 82 +++++++++++++++++++++++++++----
M web/app/controllers/analyze_contro… | 19 +++++++++++++++++++
M web/app/views/analyze/view.html.erb | 21 +++++++++++++--------
A web/db/migrate/20090304013815_add_… | 9 +++++++++
A web/db/migrate/20090304013839_add_… | 9 +++++++++
A web/db/migrate/20090304013909_add_… | 9 +++++++++
A web/db/migrate/20090304014018_add_… | 9 +++++++++
A web/db/migrate/20090304014033_add_… | 9 +++++++++
M web/db/schema.rb | 7 ++++++-
R web/public/images/overlay.png -> w… | 0
10 files changed, 156 insertions(+), 18 deletions(-)
---
(DIR) diff --git a/lib/warvox/jobs/analysis.rb b/lib/warvox/jobs/analysis.rb
@@ -7,7 +7,7 @@ class Analysis < Base
@@kissfft_loaded = false
begin
require 'kissfft'
- @kissfft_loaded = true
+ @@kissfft_loaded = true
rescue ::LoadError
end
@@ -62,11 +62,16 @@ class Analysis < Base
#
# Create the signature database
#
- raw = WarVOX::Audio::Raw.from_file(r.rawfile)
- fd = File.new("#{bname}.sig", "wb")
- fd.write raw.to_flow
+
+ raw = WarVOX::Audio::Raw.from_file(r.rawfile)
+ flow = raw.to_flow
+ fd = File.new("#{bname}.sig", "wb")
+ fd.write flow
fd.close
+ # Save the signature data
+ r.sig_data = flow
+
#
# Create a raw decompressed file
#
@@ -108,6 +113,9 @@ class Analysis < Base
end
end
+ # Save the peak frequency
+ r.peak_freq = maxf
+
# Calculate average frequency and peaks over time
avg = {}
pks = []
@@ -118,17 +126,73 @@ class Analysis < Base
avg[ freq[0] ] += freq[1]
end
end
+
+ # Save the peak frequencies over time
+ r.peak_freq_data = pks.map{|f| "#{f[0]}-#{f[1]}" }.join(" ")
+
+ # Generate the frequency file
avg.keys.sort.each do |k|
avg[k] = avg[k] / res.length
frefile.write("#{k} #{avg[k]}\n")
end
frefile.flush
- # XXX: Store all frequency information
- # maxf == peak frequency
- # avg == averages over whole sample
- # pks == peaks over time
- # tones == significant frequencies
+ #
+ # 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 modems by detecting 2250hz tones
+ 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
+
+ # Look for the 1000hz voicemail BEEP
+ if(r.peak_freq > 990 and r.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).length >= 2)
+ 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
+ end
+
+ # Detect humans based on long pauses
+
+ # Default to voice
+ line_type = 'voice'
+ end
+
+ # Save the guessed line type
+ r.line_type = line_type
# Plot samples to a graph
plotter = Tempfile.new("gnuplot")
(DIR) diff --git a/web/app/controllers/analyze_controller.rb b/web/app/controllers/analyze_controller.rb
@@ -19,6 +19,25 @@ class AnalyzeController < ApplicationController
:per_page => 10,
:conditions => [ 'completed = ? and processed = ? and busy = ?', true, true, false ]
)
+
+ @g1 = Ezgraphix::Graphic.new(:c_type => 'pie2d', :div_name => 'calls_pie1')
+ @g1.render_options(:caption => 'Line Types')
+
+ @g2 = Ezgraphix::Graphic.new(:c_type => 'pie2d', :div_name => 'calls_pie2')
+ @g2.render_options(:caption => 'Ring Time')
+
+ res_types = {}
+ res_rings = {}
+
+ @results.each do |r|
+ res_rings[ r.ringtime ] ||= 0
+ res_rings[ r.ringtime ] += 1
+ res_types[ r.line_type.capitalize.to_sym ] ||= 0
+ res_types[ r.line_type.capitalize.to_sym ] += 1
+ end
+
+ @g1.data = res_types
+ @g2.data = res_rings
end
# GET /dial_results/1/resource?id=XXX&type=YYY
(DIR) diff --git a/web/app/views/analyze/view.html.erb b/web/app/views/analyze/view.html.erb
@@ -2,8 +2,8 @@
<table width='100%' align='center' border=0 cellspacing=0 cellpadding=6>
<tr>
- <td align='center'> </td>
- <td align='center'> </td>
+ <td align='center'><%= render_ezgraphix @g1 %></td>
+ <td align='center'><%= render_ezgraphix @g2 %></td>
</tr>
</table>
@@ -11,11 +11,13 @@
<table class='table_scaffold' width='100%'>
<tr>
- <th>ID</th>
+ <th>ID</th>
+ <th>Number</th>
+ <th>Type</th>
+ <th>Peak Freq</th>
<th>Signal</th>
<th>Spectrum</th>
- <th>Number</th>
- <th>CallerID</th>
+ <th>CID</th>
<th>Provider</th>
<th>Call Time</th>
<th>Ring Time</th>
@@ -24,15 +26,18 @@
<% @results.each do |dial_result| %>
<tr>
<td><%=h dial_result.id %></td>
+ <td>
+ <a href="<%=resource_analyze_path(@job_id)%>?result_id=<%= dial_result.id %>&type=mp3" target="_new"><%= dial_result.number %></a>
+ </td>
+ <td><%=h dial_result.line_type %></td>
+ <td><%=h dial_result.peak_freq.to_i %></td>
<td>
<a href="<%=resource_analyze_path(@job_id)%>?result_id=<%= dial_result.id %>&type=big_sig_dots" rel="lightbox"><img src="<%=resource_analyze_path(@job_id)%>?result_id=<%= dial_result.id %>&type=small_sig" /></a>
</td>
<td>
<a href="<%=resource_analyze_path(@job_id)%>?result_id=<%= dial_result.id %>&type=big_freq" rel="lightbox"><img src="<%=resource_analyze_path(@job_id)%>?result_id=<%= dial_result.id %>&type=small_freq" /></a>
</td>
- <td>
- <a href="<%=resource_analyze_path(@job_id)%>?result_id=<%= dial_result.id %>&type=mp3" target="_new"><%= dial_result.number %></a>
- </td>
+
<td><%=h dial_result.cid %></td>
<td><%=h dial_result.provider.name %></td>
<td><%=h dial_result.seconds %></td>
(DIR) diff --git a/web/db/migrate/20090304013815_add_peak_freq_to_dial_results.rb b/web/db/migrate/20090304013815_add_peak_freq_to_dial_results.rb
@@ -0,0 +1,9 @@
+class AddPeakFreqToDialResults < ActiveRecord::Migration
+ def self.up
+ add_column :dial_results, :peak_freq, :number
+ end
+
+ def self.down
+ remove_column :dial_results, :peak_freq
+ end
+end
(DIR) diff --git a/web/db/migrate/20090304013839_add_peak_freq_data_to_dial_results.rb b/web/db/migrate/20090304013839_add_peak_freq_data_to_dial_results.rb
@@ -0,0 +1,9 @@
+class AddPeakFreqDataToDialResults < ActiveRecord::Migration
+ def self.up
+ add_column :dial_results, :peak_freq_data, :string
+ end
+
+ def self.down
+ remove_column :dial_results, :peak_freq_data
+ end
+end
(DIR) diff --git a/web/db/migrate/20090304013909_add_sig_data_to_dial_results.rb b/web/db/migrate/20090304013909_add_sig_data_to_dial_results.rb
@@ -0,0 +1,9 @@
+class AddSigDataToDialResults < ActiveRecord::Migration
+ def self.up
+ add_column :dial_results, :sig_data, :string
+ end
+
+ def self.down
+ remove_column :dial_results, :sig_data
+ end
+end
(DIR) diff --git a/web/db/migrate/20090304014018_add_line_type_to_dial_results.rb b/web/db/migrate/20090304014018_add_line_type_to_dial_results.rb
@@ -0,0 +1,9 @@
+class AddLineTypeToDialResults < ActiveRecord::Migration
+ def self.up
+ add_column :dial_results, :line_type, :string
+ end
+
+ def self.down
+ remove_column :dial_results, :line_type
+ end
+end
(DIR) diff --git a/web/db/migrate/20090304014033_add_notes_to_dial_results.rb b/web/db/migrate/20090304014033_add_notes_to_dial_results.rb
@@ -0,0 +1,9 @@
+class AddNotesToDialResults < ActiveRecord::Migration
+ def self.up
+ add_column :dial_results, :notes, :string
+ end
+
+ def self.down
+ remove_column :dial_results, :notes
+ end
+end
(DIR) diff --git a/web/db/schema.rb b/web/db/schema.rb
@@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20090303225838) do
+ActiveRecord::Schema.define(:version => 20090304014033) do
create_table "dial_jobs", :force => true do |t|
t.string "range"
@@ -39,6 +39,11 @@ ActiveRecord::Schema.define(:version => 20090303225838) do
t.datetime "updated_at"
t.datetime "processed_at"
t.string "cid"
+ t.decimal "peak_freq"
+ t.string "peak_freq_data"
+ t.string "sig_data"
+ t.string "line_type"
+ t.string "notes"
end
create_table "providers", :force => true do |t|
(DIR) diff --git a/web/public/images/overlay.png b/web/public/stylesheets/overlay.png
Binary files differ.