| overhaul of the analysis view, addition of a type filter - warvox - VoIP based … | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit 953ea21a9aeace23a66b41311f6cb5e21c01137d | |
| parent 72d086e74af1fc956e851c7a27e000685c52c17a | |
| Author: HD Moore <[email protected]> | |
| 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(-) | |
| --- | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| # | |
| 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 | |
| diff --git a/web/app/controllers/analyze_controller.rb b/web/app/controllers/an… | |
| @@ -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 = ?… | |
| - ) | |
| + @job_id = params[:id] | |
| + @dial_job = DialJob.find(@job_id) | |
| + @shown = params[:show] | |
| + | |
| + @g1 = Ezgraphix::Graphic.new(:c_type => 'col3d', :div_name => 'calls_p… | |
| + @g1.render_options(:caption => 'Detected Lines by Type', :y_name => 'L… | |
| + ltypes = DialResult.find( :all, :select => 'DISTINCT line_type', :cond… | |
| + 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 = ?', @… | |
| + ) | |
| + 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 … | |
| + ) | |
| + 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 … | |
| + ) | |
| + 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_p… | |
| @g1.render_options(:caption => 'Detected Lines by Type', :y_name => 'L… | |
| @@ -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 … | |
| + ) | |
| + 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 … | |
| + ) | |
| + 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' | |
| diff --git a/web/app/controllers/dial_jobs_controller.rb b/web/app/controllers/… | |
| @@ -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 | |
| diff --git a/web/app/helpers/application_helper.rb b/web/app/helpers/applicatio… | |
| @@ -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.val… | |
| + nvpairs.each do |pair| | |
| + _html << %{<option value="#{pair[:scope]}"} | |
| + if params[:show] == pair[:scope] || ((params[:show].nil? || params… | |
| + _html << %{ selected="selected"} | |
| + end | |
| + _html << %{>#{pair[:label]}} | |
| + _html << %{</option>} | |
| + end | |
| + _html << %{</select>} | |
| + end | |
| end | |
| diff --git a/web/app/views/analyze/index.html.erb b/web/app/views/analyze/index… | |
| @@ -21,9 +21,10 @@ | |
| "/" + | |
| DialResult.count(:conditions => ['dial_job_id = ?', dial_job.i… | |
| )%></td> | |
| - <td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %>… | |
| - <td><%= link_to 'View', view_analyze_path(dial_job) %></td> | |
| - <td><%= link_to 'ReAnalyze', reanalyze_dial_result_path(dial_job), :co… | |
| + <td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S") %></t… | |
| + <!-- <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), :c… | |
| </tr> | |
| <% end %> | |
| </table> | |
| diff --git a/web/app/views/analyze/show.html.erb b/web/app/views/analyze/show.h… | |
| @@ -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> | |
| + | |
| + | |
| diff --git a/web/app/views/analyze/view.html.erb b/web/app/views/analyze/view.h… | |
| @@ -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_ana… | |
| width="20" | |
| height="17" | |
| + style="margin-bottom: -5px;" | |
| > | |
| <param name="movie" value="/musicplayer.swf?song_url=<… | |
| <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.i… | |
| + <a href="<%=resource_analyze_path(@job_id)%>/<%= dial_result.i… | |
| + <% (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 … | |
| + <% end %> | |
| </td> | |
| - <td> | |
| - <a href="<%=resource_analyze_path(@job_id)%>/<%= dial_result.i… | |
| - </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> | |
| diff --git a/web/app/views/dial_results/index.html.erb b/web/app/views/dial_res… | |
| @@ -20,7 +20,7 @@ | |
| "/" + | |
| DialResult.count(:conditions => ['dial_job_id = ?', dial_job.i… | |
| )%></td> | |
| - <td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %>… | |
| + <td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S") %></t… | |
| <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… | |
| 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 … | |
| - map.resources :analyze, :member => { :view => :get, :resource => :get } | |
| + map.resources :analyze, :member => { :view => :get, :resource => :get, :show… | |
| map.connect 'analyze/:id/resource/:result_id/:type', :controller => 'analy… | |