overhaul of the analysis view, addition of a type filter - warvox - VoIP based wardialing tool, forked from rapid7/warvox.
DIR Log
DIR Files
DIR Refs
DIR README
---
DIR commit 953ea21a9aeace23a66b41311f6cb5e21c01137d
DIR parent 72d086e74af1fc956e851c7a27e000685c52c17a
HTML Author: HD Moore <hd_moore@rapid7.com>
Date: Tue, 26 May 2009 02:36:04 +0000
overhaul of the analysis view, addition of a type filter
Diffstat:
M bin/warvox.agi | 3 ++-
M docs/ChangeLog | 7 +++++++
M etc/sigs/01.default.rb | 25 -------------------------
M etc/sigs/99.default.rb | 20 ++++++++++++++++++--
M lib/warvox.rb | 2 +-
M web/app/controllers/analyze_contro… | 82 ++++++++++++++++++++++++++++---
M web/app/controllers/dial_jobs_cont… | 5 +++++
M web/app/helpers/application_helper… | 16 ++++++++++++++++
M web/app/views/analyze/index.html.e… | 7 ++++---
A web/app/views/analyze/show.html.erb | 9 +++++++++
M web/app/views/analyze/view.html.erb | 44 ++++++++++++++++---------------
M web/app/views/dial_results/index.h… | 2 +-
M web/config/routes.rb | 2 +-
13 files changed, 161 insertions(+), 63 deletions(-)
---
DIR diff --git a/bin/warvox.agi b/bin/warvox.agi
@@ -4,7 +4,8 @@
# This script can be used to redial an existing job through Asterix.
# To use this script, add an entry to extensions.conf:
#
-# exten => _777.,1,agi,warvox.agi|/warvox/data/20
+# exten => _777.,1,Answer()
+# exten => _777.,2,agi,warvox.agi|/warvox/data/20
#
base = ARGV.shift
DIR diff --git a/docs/ChangeLog b/docs/ChangeLog
@@ -1,3 +1,10 @@
+2009-05-25 H D Moore <hdm[at]metasploit.com>
+ * switched MP3 quality to 32kbps from 8kpbs for better listening
+ * added bin/warvox.agi as an asterisk plugin to allow job re-dialing
+ * overhaul of the signature system (etc/sigs/*.rb)
+ * filter analysis results by line type
+ * overhaul of results view + show signatures
+
2009-05-10 H D Moore <hdm[at]metasploit.com>
* release of version 1.0.1
DIR diff --git a/etc/sigs/01.default.rb b/etc/sigs/01.default.rb
@@ -19,14 +19,6 @@ fcnt = data[:fcnt]
maxf = data[:maxf]
#
-# Look for silence by checking the frequency signature
-#
-if(freq.map{|f| f.length}.inject(:+) == 0)
- @line_type = 'silence'
- break
-end
-
-#
# Look for silence by checking for a strong frequency in each sample
#
scnt = 0
@@ -42,10 +34,6 @@ freq.each do |fsec|
savg = sump / fsec.length
ecnt += 1 if (savg < 100)
end
-if(ecnt == scnt)
- @line_type = 'silence'
- break
-end
# Store these into data for use later on
data[:scnt] = scnt
@@ -98,19 +86,6 @@ if(fcnt[440] > 1.0 and fcnt[350] > 1.0)
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.
-#
-if(fcnt[1000] >= 1.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
DIR diff --git a/etc/sigs/99.default.rb b/etc/sigs/99.default.rb
@@ -9,6 +9,9 @@
freq = data[:freq]
fcnt = data[:fcnt]
maxf = data[:maxf]
+ecnt = data[:ecnt]
+scnt = data[:scnt]
+
# Look for voice mail by detecting the 1000hz BEEP
# If the call length was too short to catch the beep,
@@ -16,7 +19,7 @@ maxf = data[:maxf]
# is often a different frequency entirely.
if(fcnt[1000] >= 1.0)
@line_type = 'voicemail'
- break
+ break
end
# Look for voicemail by detecting a peak frequency of
@@ -24,7 +27,20 @@ end
# the fallback script.
if(maxf > 995 and maxf < 1005)
@line_type = 'voicemail'
- break
+ break
+end
+
+#
+# Look for silence by checking the frequency signature
+#
+if(freq.map{|f| f.length}.inject(:+) == 0)
+ @line_type = 'silence'
+ break
+end
+
+if(ecnt == scnt)
+ @line_type = 'silence'
+ break
end
#
DIR diff --git a/lib/warvox.rb b/lib/warvox.rb
@@ -11,7 +11,7 @@ require 'warvox/db'
# Global configuration
module WarVOX
- VERSION = '1.0.1'
+ VERSION = '1.0.2'
Base = File.expand_path(File.join(File.dirname(__FILE__), '..'))
Conf = File.expand_path(File.join(Base, 'etc', 'warvox.conf'))
JobManager = WarVOX::JobQueue.new
DIR diff --git a/web/app/controllers/analyze_controller.rb b/web/app/controllers/analyze_controller.rb
@@ -11,16 +11,56 @@ class AnalyzeController < ApplicationController
end
def view
- @job_id = params[:id]
- @results = DialResult.paginate_all_by_dial_job_id(
- @job_id,
- :page => params[:page],
- :order => 'number ASC',
- :per_page => 10,
- :conditions => [ 'completed = ? and processed = ? and busy = ?', true, true, false ]
- )
+ @job_id = params[:id]
+ @dial_job = DialJob.find(@job_id)
+ @shown = params[:show]
+
+ @g1 = Ezgraphix::Graphic.new(:c_type => 'col3d', :div_name => 'calls_pie1')
+ @g1.render_options(:caption => 'Detected Lines by Type', :y_name => 'Lines', :w => 700, :h => 300)
+ ltypes = DialResult.find( :all, :select => 'DISTINCT line_type', :conditions => ["dial_job_id = ?", @job_id] ).map{|r| r.line_type}
+ res_types = {}
+ ltypes.each do |k|
+ next if not k
+ res_types[k.capitalize.to_sym] = DialResult.count(
+ :conditions => ['dial_job_id = ? and line_type = ?', @job_id, k]
+ )
+ end
+
+ @g1.data = res_types
+
+ if(@shown and @shown != 'all')
+ @results = DialResult.paginate_all_by_dial_job_id(
+ @job_id,
+ :page => params[:page],
+ :order => 'number ASC',
+ :per_page => 10,
+ :conditions => [ 'completed = ? and processed = ? and busy = ? and line_type = ?', true, true, false, @shown ]
+ )
+ else
+ @results = DialResult.paginate_all_by_dial_job_id(
+ @job_id,
+ :page => params[:page],
+ :order => 'number ASC',
+ :per_page => 10,
+ :conditions => [ 'completed = ? and processed = ? and busy = ?', true, true, false ]
+ )
+ end
+
+ @filters = []
+ @filters << { :scope => "all", :label => "All" }
+ res_types.keys.each do |t|
+ @filters << { :scope => t.to_s.downcase, :label => t.to_s }
+ end
+
+ end
+
+ def show
+ @job_id = params[:id]
+ @dial_job = DialJob.find(@job_id)
+ @shown = params[:show]
+
@g1 = Ezgraphix::Graphic.new(:c_type => 'col3d', :div_name => 'calls_pie1')
@g1.render_options(:caption => 'Detected Lines by Type', :y_name => 'Lines', :w => 700, :h => 300)
@@ -35,8 +75,34 @@ class AnalyzeController < ApplicationController
end
@g1.data = res_types
+
+ if(@shown and @shown != 'all')
+ @results = DialResult.paginate_all_by_dial_job_id(
+ @job_id,
+ :page => params[:page],
+ :order => 'number ASC',
+ :per_page => 10,
+ :conditions => [ 'completed = ? and processed = ? and busy = ? and line_type = ?', true, true, false, @shown ]
+ )
+ else
+ @results = DialResult.paginate_all_by_dial_job_id(
+ @job_id,
+ :page => params[:page],
+ :order => 'number ASC',
+ :per_page => 10,
+ :conditions => [ 'completed = ? and processed = ? and busy = ?', true, true, false ]
+ )
+ end
+
+ @filters = []
+ @filters << { :scope => "all", :label => "All" }
+ res_types.keys.each do |t|
+ @filters << { :scope => t.to_s.downcase, :label => t.to_s }
+ end
+
end
+
# GET /dial_results/1/resource?id=XXX&type=YYY
def resource
ctype = 'text/html'
DIR diff --git a/web/app/controllers/dial_jobs_controller.rb b/web/app/controllers/dial_jobs_controller.rb
@@ -23,10 +23,13 @@ class DialJobsController < ApplicationController
end
end
+=begin
# GET /dial_jobs/1/edit
def edit
@dial_job = DialJob.find(params[:id])
end
+=end
+
# GET /dial_jobs/1/run
def run
@@ -118,6 +121,7 @@ class DialJobsController < ApplicationController
# PUT /dial_jobs/1
# PUT /dial_jobs/1.xml
+=begin
def update
@dial_job = DialJob.find(params[:id])
respond_to do |format|
@@ -131,5 +135,6 @@ class DialJobsController < ApplicationController
end
end
end
+=end
end
DIR diff --git a/web/app/helpers/application_helper.rb b/web/app/helpers/application_helper.rb
@@ -49,4 +49,20 @@ module ApplicationHelper
end
html << "\n</ul></div>\n"
end
+
+ def select_tag_for_filter(nvpairs, params)
+ _url = ( url_for :overwrite_params => { }).split('?')[0]
+ _html = %{<label for="show">Filter: </label>}
+ _html << %{<select name="show" id="show"}
+ _html << %{onchange="window.location='#{_url}' + '?show=' + this.value">}
+ nvpairs.each do |pair|
+ _html << %{<option value="#{pair[:scope]}"}
+ if params[:show] == pair[:scope] || ((params[:show].nil? || params[:show].empty?) && pair[:scope] == "all")
+ _html << %{ selected="selected"}
+ end
+ _html << %{>#{pair[:label]}}
+ _html << %{</option>}
+ end
+ _html << %{</select>}
+ end
end
DIR diff --git a/web/app/views/analyze/index.html.erb b/web/app/views/analyze/index.html.erb
@@ -21,9 +21,10 @@
"/" +
DialResult.count(:conditions => ['dial_job_id = ?', dial_job.id]).to_s
)%></td>
- <td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %></td>
- <td><%= link_to 'View', view_analyze_path(dial_job) %></td>
- <td><%= link_to 'ReAnalyze', reanalyze_dial_result_path(dial_job), :confirm => 'Process this job again?' %></td>
+ <td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S") %></td>
+ <!-- <td><%= link_to 'Overview', show_analyze_path(dial_job) %></td> -->
+ <td><%= link_to 'Browse', view_analyze_path(dial_job) %></td>
+ <td><%= link_to 'ReAnalyze', reanalyze_dial_result_path(@dial_job), :confirm => 'Process this job again?' %></td>
</tr>
<% end %>
</table>
DIR diff --git a/web/app/views/analyze/show.html.erb b/web/app/views/analyze/show.html.erb
@@ -0,0 +1,9 @@
+<h1 class='title'>Overview of Job ID <%= @job_id %></h1>
+
+<table width='100%' align='center' border=0 cellspacing=0 cellpadding=6>
+<tr>
+ <td align='center'><%= render_ezgraphix @g1 %></td>
+</tr>
+</table>
+
+
DIR diff --git a/web/app/views/analyze/view.html.erb b/web/app/views/analyze/view.html.erb
@@ -1,5 +1,7 @@
<h1 class='title'>Analysis of Job ID <%= @job_id %></h1>
+<%= select_tag_for_filter(@filters, params) %>
+
<table width='100%' align='center' border=0 cellspacing=0 cellpadding=6>
<tr>
<td align='center'><%= render_ezgraphix @g1 %></td>
@@ -10,44 +12,44 @@
<table class='table_scaffold' width='100%'>
<tr>
- <th>ID</th>
<th>Number</th>
- <th>Type</th>
<th>Signal</th>
- <th>Spectrum</th>
- <th>CID</th>
- <th>Provider</th>
- <th>Time</th>
- <th>Ring</th>
</tr>
<% @results.each do |dial_result| %>
<tr>
- <td><%=h dial_result.id %></td>
- <td>
- <b><%= dial_result.number %></b><br/>
+ <td align='center'>
+
<object
type="application/x-shockwave-flash"
data="/images/musicplayer.swf?song_url=<%=resource_analyze_path(@job_id)%>/<%= dial_result.id %>/mp3"
width="20"
height="17"
+ style="margin-bottom: -5px;"
>
<param name="movie" value="/musicplayer.swf?song_url=<%=resource_analyze_path(@job_id)%>/<%= dial_result.id %>/mp3"></param>
<param name="wmode" value="transparent"></param>
- </object>
+ </object>
+ <b><%= dial_result.number %></b>
+ <hr width='100%' size='1'/>
+ CallerID: <%= dial_result.cid%><br/>
+ Provider: <%=h dial_result.provider.name %><br/>
+ Audio: <%=h dial_result.seconds %> Seconds<br/>
+ Ringer: <%=h dial_result.ringtime %> Seconds
+
</td>
- <td><%=h dial_result.line_type.upcase %></td>
- <td>
+ <td align='center'>
+ <b><%=h dial_result.line_type.upcase %></b><br/>
<a href="<%=resource_analyze_path(@job_id)%>/<%= dial_result.id %>/big_sig_dots" rel="lightbox"><img src="<%=resource_analyze_path(@job_id)%>/<%= dial_result.id %>/small_sig" /></a>
+ <a href="<%=resource_analyze_path(@job_id)%>/<%= dial_result.id %>/big_freq" rel="lightbox"><img src="<%=resource_analyze_path(@job_id)%>/<%= dial_result.id %>/small_freq" /></a><br/>
+ <% (dial_result.signatures||"").split("\n").each do |s|
+ sid,mat,name = s.split(':', 3)
+ str = [mat.to_i * 6.4, 255].min
+ col = ("%.2x" % (255 - str)) * 3
+ %>
+ <div style="color: #<%= col%>;"><%=h name%> (<%=h sid %>@<%=h mat %>)</div>
+ <% end %>
</td>
- <td>
- <a href="<%=resource_analyze_path(@job_id)%>/<%= dial_result.id %>/big_freq" rel="lightbox"><img src="<%=resource_analyze_path(@job_id)%>/<%= dial_result.id %>/small_freq" /></a>
- </td>
-
- <td><%=h dial_result.cid %></td>
- <td><%=h dial_result.provider.name %></td>
- <td><%=h dial_result.seconds %></td>
- <td><%=h dial_result.ringtime %></td>
</tr>
<% end %>
</table>
DIR diff --git a/web/app/views/dial_results/index.html.erb b/web/app/views/dial_results/index.html.erb
@@ -20,7 +20,7 @@
"/" +
DialResult.count(:conditions => ['dial_job_id = ?', dial_job.id]).to_s
)%></td>
- <td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %></td>
+ <td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S") %></td>
<td><%= link_to 'View', view_dial_result_path(dial_job) %></td>
<% if(dial_job.processed) %>
<td><%= link_to 'View Analysis', analyze_dial_result_path(dial_job) %></td>
DIR diff --git a/web/config/routes.rb b/web/config/routes.rb
@@ -3,7 +3,7 @@ ActionController::Routing::Routes.draw do |map|
map.resources :dial_jobs, :has_many => [ :dial_results ], :member => { :run => :get, :stop => :get }
- map.resources :analyze, :member => { :view => :get, :resource => :get }
+ map.resources :analyze, :member => { :view => :get, :resource => :get, :show => :get }
map.connect 'analyze/:id/resource/:result_id/:type', :controller => 'analyze', :action => 'resource'