dap 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
 - data/.rspec +2 -0
 - data/Gemfile +15 -0
 - data/Gemfile.lock +55 -0
 - data/LICENSE +20 -0
 - data/README.md +15 -0
 - data/bin/dap +137 -0
 - data/dap.gemspec +42 -0
 - data/data/.gitkeep +0 -0
 - data/lib/dap.rb +101 -0
 - data/lib/dap/filter.rb +8 -0
 - data/lib/dap/filter/base.rb +37 -0
 - data/lib/dap/filter/geoip.rb +72 -0
 - data/lib/dap/filter/http.rb +173 -0
 - data/lib/dap/filter/names.rb +151 -0
 - data/lib/dap/filter/openssl.rb +53 -0
 - data/lib/dap/filter/recog.rb +23 -0
 - data/lib/dap/filter/simple.rb +340 -0
 - data/lib/dap/filter/udp.rb +401 -0
 - data/lib/dap/input.rb +74 -0
 - data/lib/dap/input/csv.rb +60 -0
 - data/lib/dap/input/warc.rb +81 -0
 - data/lib/dap/output.rb +117 -0
 - data/lib/dap/proto/addp.rb +0 -0
 - data/lib/dap/proto/dtls.rb +21 -0
 - data/lib/dap/proto/ipmi.rb +94 -0
 - data/lib/dap/proto/natpmp.rb +19 -0
 - data/lib/dap/proto/wdbrpc.rb +58 -0
 - data/lib/dap/utils/oui.rb +16586 -0
 - data/lib/dap/version.rb +3 -0
 - data/samples/http_get_reply.ic12.bz2 +0 -0
 - data/samples/http_get_reply.ic12.sh +1 -0
 - data/samples/http_get_reply_iframes.json.bz2 +0 -0
 - data/samples/http_get_reply_iframes.json.sh +1 -0
 - data/samples/http_get_reply_links.json.sh +1 -0
 - data/samples/iawide.warc.bz2 +0 -0
 - data/samples/iawide_warc.sh +1 -0
 - data/samples/ipmi_chan_auth_replies.crd.bz2 +0 -0
 - data/samples/ipmi_chan_auth_replies.sh +1 -0
 - data/samples/ssl_certs.bz2 +0 -0
 - data/samples/ssl_certs_geo.sh +1 -0
 - data/samples/ssl_certs_names.sh +1 -0
 - data/samples/ssl_certs_names_expanded.sh +1 -0
 - data/samples/ssl_certs_org.sh +1 -0
 - data/samples/udp-netbios.csv.bz2 +0 -0
 - data/samples/udp-netbios.sh +1 -0
 - data/spec/dap/proto/ipmi_spec.rb +19 -0
 - data/tools/geo-ip-summary.rb +149 -0
 - data/tools/ipmi-vulns.rb +27 -0
 - data/tools/json-summarize.rb +81 -0
 - data/tools/netbios-counts.rb +271 -0
 - data/tools/upnp-vulns.rb +35 -0
 - data/tools/value-counts-to-md-table.rb +23 -0
 - metadata +264 -0
 
| 
         @@ -0,0 +1,72 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'geoip'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Dap
         
     | 
| 
      
 4 
     | 
    
         
            +
            module Filter
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module GeoIPLibrary
         
     | 
| 
      
 7 
     | 
    
         
            +
              GEOIP_DIRS = [ 
         
     | 
| 
      
 8 
     | 
    
         
            +
                File.expand_path( File.join( File.dirname(__FILE__), "..", "..", "..", "data")),
         
     | 
| 
      
 9 
     | 
    
         
            +
                "/var/lib/geoip"
         
     | 
| 
      
 10 
     | 
    
         
            +
              ]
         
     | 
| 
      
 11 
     | 
    
         
            +
              GEOIP_CITY = %W{ geoip.dat geoip_city.dat GeoCity.dat IP_V4_CITY.dat GeoCityLite.dat }
         
     | 
