Skip to content

Writing WhatWeb Plugins

yehgdotnet edited this page Oct 13, 2010 · 23 revisions

To get started modify plugin-template.rb.txt in the my-plugins folder. Rename it to your desired one like my-first-plugin.rb which will be run by WhatWeb without your needing to put it into ./plugins/ folder.

Also read the tutorial on writing WhatWeb plugins at How to develop WhatWeb plugins.

Typical Plugin (Example)

A typical plugin looks like this:

	Plugin.define "Plone" do
	author "Andrew Horton"
	version "0.2"
	description "CMS http://plone.org"
	examples %w| www.norden.org www.trolltech.com www.plone.net www.smeal.psu.edu|

	matches [
	{:name=>"meta generator tag",
	:regexp=>/<meta name="generator" content="[^>]*http:\/\/plone.org" \/>/},

	{:name=>"plone css",
	:regexp=>/(@import url|text\/css)[^>]*portal_css\/.*plone.*css(\)|")/}, #"

	{:name=>"plone javascript",
	:regexp=>/src="[^"]*ploneScripts[0-9]+.js"/}, #"

	{:text=>'<div class="visualIcon contenttype-plone-site">'},

	{:name=>"div tag, visual-portal-wrapper",
	:certainty=>75,
	:text=>'<div id="visual-portal-wrapper">'},
	]

	def passive
		m=[]
		#X-Caching-Rule-Id: plone-content-types
		#X-Cache-Rule: plone-content-types
		m << {:name=>"X-Caching-Rule-Id: plone-content-types" } if @meta["x-caching-rule-id"] =~ /plone-content-types/i
		m << {:name=>"X-Cache-Rule: plone-content-types" } if @meta["x-cache-rule"] =~ /plone-content-types/i
		m
	end


	end

Matches

There are 3 levels to a plugin. Simple matches, passive and aggressive tests. You don’t need to know ruby to write plugins with simple matches. Passive and aggressive tests are written in ruby.

The matches [] array contains a set of ways to match a website to a system.

The methods are:

* :text			Matches text within the webpage
* :regexp		A regular expression. Append /i for case insensitive matches
* :ghdb			Like a google query
* :md5			MD5 hash of the HTML page
* :tagpattern		Pattern of HTML tags
* :name			This is the name of the match, and is optional.
* :url			The URL has to match this. Used for passive and agressive testing
* :certainty		Optional, defaults to 100. Values are maybe (25), probably (75) and certain (100).
* :version		As a string or number this is a version returned when other methods match
* :version		As a regular expression, this extracts the version information from the HTML. Also requires :version_regexp_offset=>1

If you port a GHDB match, use :ghdb. I usually rewrite the GHDB matches with regular expressions, especially if they require inurl:

Example:

# http://johnny.ihackstuff.com/ghdb?function=detail&id=1840

{ :ghdb=>'"Powered by Vsns Lemon" intitle:"Vsns Lemon"' }

Note the GHDB queries are case insensitive, as a Google query is.

Supported GHDB codes are:

* intitle:
* inurl:
* filetype:

Each plugin can access @body, @meta, @status, @base_uri, @md5 and @tagpattern variables.

Passive tests add matches to the m array, each match is a hash containing the name of the match, probability and more. The entire hash is returned with Full output, Brief output returns just the match, :version and :string

To discover the regular expressions to match against, wget about 20-30 examples into the tests/ folder. Be aware that some software can have dramatic variations between versions.

==How to generate a signature with ease==

//TODO

Clone this wiki locally