1#!/usr/bin/env ruby
2# Page Pattern Generator
3#  Aung Khant, http://yehg.net
4
5# Feed a url
6# Get its tag pattern that's ready to use in your plugin
7
8# Codes taken from Andrew Horton
9
10require 'net/http'
11require 'net/https'
12require 'open-uri'
13
14if RUBY_VERSION =~ /^1\.9/ || RUBY_VERSION =~ /^2\./
15  require 'digest/md5'
16else
17  require 'md5'
18end
19
20
21$VERBOSE = false
22
23def main
24  if ARGV.length < 1
25    usage
26    exit 1
27  end
28  banner
29  req = fetch_url(ARGV[0].to_s)
30  return if req.nil?
31  res = generate_pattern(req.body)
32  if res.empty?
33    puts "[-] Error: No matches"
34  else
35    puts "[+] Matches:"
36    puts res.flatten.join(",\n")
37  end
38end
39
40# from tag_pattern.rb
41def pg_tag_pattern(b)
42  return if b.nil?
43  # remove stuff between script and /script
44  # don't bother with  !--, --> or noscript and /noscript
45  inscript=false
46
47  tag_pattern = b.scan(/<([^\s>]*)/).flatten.map {|x| x.downcase!; r=nil;
48    r=x unless inscript
49    if x == 'script'
50      inscript=true
51    elsif x == '/script'
52      inscript=false
53      r=x
54    end
55    r
56  }.compact.join(",")
57end
58
59def banner
60  puts "
61== Page Pattern Generator 0.1 for WhatWeb ==
62        by Aung Khant, http://yehg.net
63
64"
65end
66
67def usage
68  puts "Usage: ./get-pattern http://www.example.com/\n"
69end
70
71def fetch_url(url)
72  puts "[*] URL: #{url}"
73  url = 'http://' + url if url !~ /^https?:\/\//
74  uri = URI.parse(url)
75  uri.path += '/' if uri.path.size == 0
76
77  http = Net::HTTP.new(uri.host,uri.port)
78  http.open_timeout = 180
79  http.read_timeout = 180
80  if uri.scheme == 'https'
81    http.use_ssl = true
82    http.verify_mode = OpenSSL::SSL::VERIFY_NONE # insecure
83  end
84
85  begin
86    req = http.get(uri.path)
87  rescue
88    puts "[-] Error: Could not connect to URL - #{uri}"
89  end
90  req
91end
92
93def generate_pattern(body)
94  res = []
95  title = body.scan(/(<title>[^<]+<\/title>)/i).flatten.first
96  if title.nil?
97    puts "[-] Error: Could not title match - no title in response body" if $VERBOSE
98  else
99    res << {:name => 'HTML Page Title', :text => title.to_s}
100  end
101  pattern = pg_tag_pattern(body)
102  if pattern.length > 0
103    res << {:name => 'HTML Tag Pattern', :tagpattern => pattern.to_s}
104  else
105    puts "[-] Error: Could not generate tag pattern - no tags in response body" if $VERBOSE
106  end
107  md5 = Digest::MD5.hexdigest(body)
108  if md5 == 'd41d8cd98f00b204e9800998ecf8427e'
109    puts "[-] Error: MD5 hash is hash of a blank page" if $VERBOSE
110  else
111    res << {:name => 'MD5 hash', :md5 => md5}
112  end
113  res
114end
115
116main
117