| 
      
 12 
     | 
    
         
            +
              GEOIP_ORGS = %W{ geoip_org.dat IP_V4_ORG.dat  }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              @@geo_city = nil
         
     | 
| 
      
 15 
     | 
    
         
            +
              @@geo_orgs = nil
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              GEOIP_DIRS.each do |d|
         
     | 
| 
      
 18 
     | 
    
         
            +
                GEOIP_CITY.each do |f|
         
     | 
| 
      
 19 
     | 
    
         
            +
                  path = File.join(d, f)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  if ::File.exist?(path)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    @@geo_city = GeoIP::City.new(path)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    break
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
                GEOIP_ORGS.each do |f|
         
     | 
| 
      
 26 
     | 
    
         
            +
                  path = File.join(d, f)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  if ::File.exist?( path )
         
     | 
| 
      
 28 
     | 
    
         
            +
                    @@geo_orgs = GeoIP::Organization.new(path)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    break
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                end  
         
     | 
| 
      
 32 
     | 
    
         
            +
              end  
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            #
         
     | 
| 
      
 37 
     | 
    
         
            +
            # Add GeoIP tags using the MaxMind GeoIP::City 
         
     | 
| 
      
 38 
     | 
    
         
            +
            #
         
     | 
| 
      
 39 
     | 
    
         
            +
            class FilterGeoIP
         
     | 
| 
      
 40 
     | 
    
         
            +
              include BaseDecoder
         
     | 
| 
      
 41 
     | 
    
         
            +
              include GeoIPLibrary
         
     | 
| 
      
 42 
     | 
    
         
            +
              def decode(ip)
         
     | 
| 
      
 43 
     | 
    
         
            +
                return unless @@geo_city
         
     | 
| 
      
 44 
     | 
    
         
            +
                geo_hash = @@geo_city.look_up(ip)
         
     | 
| 
      
 45 
     | 
    
         
            +
                return unless geo_hash
         
     | 
| 
      
 46 
     | 
    
         
            +
                ret = {}
         
     | 
| 
      
 47 
     | 
    
         
            +
                geo_hash.each_pair do |k,v|
         
     | 
| 
      
 48 
     | 
    
         
            +
                  next unless k
         
     | 
| 
      
 49 
     | 
    
         
            +
                  ret[k.to_s] = v.to_s
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
                
         
     | 
| 
      
 52 
     | 
    
         
            +
                ret
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
            end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            #
         
     | 
| 
      
 57 
     | 
    
         
            +
            # Add GeoIP tags using the MaxMind GeoIP::Organization database
         
     | 
| 
      
 58 
     | 
    
         
            +
            #
         
     | 
| 
      
 59 
     | 
    
         
            +
            class FilterGeoIPOrg
         
     | 
| 
      
 60 
     | 
    
         
            +
              include BaseDecoder
         
     | 
| 
      
 61 
     | 
    
         
            +
              include GeoIPLibrary
         
     | 
| 
      
 62 
     | 
    
         
            +
              def decode(ip)
         
     | 
| 
      
 63 
     | 
    
         
            +
                return unless @@geo_orgs
         
     | 
| 
      
 64 
     | 
    
         
            +
                geo_hash = @@geo_orgs.look_up(ip)
         
     | 
| 
      
 65 
     | 
    
         
            +
                return unless (geo_hash and geo_hash[:name])
         
     | 
| 
      
 66 
     | 
    
         
            +
                { :org => geo_hash[:name] }
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
            end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            end
         
     | 
| 
      
 72 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,173 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Dap
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Filter
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'htmlentities'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'nokogiri'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'uri'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            class FilterHTMLIframes
         
     | 
| 
      
 9 
     | 
    
         
            +
              include Base
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def process(doc)
         
     | 
| 
      
 12 
     | 
    
         
            +
                out = []
         
     | 
| 
      
 13 
     | 
    
         
            +
                self.opts.each_pair do |k,v|
         
     | 
| 
      
 14 
     | 
    
         
            +
                  next unless doc.has_key?(k)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  extract(doc[k]).each do |url|
         
     | 
