| Merge in first round of scripts - warvox - VoIP based wardialing tool, forked f… | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit 18b3b7c1dbb56be8aed57018765ebad24655d98b | |
| parent 2458e746c691176083d95c7bb1585b5cc74bc1e2 | |
| Author: HD Moore <[email protected]> | |
| Date: Fri, 13 Feb 2009 04:39:10 +0000 | |
| Merge in first round of scripts | |
| Diffstat: | |
| A bin/automatch.rb | 51 +++++++++++++++++++++++++++++… | |
| A bin/create_flow.rb | 105 +++++++++++++++++++++++++++++… | |
| A bin/create_samples.rb | 31 +++++++++++++++++++++++++++++… | |
| A bin/create_sig.rb | 95 ++++++++++++++++++++++++++++++ | |
| A bin/create_ui.rb | 176 +++++++++++++++++++++++++++++… | |
| A bin/search_sig.rb | 80 +++++++++++++++++++++++++++++… | |
| A lib/warvox.rb | 8 ++++++++ | |
| A ui/player.swf | 0 | |
| A ui/styles.css | 16 ++++++++++++++++ | |
| 9 files changed, 562 insertions(+), 0 deletions(-) | |
| --- | |
| diff --git a/bin/automatch.rb b/bin/automatch.rb | |
| @@ -0,0 +1,51 @@ | |
| +#!/usr/bin/env ruby | |
| +################### | |
| + | |
| +# | |
| +# Load the library path | |
| +# | |
| +base = __FILE__ | |
| +while File.symlink?(base) | |
| + base = File.expand_path(File.readlink(base), File.dirname(base)) | |
| +end | |
| +$:.unshift(File.join(File.expand_path(File.dirname(base)), '..', 'lib')) | |
| +require 'warvox' | |
| + | |
| +# | |
| +# Script | |
| +# | |
| + | |
| +names = [] | |
| +inp = ARGV.shift() || exit | |
| +fd = File.open(inp, "r") | |
| +fd.each_line do |line| | |
| + data = line.strip.split(/\s+/) | |
| + if(data.shift =~ /(\d+)/) | |
| + if(data.length < 20) | |
| + puts "[*] Skipping carrier #{$1}..." | |
| + next | |
| + end | |
| + names << $1 | |
| + end | |
| +end | |
| + | |
| + | |
| +found = {} | |
| + | |
| +names.each do |n1| | |
| + puts "[*] Searching for matches to #{n1}" | |
| + best = 0 | |
| + names.each do |n2| | |
| + next if found[n2] | |
| + data = `ruby t.rb #{inp} #{n1} #{n2} 2>/dev/null` | |
| + next if not data | |
| + | |
| + data.strip! | |
| + head,dead = data.split(/\s+/, 2) | |
| + next if not head | |
| + | |
| + p head | |
| + | |
| + end | |
| +end | |
| + | |
| diff --git a/bin/create_flow.rb b/bin/create_flow.rb | |
| @@ -0,0 +1,105 @@ | |
| +#!/usr/bin/env ruby | |
| +################### | |
| + | |
| +# | |
| +# Load the library path | |
| +# | |
| +base = __FILE__ | |
| +while File.symlink?(base) | |
| + base = File.expand_path(File.readlink(base), File.dirname(base)) | |
| +end | |
| +$:.unshift(File.join(File.expand_path(File.dirname(base)), '..', 'lib')) | |
| +require 'warvox' | |
| + | |
| +# | |
| +# Script | |
| +# | |
| + | |
| +# | |
| +# Parameters | |
| +# | |
| +lo_lim = 100 | |
| +lo_min = 5 | |
| +lo_cnt = 0 | |
| +hi_min = 5 | |
| +hi_cnt = 0 | |
| + | |
| +# | |
| +# Input | |
| +# | |
| +cnt = 0 | |
| +inp = ARGV.shift || exit | |
| +raw = File.read(inp) | |
| +data = raw.unpack("s*").map {|c| c.abs} | |
| + | |
| +# | |
| +# Granular hi/low state change list | |
| +# | |
| +fprint = [] | |
| +state = :lo | |
| +idx = 0 | |
| +buff = [] | |
| + | |
| +while (idx < data.length) | |
| + case state | |
| + when :lo | |
| + while(idx < data.length and data[idx] <= lo_lim) | |
| + buff << data[idx] | |
| + idx += 1 | |
| + end | |
| + | |
| + # Ignore any sequence that is too small | |
| + fprint << [:lo, buff.length, buff - [0]] if buff.length > lo_m… | |
| + state = :hi | |
| + buff = [] | |
| + next | |
| + when :hi | |
| + while(idx < data.length and data[idx] > lo_lim) | |
| + buff << data[idx] | |
| + idx += 1 | |
| + end | |
| + | |
| + # Ignore any sequence that is too small | |
| + fprint << [:hi, buff.length, buff] if buff.length > hi_min | |
| + state = :lo | |
| + buff = [] | |
| + next | |
| + end | |
| +end | |
| + | |
| + | |
| +# | |
| +# Merge similar blocks | |
| +# | |
| +final = [] | |
| +prev = fprint[0] | |
| +idx = 1 | |
| + | |
| +while(idx < fprint.length) | |
| + | |
| + if(fprint[idx][0] == prev[0]) | |
| + prev[1] += fprint[idx][1] | |
| + prev[2] += fprint[idx][2] | |
| + else | |
| + final << prev | |
| + prev = fprint[idx] | |
| + end | |
| + | |
| + idx += 1 | |
| +end | |
| +final << prev | |
| + | |
| + | |
| +# | |
| +# Process results | |
| +# | |
| +sig = "#{inp} " | |
| + | |
| +final.each do |f| | |
| + sum = 0 | |
| + f[2].each {|i| sum += i } | |
| + avg = (sum == 0) ? 0 : sum / f[2].length | |
| + sig << "#{f[0].to_s.upcase[0,1]},#{f[1]},#{avg} " | |
| +end | |
| + | |
| +puts sig | |
| diff --git a/bin/create_samples.rb b/bin/create_samples.rb | |
| @@ -0,0 +1,31 @@ | |
| +#!/usr/bin/env ruby | |
| +################### | |
| + | |
| +# | |
| +# Load the library path | |
| +# | |
| +base = __FILE__ | |
| +while File.symlink?(base) | |
| + base = File.expand_path(File.readlink(base), File.dirname(base)) | |
| +end | |
| +$:.unshift(File.join(File.expand_path(File.dirname(base)), '..', 'lib')) | |
| +require 'warvox' | |
| + | |
| +# | |
| +# Script | |
| +# | |
| + | |
| +=begin | |
| + 8,000 samples per second | |
| + 160 samples per block of data | |
| +=end | |
| + | |
| +cnt = 0 | |
| +inp = ARGV.shift || exit | |
| +raw = File.read(inp) | |
| +raw.unpack("v*").each do |s| | |
| + val = (s > 0x7fff) ? (0x10000 - s) * -1 : s | |
| + puts "#{cnt} #{val}" | |
| + cnt += 1 | |
| +end | |
| + | |
| diff --git a/bin/create_sig.rb b/bin/create_sig.rb | |
| @@ -0,0 +1,95 @@ | |
| +#!/usr/bin/env ruby | |
| +################### | |
| + | |
| +# | |
| +# Load the library path | |
| +# | |
| +base = __FILE__ | |
| +while File.symlink?(base) | |
| + base = File.expand_path(File.readlink(base), File.dirname(base)) | |
| +end | |
| +$:.unshift(File.join(File.expand_path(File.dirname(base)), '..', 'lib')) | |
| +require 'warvox' | |
| + | |
| +# | |
| +# Script | |
| +# | |
| + | |
| +inp = ARGV.shift() | |
| +num1 = ARGV.shift() || exit | |
| +num2 = ARGV.shift() || exit | |
| + | |
| +min_len = 800 | |
| + | |
| + | |
| +info1 = [] | |
| +info2 = [] | |
| + | |
| +fd = File.open(inp, "r") | |
| +fd.each_line do |line| | |
| + data = line.strip.split(/\s+/) | |
| + name = data.shift | |
| + next if name !~ /#{num1}|#{num2}/ | |
| + | |
| + # Bump the leading silence off | |
| + data.shift if data[0] =~ /^L/ | |
| + | |
| + data.each do |d| | |
| + s,l,a = d.split(",") | |
| + next if l.to_i < min_len | |
| + plot = [s, l.to_i, a.to_i] | |
| + name =~ /#{num1}/ ? info1 << plot : info2 << plot | |
| + end | |
| + | |
| + break if (info1.length > 0 and info2.length > 0) | |
| +end | |
| + | |
| +if (not (info1.length > 0 and info2.length > 0)) | |
| + $stderr.puts "error: could not find both numbers in the database" | |
| + exit | |
| +end | |
| + | |
| + | |
| +min_sig = 2 | |
| +fuzz = 100 | |
| +idx = 0 | |
| +fnd = nil | |
| +r = 0 | |
| + | |
| +while(idx < info1.length-min_sig) | |
| + sig = info1[idx,info1.length] | |
| + idx2 = 0 | |
| + | |
| + while (idx2 < info2.length) | |
| + c = 0 | |
| + 0.upto(sig.length-1) do |si| | |
| + break if not info2[idx2+si] | |
| + break if not ( | |
| + sig[si][0] == info2[idx2+si][0] and | |
| + info2[idx2 + si][1] > sig[si][1]-fuzz and | |
| + info2[idx2 + si][1] < sig[si][1]+fuzz | |
| + ) | |
| + c += 1 | |
| + end | |
| + | |
| + if (c > r) | |
| + r = c | |
| + fnd = sig[0, r] | |
| + end | |
| + idx2 += 1 | |
| + end | |
| + idx += 1 | |
| +end | |
| + | |
| + | |
| + | |
| + | |
| +version = "1.0" | |
| + | |
| +if(fnd) | |
| + sig = "V=#{version},F=#{fuzz},S1=#{num1},S2=#{num2},L=#{r} " | |
| + fnd.each do |i| | |
| + sig << i.join(",") + " " | |
| + end | |
| + puts sig | |
| +end | |
| diff --git a/bin/create_ui.rb b/bin/create_ui.rb | |
| @@ -0,0 +1,176 @@ | |
| +#!/usr/bin/env ruby | |
| +################### | |
| + | |
| +# | |
| +# Load the library path | |
| +# | |
| +base = __FILE__ | |
| +while File.symlink?(base) | |
| + base = File.expand_path(File.readlink(base), File.dirname(base)) | |
| +end | |
| +$:.unshift(File.join(File.expand_path(File.dirname(base)), '..', 'lib')) | |
| +require 'warvox' | |
| + | |
| +# | |
| +# Script | |
| +# | |
| +require "fileutils" | |
| +require "tempfile" | |
| + | |
| +def usage | |
| + "#{$0} src/ dst/" | |
| + exit(0) | |
| +end | |
| + | |
| +src = ARGV.shift || usage | |
| +dst = ARGV.shift || usage | |
| + | |
| + | |
| +FileUtils.mkdir_p(dst) | |
| +FileUtils.copy(File.join(base, "ui", "player.swf"), File.join(dst, "player.swf… | |
| +FileUtils.copy(File.join(base, "ui", "styles.css"), File.join(dst, "styles.css… | |
| + | |
| +calls = [] | |
| +dir = Dir.new(src) | |
| +dir.entries.sort.each do |ent| | |
| + | |
| + path = File.join(src, ent) | |
| + next if ent !~ /(.*)\.raw.gz$/m | |
| + num = $1 | |
| + | |
| + calls << num | |
| + if(File.exists?(File.join(dst, "#{num}.html"))) | |
| + puts "Skipping #{num}..." | |
| + next | |
| + end | |
| + | |
| + puts "Processing #{num}..." | |
| + | |
| + # Decompress the audio file | |
| + rawfile = Tempfile.new("rawfile") | |
| + system("zcat #{path} > #{rawfile.path}") | |
| + | |
| + # Generate data samples | |
| + system("ruby #{base}/bin/sampler.rb #{rawfile.path} > #{dst}/#{num}.da… | |
| + | |
| + # Plot samples to a graph | |
| + plotter = Tempfile.new("gnuplot") | |
| + | |
| + | |
| + plotter.puts("set ylabel \"Frequency\"") | |
| + plotter.puts("set xlabel \"Time\"") | |
| + | |
| + plotter.puts("set terminal png medium size 640,480 transparent") | |
| + plotter.puts("set output \"#{dst}/#{num}_big.png\"") | |
| + plotter.puts("plot \"#{dst}/#{num}.dat\" using 1:2 title \"#{num}\" wi… | |
| + | |
| + plotter.puts("set terminal png small size 160,120 transparent") | |
| + plotter.puts("set format x ''") | |
| + plotter.puts("set format y ''") | |
| + plotter.puts("set output \"#{dst}/#{num}.png\"") | |
| + plotter.puts("plot \"#{dst}/#{num}.dat\" using 1:2 title \"#{num}\" wi… | |
| + | |
| + plotter.flush | |
| + system("gnuplot #{plotter.path}") | |
| + File.unlink(plotter.path) | |
| + File.unlink("#{dst}/#{num}.dat") | |
| + plotter.close | |
| + | |
| + # Detect the carrier | |
| + carrier = `ruby #{base}/bin/detect_carrier.rb #{rawfile.path}` | |
| + eout = File.new(File.join(dst, "#{num}.info"), "w") | |
| + eout.write("#{num} #{carrier}") | |
| + eout.close | |
| + | |
| + | |
| + # Generate a MP3 audio file | |
| + system("sox -s -w -r 8000 -t raw -c 1 #{rawfile.path} #{dst}/#{num}.wa… | |
| + system("lame #{dst}/#{num}.wav #{dst}/#{num}.mp3 >/dev/null 2>&1") | |
| + File.unlink("#{dst}/#{num}.wav") | |
| + File.unlink(rawfile.path) | |
| + rawfile.close | |
| + | |
| + # Generate the HTML | |
| + html = %Q{ | |
| +<html> | |
| + <head> | |
| + <title>Analysis of #{num}</title> | |
| + <link rel="stylesheet" href="styles.css" type="text/css" /> | |
| + </head> | |
| +<body> | |
| + | |
| +<center> | |
| + | |
| +<h1>#{num}</h1> | |
| +<img src="#{num}_big.png"><br/><br/> | |
| +<object class="playerpreview" type="application/x-shockwave-flash" data="playe… | |
| + <param name="movie" value="player.swf" /> | |
| + <param name="FlashVars" value="mp3=#{num}.mp3&showstop=1&showvolum… | |
| +</object> | |
| + | |
| +<p>#{num} - #{carrier}</p> | |
| +<p><a href="index.html"><<< Back</a></p> | |
| + | |
| +</center> | |
| +</body> | |
| +</html> | |
| + } | |
| + | |
| + eout = File.new(File.join(dst, "#{num}.html"), "w") | |
| + eout.write(html) | |
| + eout.close | |
| + | |
| +# break if calls.length > 10 | |
| +end | |
| + | |
| +# Create the final output web page | |
| +eout = File.new(File.join(dst, "index.html"), "w") | |
| + | |
| +html = %Q{ | |
| +<html> | |
| + <head> | |
| + <title>Call Analysis</title> | |
| + <link rel="stylesheet" href="styles.css" type="text/css" /> | |
| + </head> | |
| +<body> | |
| +<center> | |
| + | |
| +<h1>Results for #{calls.length} Calls</h1> | |
| +<table align="center" border=0 cellspacing=0 cellpadding=6> | |
| +} | |
| + | |
| +max = 6 | |
| +cnt = 0 | |
| +calls.sort.each do |num| | |
| + if(cnt == max) | |
| + html << %Q{</tr>\n} | |
| + cnt = 0 | |
| + end | |
| + | |
| + if(cnt == 0) | |
| + html << %Q{<tr>} | |
| + end | |
| + | |
| + live = ( File.read(File.join(dst, "#{num}.info")) =~ /CARRIER/ ) ? "ca… | |
| + html << %Q{<td class="#{live}"><a href="#{num}.html"><img src="#{num}.… | |
| + cnt += 1 | |
| +end | |
| + | |
| +while(cnt < max) | |
| + html << "<td> </td>" | |
| + cnt += 1 | |
| +end | |
| +html << "</tr>\n" | |
| + | |
| +html << %Q{ | |
| +</table> | |
| +</center> | |
| +</body> | |
| +</html> | |
| +} | |
| + | |
| + | |
| +eout.write(html) | |
| +eout.close | |
| + | |
| +puts "Completed" | |
| diff --git a/bin/search_sig.rb b/bin/search_sig.rb | |
| @@ -0,0 +1,80 @@ | |
| +#!/usr/bin/env ruby | |
| +################### | |
| + | |
| +# | |
| +# Load the library path | |
| +# | |
| +base = __FILE__ | |
| +while File.symlink?(base) | |
| + base = File.expand_path(File.readlink(base), File.dirname(base)) | |
| +end | |
| +$:.unshift(File.join(File.expand_path(File.dirname(base)), '..', 'lib')) | |
| +require 'warvox' | |
| + | |
| +# | |
| +# Script | |
| +# | |
| + | |
| +inp = ARGV.shift() | |
| +sig = ARGV.join(' ') | |
| + | |
| +min_len = 800 | |
| + | |
| +# Load the signature from the command line | |
| + | |
| +info1 = [] | |
| +bits = sig.split(/\s+/) | |
| +head = bits.shift | |
| +bits.each do |s| | |
| + inf = s.split(",") | |
| + info1 << [inf[0], inf[1].to_i, inf[2].to_i] | |
| +end | |
| + | |
| +# Search for matching numbers | |
| + | |
| +fd = File.open(inp, "r") | |
| +fd.each_line do |line| | |
| + data = line.strip.split(/\s+/) | |
| + name = data.shift | |
| + | |
| + # Bump the leading silence off | |
| + data.shift if data[0] =~ /^L/ | |
| + | |
| + fnd = nil | |
| + info2 = [] | |
| + data.each do |d| | |
| + s,l,a = d.split(",") | |
| + next if l.to_i < min_len | |
| + info2 << [s, l.to_i, a.to_i] | |
| + end | |
| + | |
| + fuzz = 100 #XXX read from sig | |
| + idx2 = 0 | |
| + fnd = nil | |
| + r = 0 | |
| + | |
| + sig = info1 | |
| + | |
| + while (idx2 < info2.length) | |
| + c = 0 | |
| + 0.upto(sig.length-1) do |si| | |
| + break if not info2[idx2+si] | |
| + break if not ( | |
| + sig[si][0] == info2[idx2+si][0] and | |
| + info2[idx2 + si][1] > sig[si][1]-fuzz and | |
| + info2[idx2 + si][1] < sig[si][1]+fuzz | |
| + ) | |
| + c += 1 | |
| + end | |
| + | |
| + if (c > r) | |
| + r = c | |
| + fnd = sig[0, r] | |
| + end | |
| + idx2 += 1 | |
| + end | |
| + | |
| + if(fnd and r == sig.length) | |
| + puts "MATCHED: #{name} #{r}" | |
| + end | |
| +end | |
| diff --git a/lib/warvox.rb b/lib/warvox.rb | |
| @@ -0,0 +1,8 @@ | |
| +## | |
| +# top level include file for warvox libaries | |
| +## | |
| + | |
| +module WarVOX | |
| + | |
| + | |
| +end | |
| diff --git a/ui/player.swf b/ui/player.swf | |
| Binary files differ. | |
| diff --git a/ui/styles.css b/ui/styles.css | |
| @@ -0,0 +1,16 @@ | |
| +BODY { | |
| + margin: 20px; | |
| + background: white; | |
| + font-family: verdana; | |
| + font-size: 14px; | |
| +} | |
| + | |
| + | |
| +.carrier { | |
| + background: #fffaa2; | |
| +} | |
| + | |
| + | |
| +.voice { | |
| + background: #ddffdf; | |
| +} |