#!/usr/bin/env ruby # # Copyright (c) 2007, Gregory Fleischer (gfleischer@gmail.com) # License: Revised BSD # # confoonu.rb - # take two web pages and create two new web pages that have the same MD5 sum # optionally, you can specify an additional web page that is used as the default when no javascript is used # based on confoo.pl by Dan Kaminsky (www.doxpara.com/research/md5/confoo.pl) # require 'uri' require 'net/http' #### def readPage(page) if page =~ /^http:\/\//i readWeb(page) else readLocal(page) end end def readWeb(page) uri = URI.parse(page) res = Net::HTTP.start(uri.host, uri.port) { |http| http.get(uri.path) } body = res.body base_href = "" if body =~ /(]*>)/i base_href = $1 end body.sub!(/^.*/mi, "") body.sub!(/<\/html[^<]*>.*$/mi, "") if body !~ //i body.sub!(//i) { |m| "#{m}#{base_href}" } elsif body =~ /#{base_href}#{m}" } else body = "#{base_href}" + body end end body end def readLocal(page) data = [] File.foreach(page) { |line| data << line} data.join end def makeFile(file, num, page1, page2, defaultpage) prefix = [ 0x3C,0x68,0x74,0x6D,0x6C,0x3E,0x20,0x20,0x0A,0x20,0x3C,0x73,0x63,0x72,0x69,0x70, 0x74,0x3E,0x20,0x0A,0x20,0x3C,0x21,0x2D,0x2D,0x20,0x2F,0x2F,0x20,0x68,0x69,0x64, 0x65,0x20,0x6A,0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70,0x74,0x0A,0x20,0x20,0x20, 0x76,0x61,0x72,0x20,0x5F,0x5F,0x76,0x65,0x63,0x74,0x6F,0x72,0x20,0x3D,0x20,0x22, ] vectors = [ # 1 [ 0xCF,0xB2,0xB8,0x8C,0x08,0xCE,0x55,0xD4,0x58,0x6A,0x9C,0x23,0x27,0xFF,0x7E,0xDC, 0x4E,0xC2,0xC5,0xB3,0xF4,0x86,0x27,0xFF,0x52,0xAF,0x3A,0x17,0x40,0xA7,0x62,0xD5, 0x55,0x2D,0x34,0x06,0x05,0x64,0x34,0x04,0x57,0xE7,0xB0,0x79,0xE7,0xE4,0x29,0x94, 0xDE,0x16,0x5F,0xC7,0xDA,0xD1,0xDA,0xFD,0xE8,0xB7,0x63,0xF8,0x56,0xF9,0x49,0xFD, 0x41,0xF9,0x74,0xBE,0xE0,0x65,0xDB,0x33,0xA5,0x14,0x88,0x2B,0xE1,0x9E,0x60,0xDB, 0xCA,0xF7,0xE2,0x16,0x8C,0x47,0x48,0x1E,0xF2,0xE8,0xE6,0xF7,0x4A,0xDB,0xDD,0xCE, 0xFD,0x6E,0x37,0x2F,0xCA,0xB6,0x23,0x07,0xFA,0xE9,0x49,0x4A,0x93,0x28,0xA5,0x5C, 0x0E,0x85,0x7B,0xA3,0xD2,0xA4,0x9B,0x8B,0x78,0xF8,0x88,0x1C,0x2F,0x59,0xD5,0x78, ], # 2 [ 0xCF,0xB2,0xB8,0x8C,0x08,0xCE,0x55,0xD4,0x58,0x6A,0x9C,0x23,0x27,0xFF,0x7E,0xDC, 0x4E,0xC2,0xC5,0x33,0xF4,0x86,0x27,0xFF,0x52,0xAF,0x3A,0x17,0x40,0xA7,0x62,0xD5, 0x55,0x2D,0x34,0x06,0x05,0x64,0x34,0x04,0x57,0xE7,0xB0,0x79,0xE7,0x64,0x2A,0x94, 0xDE,0x16,0x5F,0xC7,0xDA,0xD1,0xDA,0xFD,0xE8,0xB7,0x63,0x78,0x56,0xF9,0x49,0xFD, 0x41,0xF9,0x74,0xBE,0xE0,0x65,0xDB,0x33,0xA5,0x14,0x88,0x2B,0xE1,0x9E,0x60,0xDB, 0xCA,0xF7,0xE2,0x96,0x8C,0x47,0x48,0x1E,0xF2,0xE8,0xE6,0xF7,0x4A,0xDB,0xDD,0xCE, 0xFD,0x6E,0x37,0x2F,0xCA,0xB6,0x23,0x07,0xFA,0xE9,0x49,0x4A,0x93,0xA8,0xA4,0x5C, 0x0E,0x85,0x7B,0xA3,0xD2,0xA4,0x9B,0x8B,0x78,0xF8,0x88,0x9C,0x2F,0x59,0xD5,0x78, ] ] vector = vectors[num-1] prefix.each {|b| file.putc b} vector.each {|b| file.putc b} file << "\";\n" # add the script to build the page file << " var __v1 = \"" vectors[0].each {|b| file.putc b} file << "\";\n" file << " var __v2 = \"" vectors[1].each {|b| file.putc b} file << "\";\n" file << " var __t1 = \"" file << page1.gsub(/[^a-zA-Z0-9]/) {|c| "%%%02X" % c[0]} file << "\";\n" file << " var __t2 = \"" file << page2.gsub(/[^a-zA-Z0-9]/) {|c| "%%%02X" % c[0]} file << "\";\n" file << " var __df = \"" if defaultpage file << defaultpage.gsub(/[^a-zA-Z0-9]/) {|c| "%%%02X" % c[0]} end file << "\";\n" # add the logic to build the page on the fly file << %[ var index = 0; if (__vector == __v1) { index = 1; } else if (__vector == __v2) { index = 2; } if (0 != index) { try { var body = document.body; if (body) { body.innerHTML = ""; var g = 0; while (body.attributes.length > 0 && (++g < 256)) { body.attributes.removeNamedItem(body.attributes[0].nodeName); } } var head = document.getElementsByTagName("HEAD")[0]; if (head) { try { head.innerHTML = ""; } catch(e) { } } } catch (e) {} } if (1 == index) { document.write(unescape(__t1)); } else if (2 == index) { document.write(unescape(__t2)); } else { document.write(unescape(__df)); } ] file << "\n//-->\n" file << "\n" file << "\n" file << "\n\n" end #### if ARGV.length < 2 puts "usage: confoonu.rb [defaultpage]" exit 1 end page1 = readPage(ARGV[0]) page2 = readPage(ARGV[1]) defaultpage = nil if ARGV.length > 2 defaultpage = readPage(ARGV[2]) end File.open("t1.html", 'w') { |file| makeFile(file, 1, page1, page2, defaultpage) } File.open("t2.html", 'w') { |file| makeFile(file, 2, page1, page2, defaultpage) } exit 0 # eof