| 
      
 16 
     | 
    
         
            +
                    out << doc.merge({ 'iframe' => url })
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
               out
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def extract(data)
         
     | 
| 
      
 23 
     | 
    
         
            +
                @coder ||= HTMLEntities.new
         
     | 
| 
      
 24 
     | 
    
         
            +
                urls = []
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                data = data.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')
         
     | 
| 
      
 27 
     | 
    
         
            +
                html = nil
         
     | 
| 
      
 28 
     | 
    
         
            +
                begin
         
     | 
| 
      
 29 
     | 
    
         
            +
                  html = Nokogiri::HTML(data) do |conf|
         
     | 
| 
      
 30 
     | 
    
         
            +
                    conf.strict.noent
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                rescue ::Exception
         
     | 
| 
      
 33 
     | 
    
         
            +
                  return urls
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                html.xpath('//iframe').each do |e|
         
     | 
| 
      
 37 
     | 
    
         
            +
                  url = e['src']
         
     | 
| 
      
 38 
     | 
    
         
            +
                  next unless url
         
     | 
| 
      
 39 
     | 
    
         
            +
                  urls << url
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                urls
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            class FilterHTMLLinks
         
     | 
| 
      
 48 
     | 
    
         
            +
              include Base
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              def process(doc)
         
     | 
| 
      
 51 
     | 
    
         
            +
                out = []
         
     | 
| 
      
 52 
     | 
    
         
            +
                self.opts.each_pair do |k,v|
         
     | 
| 
      
 53 
     | 
    
         
            +
                  next unless doc.has_key?(k)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  extract(doc[k]).each do |link_info|
         
     | 
| 
      
 55 
     | 
    
         
            +
                    out << doc.merge(link_info)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
               out
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              def extract(data)
         
     | 
| 
      
 62 
     | 
    
         
            +
                urls = []
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                data = data.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')
         
     | 
| 
      
 65 
     | 
    
         
            +
                html = nil
         
     | 
| 
      
 66 
     | 
    
         
            +
                begin
         
     | 
| 
      
 67 
     | 
    
         
            +
                  html = Nokogiri::HTML(data) do |conf|
         
     | 
| 
      
 68 
     | 
    
         
            +
                    conf.strict.noent
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
                rescue ::Exception
         
     | 
| 
      
 71 
     | 
    
         
            +
                 return urls
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                html.xpath('//*').each do |e|
         
     | 
| 
      
 75 
     | 
    
         
            +
                  url = e['href'] || e['src']
         
     | 
| 
      
 76 
     | 
    
         
            +
                  next unless url
         
     | 
| 
      
 77 
     | 
    
         
            +
                  urls << { 'link' => url, 'element' => e.name }
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                urls
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
            end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            class FilterDecodeURI
         
     | 
| 
      
 85 
     | 
    
         
            +
              include BaseDecoder
         
     | 
| 
      
 86 
     | 
    
         
            +
              def decode(data)
         
     | 
| 
      
 87 
     | 
    
         
            +
                save = {}
         
     | 
| 
      
 88 
     | 
    
         
            +
                uri  = URI.parse(data) rescue nil
         
     | 
| 
      
 89 
     | 
    
         
            +
                return unless uri
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                save["host"] = uri.host if uri.host
         
     | 
| 
      
 92 
     | 
    
         
            +
                save["port"] = uri.port.to_s if uri.port
         
     | 
| 
      
 93 
     | 
    
         
            +
                save["path"] = uri.path if uri.path
         
     | 
| 
      
 94 
     | 
    
         
            +
                save["query"]  = uri.query if uri.query
         
     | 
| 
      
 95 
     | 
    
         
            +
                save["scheme"] = uri.scheme if uri.scheme
         
     | 
| 
      
 96 
     | 
    
         
            +
                save["user"] = uri.user if uri.user
         
     | 
| 
      
 97 
     | 
    
         
            +
                save["password"] = uri.password if uri.password
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                save
         
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
            end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            class FilterDecodeHTTPReply
         
     | 
| 
      
 105 
     | 
    
         
            +
              include BaseDecoder
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
              # TODO: Decode transfer-chunked responses
         
     | 
| 
      
 108 
     | 
    
         
            +
              def decode(data)
         
     | 
| 
      
 109 
     | 
    
         
            +
                lines = data.split(/\r?\n/)
         
     | 
| 
      
 110 
     | 
    
         
            +
                resp  = lines.shift
         
     | 
| 
      
 111 
     | 
    
         
            +
                save  = {}
         
     | 
| 
      
 112 
     | 
    
         
            +
                return save if resp !~ /^HTTP\/\d+\.\d+\s+(\d+)\s+(.*)/
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                save["http_code"] = $1.to_i
         
     | 
| 
      
 115 
     | 
    
         
            +
                save["http_message"] = $2.strip
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                clen = nil
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                while lines.length > 0
         
     | 
| 
      
 120 
     | 
    
         
            +
                  hline = lines.shift
         
     | 
| 
      
 121 
     | 
    
         
            +
                  case hline
         
     | 
| 
      
 122 
     | 
    
         
            +
                  when /^ETag:\s*(.*)/i
         
     | 
| 
      
 123 
     | 
    
         
            +
                    save["http_etag"] = $1
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  when /^Set-Cookie:\s*(.*)/i
         
     | 
| 
      
 126 
     | 
    
         
            +
                    bits = $1.gsub(/\;?\s*path=.*/i, '').gsub(/\;?\s*expires=.*/i, '').gsub(/\;\s*HttpOnly.*/, '')
         
     | 
| 
      
 127 
     | 
    
         
            +
                    save["http_cookie"] = bits.strip
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                  when /^Server:\s*(.*)/i
         
     | 
| 
      
 130 
     | 
    
         
            +
                    save["http_server"] = $1.strip
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                  when /^X-Powered-By:\s*(.*)/i
         
     | 
| 
      
 133 
     | 
    
         
            +
                    save["http_powered"] = $1.strip
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                  when /^Date:\s*(.*)/i
         
     | 
| 
      
 136 
     | 
    
         
            +
                    d = DateTime.parse($1.strip) rescue nil
         
     | 
| 
      
 137 
     | 
    
         
            +
                    save["http_date"] = d.to_time.strftime("%Y%m%dT%H:%M:%S") if d
         
     | 
| 
      
 138 
     | 
    
         
            +
                      
         
     | 
| 
      
 139 
     | 
    
         
            +
                  when /^Last-modified:\s*(.*)/i
         
     | 
| 
      
 140 
     | 
    
         
            +
                    d = DateTime.parse($1.strip) rescue nil
         
     | 
| 
      
 141 
     | 
    
         
            +
                    save["http_modified"] = d.to_time.strftime("%Y%m%dT%H:%M:%S") if d
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                  when /^Location:\s*(.*)/i
         
     | 
| 
      
 144 
     | 
    
         
            +
                    save["http_location"] = $1.strip  
         
     | 
| 
      
 145 
     | 
    
         
            +
                  
         
     | 
| 
      
 146 
     | 
    
         
            +
                  when /^WWW-Authenticate:\s*(.*)/i
         
     | 
| 
      
 147 
     | 
    
         
            +
                    save["http_auth"] = $1.strip
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                  when /^Content-Length:\s*(.*)/i
         
     | 
| 
      
 150 
     | 
    
         
            +
                    clen = $1.strip.to_i
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                  when ""
         
     | 
| 
      
 153 
     | 
    
         
            +
                    break
         
     | 
| 
      
 154 
     | 
    
         
            +
                  end
         
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                head, body = data.split(/\r?\n\r?\n/, 2)
         
     | 
| 
      
 158 
     | 
    
         
            +
                
         
     | 
| 
      
 159 
     | 
    
         
            +
                # Some buggy systems exclude the header entirely
         
     | 
| 
      
 160 
     | 
    
         
            +
                body ||= head
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                save["http_body"] = body
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                if body =~ /<title>([^>]+)</min
         
     | 
| 
      
 165 
     | 
    
         
            +
                  save["http_title"] = $1.strip
         
     | 
| 
      
 166 
     | 
    
         
            +
                end
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
                save
         
     | 
| 
      
 169 
     | 
    
         
            +
              end
         
     | 
| 
      
 170 
     | 
    
         
            +
            end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
            end
         
     | 
| 
      
 173 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,151 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Dap
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Filter
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            MATCH_FQDN = /^([a-z0-9\_\-]+\.)+[a-z0-9\-]+\.?$/
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class FilterExtractHostname
         
     | 
| 
      
 8 
     | 
    
         
            +
              include BaseDecoder
         
     | 
| 
      
 9 
     | 
    
         
            +
              def decode(data)
         
     | 
| 
      
 10 
     | 
    
         
            +
                data = data.strip.gsub(/.*\@/, '').gsub(/^\*+/, '').gsub(/^\.+/, '').gsub(/\.+$/, '').downcase
         
     | 
| 
      
 11 
     | 
    
         
            +
                return unless data =~ MATCH_FQDN
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                # https://data.iana.org/TLD/tlds-alpha-by-domain.txt
         
     | 
| 
      
 14 
     | 
    
         
            +
                return unless %w{ 
         
     | 
| 
      
 15 
     | 
    
         
            +
                  AC AD AE AERO AF AG AI AL AM AN AO AQ AR ARPA AS ASIA AT AU AW AX AZ BA BB BD BE BF BG BH BI BIKE BIZ
         
     | 
| 
      
 16 
     | 
    
         
            +
                  BJ BM BN BO BR BS BT BV BW BY BZ CA CAMERA CAT CC CD CF CG CH CI CK CL CLOTHING CM CN CO COM CONSTRUCTION
         
     | 
| 
      
 17 
     | 
    
         
            +
                  CONTRACTORS COOP CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EDU EE EG EQUIPMENT ER ES ESTATE ET EU FI FJ FK
         
     | 
| 
      
 18 
     | 
    
         
            +
                  FM FO FR GA GALLERY GB GD GE GF GG GH GI GL GM GN GOV GP GQ GR GRAPHICS GS GT GU GURU GW GY HK HM HN 
         
     | 
| 
      
 19 
     | 
    
         
            +
                  HOLDINGS HR HT HU ID IE IL IM IN INFO INT IO IQ IR IS IT JE JM JO JOBS JP KE KG KH KI KM KN KP KR KW KY KZ
         
     | 
| 
      
 20 
     | 
    
         
            +
                  LA LAND LB LC LI LIGHTING LK LR LS LT LU LV LY MA MC MD ME MG MH MIL MK ML MM MN MO MOBI MP MQ MR MS MT MU
         
     | 
| 
      
 21 
     | 
    
         
            +
                  MUSEUM MV MW MX MY MZ NA NAME NC NE NET NF NG NI NL NO NP NR NU NZ OM ORG PA PE PF PG PH PK PL PLUMBING PM
         
     | 
| 
      
 22 
     | 
    
         
            +
                  PN POST PR PRO PS PT PW PY QA RE RO RS RU RW SA SB SC SD SE SEXY SG SH SI SINGLES SJ SK SL SM SN SO SR ST
         
     | 
| 
      
 23 
     | 
    
         
            +
                  SU SV SX SY SZ TATTOO TC TD TECHNOLOGY TEL TF TG TH TJ TK TL TM TN TO TP TR TRAVEL TT TV TW TZ UA UG UK US
         
     | 
| 
      
 24 
     | 
    
         
            +
                  UY UZ VA VC VE VENTURES VG VI VN VOYAGE VU WF WS XN--3E0B707E XN--45BRJ9C XN--80AO21A XN--80ASEHDB 
         
     | 
| 
      
 25 
     | 
    
         
            +
                  XN--80ASWG XN--90A3AC XN--CLCHC0EA0B2G2A9GCD XN--FIQS8S XN--FIQZ9S XN--FPCRJ9C3D XN--FZC2C9E2C XN--GECRJ9C
         
     | 
| 
      
 26 
     | 
    
         
            +
                  XN--H2BRJ9C XN--J1AMH XN--J6W193G XN--KPRW13D XN--KPRY57D XN--L1ACC XN--LGBBAT1AD8J XN--MGB9AWBF 
         
     | 
| 
      
 27 
     | 
    
         
            +
                  XN--MGBA3A4F16A XN--MGBAAM7A8H XN--MGBAYH7GPA XN--MGBBH1A71E XN--MGBC0A9AZCG XN--MGBERP4A5D4AR 
         
     | 
| 
      
 28 
     | 
    
         
            +
                  XN--MGBX4CD0AB XN--NGBC5AZD XN--O3CW4H XN--OGBPF8FL XN--P1AI XN--PGBS0DH XN--S9BRJ9C XN--UNUP4Y 
         
     | 
| 
      
 29 
     | 
    
         
            +
                  XN--WGBH1C XN--WGBL6A XN--XKC2AL3HYE2A XN--XKC2DL3A5EE0H XN--YFRO4I67O XN--YGBI2AMMX XXX YE YT ZA ZM ZW
         
     | 
| 
      
 30 
     | 
    
         
            +
                  }.include?(data.split('.').last.upcase)
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                { 'hostname' => data }
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            class FilterSplitDomains
         
     | 
| 
      
 37 
     | 
    
         
            +
              include Base
         
     | 
| 
      
 38 
     | 
    
         
            +
              def process(doc)
         
     | 
| 
      
 39 
     | 
    
         
            +
                lines = [ ]
         
     | 
| 
      
 40 
     | 
    
         
            +
                self.opts.each_pair do |k,v|
         
     | 
| 
      
 41 
     | 
    
         
            +
                  if doc.has_key?(k)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    expand(doc[k]).each do |line|
         
     | 
| 
      
 43 
     | 
    
         
            +
                      lines << doc.merge({ "#{k}.domain" => line })
         
     | 
| 
      
 44 
     | 
    
         
            +
                    end
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
               lines.length == 0 ? [ doc ] : [ lines ]
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              def expand(data)
         
     | 
| 
      
 51 
     | 
    
         
            +
                names = []
         
     | 
| 
      
 52 
     | 
    
         
            +
                bits  = data.split('.')
         
     | 
| 
      
 53 
     | 
    
         
            +
                while (bits.length > 1)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  names << bits.join('.')
         
     | 
| 
      
 55 
     | 
    
         
            +
                  bits.shift
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
                names
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            class FilterPrependSubdomains
         
     | 
| 
      
 63 
     | 
    
         
            +
              include Base
         
     | 
| 
      
 64 
     | 
    
         
            +
              def process(doc)
         
     | 
| 
      
 65 
     | 
    
         
            +
                lines = [ ]
         
     | 
| 
      
 66 
     | 
    
         
            +
                self.opts.each_pair do |k,v|
         
     | 
| 
      
 67 
     | 
    
         
            +
                  if doc.has_key?(k)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    expand(doc[k], v).each do |line|
         
     | 
| 
      
 69 
     | 
    
         
            +
                      lines << doc.merge({ k => line })
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
               lines.length == 0 ? [ ] : [ lines ]
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              def expand(data, names)
         
     | 
| 
      
 77 
     | 
    
         
            +
                outp = [ data ]
         
     | 
| 
      
 78 
     | 
    
         
            +
                bits = data.split(".")
         
     | 
| 
      
 79 
     | 
    
         
            +
                subs = names.split(",")
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                # Avoid www.www.domain.tld and mail.www.domain.tld
         
     | 
| 
      
 82 
     | 
    
         
            +
                return outp if subs.include?(bits.first)
         
     | 
| 
      
 83 
     | 
    
         
            +
                subs.each do |sub|
         
     | 
| 
      
 84 
     | 
    
         
            +
                  outp << "#{sub}.#{data}"
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
                
         
     | 
| 
      
 87 
     | 
    
         
            +
                outp
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
              
         
     | 
| 
      
 90 
     | 
    
         
            +
            end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            #
         
     | 
| 
      
 93 
     | 
    
         
            +
            # Acts like SplitDomains but strips out common dynamic IP RDNS formats
         
     | 
| 
      
 94 
     | 
    
         
            +
            #
         
     | 
| 
      
 95 
     | 
    
         
            +
            # XXX - Lots of work left to do
         
     | 
| 
      
 96 
     | 
    
         
            +
            #
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            class FilterSplitNonDynamicDomains
         
     | 
| 
      
 99 
     | 
    
         
            +
              include Base
         
     | 
| 
      
 100 
     | 
    
         
            +
              def process(doc)
         
     | 
| 
      
 101 
     | 
    
         
            +
                lines = [ ]
         
     | 
| 
      
 102 
     | 
    
         
            +
                self.opts.each_pair do |k,v|
         
     | 
| 
      
 103 
     | 
    
         
            +
                  if doc.has_key?(k)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    expand(doc[k]).each do |line|
         
     | 
| 
      
 105 
     | 
    
         
            +
                      lines << doc.merge({ "#{k}.domain" => line })
         
     | 
| 
      
 106 
     | 
    
         
            +
                    end
         
     | 
| 
      
 107 
     | 
    
         
            +
                  end
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
               lines.length == 0 ? [ doc ] : [ lines ]
         
     | 
| 
      
 110 
     | 
    
         
            +
              end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
              def expand(data)
         
     | 
| 
      
 113 
     | 
    
         
            +
                names = []
         
     | 
| 
      
 114 
     | 
    
         
            +
                data  = data.unpack("C*").pack("C*").
         
     | 
| 
      
 115 
     | 
    
         
            +
                  gsub(/.*ip\d+\.ip\d+\.ip\d+\.ip\d+\./, '').
         
     | 
| 
      
 116 
     | 
    
         
            +
                  gsub(/.*\d+[\_\-\.x]\d+[\_\-\.x]\d+[\_\-\.x]\d+[^\.]+/, '').
         
     | 
| 
      
 117 
     | 
    
         
            +
                  gsub(/.*node-[a-z0-9]+.*pool.*dynamic\./, '').
         
     | 
| 
      
 118 
     | 
    
         
            +
                  gsub(/.*[a-z][a-z]\d+\.[a-z]as[a-z0-9]+\./, '').
         
     | 
| 
      
 119 
     | 
    
         
            +
                  # cl223.001033200.technowave.ne.jp
         
     | 
| 
      
 120 
     | 
    
         
            +
                  gsub(/^cl\d+.[0-9]{6,14}\./, '').
         
     | 
| 
      
 121 
     | 
    
         
            +
                  # n157.s1117.m-zone.jp
         
     | 
| 
      
 122 
     | 
    
         
            +
                  gsub(/^n\d+.s\d+\.m-zone.jp/, 'm-zone.jp').
         
     | 
| 
      
 123 
     | 
    
         
            +
                  # u570054.xgsnu2.imtp.tachikawa.mopera.net
         
     | 
| 
      
 124 
     | 
    
         
            +
                  # s505207.xgsspn.imtp.tachikawa.spmode.ne.jp
         
     | 
| 
      
 125 
     | 
    
         
            +
                  gsub(/^[us]\d+.xgs[a-z0-9]+\.imtp/, 'imtp').
         
     | 
| 
      
 126 
     | 
    
         
            +
                  # tzbm6501209.tobizaru.jp
         
     | 
| 
      
 127 
     | 
    
         
            +
                  gsub(/^tzbm[0-9]{6,9}\./, '').
         
     | 
| 
      
 128 
     | 
    
         
            +
                  # ARennes-556-1-256-bdcst.w2-14.abo.wanadoo.fr
         
     | 
| 
      
 129 
     | 
    
         
            +
                  gsub(/.*\-\d+\-\d+\-\d+\-(net|bdcst)\./, '').
         
     | 
| 
      
 130 
     | 
    
         
            +
                  # bl19-128-119.dsl.telepac.pt
         
     | 
| 
      
 131 
     | 
    
         
            +
                  gsub(/.*\d+\-\d+\-\d+\.dsl/, 'dsl').
         
     | 
| 
      
 132 
     | 
    
         
            +
                  gsub(/.*pool\./, '').
         
     | 
| 
      
 133 
     | 
    
         
            +
                  gsub(/.*dynamic\./, '').
         
     | 
| 
      
 134 
     | 
    
         
            +
                  gsub(/.*static\./, '').
         
     | 
| 
      
 135 
     | 
    
         
            +
                  gsub(/.*dhcp[^\.]+\./, '').
         
     | 
| 
      
 136 
     | 
    
         
            +
                  gsub(/^\d{6,100}\./, '').
         
     | 
| 
      
 137 
     | 
    
         
            +
                  gsub(/^\.+/, '').
         
     | 
| 
      
 138 
     | 
    
         
            +
                  tr('^a-z0-9.-', '')
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                bits  = data.split('.')
         
     | 
| 
      
 141 
     | 
    
         
            +
                while (bits.length > 1)
         
     | 
| 
      
 142 
     | 
    
         
            +
                  names << bits.join('.')
         
     | 
| 
      
 143 
     | 
    
         
            +
                  bits.shift
         
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
                names
         
     | 
| 
      
 146 
     | 
    
         
            +
              end
         
     | 
| 
      
 147 
     | 
    
         
            +
            end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
            end
         
     | 
| 
      
 151 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Dap
         
     | 
| 
      
 2 
     | 
    
         
            +
            module Filter
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'openssl'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class FilterDecodeX509
         
     | 
| 
      
 7 
     | 
    
         
            +
              include BaseDecoder
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def decode(data)
         
     | 
| 
      
 10 
     | 
    
         
            +
                save = {}
         
     | 
| 
      
 11 
     | 
    
         
            +
                cert = OpenSSL::X509::Certificate.new(data) rescue nil
         
     | 
| 
      
 12 
     | 
    
         
            +
                return unless cert 
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                dnames = []
         
     | 
| 
      
 15 
     | 
    
         
            +
                cert.subject.to_s.split("/").each do |bit|
         
     | 
| 
      
 16 
     | 
    
         
            +
                  var,val = bit.split("=", 2)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  next unless (var and val)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  var = var.to_s.downcase.strip
         
     | 
| 
      
 19 
     | 
    
         
            +
                  save["s_#{var}"] = val 
         
     | 
| 
      
 20 
     | 
    
         
            +
                  if var == "cn"
         
     | 
| 
      
 21 
     | 
    
         
            +
                    dnames << val
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                cert.issuer.to_s.split("/").each do |bit|
         
     | 
| 
      
 26 
     | 
    
         
            +
                  var,val = bit.split("=", 2)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  next unless (var and val)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  var = var.to_s.downcase.strip
         
     | 
| 
      
 29 
     | 
    
         
            +
                  save["i_#{var}"] = val 
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                cert.extensions.each do |e|
         
     | 
| 
      
 33 
     | 
    
         
            +
                  next unless e.to_s =~ /^([^\s]+)\s*=\s*(.*)/
         
     | 
| 
      
 34 
     | 
    
         
            +
                  var,val = $1,$2
         
     | 
| 
      
 35 
     | 
    
         
            +
                  var = var.to_s.downcase.strip
         
     | 
| 
      
 36 
     | 
    
         
            +
                  save["e_#{var}"] = val.strip
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  if var == "subjectaltname"
         
     | 
| 
      
 39 
     | 
    
         
            +
                    val.split(",").map{|x| x.gsub("DNS:", "").gsub("IP:", "").gsub("email:", "").strip }.each do |name|
         
     | 
| 
      
 40 
     | 
    
         
            +
                      dnames << name
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                save["names"] = dnames
         
     | 
| 
      
 47 
     | 
    
         
            +
                save
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     |