diff --git a/nselib/data/folders.lst b/nselib/data/folders.lst
deleted file mode 100644
index 5afbc429a..000000000
--- a/nselib/data/folders.lst
+++ /dev/null
@@ -1,856 +0,0 @@
-
-1
-10
-2
-3
-4
-5
-6
-7
-8
-9
-Admin_files
-AdvWebAdmin
-Agent
-Agents
-Album
-CS
-CVS
-DMR
-DocuColor
-GXApp
-HB
-HBTemplates
-I
-IBMWebAS
-JBookIt
-Msword
-NSearch
-NetDynamic
-NetDynamics
-News
-PDG_Cart
-ROADS
-Readme
-ScriptLibrary
-SilverStream
-StoreDB
-ToDo
-WS_FTP
-WebBank
-WebCalendar
-WebShop
-WebTrend
-Web_store
-XSL
-_pages
-a
-acceso
-access
-accesswatch
-acciones
-account
-accounting
-active
-activex
-adm
-admcgi
-admentor
-admin
-admin-bak
-admin-old
-admin.back
-adminWeb
-admin_
-administration
-administrator
-adminuser
-adminweb
-admisapi
-agentes
-allow
-analog
-anthill
-apache
-app
-appl
-applets
-application
-applications
-applmgr
-apply
-apps
-appsec
-ar
-archive
-archives
-asa
-asp
-atc
-aut
-auth
-authadmin
-author
-authors
-aw
-ayuda
-b
-b2-include
-back
-backend
-backup
-backups
-bad
-bak
-banca
-banco
-bank
-banner
-banner01
-banners
-bar
-batch
-bb-dnbd
-bbv
-bdata
-bdatos
-beta
-billpay
-bin
-binaries
-binary
-boadmin
-boot
-bottom
-browse
-browser
-bsd
-btauxdir
-bug
-bugs
-bugzilla
-buy
-buynow
-c
-cache
-cache-stats
-cached
-caja
-card
-cards
-cart
-cash
-caspsamp
-catalog
-cbi-bin
-ccard
-ccards
-cd
-cd-cgi
-cdrom
-ce_html
-cert
-certificado
-certificate
-cfappman
-cfdocs
-cfide
-cgi
-cgi-auth
-cgi-bin
-cgi-bin2
-cgi-csc
-cgi-lib
-cgi-local
-cgi-scripts
-cgi-shl
-cgi-shop
-cgi-sys
-cgi-weddico
-cgi-win
-cgibin
-cgilib
-cgis
-cgiscripts
-cgiwin
-class
-classes
-client
-cliente
-clientes
-clients
-cm
-cmsample
-cobalt-images
-code
-com
-comments
-common
-communicator
-comp
-company
-compra
-compras
-compressed
-conecta
-conf
-config
-configs
-configure
-connect
-console
-contact
-contacts
-content
-controlpanel
-core
-corp
-correo
-counter
-credit
-cron
-crons
-crypto
-csr
-css
-cuenta
-cuentas
-currency
-cust
-custom
-customer
-customers
-cvsweb
-cybercash
-d
-darkportal
-dat
-data
-database
-databases
-datafiles
-dato
-datos
-db
-dbase
-dcforum
-ddreport
-ddrint
-debug
-debugs
-default
-delete
-demo
-demoauct
-demomall
-demos
-demouser
-deny
-derived
-design
-dev
-devel
-development
-dir
-directories
-directory
-directorymanager
-dl
-dm
-dms
-dms0
-dmsdump
-doc
-doc-html
-doc1
-docs
-docs1
-document
-documentation
-documents
-down
-download
-downloads
-dump
-durep
-e
-easylog
-eforum
-ejemplo
-ejemplos
-email
-emailclass
-employees
-empoyees
-empris
-enter
-envia
-enviamail
-error
-errors
-es
-estmt
-etc
-example
-examples
-exc
-excel
-exchange
-exe
-exec
-exit
-export
-external
-extranet
-f
-failure
-fbsd
-fcgi
-fcgi-bin
-features
-file
-filemanager
-files
-find
-flash
-foldoc
-foo
-foobar
-form
-form-totaller
-forms
-formsmgr
-forum
-forums
-foto
-fotos
-fpadmin
-fpclass
-fpdb
-fpe
-fpsample
-frames
-framesets
-frontpage
-ftp
-ftproot
-fun
-func
-function
-functions
-g
-general
-gfx
-gif
-gifs
-global
-globals
-good
-graphics
-grocery
-guest
-guestbook
-guests
-h
-help
-helpdesk
-hidden
-hide
-hit_tracker
-hitmatic
-hlstats
-home
-host
-hosted
-hosting
-hostingcontroller
-ht
-htbin
-htdocs
-htm
-html
-http
-https
-hyperstat
-ibank
-ibill
-icons
-idea
-ideas
-iisadmin
-iissamples
-image
-imagenes
-imagery
-images
-img
-imp
-import
-impreso
-in
-inc
-include
-includes
-incoming
-index
-inet
-inf
-info
-information
-ingresa
-ingreso
-install
-internal
-internet
-intranet
-inventory
-invitado
-isapi
-j
-japidoc
-java
-javascript
-javasdk
-javatest
-jave
-jdbc
-job
-jrun
-js
-jsa
-jscript
-jserv
-jslib
-jsp
-junk
-k
-kiva
-known
-l
-labs
-lcgi
-lib
-libraries
-library
-libro
-license
-licenses
-links
-linux
-loader
-local
-location
-locations
-log
-logfile
-logfiles
-logg
-logger
-logging
-login
-logon
-logout
-logs
-lost+found
-m
-mail
-mail_log_files
-mailman
-mailroot
-makefile
-mall_log_files
-man
-manage
-management
-manager
-manual
-map
-maps
-marketing
-mem
-mem_bin
-member
-members
-message
-messaging
-metacart
-microsoft
-misc
-mkstats
-mod
-module
-modules
-movimientos
-mqseries
-ms
-msfpe
-msql
-my
-mysql
-mysql_admin
-n
-name
-names
-ncadmin
-nchelp
-ncsample
-net
-netbasic
-netcat
-netmagstats
-netscape
-netshare
-nettracker
-network
-new
-news
-nextgeneration
-nl
-notes
-noticias
-o
-objects
-odbc
-old
-old_files
-oldfiles
-oprocmgr-service
-oprocmgr-status
-oracle
-oradata
-order
-orders
-os
-out
-outgoing
-owners
-p
-page
-pages
-partner
-partners
-passport
-password
-passwords
-path
-payment
-payments
-pccsmysqladm
-perl
-perl5
-personal
-pforum
-phorum
-php
-phpBB
-phpMyAdmin
-phpmyadmin
-phpPhotoAlbum
-phpSecurePages
-php_classes
-phpclassifieds
-phpimageview
-phpnuke
-phpprojekt
-pics
-pictures
-pike
-piranha
-pls
-plsql
-poll
-polls
-portal
-portals
-postgres
-ppwb
-printers
-priv
-privacy
-privado
-private
-prod
-protected
-proxy
-prueba
-pruebas
-prv
-pub
-public
-publica
-publicar
-publico
-publish
-purchase
-purchases
-pw
-python
-q
-r
-random_banner
-rdp
-register
-registered
-registry
-remote
-remove
-report
-reports
-reseller
-restricted
-retail
-reveal
-reviews
-robot
-robots
-root
-rsrc
-ruby
-s
-sales
-sample
-samples
-save
-script
-scripts
-search
-search-ui
-sec
-secret
-secure
-secured
-security
-sell
-server
-server-info
-server-status
-server_stats
-servers
-serverstats
-service
-services
-servicio
-servicios
-servlet
-servlets
-session
-setup
-share
-shared
-sharedtemplates
-shell-cgi
-shipping
-shop
-shopper
-show
-site
-siteadmin
-sitemgr
-siteminder
-siteminderagent
-sites
-siteserver
-sitestats
-siteupdate
-smreports
-smreportsviewer
-soap
-soapdocs
-software
-solaris
-source
-sql
-squid
-src
-srchadm
-ssi
-ssl
-sslkeys
-staff
-stat
-state
-statistic
-statistics
-stats
-stats-bin-p
-stats_old
-status
-storage
-store
-storemgr
-stronghold-info
-stronghold-status
-stuff
-style
-styles
-stylesheet
-stylesheets
-subir
-sun
-super_stats
-supplier
-suppliers
-supply
-support
-supporter
-sys
-sysadmin
-sysbackup
-system
-systems
-t
-tar
-target
-tarjetas
-te_html
-tech
-technote
-temp
-template
-templates
-temporal
-test
-test-cgi
-testing
-tests
-testweb
-themes
-ticket
-tickets
-tip
-tips
-tmp
-tool
-tools
-top
-tpv
-trabajo
-track
-tracking
-transfer
-transito
-transpolar
-tree
-trees
-trick
-tricks
-u
-u02
-unix
-unknown
-updates
-upload
-uploads
-us
-usage
-user
-userdb
-users
-usr
-ustats
-usuario
-usuarios
-util
-utils
-v
-vendor
-vfs
-vti_bin
-vti_bot
-vti_log
-vti_pvt
-vti_shm
-vti_txt
-w
-w-agora
-w2000
-w2k
-w3perl
-way-board
-web
-web-inf
-web800fo
-webAdmin
-webDB
-webMathematica
-web_usage
-webaccess
-webadmin
-webalizer
-webapps
-webboard
-webcart
-webcart-lite
-webdata
-webdav
-webdb
-webimages
-webimages2
-weblog
-weblogs
-webmaster
-webmaster_logs
-webpub
-webpub-ui
-webreports
-webreps
-webshare
-website
-webstat
-webstats
-webtrace
-webtrends
-win
-win2k
-window
-windows
-word
-work
-world
-wsdocs
-wstats
-wusage
-www
-www-sql
-www0
-www2
-www3
-www4
-wwwjoin
-wwwlog
-wwwrooot
-wwwstat
-wwwstats
-x
-xGB
-xml
-xtemp
-y
-z
-zb41
-zip
-zipfiles
-winnt
-secure
-protected
-cgi-bin
-j2ee
-j2ee/examples
-j2ee/examples/jsp
-ojspdemos
-pls
-pls/sample
-pls/sample/admin
-pls/sample/admin_
-pls/sample/admin_/help
-recycler
-deleted
-tmp
-intranet
-network
-AlbumArt
-AlbumArt_
-My Shared Folder
-fileadmin
-webadmin
-content.ie5
diff --git a/nselib/data/http-fingerprints b/nselib/data/http-fingerprints
deleted file mode 100644
index 876fca941..000000000
--- a/nselib/data/http-fingerprints
+++ /dev/null
@@ -1,141 +0,0 @@
-# Apache configuration file
-/.htaccess
-/.htpasswd
-
-# Subversion data
-/.svn/
-/.svn/text-base/Web.config.svn-base
-/.svn/text-base/.htaccess.svn-base
-/.svn/text-base/.htpasswd.svn-base
-
-# FrontPage directory
-/_vti_bin/
-/_vti_cnf/
-/_vti_log/
-/_vti_pvt/
-/_vti_txt/
-
-# Admin directory
-/admin/
-
-# Backup
-/backup/
-/bak/
-/backup.sql
-
-# Beta directory
-/beta/
-
-# Bin directory
-/bin/
-
-# CSS directory
-/css/
-
-# Data directory
-/data/
-
-# Database directory
-/db/
-
-# Demo directory
-/demo/
-
-# Development directory
-/dev/
-
-# Downloads directory
-/downloads/
-
-# Password file
-/etc/passwd
-
-# Forum software
-/forum/
-/forums/
-
-# Icons and images
-/icons/
-/images/
-
-# IIS sample scripts
-/iissamples/
-
-# Includes directory
-/includes/
-
-# Inicoming files directory
-/incoming/
-
-# Install directory
-/install/
-
-# Intranet directory
-/intranet/
-
-# Logs
-/logs/
-/log.htm
-
-# Login
-/login/
-/login.htm
-/login.html
-/login.php
-/login.aspx
-/login.asp
-
-# Mail directory
-/mail/
-/webmail/
-
-# Manual directory (apache)
-/manual/
-
-# phpMyAdmin
-/phpmyadmin/
-/phpMyAdmin/
-
-# Test
-/test.htm
-/test.html
-/test.asp
-/test.php
-/test.txt
-/test.class
-/test/
-
-# RSS
-/rss/
-/rss.php
-/rss.xml
-/rss.aspx
-/atom/
-/atom.php
-/atom.xml
-/atom.aspx
-
-# Robots file
-/robots.txt
-
-# Ruby on Rails
-/images/rails.png
-
-# Private
-/private/
-/_private/
-
-# Public
-/public/
-/_public/
-/pub/
-
-# Classes
-/classes/
-
-# Blog
-/blog/
-
-# Wiki
-/wiki/
-
diff --git a/nselib/data/http-fingerprints.lua b/nselib/data/http-fingerprints.lua
new file mode 100644
index 000000000..56bc900b4
--- /dev/null
+++ b/nselib/data/http-fingerprints.lua
@@ -0,0 +1,1666 @@
+---HTTP Fingerprint files, compiled by Ron Bowes from three sources:
+-- 1) The yokoso project's fingerprint file, used with permission
+-- (See http://yokoso.inguardians.com/ for more information)
+-- 2) A list of interesting folders that Nmap already had (uncredited,
+-- please contact nmap-dev@insecure.org if you're aware of where they
+-- came from.
+-- 3) A significant amount of manual effort by Ron Bowes in actually
+-- installing and scanning different programs.
+--
+-- This file is released under the Nmap license; see:
+-- http://nmap.org/book/man-legal.html
+--
+-- Although this format was originally modeled after the Nikto format, that ended
+-- up being too restrictive. The current format is a simple Lua table. There are many
+-- advantages to this technique; it's powerful, we don't need to write custom parsing
+-- code, anybody who codes in Lua can easily add checks, and we can write converters
+-- to read Nikto and other formats if we want to.
+--
+-- The 'fingerprints' table is the key. It's an array of checks that will be run in the
+-- order they're given. Each check consists of a path, zero or more matches, output text,
+-- and other optional fields. Here are all the currently defined fields:
+--
+-- fingerprint.probes
+-- A list of one or more probes to send to the server. Each probe is either a table containing
+-- the key 'path' (and potentially others), or it's a string indicating the path.
+--
+-- fingerprint.probes[i].path
+-- The URI to check, optionally containing GET arguments. This should start with a '/'
+-- and, if it's a directory, end with a '/'.
+--
+-- fingerprint.probes[i].method [optional; default: 'GET'}}]
+-- The HTTP method to use when making requests ('GET'}}, 'POST', 'HEAD', 'PUT', 'DELETE', etc
+--
+-- fingerprint.ignore_404 [optional; default: false]
+-- If set, the automatic checks for 404 and custom 404 pages are disabled for that check.
+-- Every page will be included unless fingerprint.matches.dontmatch excludes it.
+--
+-- fingerprint.severity [optional; default: 1]
+-- Give a severity rating, if it's a vulnerability. The scale is:
+-- 1 - Info
+-- 2 - Low priority
+-- 3 - Warning
+-- 4 - Critical
+--
+-- fingerprint.matches
+-- An array of tables, each of which contains three fields. These will be checked, starting
+-- from the first, until one is matched. If there is no 'match' text, it will fire as long
+-- as the result isn't a 404. This match is not case sensitive.
+--
+-- fingerprint.matches[i].match
+-- A string (specifically, a Lua pattern) that has to be found somewhere in the output to
+-- count as a match. The string can be in the status line, in a header, or in the body.
+-- In addition to matching, this field can contain captures that'll be included in the
+-- output. See: http://lua-users.org/wiki/PatternsTutorial
+--
+-- fingerprint.matches[i].dontmatch
+-- A string (specifically, a lua pattern) that cannot be found somewhere in the output.
+-- This takes precedence over any text matched in the 'match' field
+--
+-- fingerprint.matches[i].output
+-- The text to output if this match happens. If the 'match' field contains captures, these
+-- captures can be used with \1, \2, etc.
+--
+--
+-- If you have any questions, feel free to email nmap-dev@insecure.org or contact Ron Bowes!
+--
+
+fingerprints = {}
+
+------------------------------------------------
+---- GENERAL CHECKS ----
+------------------------------------------------
+-- These are checks for generic paths, like /wiki, /images, /admin, etc
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/', method='GET'}
+ },
+ matches={
+ {match='
Index of .*(Apache.*) Server at', output='Root directory w/ listing on \'\\1\''},
+ {match='Index of', output='Root directory w/ directory listing'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/blog/', method='HEAD'},
+ {path='/weblog/', method='HEAD'},
+ {path='/weblogs/', method='HEAD'},
+ {path='/wordpress/', method='HEAD'}
+ },
+ matches={
+ {output='Blog'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/wiki/', method='HEAD'},
+ {path='/mediawiki/', method='HEAD'}
+ },
+ matches={
+ {output='Wiki'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/forum/', method='HEAD'},
+ {path='/forums/', method='HEAD'},
+ {path='/smf/', method='HEAD'},
+ {path='/phpbb/', method='HEAD'}
+ },
+ matches={
+ {output='Forum'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/admin/', method='GET'},
+ {path='/admin_', method='GET'},
+ {path='/administration/', method='GET'},
+ {path='/administrator/', method='GET'},
+ {path='/admin-old/', method='GET'},
+ {path='/adminuser/', method='GET'},
+ {path='/adminweb/', method='GET'},
+ {path='/adminWeb/', method='GET'},
+ {path='/Admin_files/', method='GET'},
+ {path='/admin-bak/', method='GET'},
+ {path='/admin.back/', method='GET'},
+ {path='/adm/', method='GET'}
+ },
+ matches={
+ {match='Index of', output='Possible admin folder w/ directory listing'},
+ {output='Possible admin folder'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/backup/', method='GET'},
+ {path='/backup', method='GET'},
+ {path='/backup.sql', method='GET'},
+ {path='/backup.sql.gz', method='GET'},
+ {path='/backup.sql.bz2', method='GET'},
+ {path='/backup.zip', method='GET'},
+ {path='/backups/', method='GET'},
+ {path='/bak/', method='GET'},
+ {path='/back/', method='GET'}
+ },
+ matches={
+ {match='Index of', output='Backup folder w/ directory listing'},
+ {match='', output='Possible backup'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/atom/', method='HEAD'},
+ {path='/atom.aspx', method='HEAD'},
+ {path='/atom.php', method='HEAD'},
+ {path='/atom.xml', method='HEAD'},
+ {path='/atom.jsp', method='HEAD'},
+ {path='/rss/', method='HEAD'},
+ {path='/rss.aspx', method='HEAD'},
+ {path='/rss.php', method='HEAD'},
+ {path='/rss.xml', method='HEAD'},
+ {path='/rss.jsp', method='HEAD'}
+ },
+ matches={
+ {output='RSS or Atom feed'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/etc/passwd', method='GET'},
+ {path='/boot.ini', method='GET'}
+ },
+ matches={
+ {match='root:', output='Webroot appears to be in / (Linux)'},
+ {match='boot loader', output='Webroot appears to be in c:\\ (Windows)'},
+ {match='', output='Webroot might be in root folder'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/example/', method='GET'},
+ {path='/examples/', method='GET'},
+ {path='/iissamples/', method='GET'},
+ {path='/j2eeexamples/', method='GET'},
+ {path='/j2eeexamplesjsp/', method='GET'},
+ {path='/sample/', method='GET'},
+ {path='/ncsample/', method='GET'},
+ {path='/fpsample/', method='GET'},
+ {path='/cmsample/', method='GET'},
+ {path='/samples/', method='GET'},
+ {path='/mono/1.1/index.aspx', method='GET'}
+ },
+ matches= {
+ {match='Index of .*(Apache.*) Server at', output='Sample scripts w/ listing on \'\\1\''},
+ {match='Index of', output='Sample scripts w/ directory listing'},
+ {match='', output='Sample scripts'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/login.asp', method='HEAD'},
+ {path='/login.aspx', method='HEAD'},
+ {path='/login/', method='HEAD'},
+ {path='/login.htm', method='HEAD'},
+ {path='/login.html', method='HEAD'},
+ {path='/login.php', method='HEAD'},
+ {path='/login.jsp', method='HEAD'}
+ },
+ matches= {
+ {match='', output='Login page'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/test.asp', method='HEAD'},
+ {path='/test.class', method='HEAD'},
+ {path='/test/', method='HEAD'},
+ {path='/test.htm', method='HEAD'},
+ {path='/test.html', method='HEAD'},
+ {path='/test.php', method='HEAD'},
+ {path='/test.txt', method='HEAD'}
+ },
+ matches= {
+ {match='', output='Test page'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/webmail/', method='HEAD'},
+ {path='/mail/', method='HEAD'}
+ },
+ matches= {
+ {match='', output='Mail folder'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/log/', method='HEAD'},
+ {path='/log.htm', method='HEAD'},
+ {path='/log.php', method='HEAD'},
+ {path='/log.asp', method='HEAD'},
+ {path='/log.aspx', method='HEAD'},
+ {path='/log.jsp', method='HEAD'},
+ {path='/logs/', method='HEAD'},
+ {path='/logs.htm', method='HEAD'},
+ {path='/logs.php', method='HEAD'},
+ {path='/logs.asp', method='HEAD'},
+ {path='/logs.aspx', method='HEAD'},
+ {path='/logs.jsp', method='HEAD'},
+ {path='/wwwlog/', method='HEAD'},
+ {path='/wwwlogs/', method='HEAD'},
+ {path='/mail_log_files/', method='HEAD'}
+ },
+ matches= {
+ {match='', output='Logs'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/images/rails.png', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Ruby on Rails'}
+ }
+})
+
+ table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/mono/', method='HEAD'},
+ },
+
+ matches= {
+ {match='', output='Mono'}
+ }
+})
+
+
+table.insert(fingerprints, {
+ category='general',
+ probes={
+ {path='/robots.txt', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Robots file'}
+ }
+})
+
+------------------------------------------------
+---- SECURITY SOFTWARE ----
+------------------------------------------------
+-- These checks will find specific installed software. If possible, it will also
+-- find versions, etc.
+
+table.insert(fingerprints, {
+ category='security',
+ probes={
+ {path='/arcsight/', method='HEAD'},
+ {path='/arcsight/images/logo-login-arcsight.gif', method='HEAD'},
+ {path='/arcsight/images/navbar-icon-logout-on.gif', method='HEAD'},
+ {path='/images/logo-arcsight.gif', method='HEAD'},
+ {path='/logger/monitor.ftl', method='HEAD'},
+ },
+ matches={
+ {output='Arcsight'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='security',
+ probes={
+ {path='/beef/', method='HEAD'},
+ {path='/BEEF/', method='HEAD'},
+ {path='/beef/images/beef.gif', method='HEAD'}
+ },
+ matches={
+ {output='BeEF Browser Exploitation Framework'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='security',
+ probes={
+ {path='/gfx/form_top_left_corner.gif', method='HEAD'},
+ {path='/gfx/logout_24.png', method='HEAD'},
+ {path='/gfx/new_logo.gif', method='HEAD'},
+ {path='/javascript/sorttable.js', method='HEAD'}
+ },
+ matches= {
+ {match='', output='Secunia NSI'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='security',
+ probes={
+ {path='/images/btn_help_nml.gif', method='HEAD'},
+ {path='/images/hdr_icon_homeG.gif', method='HEAD'},
+ {path='/spControl.php', method='HEAD'},
+ {path='/images/isslogo.gif', method='HEAD'},
+ {path='/deploymentmanager/', method='HEAD'},
+ },
+ matches= {
+ {match='', output='IBM Proventia'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='security',
+ probes={
+ {path='/i18n/EN/css/foundstone.css', method='HEAD'},
+ {path='/i18n/EN/images/external_nav_square.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Foundstone'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='security',
+ probes={
+ {path='/officescan/console/html/cgi/cgiChkMasterPwd.exe', method='HEAD'},
+ {path='/officescan/console/html/ClientInstall/officescannt.htm', method='HEAD'},
+ {path='/officescan/console/html/images/icon_refresh.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Trend Micro OfficeScan Server'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='security',
+ probes={
+ {path='/picts/BC_bwlogorev.gif', method='HEAD'},
+ {path='/picts/menu_leaf.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='BlueCoat Reporter'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='security',
+ probes={
+ {path='/theme/images/en/login1.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Fortinet VPN/Firewall'}
+ }
+})
+
+------------------------------------------------
+---- MANAGEMENT SOFTWARE ----
+------------------------------------------------
+table.insert(fingerprints, {
+ category='management',
+ probes={
+ {path='/vmware/', method='HEAD'},
+ {path='/vmware/imx/vmware_boxes-16x16.png', method='HEAD'},
+ {path='/ui/', method='HEAD'},
+ {path='/ui/imx/vmwareLogo-16x16.png', method='HEAD'},
+ {path='/ui/imx/vmwarePaperBagLogo-16x16.png', method='HEAD'},
+ {path='/ui/vManage.do', method='HEAD'},
+ {path='/client/VMware-viclient.exe', method='HEAD'},
+ {path='/en/welcomeRes.js', method='HEAD'}
+ },
+ matches={
+ {output='VMWare'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='management',
+ probes={
+ {path='/citrix/', method='HEAD'},
+ {path='/Citrix/', method='HEAD'},
+ {path='/Citrix/MetaFrame/auth/login.aspx', method='HEAD'},
+ {path='/images/ctxHeader01.jpg', method='HEAD'},
+ {path='/images/Safeword_Token.jpg', method='HEAD'},
+ {path='/sw/auth/login.aspx', method='HEAD'},
+ {path='/vpn/images/AccessGateway.ico', method='HEAD'}
+ },
+ matches={
+ {output='Citrix'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='management',
+ probes={
+ {path='/cgi-bin/image/shikaku2.png', method='HEAD'},
+ },
+ matches= {
+ {match='', output='TeraStation PRO RAID 0/1/5 Network Attached Storage'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='management',
+ probes={
+ {path='/config/public/usergrp.gif', method='HEAD'},
+ {path='/pictures/buttons/file_view_mark.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='AXIS StorPoint'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='management',
+ probes={
+ {path='/cpqlogin.htm?RedirectUrl=/&RedirectQueryString=', method='HEAD'},
+ {path='/hplogo.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='HP System Management Homepage'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='management',
+ probes={
+ {path='/ie_index.htm', method='HEAD'},
+ {path='/ilo.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='HP Integrated Lights Out'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='management',
+ probes={
+ {path='/images/icon_server_connected.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='HP Blade Enclosure'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='management',
+ probes={
+ {path='/mxhtml/images/signin_logo.gif', method='HEAD'},
+ {path='/mxhtml/images/status_critical_15.gif', method='HEAD'},
+ {path='/mxportal/home/en_US/servicetools.gif', method='HEAD'},
+ {path='/mxportal/home/MxPortalFrames.jsp', method='HEAD'},
+ },
+ matches= {
+ {match='', output='HP Insight Manager'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='management',
+ probes={
+ {path='/xymon/menu/menu.css', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Xymon'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='management',
+ probes={
+ {path='/rrc.htm', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Raritan Remote Client'}
+ }
+})
+
+------------------------------------------------
+---- PRINTERS, WEBCAMS, PROJECTORS ----
+------------------------------------------------
+table.insert(fingerprints, {
+ category='printer',
+ probes={
+ {path='x_logo.gif', method='HEAD'}
+ },
+ matches= {
+ {match='', output='Xerox printer'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='printer',
+ probes={
+ {path='/gif/hp.gif', method='HEAD'},
+ {path='/gif/hp_invent_logo.gif', method='HEAD'},
+ {path='/gif/printer.gif', method='HEAD'},
+ {path='/hp/device/this.LCDispatcher', method='HEAD'},
+ {path='/hp/device/webAccess/index.htm', method='HEAD'},
+ {path='/PageSelector.class', method='HEAD'}
+ },
+ matches= {
+ {match='', output='HP Printer'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='printer',
+ probes={
+ {path='/images/lexbold.gif', method='HEAD'},
+ {path='/images/lexlogo.gif', method='HEAD'},
+ {path='/images/printer.gif', method='HEAD'},
+ {path='/printer/image', method='HEAD'}
+ },
+ matches= {
+ {match='', output='Lexmark Printer'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='printer',
+ probes={
+ {path='/images/mute_alloff.gif', method='HEAD'},
+ {path='/images/pic_bri.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='NEC Projector'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='printer',
+ probes={
+ {path='/scanweb/images/scanwebtm.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='SCAN Web (Webcam)'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='printer',
+ probes={
+ {path='/view/index.shtml', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Axis 212 PTZ Network Camera'}
+ }
+})
+
+------------------------------------------------
+---- DATABASES ----
+------------------------------------------------
+table.insert(fingerprints, {
+ category='database',
+ probes={
+ {path='/phpmyadmin/', method='HEAD'},
+ {path='/phpMyAdmin/', method='HEAD'},
+ {path='/PHPMyAdmin/', method='HEAD'}
+ },
+ matches={
+ {output='phpMyAdmin'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='database',
+ probes={
+ {path='/footer1.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='(possible) Oracle Web server'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='database',
+ probes={
+ {path='/homepage.nsf/homePage.gif?OpenImageResource', method='HEAD'},
+ {path='/icons/ecblank.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Lotus Domino'}
+ }
+})
+
+------------------------------------------------
+---- MICROSOFT ----
+------------------------------------------------
+table.insert(fingerprints, {
+ category='microsoft',
+ probes={
+ {path='/_layouts/images/helpicon.gif', method='HEAD'},
+ {path='/Pages/Default.aspx', method='HEAD'},
+ {path='/PublishingImages/NewsArticleImage.jpg', method='HEAD'},
+ },
+ matches= {
+ {match='', output='MS Sharepoint'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='microsoft',
+ probes={
+ {path='/projectserver/Home/HomePage.asp', method='HEAD'},
+ {path='/projectserver/images/branding.gif', method='HEAD'},
+ {path='/projectserver/images/pgHome.gif', method='HEAD'},
+ {path='/projectserver/images/pgTask.gif', method='HEAD'},
+ {path='/projectserver/Tasks/Taskspage.asp', method='HEAD'},
+ },
+ matches= {
+ {match='', output='MS Project Server'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='microsoft',
+ probes={
+ {path='/exchweb/bin/auth/owalogon.asp', method='HEAD'},
+ {path='/images/outlook.jpg', method='HEAD'},
+ {path='/owa/8.1.375.2/themes/base/lgntopl.gif', method='HEAD'},
+ {path='/owa/', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Outlook Web Access'}
+ }
+})
+
+
+
+------------------------------------------------
+---- ATTACKS ----
+------------------------------------------------
+-- These will search for and possibly exploit vulnerabilities.
+
+table.insert(fingerprints, {
+ category='attacks',
+ probes={
+ {path='/sdk/../../../../../../../etc/vmware/hostd/vmInventory.xml', method='GET'},
+ {path='/sdk/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/etc/vmware/hostd/vmInventory.xml', method='GET'}
+ },
+ matches={
+ {match='', output='Path traversal in VMWare (CVE-2009-3733)'},
+ {match='', output='Possible path traversal in VMWare (CVE-2009-3733)'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='attacks',
+ probes={
+ {path='/../../../../../../../../../../etc/passwd', method='GET'},
+ {path='/../../../../../../../../../../boot.ini', method='GET'}
+ },
+ matches={
+ {match='root:', output='Simple path traversal in URI (Linux)'},
+ {match='boot loader', output='Simple path traversal in URI (Windows)'},
+ {match='', output='Possible path traversal in URI'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='attacks',
+ probes={
+ {path='.htaccess', method='GET'},
+ {path='.htpasswd', method='GET'}
+ },
+ matches={
+ -- We look for a '200 OK' message on this one, because most Apache servers return an access denied
+ {match='200 OK', output='Incorrect permissions on .htaccess or .htpasswd files'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='attacks',
+ probes={
+ {path='/_vti_bin/', method='GET'},
+ {path='/_vti_cnf/', method='GET'},
+ {path='/_vti_log/', method='GET'},
+ {path='/_vti_pvt/', method='GET'},
+ {path='/_vti_txt/', method='GET'}
+ },
+ matches= {
+ {match='200', output='Frontpage folder'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='attacks',
+ probes={
+ {path='/.svn/', method='GET'},
+ {path='/.svn/text-base/.htaccess.svn-base', method='GET'},
+ {path='/.svn/text-base/.htpasswd.svn-base', method='GET'},
+ {path='/.svn/text-base/Web.config.svn-base', method='GET'}
+ },
+ matches= {
+ {match='200', output='Subversion folder'}
+ }
+})
+
+------------------------------------------------
+---- UNCATEGORIZED ----
+------------------------------------------------
+
+table.insert(fingerprints, {
+ category='uncategorized',
+ probes={
+ {path='/TopAccess/images/RioGrande/Rio_PPC.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='TopAccess Toshiba e-Studio520'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='uncategorized',
+ probes={
+ {path='/archive/flash:home/html/images/Cisco_logo.gif', method='HEAD'},
+ },
+ matches= {
+ {match='', output='Cisco SDM'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='uncategorized',
+ probes={
+ {path='/Default?MAIN=DEVICE', method='HEAD'},
+ },
+ matches= {
+ {match='', output='TopAccess Toshiba e-Studio520'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='uncategorized',
+ probes={
+ {path='/jwsappmngr.jnlp', method='HEAD'},
+ {path='/nfdesktop.jnlp', method='HEAD'},
+ {path='/nfservlets/servlet/SPSRouterServlet/', method='HEAD'},
+ },
+ matches= {
+ {match='', output='netForensics'}
+ }
+})
+
+table.insert(fingerprints, {
+ category='uncategorized',
+ probes={
+ {path='/na_admin/styles/dfm.css', method='HEAD'},
+ },
+ matches= {
+ {match='', output='NetworkAppliance NetApp Release 6.5.3P4'}
+ }
+})
+
+
+------------------------------------------------
+---- MISCELLANEOUS ITEMS OF INTEREST ----
+------------------------------------------------
+
+table.insert(fingerprints, {
+ category='miscellaneous',
+ probes={
+ {path='/0/', method='GET'},
+ {path='/1/', method='GET'},
+ {path='/2/', method='GET'},
+ {path='/3/', method='GET'},
+ {path='/4/', method='GET'},
+ {path='/5/', method='GET'},
+ {path='/6/', method='GET'},
+ {path='/7/', method='GET'},
+ {path='/8/', method='GET'},
+ {path='/9/', method='GET'},
+ {path='/10/', method='GET'},
+ {path='/a/', method='GET'},
+ {path='/b/', method='GET'},
+ {path='/c/', method='GET'},
+ {path='/d/', method='GET'},
+ {path='/e/', method='GET'},
+ {path='/f/', method='GET'},
+ {path='/g/', method='GET'},
+ {path='/h/', method='GET'},
+ {path='/i/', method='GET'},
+ {path='/j/', method='GET'},
+ {path='/k/', method='GET'},
+ {path='/l/', method='GET'},
+ {path='/m/', method='GET'},
+ {path='/n/', method='GET'},
+ {path='/o/', method='GET'},
+ {path='/p/', method='GET'},
+ {path='/q/', method='GET'},
+ {path='/r/', method='GET'},
+ {path='/s/', method='GET'},
+ {path='/t/', method='GET'},
+ {path='/u/', method='GET'},
+ {path='/v/', method='GET'},
+ {path='/w/', method='GET'},
+ {path='/x/', method='GET'},
+ {path='/x/', method='GET'},
+ {path='/y/', method='GET'},
+ {path='/z/', method='GET'},
+ {path='/acceso/', method='GET'},
+ {path='/access/', method='GET'},
+ {path='/accesswatch/', method='GET'},
+ {path='/acciones/', method='GET'},
+ {path='/account/', method='GET'},
+ {path='/accounting/', method='GET'},
+ {path='/active/', method='GET'},
+ {path='/activex/', method='GET'},
+ {path='/admcgi/', method='GET'},
+ {path='/admisapi/', method='GET'},
+ {path='/AdvWebAdmin/', method='GET'},
+ {path='/agentes/', method='GET'},
+ {path='/Agent/', method='GET'},
+ {path='/Agents/', method='GET'},
+ {path='/AlbumArt_/', method='GET'},
+ {path='/AlbumArt/', method='GET'},
+ {path='/Album/', method='GET'},
+ {path='/allow/', method='GET'},
+ {path='/analog/', method='GET'},
+ {path='/anthill/', method='GET'},
+ {path='/apache/', method='GET'},
+ {path='/app/', method='GET'},
+ {path='/applets/', method='GET'},
+ {path='/appl/', method='GET'},
+ {path='/application/', method='GET'},
+ {path='/applications/', method='GET'},
+ {path='/applmgr/', method='GET'},
+ {path='/apply/', method='GET'},
+ {path='/appsec/', method='GET'},
+ {path='/apps/', method='GET'},
+ {path='/archive/', method='GET'},
+ {path='/archives/', method='GET'},
+ {path='/ar/', method='GET'},
+ {path='/asa/', method='GET'},
+ {path='/asp/', method='GET'},
+ {path='/atc/', method='GET'},
+ {path='/aut/', method='GET'},
+ {path='/authadmin/', method='GET'},
+ {path='/auth/', method='GET'},
+ {path='/author/', method='GET'},
+ {path='/authors/', method='GET'},
+ {path='/aw/', method='GET'},
+ {path='/ayuda/', method='GET'},
+ {path='/b2-include/', method='GET'},
+ {path='/backend/', method='GET'},
+ {path='/bad/', method='GET'},
+ {path='/banca/', method='GET'},
+ {path='/banco/', method='GET'},
+ {path='/bank/', method='GET'},
+ {path='/banner01/', method='GET'},
+ {path='/banner/', method='GET'},
+ {path='/banners/', method='GET'},
+ {path='/bar/', method='GET'},
+ {path='/batch/', method='GET'},
+ {path='/bb-dnbd/', method='GET'},
+ {path='/bbv/', method='GET'},
+ {path='/bdata/', method='GET'},
+ {path='/bdatos/', method='GET'},
+ {path='/beta/', method='GET'},
+ {path='/billpay/', method='GET'},
+ {path='/bin/', method='GET'},
+ {path='/binaries/', method='GET'},
+ {path='/binary/', method='GET'},
+ {path='/boadmin/', method='GET'},
+ {path='/boot/', method='GET'},
+ {path='/bottom/', method='GET'},
+ {path='/browse/', method='GET'},
+ {path='/browser/', method='GET'},
+ {path='/bsd/', method='GET'},
+ {path='/btauxdir/', method='GET'},
+ {path='/bug/', method='GET'},
+ {path='/bugs/', method='GET'},
+ {path='/bugzilla/', method='GET'},
+ {path='/buy/', method='GET'},
+ {path='/buynow/', method='GET'},
+ {path='/cached/', method='GET'},
+ {path='/cache/', method='GET'},
+ {path='/cache-stats/', method='GET'},
+ {path='/caja/', method='GET'},
+ {path='/card/', method='GET'},
+ {path='/cards/', method='GET'},
+ {path='/cart/', method='GET'},
+ {path='/cash/', method='GET'},
+ {path='/caspsamp/', method='GET'},
+ {path='/catalog/', method='GET'},
+ {path='/cbi-bin/', method='GET'},
+ {path='/ccard/', method='GET'},
+ {path='/ccards/', method='GET'},
+ {path='/cd-cgi/', method='GET'},
+ {path='/cd/', method='GET'},
+ {path='/cdrom/', method='GET'},
+ {path='/ce_html/', method='GET'},
+ {path='/cert/', method='GET'},
+ {path='/certificado/', method='GET'},
+ {path='/certificate/', method='GET'},
+ {path='/cfappman/', method='GET'},
+ {path='/cfdocs/', method='GET'},
+ {path='/cfide/', method='GET'},
+ {path='/cgi-914/', method='GET'},
+ {path='/cgi-915/', method='GET'},
+ {path='/cgi-auth/', method='GET'},
+ {path='/cgi-bin2/', method='GET'},
+ {path='/cgi-bin/', method='GET'},
+ {path='/cgibin/', method='GET'},
+ {path='/cgi.cgi/', method='GET'},
+ {path='/cgi-csc/', method='GET'},
+ {path='/cgi-exe/', method='GET'},
+ {path='/cgi/', method='GET'},
+ {path='/cgi-home/', method='GET'},
+ {path='/cgi-lib/', method='GET'},
+ {path='/cgilib/', method='GET'},
+ {path='/cgi-local/', method='GET'},
+ {path='/cgi-perl/', method='GET'},
+ {path='/cgi-scripts/', method='GET'},
+ {path='/cgiscripts/', method='GET'},
+ {path='/cgis/', method='GET'},
+ {path='/cgi-shl/', method='GET'},
+ {path='/cgi-shop/', method='GET'},
+ {path='/cgi-sys/', method='GET'},
+ {path='/cgi-weddico/', method='GET'},
+ {path='/cgi-win/', method='GET'},
+ {path='/cgiwin/', method='GET'},
+ {path='/class/', method='GET'},
+ {path='/classes/', method='GET'},
+ {path='/cliente/', method='GET'},
+ {path='/clientes/', method='GET'},
+ {path='/client/', method='GET'},
+ {path='/clients/', method='GET'},
+ {path='/cm/', method='GET'},
+ {path='/cobalt-images/', method='GET'},
+ {path='/code/', method='GET'},
+ {path='/com/', method='GET'},
+ {path='/comments/', method='GET'},
+ {path='/common/', method='GET'},
+ {path='/communicator/', method='GET'},
+ {path='/company/', method='GET'},
+ {path='/comp/', method='GET'},
+ {path='/compra/', method='GET'},
+ {path='/compras/', method='GET'},
+ {path='/compressed/', method='GET'},
+ {path='/conecta/', method='GET'},
+ {path='/conf/', method='GET'},
+ {path='/config/', method='GET'},
+ {path='/configs/', method='GET'},
+ {path='/configure/', method='GET'},
+ {path='/connect/', method='GET'},
+ {path='/console/', method='GET'},
+ {path='/contact/', method='GET'},
+ {path='/contacts/', method='GET'},
+ {path='/content/', method='GET'},
+ {path='/content.ie5/', method='GET'},
+ {path='/controlpanel/', method='GET'},
+ {path='/core/', method='GET'},
+ {path='/corp/', method='GET'},
+ {path='/correo/', method='GET'},
+ {path='/counter/', method='GET'},
+ {path='/credit/', method='GET'},
+ {path='/cron/', method='GET'},
+ {path='/crons/', method='GET'},
+ {path='/crypto/', method='GET'},
+ {path='/CS/', method='GET'},
+ {path='/csr/', method='GET'},
+ {path='/css/', method='GET'},
+ {path='/cuenta/', method='GET'},
+ {path='/cuentas/', method='GET'},
+ {path='/currency/', method='GET'},
+ {path='/cust/', method='GET'},
+ {path='/customer/', method='GET'},
+ {path='/customers/', method='GET'},
+ {path='/custom/', method='GET'},
+ {path='/CVS/', method='GET'},
+ {path='/cvsweb/', method='GET'},
+ {path='/cybercash/', method='GET'},
+ {path='/darkportal/', method='GET'},
+ {path='/database/', method='GET'},
+ {path='/databases/', method='GET'},
+ {path='/datafiles/', method='GET'},
+ {path='/dat/', method='GET'},
+ {path='/data/', method='GET'},
+ {path='/dato/', method='GET'},
+ {path='/datos/', method='GET'},
+ {path='/db/', method='GET'},
+ {path='/dbase/', method='GET'},
+ {path='/dcforum/', method='GET'},
+ {path='/ddreport/', method='GET'},
+ {path='/ddrint/', method='GET'},
+ {path='/debug/', method='GET'},
+ {path='/debugs/', method='GET'},
+ {path='/default/', method='GET'},
+ {path='/deleted/', method='GET'},
+ {path='/delete/', method='GET'},
+ {path='/demoauct/', method='GET'},
+ {path='/demomall/', method='GET'},
+ {path='/demo/', method='GET'},
+ {path='/demos/', method='GET'},
+ {path='/demouser/', method='GET'},
+ {path='/deny/', method='GET'},
+ {path='/derived/', method='GET'},
+ {path='/design/', method='GET'},
+ {path='/dev/', method='GET'},
+ {path='/devel/', method='GET'},
+ {path='/development/', method='GET'},
+ {path='/directories/', method='GET'},
+ {path='/directory/', method='GET'},
+ {path='/directorymanager/', method='GET'},
+ {path='/dir/', method='GET'},
+ {path='/dl/', method='GET'},
+ {path='/dm/', method='GET'},
+ {path='/DMR/', method='GET'},
+ {path='/dms0/', method='GET'},
+ {path='/dmsdump/', method='GET'},
+ {path='/dms/', method='GET'},
+ {path='/dnn/', method='GET'},
+ {path='/doc1/', method='GET'},
+ {path='/doc/', method='GET'},
+ {path='/doc-html/', method='GET'},
+ {path='/docs1/', method='GET'},
+ {path='/docs/', method='GET'},
+ {path='/DocuColor/', method='GET'},
+ {path='/documentation/', method='GET'},
+ {path='/document/', method='GET'},
+ {path='/documents/', method='GET'},
+ {path='/dotnetnuke/', method='GET'},
+ {path='/down/', method='GET'},
+ {path='/download/', method='GET'},
+ {path='/downloads/', method='GET'},
+ {path='/dump/', method='GET'},
+ {path='/durep/', method='GET'},
+ {path='/easylog/', method='GET'},
+ {path='/eforum/', method='GET'},
+ {path='/ejemplo/', method='GET'},
+ {path='/ejemplos/', method='GET'},
+ {path='/emailclass/', method='GET'},
+ {path='/email/', method='GET'},
+ {path='/employees/', method='GET'},
+ {path='/empoyees/', method='GET'},
+ {path='/empris/', method='GET'},
+ {path='/enter/', method='GET'},
+ {path='/envia/', method='GET'},
+ {path='/enviamail/', method='GET'},
+ {path='/error/', method='GET'},
+ {path='/errors/', method='GET'},
+ {path='/es/', method='GET'},
+ {path='/estmt/', method='GET'},
+ {path='/etc/', method='GET'},
+ {path='/etcpasswd/', method='GET'},
+ {path='/excel/', method='GET'},
+ {path='/exc/', method='GET'},
+ {path='/exchange/', method='GET'},
+ {path='/exchweb/', method='GET'},
+ {path='/exec/', method='GET'},
+ {path='/exe/', method='GET'},
+ {path='/exit/', method='GET'},
+ {path='/export/', method='GET'},
+ {path='/external/', method='GET'},
+ {path='/extranet/', method='GET'},
+ {path='/failure/', method='GET'},
+ {path='/fbsd/', method='GET'},
+ {path='/fcgi-bin/', method='GET'},
+ {path='/fcgi/', method='GET'},
+ {path='/features/', method='GET'},
+ {path='/fileadmin/', method='GET'},
+ {path='/file/', method='GET'},
+ {path='/filemanager/', method='GET'},
+ {path='/files/', method='GET'},
+ {path='/find/', method='GET'},
+ {path='/flash/', method='GET'},
+ {path='/foldoc/', method='GET'},
+ {path='/foobar/', method='GET'},
+ {path='/foo/', method='GET'},
+ {path='/form/', method='GET'},
+ {path='/forms/', method='GET'},
+ {path='/formsmgr/', method='GET'},
+ {path='/form-totaller/', method='GET'},
+ {path='/foto/', method='GET'},
+ {path='/fotos/', method='GET'},
+ {path='/fpadmin/', method='GET'},
+ {path='/fpclass/', method='GET'},
+ {path='/fpdb/', method='GET'},
+ {path='/fpe/', method='GET'},
+ {path='/framesets/', method='GET'},
+ {path='/frames/', method='GET'},
+ {path='/frontpage/', method='GET'},
+ {path='/ftp/', method='GET'},
+ {path='/ftproot/', method='GET'},
+ {path='/func/', method='GET'},
+ {path='/function/', method='GET'},
+ {path='/functions/', method='GET'},
+ {path='/fun/', method='GET'},
+ {path='/general/', method='GET'},
+ {path='/gfx/', method='GET'},
+ {path='/gif/', method='GET'},
+ {path='/gifs/', method='GET'},
+ {path='/global/', method='GET'},
+ {path='/globals/', method='GET'},
+ {path='/good/', method='GET'},
+ {path='/graphics/', method='GET'},
+ {path='/grocery/', method='GET'},
+ {path='/guestbook/', method='GET'},
+ {path='/guest/', method='GET'},
+ {path='/guests/', method='GET'},
+ {path='/GXApp/', method='GET'},
+ {path='/HB/', method='GET'},
+ {path='/HBTemplates/', method='GET'},
+ {path='/helpdesk/', method='GET'},
+ {path='/help/', method='GET'},
+ {path='/hidden/', method='GET'},
+ {path='/hide/', method='GET'},
+ {path='/hitmatic/', method='GET'},
+ {path='/hit_tracker/', method='GET'},
+ {path='/hlstats/', method='GET'},
+ {path='/home/', method='GET'},
+ {path='/hosted/', method='GET'},
+ {path='/host/', method='GET'},
+ {path='/hostingcontroller/', method='GET'},
+ {path='/hosting/', method='GET'},
+ {path='/hp/', method='GET'},
+ {path='/htbin/', method='GET'},
+ {path='/htdocs/', method='GET'},
+ {path='/ht/', method='GET'},
+ {path='/htm/', method='GET'},
+ {path='/html/', method='GET'},
+ {path='/http/', method='GET'},
+ {path='/https/', method='GET'},
+ {path='/hyperstat/', method='GET'},
+ {path='/i18n/', method='GET'},
+ {path='/ibank/', method='GET'},
+ {path='/ibill/', method='GET'},
+ {path='/IBMWebAS/', method='GET'},
+ {path='/icons/', method='GET'},
+ {path='/idea/', method='GET'},
+ {path='/ideas/', method='GET'},
+ {path='/I/', method='GET'},
+ {path='/iisadmin/', method='GET'},
+ {path='/image/', method='GET'},
+ {path='/images/', method='GET'},
+ {path='/imagenes/', method='GET'},
+ {path='/imagery/', method='GET'},
+ {path='/img/', method='GET'},
+ {path='/imp/', method='GET'},
+ {path='/import/', method='GET'},
+ {path='/impreso/', method='GET'},
+ {path='/inc/', method='GET'},
+ {path='/include/', method='GET'},
+ {path='/includes/', method='GET'},
+ {path='/incoming/', method='GET'},
+ {path='/index/', method='GET'},
+ {path='/inet/', method='GET'},
+ {path='/inf/', method='GET'},
+ {path='/info/', method='GET'},
+ {path='/information/', method='GET'},
+ {path='/in/', method='GET'},
+ {path='/ingresa/', method='GET'},
+ {path='/ingreso/', method='GET'},
+ {path='/install/', method='GET'},
+ {path='/internal/', method='GET'},
+ {path='/internet/', method='GET'},
+ {path='/intranet/', method='GET'},
+ {path='/inventory/', method='GET'},
+ {path='/invitado/', method='GET'},
+ {path='/isapi/', method='GET'},
+ {path='/j2ee/', method='GET'},
+ {path='/japidoc/', method='GET'},
+ {path='/java/', method='GET'},
+ {path='/javascript/', method='GET'},
+ {path='/javasdk/', method='GET'},
+ {path='/javatest/', method='GET'},
+ {path='/jave/', method='GET'},
+ {path='/JBookIt/', method='GET'},
+ {path='/jdbc/', method='GET'},
+ {path='/job/', method='GET'},
+ {path='/jrun/', method='GET'},
+ {path='/jsa/', method='GET'},
+ {path='/jscript/', method='GET'},
+ {path='/jserv/', method='GET'},
+ {path='/js/', method='GET'},
+ {path='/jslib/', method='GET'},
+ {path='/jsp/', method='GET'},
+ {path='/junk/', method='GET'},
+ {path='/kiva/', method='GET'},
+ {path='/known/', method='GET'},
+ {path='/labs/', method='GET'},
+ {path='/lcgi/', method='GET'},
+ {path='/lib/', method='GET'},
+ {path='/libraries/', method='GET'},
+ {path='/library/', method='GET'},
+ {path='/libro/', method='GET'},
+ {path='/license/', method='GET'},
+ {path='/licenses/', method='GET'},
+ {path='/links/', method='GET'},
+ {path='/linux/', method='GET'},
+ {path='/loader/', method='GET'},
+ {path='/local/', method='GET'},
+ {path='/location/', method='GET'},
+ {path='/locations/', method='GET'},
+ {path='/logfile/', method='GET'},
+ {path='/logfiles/', method='GET'},
+ {path='/logger/', method='GET'},
+ {path='/logg/', method='GET'},
+ {path='/logging/', method='GET'},
+ {path='/logon/', method='GET'},
+ {path='/logout/', method='GET'},
+ {path='/lost+found/', method='GET'},
+ {path='/mailman/', method='GET'},
+ {path='/mailroot/', method='GET'},
+ {path='/makefile/', method='GET'},
+ {path='/manage/', method='GET'},
+ {path='/management/', method='GET'},
+ {path='/manager/', method='GET'},
+ {path='/man/', method='GET'},
+ {path='/manual/', method='GET'},
+ {path='/map/', method='GET'},
+ {path='/maps/', method='GET'},
+ {path='/marketing/', method='GET'},
+ {path='/member/', method='GET'},
+ {path='/members/', method='GET'},
+ {path='/mem_bin/', method='GET'},
+ {path='/mem/', method='GET'},
+ {path='/message/', method='GET'},
+ {path='/messaging/', method='GET'},
+ {path='/metacart/', method='GET'},
+ {path='/microsoft/', method='GET'},
+ {path='/misc/', method='GET'},
+ {path='/mkstats/', method='GET'},
+ {path='/mod/', method='GET'},
+ {path='/module/', method='GET'},
+ {path='/modules/', method='GET'},
+ {path='/movimientos/', method='GET'},
+ {path='/mpcgi/', method='GET'},
+ {path='/mqseries/', method='GET'},
+ {path='/msfpe/', method='GET'},
+ {path='/ms/', method='GET'},
+ {path='/msql/', method='GET'},
+ {path='/Msword/', method='GET'},
+ {path='/mxhtml/', method='GET'},
+ {path='/mxportal/', method='GET'},
+ {path='/my/', method='GET'},
+ {path='/My Shared Folder/', method='GET'},
+ {path='/mysql_admin/', method='GET'},
+ {path='/mysql/', method='GET'},
+ {path='/name/', method='GET'},
+ {path='/names/', method='GET'},
+ {path='/ncadmin/', method='GET'},
+ {path='/nchelp/', method='GET'},
+ {path='/netbasic/', method='GET'},
+ {path='/netcat/', method='GET'},
+ {path='/NetDynamic/', method='GET'},
+ {path='/NetDynamics/', method='GET'},
+ {path='/net/', method='GET'},
+ {path='/netmagstats/', method='GET'},
+ {path='/netscape/', method='GET'},
+ {path='/netshare/', method='GET'},
+ {path='/nettracker/', method='GET'},
+ {path='/network/', method='GET'},
+ {path='/new/', method='GET'},
+ {path='/news/', method='GET'},
+ {path='/News/', method='GET'},
+ {path='/nextgeneration/', method='GET'},
+ {path='/nl/', method='GET'},
+ {path='/notes/', method='GET'},
+ {path='/noticias/', method='GET'},
+ {path='/NSearch/', method='GET'},
+ {path='/objects/', method='GET'},
+ {path='/odbc/', method='GET'},
+ {path='/officescan/', method='GET'},
+ {path='/ojspdemos/', method='GET'},
+ {path='/old_files/', method='GET'},
+ {path='/oldfiles/', method='GET'},
+ {path='/old/', method='GET'},
+ {path='/oprocmgr-service/', method='GET'},
+ {path='/oprocmgr-status/', method='GET'},
+ {path='/oracle/', method='GET'},
+ {path='/oradata/', method='GET'},
+ {path='/order/', method='GET'},
+ {path='/orders/', method='GET'},
+ {path='/os/', method='GET'},
+ {path='/out/', method='GET'},
+ {path='/outgoing/', method='GET'},
+ {path='/owners/', method='GET'},
+ {path='/ows-bin/', method='GET'},
+ {path='/page/', method='GET'},
+ {path='/_pages/', method='GET'},
+ {path='/pages/', method='GET'},
+ {path='/partner/', method='GET'},
+ {path='/partners/', method='GET'},
+ {path='/passport/', method='GET'},
+ {path='/password/', method='GET'},
+ {path='/passwords/', method='GET'},
+ {path='/path/', method='GET'},
+ {path='/payment/', method='GET'},
+ {path='/payments/', method='GET'},
+ {path='/pccsmysqladm/', method='GET'},
+ {path='/PDG_Cart/', method='GET'},
+ {path='/perl5/', method='GET'},
+ {path='/perl/', method='GET'},
+ {path='/personal/', method='GET'},
+ {path='/pforum/', method='GET'},
+ {path='/phorum/', method='GET'},
+ {path='/phpBB/', method='GET'},
+ {path='/php_classes/', method='GET'},
+ {path='/phpclassifieds/', method='GET'},
+ {path='/php/', method='GET'},
+ {path='/phpimageview/', method='GET'},
+ {path='/phpnuke/', method='GET'},
+ {path='/phpPhotoAlbum/', method='GET'},
+ {path='/phpprojekt/', method='GET'},
+ {path='/phpSecurePages/', method='GET'},
+ {path='/pics/', method='GET'},
+ {path='/pictures/', method='GET'},
+ {path='/pike/', method='GET'},
+ {path='/piranha/', method='GET'},
+ {path='/pls/', method='GET'},
+ {path='/plsql/', method='GET'},
+ {path='/plssampleadmin_/', method='GET'},
+ {path='/plssampleadmin/', method='GET'},
+ {path='/plssampleadmin_help/', method='GET'},
+ {path='/plssample/', method='GET'},
+ {path='/poll/', method='GET'},
+ {path='/polls/', method='GET'},
+ {path='/porn/', method='GET'},
+ {path='/portal/', method='GET'},
+ {path='/portals/', method='GET'},
+ {path='/postgres/', method='GET'},
+ {path='/postnuke/', method='GET'},
+ {path='/ppwb/', method='GET'},
+ {path='/printer/', method='GET'},
+ {path='/printers/', method='GET'},
+ {path='/privacy/', method='GET'},
+ {path='/privado/', method='GET'},
+ {path='/_private/', method='GET'},
+ {path='/private/', method='GET'},
+ {path='/priv/', method='GET'},
+ {path='/prod/', method='GET'},
+ {path='/projectserver/', method='GET'},
+ {path='/protected/', method='GET'},
+ {path='/proxy/', method='GET'},
+ {path='/prueba/', method='GET'},
+ {path='/pruebas/', method='GET'},
+ {path='/prv/', method='GET'},
+ {path='/pub/', method='GET'},
+ {path='/_public/', method='GET'},
+ {path='/public/', method='GET'},
+ {path='/publica/', method='GET'},
+ {path='/publicar/', method='GET'},
+ {path='/publico/', method='GET'},
+ {path='/publish/', method='GET'},
+ {path='/purchase/', method='GET'},
+ {path='/purchases/', method='GET'},
+ {path='/pw/', method='GET'},
+ {path='/python/', method='GET'},
+ {path='/random_banner/', method='GET'},
+ {path='/rdp/', method='GET'},
+ {path='/Readme/', method='GET'},
+ {path='/recycler/', method='GET'},
+ {path='/registered/', method='GET'},
+ {path='/register/', method='GET'},
+ {path='/registry/', method='GET'},
+ {path='/remote/', method='GET'},
+ {path='/remove/', method='GET'},
+ {path='/report/', method='GET'},
+ {path='/reports/', method='GET'},
+ {path='/reseller/', method='GET'},
+ {path='/restricted/', method='GET'},
+ {path='/retail/', method='GET'},
+ {path='/reveal/', method='GET'},
+ {path='/reviews/', method='GET'},
+ {path='/ROADS/', method='GET'},
+ {path='/robot/', method='GET'},
+ {path='/robots/', method='GET'},
+ {path='/root/', method='GET'},
+ {path='/rsrc/', method='GET'},
+ {path='/ruby/', method='GET'},
+ {path='/sales/', method='GET'},
+ {path='/save/', method='GET'},
+ {path='/script/', method='GET'},
+ {path='/ScriptLibrary/', method='GET'},
+ {path='/scripts/', method='GET'},
+ {path='/search/', method='GET'},
+ {path='/search-ui/', method='GET'},
+ {path='/sec/', method='GET'},
+ {path='/secret/', method='GET'},
+ {path='/secured/', method='GET'},
+ {path='/secure/', method='GET'},
+ {path='/security/', method='GET'},
+ {path='/sell/', method='GET'},
+ {path='/server/', method='GET'},
+ {path='/server-info/', method='GET'},
+ {path='/servers/', method='GET'},
+ {path='/server_stats/', method='GET'},
+ {path='/serverstats/', method='GET'},
+ {path='/server-status/', method='GET'},
+ {path='/service/', method='GET'},
+ {path='/services/', method='GET'},
+ {path='/servicio/', method='GET'},
+ {path='/servicios/', method='GET'},
+ {path='/servlet/', method='GET'},
+ {path='/servlets/', method='GET'},
+ {path='/session/', method='GET'},
+ {path='/setup/', method='GET'},
+ {path='/shared/', method='GET'},
+ {path='/sharedtemplates/', method='GET'},
+ {path='/share/', method='GET'},
+ {path='/shell-cgi/', method='GET'},
+ {path='/shipping/', method='GET'},
+ {path='/shop/', method='GET'},
+ {path='/shopper/', method='GET'},
+ {path='/show/', method='GET'},
+ {path='/SilverStream/', method='GET'},
+ {path='/siteadmin/', method='GET'},
+ {path='/site/', method='GET'},
+ {path='/sitemgr/', method='GET'},
+ {path='/siteminderagent/', method='GET'},
+ {path='/siteminder/', method='GET'},
+ {path='/siteserver/', method='GET'},
+ {path='/sites/', method='GET'},
+ {path='/sitestats/', method='GET'},
+ {path='/siteupdate/', method='GET'},
+ {path='/smreports/', method='GET'},
+ {path='/smreportsviewer/', method='GET'},
+ {path='/soapdocs/', method='GET'},
+ {path='/soap/', method='GET'},
+ {path='/software/', method='GET'},
+ {path='/solaris/', method='GET'},
+ {path='/source/', method='GET'},
+ {path='/sql/', method='GET'},
+ {path='/squid/', method='GET'},
+ {path='/src/', method='GET'},
+ {path='/srchadm/', method='GET'},
+ {path='/ssi/', method='GET'},
+ {path='/ssl/', method='GET'},
+ {path='/sslkeys/', method='GET'},
+ {path='/staff/', method='GET'},
+ {path='/state/', method='GET'},
+ {path='/stat/', method='GET'},
+ {path='/statistic/', method='GET'},
+ {path='/statistics/', method='GET'},
+ {path='/stats-bin-p/', method='GET'},
+ {path='/stats/', method='GET'},
+ {path='/stats_old/', method='GET'},
+ {path='/status/', method='GET'},
+ {path='/storage/', method='GET'},
+ {path='/StoreDB/', method='GET'},
+ {path='/store/', method='GET'},
+ {path='/storemgr/', method='GET'},
+ {path='/stronghold-info/', method='GET'},
+ {path='/stronghold-status/', method='GET'},
+ {path='/stuff/', method='GET'},
+ {path='/style/', method='GET'},
+ {path='/styles/', method='GET'},
+ {path='/stylesheet/', method='GET'},
+ {path='/stylesheets/', method='GET'},
+ {path='/subir/', method='GET'},
+ {path='/sun/', method='GET'},
+ {path='/super_stats/', method='GET'},
+ {path='/supplier/', method='GET'},
+ {path='/suppliers/', method='GET'},
+ {path='/supply/', method='GET'},
+ {path='/supporter/', method='GET'},
+ {path='/support/', method='GET'},
+ {path='/sysadmin/', method='GET'},
+ {path='/sysbackup/', method='GET'},
+ {path='/sys/', method='GET'},
+ {path='/system/', method='GET'},
+ {path='/systems/', method='GET'},
+ {path='/tar/', method='GET'},
+ {path='/target/', method='GET'},
+ {path='/tarjetas/', method='GET'},
+ {path='/tech/', method='GET'},
+ {path='/technote/', method='GET'},
+ {path='/te_html/', method='GET'},
+ {path='/temp/', method='GET'},
+ {path='/template/', method='GET'},
+ {path='/templates/', method='GET'},
+ {path='/temporal/', method='GET'},
+ {path='/test-cgi/', method='GET'},
+ {path='/testing/', method='GET'},
+ {path='/tests/', method='GET'},
+ {path='/testweb/', method='GET'},
+ {path='/themes/', method='GET'},
+ {path='/ticket/', method='GET'},
+ {path='/tickets/', method='GET'},
+ {path='/tip/', method='GET'},
+ {path='/tips/', method='GET'},
+ {path='/tmp/', method='GET'},
+ {path='/ToDo/', method='GET'},
+ {path='/tool/', method='GET'},
+ {path='/tools/', method='GET'},
+ {path='/TopAccess/', method='GET'},
+ {path='/top/', method='GET'},
+ {path='/tpv/', method='GET'},
+ {path='/trabajo/', method='GET'},
+ {path='/track/', method='GET'},
+ {path='/tracking/', method='GET'},
+ {path='/transfer/', method='GET'},
+ {path='/transito/', method='GET'},
+ {path='/transpolar/', method='GET'},
+ {path='/tree/', method='GET'},
+ {path='/trees/', method='GET'},
+ {path='/trick/', method='GET'},
+ {path='/tricks/', method='GET'},
+ {path='/u02/', method='GET'},
+ {path='/unix/', method='GET'},
+ {path='/unknown/', method='GET'},
+ {path='/updates/', method='GET'},
+ {path='/upload/', method='GET'},
+ {path='/uploads/', method='GET'},
+ {path='/usage/', method='GET'},
+ {path='/userdb/', method='GET'},
+ {path='/user/', method='GET'},
+ {path='/users/', method='GET'},
+ {path='/us/', method='GET'},
+ {path='/usr/', method='GET'},
+ {path='/ustats/', method='GET'},
+ {path='/usuario/', method='GET'},
+ {path='/usuarios/', method='GET'},
+ {path='/util/', method='GET'},
+ {path='/utils/', method='GET'},
+ {path='/vendor/', method='GET'},
+ {path='/vfs/', method='GET'},
+ {path='/view/', method='GET'},
+ {path='/vpn/', method='GET'},
+ {path='/vti_txt/', method='GET'},
+ {path='/w2000/', method='GET'},
+ {path='/w2k/', method='GET'},
+ {path='/w3perl/', method='GET'},
+ {path='/w-agora/', method='GET'},
+ {path='/way-board/', method='GET'},
+ {path='/web800fo/', method='GET'},
+ {path='/webaccess/', method='GET'},
+ {path='/webadmin/', method='GET'},
+ {path='/webAdmin/', method='GET'},
+ {path='/webalizer/', method='GET'},
+ {path='/webapps/', method='GET'},
+ {path='/WebBank/', method='GET'},
+ {path='/webboard/', method='GET'},
+ {path='/WebCalendar/', method='GET'},
+ {path='/webcart/', method='GET'},
+ {path='/webcart-lite/', method='GET'},
+ {path='/webcgi/', method='GET'},
+ {path='/webdata/', method='GET'},
+ {path='/webdav/', method='GET'},
+ {path='/webdb/', method='GET'},
+ {path='/webDB/', method='GET'},
+ {path='/web/', method='GET'},
+ {path='/webimages2/', method='GET'},
+ {path='/webimages/', method='GET'},
+ {path='/web-inf/', method='GET'},
+ {path='/webmaster/', method='GET'},
+ {path='/webmaster_logs/', method='GET'},
+ {path='/webMathematica/', method='GET'},
+ {path='/webpub/', method='GET'},
+ {path='/webpub-ui/', method='GET'},
+ {path='/webreports/', method='GET'},
+ {path='/webreps/', method='GET'},
+ {path='/webshare/', method='GET'},
+ {path='/WebShop/', method='GET'},
+ {path='/website/', method='GET'},
+ {path='/webstat/', method='GET'},
+ {path='/webstats/', method='GET'},
+ {path='/Web_store/', method='GET'},
+ {path='/webtrace/', method='GET'},
+ {path='/WebTrend/', method='GET'},
+ {path='/webtrends/', method='GET'},
+ {path='/web_usage/', method='GET'},
+ {path='/win2k/', method='GET'},
+ {path='/window/', method='GET'},
+ {path='/windows/', method='GET'},
+ {path='/win/', method='GET'},
+ {path='/winnt/', method='GET'},
+ {path='/word/', method='GET'},
+ {path='/work/', method='GET'},
+ {path='/world/', method='GET'},
+ {path='/wsdocs/', method='GET'},
+ {path='/WS_FTP/', method='GET'},
+ {path='/wstats/', method='GET'},
+ {path='/wusage/', method='GET'},
+ {path='/www0/', method='GET'},
+ {path='/www2/', method='GET'},
+ {path='/www3/', method='GET'},
+ {path='/www4/', method='GET'},
+ {path='/www/', method='GET'},
+ {path='/wwwjoin/', method='GET'},
+ {path='/wwwrooot/', method='GET'},
+ {path='/www-sql/', method='GET'},
+ {path='/wwwstat/', method='GET'},
+ {path='/wwwstats/', method='GET'},
+ {path='/xGB/', method='GET'},
+ {path='/xml/', method='GET'},
+ {path='/XSL/', method='GET'},
+ {path='/xtemp/', method='GET'},
+ {path='/xymon/', method='GET'},
+ {path='/zb41/', method='GET'},
+ {path='/zipfiles/', method='GET'},
+ {path='/zip/', method='GET'}
+ },
+ matches={
+ {match='Index of .*(Apache.*) Server at', output='Potentially interesting directory w/ listing on \'\\1\''},
+ {match='Index of', output='Potentially interesting folder w/ directory listing'},
+ {match='', output='Potentially interesting folder'}
+ }
+})
+
diff --git a/nselib/data/http-folders.txt b/nselib/data/http-folders.txt
new file mode 100644
index 000000000..996cc4898
--- /dev/null
+++ b/nselib/data/http-folders.txt
@@ -0,0 +1,954 @@
+/1/
+/2/
+/3/
+/4/
+/5/
+/6/
+/7/
+/8/
+/9/
+/10/
+/a/
+/acceso/
+/access/
+/accesswatch/
+/acciones/
+/account/
+/accounting/
+/active/
+/activex/
+/adm/
+/admcgi/
+/admentor/
+/admin/
+/admin/
+/admin_/
+/admin.back/
+/admin-bak/
+/Admin_files/
+/administration/
+/administrator/
+/admin-old/
+/adminuser/
+/adminweb/
+/adminWeb/
+/admisapi/
+/AdvWebAdmin/
+/Agent/
+/agentes/
+/Agents/
+/Album/
+/AlbumArt/
+/AlbumArt_/
+/allow/
+/analog/
+/anthill/
+/apache/
+/app/
+/appl/
+/applets/
+/application/
+/applications/
+/applmgr/
+/apply/
+/apps/
+/appsec/
+/ar/
+/archive/
+/archive/
+/archives/
+/arcsight/
+/asa/
+/asp/
+/atc/
+/atom/
+/aut/
+/auth/
+/authadmin/
+/author/
+/authors/
+/aw/
+/ayuda/
+/b/
+/b2-include/
+/back/
+/backend/
+/backup/
+/backup/
+/backups/
+/bad/
+/bak/
+/bak/
+/banca/
+/banco/
+/bank/
+/banner/
+/banner01/
+/banners/
+/bar/
+/batch/
+/bb-dnbd/
+/bbv/
+/bdata/
+/bdatos/
+/beef/
+/beta/
+/beta/
+/billpay/
+/bin/
+/bin/
+/bin/
+/binaries/
+/binary/
+/blog/
+/boadmin/
+/boot/
+/bottom/
+/browse/
+/browser/
+/bsd/
+/btauxdir/
+/bug/
+/bugs/
+/bugzilla/
+/buy/
+/buynow/
+/c/
+/cache/
+/cached/
+/cache-stats/
+/caja/
+/card/
+/cards/
+/cart/
+/cash/
+/caspsamp/
+/catalog/
+/cbi-bin/
+/ccard/
+/ccards/
+/cd/
+/cd-cgi/
+/cdrom/
+/ce_html/
+/cert/
+/certificado/
+/certificate/
+/cfappman/
+/cfdocs/
+/cfide/
+/cgi/
+/cgi/
+/cgi-914/
+/cgi-915/
+/cgi-auth/
+/cgibin/
+/cgibin/
+/cgi-bin/
+/cgi-bin/
+/cgi-bin/
+/cgi-bin2/
+/cgi.cgi/
+/cgi-csc/
+/cgi-exe/
+/cgi-home/
+/cgilib/
+/cgi-lib/
+/cgi-local/
+/cgi-local/
+/cgi-perl/
+/cgis/
+/cgis/
+/cgiscripts/
+/cgi-scripts/
+/cgi-shl/
+/cgi-shop/
+/cgi-sys/
+/cgi-sys/
+/cgi-weddico/
+/cgiwin/
+/cgi-win/
+/cgi-win/
+/Citrix/
+/class/
+/classes/
+/classes/
+/client/
+/cliente/
+/clientes/
+/clients/
+/cm/
+/cmsample/
+/cobalt-images/
+/code/
+/com/
+/comments/
+/common/
+/communicator/
+/comp/
+/company/
+/compra/
+/compras/
+/compressed/
+/conecta/
+/conf/
+/config/
+/config/
+/configs/
+/configure/
+/connect/
+/console/
+/contact/
+/contacts/
+/content/
+/content.ie5/
+/controlpanel/
+/core/
+/corp/
+/correo/
+/counter/
+/credit/
+/cron/
+/crons/
+/crypto/
+/CS/
+/csr/
+/css/
+/css/
+/cuenta/
+/cuentas/
+/currency/
+/cust/
+/custom/
+/customer/
+/customers/
+/CVS/
+/cvsweb/
+/cybercash/
+/d/
+/darkportal/
+/dat/
+/data/
+/data/
+/database/
+/databases/
+/datafiles/
+/dato/
+/datos/
+/db/
+/db/
+/dbase/
+/dcforum/
+/ddreport/
+/ddrint/
+/debug/
+/debugs/
+/default/
+/delete/
+/deleted/
+/demo/
+/demo/
+/demoauct/
+/demomall/
+/demos/
+/demouser/
+/deny/
+/derived/
+/design/
+/dev/
+/dev/
+/devel/
+/development/
+/dir/
+/directories/
+/directory/
+/directorymanager/
+/dl/
+/dm/
+/DMR/
+/dms/
+/dms0/
+/dmsdump/
+/dnn/
+/doc/
+/doc1/
+/doc-html/
+/docs/
+/docs1/
+/DocuColor/
+/document/
+/documentation/
+/documents/
+/dotnetnuke/
+/down/
+/download/
+/downloads/
+/downloads/
+/dump/
+/durep/
+/e/
+/easylog/
+/eforum/
+/ejemplo/
+/ejemplos/
+/email/
+/emailclass/
+/employees/
+/empoyees/
+/empris/
+/enter/
+/envia/
+/enviamail/
+/error/
+/errors/
+/es/
+/estmt/
+/etc/
+/etcpasswd/
+/example/
+/examples/
+/exc/
+/excel/
+/exchange/
+/exchweb/
+/exe/
+/exec/
+/exit/
+/export/
+/external/
+/extranet/
+/f/
+/failure/
+/fbsd/
+/fcgi/
+/fcgi-bin/
+/fcgi-bin/
+/features/
+/file/
+/fileadmin/
+/filemanager/
+/files/
+/find/
+/flash/
+/foldoc/
+/foo/
+/foobar/
+/form/
+/forms/
+/formsmgr/
+/form-totaller/
+/forum/
+/forum/
+/forum/
+/forums/
+/forums/
+/foto/
+/fotos/
+/fpadmin/
+/fpclass/
+/fpdb/
+/fpe/
+/fpsample/
+/frames/
+/framesets/
+/frontpage/
+/ftp/
+/ftproot/
+/fun/
+/func/
+/function/
+/functions/
+/g/
+/general/
+/gfx/
+/gif/
+/gifs/
+/global/
+/globals/
+/good/
+/graphics/
+/grocery/
+/guest/
+/guestbook/
+/guests/
+/GXApp/
+/h/
+/HB/
+/HBTemplates/
+/help/
+/helpdesk/
+/hidden/
+/hide/
+/hitmatic/
+/hit_tracker/
+/hlstats/
+/home/
+/host/
+/hosted/
+/hosting/
+/hostingcontroller/
+/hp/
+/ht/
+/htbin/
+/htbin/
+/htdocs/
+/htm/
+/html/
+/http/
+/https/
+/hyperstat/
+/I/
+/i18n/
+/ibank/
+/ibill/
+/IBMWebAS/
+/icons/
+/icons/
+/idea/
+/ideas/
+/iisadmin/
+/iissamples/
+/iissamples/
+/image/
+/imagenes/
+/imagery/
+/images/
+/images/
+/img/
+/imp/
+/import/
+/impreso/
+/in/
+/inc/
+/include/
+/includes/
+/includes/
+/incoming/
+/incoming/
+/index/
+/inet/
+/inf/
+/info/
+/information/
+/ingresa/
+/ingreso/
+/install/
+/install/
+/internal/
+/internet/
+/intranet/
+/intranet/
+/intranet/
+/inventory/
+/invitado/
+/isapi/
+/j/
+/j2ee/
+/j2eeexamples/
+/j2eeexamplesjsp/
+/japidoc/
+/java/
+/javascript/
+/javasdk/
+/javatest/
+/jave/
+/JBookIt/
+/jdbc/
+/job/
+/jrun/
+/js/
+/jsa/
+/jscript/
+/jserv/
+/jslib/
+/jsp/
+/junk/
+/k/
+/kiva/
+/known/
+/l/
+/labs/
+/lcgi/
+/lib/
+/libraries/
+/library/
+/libro/
+/license/
+/licenses/
+/links/
+/linux/
+/loader/
+/local/
+/location/
+/locations/
+/log/
+/logfile/
+/logfiles/
+/logg/
+/logger/
+/logger/
+/logging/
+/login/
+/login/
+/logon/
+/logout/
+/logs/
+/logs/
+/lost+found/
+/m/
+/mail/
+/mail/
+/mail_log_files/
+/mailman/
+/mailroot/
+/makefile/
+/mall_log_files/
+/man/
+/manage/
+/management/
+/manager/
+/manual/
+/manual/
+/map/
+/maps/
+/marketing/
+/mediawiki/
+/mem/
+/member/
+/member/
+/members/
+/members/
+/mem_bin/
+/message/
+/messaging/
+/metacart/
+/microsoft/
+/misc/
+/mkstats/
+/mod/
+/module/
+/modules/
+/modules/
+/movimientos/
+/mpcgi/
+/mqseries/
+/ms/
+/msfpe/
+/msql/
+/Msword/
+/mxhtml/
+/mxportal/
+/my/
+/My Shared Folder/
+/mysql/
+/mysql_admin/
+/n/
+/name/
+/names/
+/ncadmin/
+/nchelp/
+/ncsample/
+/net/
+/netbasic/
+/netcat/
+/NetDynamic/
+/NetDynamics/
+/netmagstats/
+/netscape/
+/netshare/
+/nettracker/
+/network/
+/network/
+/new/
+/news/
+/News/
+/nextgeneration/
+/nl/
+/notes/
+/noticias/
+/NSearch/
+/o/
+/objects/
+/odbc/
+/officescan/
+/ojspdemos/
+/old/
+/oldfiles/
+/old_files/
+/oprocmgr-service/
+/oprocmgr-status/
+/oracle/
+/oradata/
+/order/
+/orders/
+/os/
+/out/
+/outgoing/
+/owa/
+/owners/
+/ows-bin/
+/p/
+/page/
+/pages/
+/_pages/
+/partner/
+/partners/
+/passport/
+/password/
+/passwords/
+/path/
+/payment/
+/payments/
+/pccsmysqladm/
+/PDG_Cart/
+/perl/
+/perl5/
+/personal/
+/pforum/
+/phorum/
+/php/
+/phpBB/
+/phpBB/
+/php_classes/
+/phpclassifieds/
+/phpimageview/
+/phpmyadmin/
+/phpmyadmin/
+/phpMyAdmin/
+/phpMyAdmin/
+/phpMyAdmin/
+/phpnuke/
+/phpPhotoAlbum/
+/phpprojekt/
+/phpSecurePages/
+/pics/
+/pictures/
+/pike/
+/piranha/
+/pls/
+/pls/
+/plsql/
+/plssample/
+/plssampleadmin/
+/plssampleadmin_/
+/plssampleadmin_help/
+/poll/
+/polls/
+/porn/
+/portal/
+/portals/
+/postgres/
+/postnuke/
+/ppwb/
+/printer/
+/printers/
+/priv/
+/privacy/
+/privado/
+/private/
+/private/
+/_private/
+/prod/
+/projectserver/
+/protected/
+/protected/
+/proxy/
+/prueba/
+/pruebas/
+/prv/
+/pub/
+/pub/
+/public/
+/public/
+/_public/
+/publica/
+/publicar/
+/publico/
+/publish/
+/purchase/
+/purchases/
+/pw/
+/python/
+/q/
+/r/
+/random_banner/
+/rdp/
+/Readme/
+/recycler/
+/register/
+/registered/
+/registry/
+/remote/
+/remove/
+/report/
+/reports/
+/reseller/
+/restricted/
+/restricted/
+/retail/
+/reveal/
+/reviews/
+/ROADS/
+/robot/
+/robots/
+/root/
+/rsrc/
+/rss/
+/ruby/
+/s/
+/sales/
+/sample/
+/samples/
+/save/
+/script/
+/ScriptLibrary/
+/scripts/
+/scripts/
+/search/
+/search-ui/
+/sec/
+/secret/
+/secure/
+/secure/
+/secured/
+/security/
+/sell/
+/server/
+/server-info/
+/servers/
+/serverstats/
+/server_stats/
+/server-status/
+/service/
+/services/
+/servicio/
+/servicios/
+/servlet/
+/servlets/
+/session/
+/setup/
+/share/
+/shared/
+/sharedtemplates/
+/shell-cgi/
+/shipping/
+/shop/
+/shopper/
+/show/
+/SilverStream/
+/site/
+/siteadmin/
+/sitemgr/
+/siteminder/
+/siteminderagent/
+/sites/
+/siteserver/
+/sitestats/
+/siteupdate/
+/smreports/
+/smreportsviewer/
+/soap/
+/soapdocs/
+/software/
+/solaris/
+/source/
+/sql/
+/squid/
+/src/
+/srchadm/
+/ssi/
+/ssl/
+/sslkeys/
+/staff/
+/stat/
+/state/
+/statistic/
+/statistics/
+/stats/
+/stats-bin-p/
+/stats_old/
+/status/
+/storage/
+/store/
+/StoreDB/
+/storemgr/
+/stronghold-info/
+/stronghold-status/
+/stuff/
+/style/
+/styles/
+/stylesheet/
+/stylesheets/
+/subir/
+/sun/
+/super_stats/
+/supplier/
+/suppliers/
+/supply/
+/support/
+/supporter/
+/.svn/
+/sys/
+/sysadmin/
+/sysbackup/
+/system/
+/systems/
+/t/
+/tar/
+/target/
+/tarjetas/
+/tech/
+/technote/
+/te_html/
+/temp/
+/template/
+/templates/
+/temporal/
+/test/
+/test/
+/test-cgi/
+/testing/
+/tests/
+/testweb/
+/themes/
+/ticket/
+/tickets/
+/tip/
+/tips/
+/tmp/
+/tmp/
+/ToDo/
+/tool/
+/tools/
+/top/
+/TopAccess/
+/tpv/
+/trabajo/
+/track/
+/tracking/
+/transfer/
+/transito/
+/transpolar/
+/tree/
+/trees/
+/trick/
+/tricks/
+/u/
+/u02/
+/ui/
+/unix/
+/unknown/
+/updates/
+/upload/
+/uploads/
+/us/
+/usage/
+/user/
+/userdb/
+/users/
+/usr/
+/ustats/
+/usuario/
+/usuarios/
+/util/
+/utils/
+/v/
+/vendor/
+/vfs/
+/view/
+/vmware/
+/vpn/
+/_vti_bin/
+/vti_bin/
+/vti_bot/
+/_vti_cnf/
+/_vti_log/
+/vti_log/
+/_vti_pvt/
+/vti_pvt/
+/vti_shm/
+/_vti_txt/
+/vti_txt/
+/w/
+/w2000/
+/w2k/
+/w3perl/
+/w-agora/
+/way-board/
+/web/
+/web800fo/
+/webaccess/
+/webadmin/
+/webadmin/
+/webAdmin/
+/webalizer/
+/webapps/
+/WebBank/
+/webboard/
+/WebCalendar/
+/webcart/
+/webcart-lite/
+/webcgi/
+/webdata/
+/webdav/
+/webdb/
+/webDB/
+/webimages/
+/webimages2/
+/web-inf/
+/weblog/
+/weblogs/
+/webmail/
+/webmaster/
+/webmaster_logs/
+/webMathematica/
+/webpub/
+/webpub-ui/
+/webreports/
+/webreps/
+/webshare/
+/WebShop/
+/website/
+/webstat/
+/webstats/
+/Web_store/
+/webtrace/
+/WebTrend/
+/webtrends/
+/web_usage/
+/wiki/
+/win/
+/win2k/
+/window/
+/windows/
+/winnt/
+/word/
+/wordpress/
+/work/
+/world/
+/wsdocs/
+/WS_FTP/
+/wstats/
+/wusage/
+/www/
+/www0/
+/www2/
+/www3/
+/www4/
+/wwwjoin/
+/wwwlog/
+/wwwrooot/
+/www-sql/
+/wwwstat/
+/wwwstats/
+/x/
+/xGB/
+/xml/
+/XSL/
+/xtemp/
+/xymon/
+/y/
+/z/
+/zb41/
+/zip/
+/zipfiles/
diff --git a/nselib/data/yokoso-fingerprints b/nselib/data/yokoso-fingerprints
deleted file mode 100644
index f5cb715d4..000000000
--- a/nselib/data/yokoso-fingerprints
+++ /dev/null
@@ -1,253 +0,0 @@
-# Yokoso! Fingerprints v. 0.1
-######################################################
-#
-# The following list is the actual fingerprint file
-# for Yokoso!. It is designed to be used within your
-# scripts. All lines that do not begin with a # are
-# the URI fingerprints.
-#
-#
-# Included in the Nmap release under the Nmap license with permission from
-# Kevin Johnson.
-# See: http://seclists.org/nmap-dev/2009/q3/0685.html
-
-# HP Integrated Lights Out
-# Pre-Auth
-/ilo.gif
-
-# Post-Auth
-/ie_index.htm
-
-# MS Project Server
-# Pre-Auth
-/projectserver/images/branding.gif
-/projectserver/images/pgHome.gif
-/projectserver/images/pgTask.gif
-
-# Post-Auth
-/projectserver/Tasks/Taskspage.asp
-/projectserver/Home/HomePage.asp
-
-# Citrix WebTop
-# Pre-Auth
-/sw/auth/login.aspx
-/images/ctxHeader01.jpg
-/images/Safeword_Token.jpg
-
-# Outlook Web Access
-# Pre-Auth
-/images/outlook.jpg
-/exchweb/bin/auth/owalogon.asp
-/owa/8.1.375.2/themes/base/lgntopl.gif
-
-# MS Sharepoint
-/_layouts/images/helpicon.gif
-/PublishingImages/NewsArticleImage.jpg
-/Pages/Default.aspx
-
-# HP Insight Manager
-/mxhtml/images/signin_logo.gif
-/mxportal/home/MxPortalFrames.jsp
-/mxhtml/images/status_critical_15.gif
-/mxportal/home/en_US/servicetools.gif
-
-# Virtual Center
-/client/VMware-viclient.exe
-/ui/
-/vmware/imx/vmware_boxes-16x16.png
-
-# TopAccess Toshiba e-Studio520
-/Default?MAIN=DEVICE
-/TopAccess/images/RioGrande/Rio_PPC.gif
-
-# Lexmark T632
-/printer/image
-/images/lexbold.gif
-
-# Lexmark C772
-/images/lexlogo.gif
-/images/printer.gif
-
-# HP Blade Enclosure
-/images/icon_server_connected.gif
-
-# HP System Management Homepage v2.0.2.106
-/cpqlogin.htm?RedirectUrl=/&RedirectQueryString=
-/hplogo.gif
-
-# Cisco SDM
-/archive/flash:home/html/images/Cisco_logo.gif
-
-# netForensics
-/nfdesktop.jnlp
-/nfservlets/servlet/SPSRouterServlet/
-/jwsappmngr.jnlp
-# Cisco SDM
-/archive/flash:home/html/images/Cisco_logo.gif
-
-# netForensics
-/nfdesktop.jnlp
-/nfservlets/servlet/SPSRouterServlet/
-/jwsappmngr.jnlp
-
-# Secunia NSI
-# Pre-Auth
-/gfx/new_logo.gif
-/gfx/form_top_left_corner.gif
-/javascript/sorttable.js
-
-# Post-Auth
-/gfx/logout_24.png
-
-
-# Foundstone Enterprise
-# Pre-Auth
-/i18n/EN/css/foundstone.css
-
-# Post-Auth
-/i18n/EN/images/external_nav_square.gif
-
-
-# Trend Micro OfficeScan Server
-# Pre-Auth
-/officescan/console/html/cgi/cgiChkMasterPwd.exe
-
-# Post-Auth
-/officescan/console/html/images/icon_refresh.gif
-
-
-# Trend Micro OfficeScan Server Client Install
-/officescan/console/html/ClientInstall/officescannt.htm
-
-
-# ArcSight Collector Appliance
-# Pre-Auth
-/images/logo-arcsight.gif
-
-# Post-Auth
-/logger/monitor.ftl
-
-
-# ArcSight Web
-# Pre-Auth
-/arcsight/images/logo-login-arcsight.gif
-
-# Post-Auth
-/arcsight/images/navbar-icon-logout-on.gif
-
-# BlueCoat Reporter
-# Pre-Auth
-/picts/BC_bwlogorev.gif
-
-# Post-Auth
-/picts/menu_leaf.gif
-
-
-# IBM Proventia Deployment Manager (SiteProtector)
-/images/isslogo.gif
-/deploymentmanager/
-
-
-# IBM Proventia Manager
-/spControl.php
-
-# IBM Proventia GX4002
-/images/hdr_icon_homeG.gif
-/images/btn_help_nml.gif
-
-
-# VMware Virtual Infrastructure Web Access
-# Pre-Auth
-/ui/imx/vmwareLogo-16x16.png
-/en/welcomeRes.js
-
-# Post-Auth
-/ui/vManage.do
-/ui/imx/vmwarePaperBagLogo-16x16.png
-
-
-# HP LaserJet Printer
-# Pre-Auth
-/hp/device/this.LCDispatcher
-
-
-# HP LaserJet 4000 series
-/PageSelector.class
-
-
-# HP DesignJet T1100ps 44in
-/hp/device/webAccess/index.htm
-
-
-# HP DesignJet 1055CM
-/gif/hp.gif
-/gif/printer.gif
-/gif/hp_invent_logo.gif
-
-# Xerox Phaser Printer
-/x_logo.gif
-
-
-# Citrix MetaFrame
-# Pre-Auth
-/Citrix/MetaFrame/auth/login.aspx
-
-
-# Citrix Access Gateway (VPN)
-# Pre-Auth
-/vpn/images/AccessGateway.ico
-
-
-# NEC Projector
-/images/pic_bri.gif
-/images/mute_alloff.gif
-
-
-# Fortinet VPN/firewall
-# Pre-Auth
-/theme/images/en/login1.gif
-
-
-# AXIS StorPoint CD100
-/config/public/usergrp.gif
-
-# AXIS StorPoint CD E100
-/pictures/buttons/file_view_mark.gif
-
-
-# SCAN Web 5.8 (webcam manager)
-/scanweb/images/scanwebtm.gif
-
-
-# Axis 212 PTZ Network Camera 4.40
-# Pre-Auth
-/view/index.shtml
-
-
-# TeraStation PRO RAID 0/1/5 Network Attached Storage
-# Pre-Auth
-/cgi-bin/image/shikaku2.png
-
-
-# Lotus Domino
-# Pre-Auth
-/homepage.nsf/homePage.gif?OpenImageResource
-/icons/ecblank.gif
-
-
-# NetworkAppliance NetApp Release 6.5.3P4
-# Pre-Auth
-/na_admin/styles/dfm.css
-
-# Xymon
-/xymon/menu/menu.css
-
-# BeEF Browser Exploitation Framework
-/beef/images/beef.gif
-
-# Raritan Remote Client
-/rrc.htm
-
-# Oracle Web Server
-/footer1.gif
-
diff --git a/nselib/http.lua b/nselib/http.lua
index 3ce3ab679..2decdd0cb 100644
--- a/nselib/http.lua
+++ b/nselib/http.lua
@@ -80,19 +80,9 @@ local function table_augment(to, from)
end
end
---- Get a suitable hostname string from the argument, which may be either a
--- string or a host table.
-local function get_hostname(host)
- if type(host) == "table" then
- return host.targetname or ( host.name ~= '' and host.name ) or host.ip
- else
- return host
- end
-end
-
--- Get a value suitable for the Host header field.
local function get_host_field(host, port)
- local hostname = get_hostname(host)
+ local hostname = stdnse.get_hostname(host)
local portno
if port == nil then
portno = 80
@@ -789,7 +779,7 @@ local function lookup_cache (method, host, port, path, options)
if type(port) == "table" then port = port.number end
- local key = get_hostname(host)..":"..port..":"..path;
+ local key = stdnse.get_hostname(host)..":"..port..":"..path;
local mutex = nmap.mutex(tostring(lookup_cache)..key);
local state = {
@@ -876,7 +866,7 @@ end
-- Return true if the given method requires a body in the request. In case no
-- body was supplied we must send "Content-Length: 0".
local function request_method_needs_content_length(method)
- return method == "POST"
+ return method == "POST"
end
-- For each of the following request functions, host may either be
@@ -940,8 +930,8 @@ local build_request = function(host, port, method, path, options)
mod_options.header["Content-Type"] = "application/x-www-form-urlencoded"
elseif options.content then
body = options.content
- elseif request_method_needs_content_length(method) then
- body = ""
+ elseif request_method_needs_content_length(method) then
+ body = ""
end
if body then
mod_options.header["Content-Length"] = #body
@@ -1136,6 +1126,32 @@ post = function( host, port, path, options, ignored, postdata )
return generic_request(host, port, "POST", path, mod_options)
end
+--- Builds a request to be used in a pipeline
+--
+-- @param host The host to query.
+-- @param port The port for the host.
+-- @param path The path of the resource.
+-- @param options A table of options, as with http.generic_request.
+-- @param ignored Ignored for backwards compatibility.
+-- @param allReqs A table with all the pipeline requests
+-- @param method The HTTP method (GET, POST, HEAD, etc)
+-- @return Table with the pipeline get requests (plus this new one)
+function addPipeline(host, port, path, options, ignored, allReqs, method)
+ allReqs = allReqs or {}
+ local mod_options = {
+ header = {
+ ["Connection"] = "keep-alive"
+ }
+ }
+ table_augment(mod_options, options or {})
+ -- This value is intended to be unpacked into arguments to build_request.
+ local object = { host, port, method, path, mod_options }
+ object.method = object[3]
+ object.options = object[5]
+ allReqs[#allReqs + 1] = object
+ return allReqs
+end
+
--- Builds a get request to be used in a pipeline request
--
-- @param host The host to query.
@@ -1146,19 +1162,7 @@ end
-- @param allReqs A table with all the pipeline requests
-- @return Table with the pipeline get requests (plus this new one)
function pGet( host, port, path, options, ignored, allReqs )
- allReqs = allReqs or {}
- local mod_options = {
- header = {
- ["Connection"] = "keep-alive"
- }
- }
- table_augment(mod_options, options or {})
- -- This value is intended to be unpacked into arguments to build_request.
- local object = { host, port, "GET", path, mod_options }
- object.method = object[3]
- object.options = object[5]
- allReqs[#allReqs + 1] = object
- return allReqs
+ return addPipeline(host, port, path, options, ignored, allReqs, 'GET')
end
--- Builds a Head request to be used in a pipeline request
@@ -1171,22 +1175,10 @@ end
-- @param allReqs A table with all the pipeline requests
-- @return Table with the pipeline get requests (plus this new one)
function pHead( host, port, path, options, ignored, allReqs )
- allReqs = allReqs or {}
- local mod_options = {
- header = {
- ["Connection"] = "keep-alive"
- }
- }
- table_augment(mod_options, options or {})
- -- This value is intended to be unpacked into arguments to build_request.
- local object = { host, port, "HEAD", path, mod_options }
- object.method = object[3]
- object.options = object[5]
- allReqs[#allReqs + 1] = object
- return allReqs
+ return addPipeline(host, port, path, options, ignored, allReqs, 'HEAD')
end
---- Performs pipelined that are in allReqs to the resource. Return an array of
+---Performs pipelined that are in allReqs to the resource. Return an array of
-- response tables.
--
-- @param host The host to query.
@@ -1518,7 +1510,7 @@ function get_status_string(data)
end
end
---- Determine whether or not the server supports HEAD by requesting / and
+---Determine whether or not the server supports HEAD by requesting / and
-- verifying that it returns 200, and doesn't return data. We implement the
-- check like this because can't always rely on OPTIONS to tell the truth.
--
@@ -1662,7 +1654,7 @@ local function clean_404(body)
return body
end
---- Try requesting a non-existent file to determine how the server responds to
+---Try requesting a non-existent file to determine how the server responds to
-- unknown pages ("404 pages"), which a) tells us what to expect when a
-- non-existent page is requested, and b) tells us if the server will be
-- impossible to scan. If the server responds with a 404 status code, as it is
@@ -1682,9 +1674,9 @@ end
--
-- @param host The host object.
-- @param port The port to which we are establishing the connection.
--- @return (status, result, body) If status is false, result is an error
--- message. Otherwise, result is the code to expect and body is the cleaned-up
--- body (or a hash of the cleaned-up body).
+-- @return status Did we succeed?
+-- @return result If status is false, result is an error message. Otherwise, it's the code to expect (typically, but not necessarily, '404').
+-- @return body Body is a hash of the cleaned-up body that can be used when detecting a 404 page that doesn't return a 404 error code.
function identify_404(host, port)
local data
local bad_responses = { 301, 302, 400, 401, 403, 499, 501, 503 }
@@ -1769,7 +1761,6 @@ function identify_404(host, port)
end
stdnse.print_debug(1, "Unexpected response returned for 404 check: %s", get_status_string(data))
--- io.write("\n\n" .. nsedebug.tostr(data) .. "\n\n")
return true, data.status
end
@@ -1820,7 +1811,7 @@ function page_exists(data, result_404, known_404, page, displayall)
if(data.status == 401) then -- "Authentication Required"
return true
- elseif(displayall == true or displayall == '1' or displayall == "true") then
+ elseif(displayall) then
return true
end
@@ -1836,6 +1827,228 @@ function page_exists(data, result_404, known_404, page, displayall)
end
end
+---Check if the response variable, which could be a return from a http.get, http.post, http.pipeline,
+-- etc, contains the given text. The text can be:
+-- * Part of a header ('content-type', 'text/html', '200 OK', etc)
+-- * An entire header ('Content-type: text/html', 'Content-length: 123', etc)
+-- * Part of the body
+--
+-- The search text is treated as a Lua pattern.
+--
+--@param response The full response table from a HTTP request.
+--@param pattern The pattern we're searching for. Don't forget to escape '-', for example, 'Content%-type'.
+-- the pattern can also contain captures, like 'abc(.*)def', which will be returned if successful.
+--@param case_sensitive [optional] Set to true for case-sensitive searches. Default: not case sensitive.
+--@return result True if the string matched, false otherwise
+--@return matches An array of captures from the match, if any
+function response_contains(response, pattern, case_sensitive)
+
+ local result, _
+ local m = {}
+
+ -- If they're searching for the empty string or nil, it's true
+ if(pattern == '' or pattern == nil) then
+ return true
+ end
+
+ -- Create a function that either lowercases everything or doesn't, depending on case sensitivity
+ local case = function(pattern) return string.lower(pattern or '') end
+ if(case_sensitive == true) then
+ case = function(pattern) return (pattern or '') end
+ end
+
+ -- Set the case of the pattern
+ pattern = case(pattern)
+
+ -- Check the status line (eg, 'HTTP/1.1 200 OK')
+ m = {string.match(case(response['status-line']), pattern)};
+ if(m and #m > 0) then
+ return true, m
+ end
+
+ -- Check the headers
+ for _, header in pairs(response['rawheader']) do
+ m = {string.match(case(header), pattern)}
+ if(m and #m > 0) then
+ return true, m
+ end
+ end
+
+ -- Check the body
+ m = {string.match(case(response['body']), pattern)}
+ if(m and #m > 0) then
+ return true, m
+ end
+
+ return false
+end
+
+---Take a URI or URL in any form and convert it to its component parts. The URL can optionally
+-- have a protocol definition ('http://'), a server ('scanme.insecure.org'), a port (':80'), a
+-- URI ('/test/file.php'), and a query string ('?username=ron&password=turtle'). At the minimum,
+-- a path or protocol and url are required.
+--
+--@param url The incoming URL to parse
+--@return result A table containing the result, which can have the following fields: protocol,
+-- hostname, port, uri, querystring. All fields are strings except querystring,
+-- which is a table containing name=value pairs.
+function parse_url(url)
+ local result = {}
+
+ -- Save the original URL
+ result['original'] = url
+
+ -- Split the protocol off, if it exists
+ local colonslashslash = string.find(url, '://')
+ if(colonslashslash) then
+ result['protocol'] = string.sub(url, 1, colonslashslash - 1)
+ url = string.sub(url, colonslashslash + 3)
+ end
+
+ -- Split the host:port from the path
+ local slash, host_port
+ slash = string.find(url, '/')
+ if(slash) then
+ host_port = string.sub(url, 1, slash - 1)
+ result['path_query'] = string.sub(url, slash)
+ else
+ -- If there's no slash, then it's just a URL (if it has a http://) or a path (if it doesn't)
+ if(result['protocol']) then
+ result['host_port'] = url
+ else
+ result['path_query'] = url
+ end
+ end
+ if(host_port == '') then
+ host_port = nil
+ end
+
+ -- Split the host and port apart, if possible
+ if(host_port) then
+ local colon = string.find(host_port, ':')
+ if(colon) then
+ result['host'] = string.sub(host_port, 1, colon - 1)
+ result['port'] = tonumber(string.sub(host_port, colon + 1))
+ else
+ result['host'] = host_port
+ end
+ end
+
+ -- Split the path and querystring apart
+ if(result['path_query']) then
+ local question = string.find(result['path_query'], '?')
+ if(question) then
+ result['path'] = string.sub(result['path_query'], 1, question - 1)
+ result['raw_querystring'] = string.sub(result['path_query'], question + 1)
+ else
+ result['path'] = result['path_query']
+ end
+
+ -- Split up the query, if necessary
+ if(result['raw_querystring']) then
+ result['querystring'] = {}
+ local values = stdnse.strsplit('&', result['raw_querystring'])
+ for i, v in ipairs(values) do
+ local name, value = unpack(stdnse.strsplit('=', v))
+ result['querystring'][name] = value
+ end
+ end
+
+ -- Get the extension of the file, if any, or set that it's a folder
+ if(string.match(result['path'], "/$")) then
+ result['is_folder'] = true
+ else
+ result['is_folder'] = false
+ local split_str = stdnse.strsplit('%.', result['path'])
+ if(split_str and #split_str > 1) then
+ result['extension'] = split_str[#split_str]
+ end
+ end
+ end
+
+ return result
+end
+
+---This function should be called whenever a valid path (a path that doesn't contain a known
+-- 404 page) is discovered. It will add the path to the registry in several ways, allowing
+-- other scripts to take advantage of it in interesting ways.
+function save_path(host, port, path, status, links_to, linked_from, contenttype)
+ -- Make sure we have a proper hostname and port
+ host = stdnse.get_hostname(host)
+ if(type(port) == 'table') then
+ port = port.number
+ end
+
+ -- Parse the path
+ local parsed = parse_url(path)
+
+ -- Add to the 'all_pages' key
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'all_pages'}, parsed['path'])
+
+ -- Add the URL with querystring to all_pages_full_query
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'all_pages_full_query'}, parsed['path_query'])
+
+ -- Add the URL to a key matching the response code
+ if(status) then
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'status_codes', status}, parsed['path'])
+ end
+
+ -- If it's a directory, add it to the directories list; otherwise, add it to the files list
+ if(parsed['is_folder']) then
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'directories'}, parsed['path'])
+ else
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'files'}, parsed['path'])
+ end
+
+
+ -- If we have an extension, add it to the extensions key
+ if(parsed['extension']) then
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'extensions', parsed['extension']}, parsed['path'])
+ end
+
+ -- Add an entry for the page and its arguments
+ if(parsed['querystring']) then
+ -- Add all scripts with a querystring to the 'cgi' and 'cgi_full_query' keys
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'cgi'}, parsed['path'])
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'cgi_full_query'}, parsed['path_query'])
+
+ -- Add the query string alone to the registry (probably not necessary)
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'cgi_querystring', parsed['path'] }, parsed['raw_querystring'])
+
+ -- Add the individual arguments for the page, along with their values
+ for key, value in pairs(parsed['querystring']) do
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'cgi_args', parsed['path']}, parsed['querystring'])
+ end
+ end
+
+ -- Save the pages it links to
+ if(links_to) then
+ if(type(links_to) == 'string') then
+ links_to = {links_to}
+ end
+
+ for _, v in ipairs(links_to) do
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'links_to', parsed['path_query']}, v)
+ end
+ end
+
+ -- Save the pages it's linked from (we save these in the 'links_to' key, reversed)
+ if(linked_from) then
+ if(type(linked_from) == 'string') then
+ linked_from = {linked_from}
+ end
+
+ for _, v in ipairs(linked_from) do
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'links_to', v}, parsed['path_query'])
+ end
+ end
+
+ -- Save it as a content-type, if we have one
+ if(contenttype) then
+ stdnse.registry_add_array({parsed['host'] or host, 'www', parsed['port'] or port, 'content-type', contenttype}, parsed['path_query'])
+ end
+end
+
get_default_timeout = function( nmap_timing )
local timeout = {}
if nmap_timing >= 0 and nmap_timing <= 3 then
@@ -1851,3 +2064,4 @@ get_default_timeout = function( nmap_timing )
end
return timeout
end
+
diff --git a/nselib/stdnse.lua b/nselib/stdnse.lua
index 9e9a93e8b..8d32d965e 100644
--- a/nselib/stdnse.lua
+++ b/nselib/stdnse.lua
@@ -23,6 +23,8 @@ local os = os
local math = math
local string = string
+local io = require 'io'; -- TODO: Remove
+
local nmap = require "nmap";
local c_funcs = require "stdnse.c";
@@ -394,106 +396,106 @@ end
--- Returns the current time in milliseconds since the epoch
-- @return The current time in milliseconds since the epoch
function clock_ms()
- return nmap.clock() * 1000
+ return nmap.clock() * 1000
end
--- Returns the current time in microseconds since the epoch
-- @return The current time in microseconds since the epoch
function clock_us()
- return nmap.clock() * 1000000
+ return nmap.clock() * 1000000
end
---Get the indentation symbols at a given level.
local function format_get_indent(indent, at_end)
- local str = ""
- local had_continue = false
+ local str = ""
+ local had_continue = false
- if(not(at_end)) then
- str = rep(' ', #indent) -- Was: "| "
- else
- for i = #indent, 1, -1 do
- if(indent[i] and not(had_continue)) then
- str = str .. " " -- Was: "|_ "
- else
- had_continue = true
- str = str .. " " -- Was: "| "
- end
- end
- end
+ if(not(at_end)) then
+ str = rep(' ', #indent) -- Was: "| "
+ else
+ for i = #indent, 1, -1 do
+ if(indent[i] and not(had_continue)) then
+ str = str .. " " -- Was: "|_ "
+ else
+ had_continue = true
+ str = str .. " " -- Was: "| "
+ end
+ end
+ end
- return str
+ return str
end
-- A helper for format_output (see below).
local function format_output_sub(status, data, indent)
- if (#data == 0) then
- return ""
- end
+ if (#data == 0) then
+ return ""
+ end
- -- Return a single line of output as-is (assuming it's top-level and a string)
- if(indent == nil and #data == 1 and type(data) == 'string' and not(data['name']) and not(data['warning'])) then
- return data[1]
- end
+ -- Return a single line of output as-is (assuming it's top-level and a string)
+ if(indent == nil and #data == 1 and type(data) == 'string' and not(data['name']) and not(data['warning'])) then
+ return data[1]
+ end
- -- Used to put 'ERROR: ' in front of all lines on error messages
- local prefix = ""
- -- Initialize the output string to blank (or, if we're at the top, add a newline)
- local output = ""
- if(not(indent)) then
- output = '\n'
- end
+ -- Used to put 'ERROR: ' in front of all lines on error messages
+ local prefix = ""
+ -- Initialize the output string to blank (or, if we're at the top, add a newline)
+ local output = ""
+ if(not(indent)) then
+ output = '\n'
+ end
- if(not(status)) then
- if(nmap.debugging() < 1) then
- return nil
- end
- prefix = "ERROR: "
- end
+ if(not(status)) then
+ if(nmap.debugging() < 1) then
+ return nil
+ end
+ prefix = "ERROR: "
+ end
- -- If a string was passed, turn it into a table
- if(type(data) == 'string') then
- data = {data}
- end
+ -- If a string was passed, turn it into a table
+ if(type(data) == 'string') then
+ data = {data}
+ end
- -- Make sure we have an indent value
- indent = indent or {}
+ -- Make sure we have an indent value
+ indent = indent or {}
- for i, value in ipairs(data) do
- if(type(value) == 'table') then
- if(value['name']) then
- if(value['warning'] and nmap.debugging() > 0) then
- output = output .. format("%s %s%s (WARNING: %s)\n", format_get_indent(indent), prefix, value['name'], value['warning'])
- else
- output = output .. format("%s %s%s\n", format_get_indent(indent), prefix, value['name'])
- end
- elseif(value['warning'] and nmap.debugging() > 0) then
- output = output .. format("%s %s(WARNING: %s)\n", format_get_indent(indent), prefix, value['warning'])
- end
+ for i, value in ipairs(data) do
+ if(type(value) == 'table') then
+ if(value['name']) then
+ if(value['warning'] and nmap.debugging() > 0) then
+ output = output .. format("%s %s%s (WARNING: %s)\n", format_get_indent(indent), prefix, value['name'], value['warning'])
+ else
+ output = output .. format("%s %s%s\n", format_get_indent(indent), prefix, value['name'])
+ end
+ elseif(value['warning'] and nmap.debugging() > 0) then
+ output = output .. format("%s %s(WARNING: %s)\n", format_get_indent(indent), prefix, value['warning'])
+ end
- -- Do a shallow copy of indent
- local new_indent = {}
- for _, v in ipairs(indent) do
- insert(new_indent, v)
- end
+ -- Do a shallow copy of indent
+ local new_indent = {}
+ for _, v in ipairs(indent) do
+ insert(new_indent, v)
+ end
- if(i ~= #data) then
- insert(new_indent, false)
- else
- insert(new_indent, true)
- end
+ if(i ~= #data) then
+ insert(new_indent, false)
+ else
+ insert(new_indent, true)
+ end
- output = output .. format_output_sub(status, value, new_indent)
-
- elseif(type(value) == 'string') then
- if(i ~= #data) then
- output = output .. format("%s %s%s\n", format_get_indent(indent, false), prefix, value)
- else
- output = output .. format("%s %s%s\n", format_get_indent(indent, true), prefix, value)
- end
- end
- end
+ output = output .. format_output_sub(status, value, new_indent)
+
+ elseif(type(value) == 'string') then
+ if(i ~= #data) then
+ output = output .. format("%s %s%s\n", format_get_indent(indent, false), prefix, value)
+ else
+ output = output .. format("%s %s%s\n", format_get_indent(indent, true), prefix, value)
+ end
+ end
+ end
- return output
+ return output
end
---Takes a table of output on the commandline and formats it for display to the
@@ -545,22 +547,22 @@ end
-- @return nil, if data is empty, otherwise a
-- multiline string.
function format_output(status, data, indent)
- -- If data is nil, die with an error (I keep doing that by accident)
- assert(data, "No data was passed to format_output()")
+ -- If data is nil, die with an error (I keep doing that by accident)
+ assert(data, "No data was passed to format_output()")
- -- Don't bother if we don't have any data
- if (#data == 0) then
- return nil
- end
+ -- Don't bother if we don't have any data
+ if (#data == 0) then
+ return nil
+ end
- local result = format_output_sub(status, data, indent)
+ local result = format_output_sub(status, data, indent)
- -- Check for an empty result
- if(result == nil or #result == "" or result == "\n" or result == "\n") then
- return nil
- end
+ -- Check for an empty result
+ if(result == nil or #result == "" or result == "\n" or result == "\n") then
+ return nil
+ end
- return result
+ return result
end
-- Get the value of a script argument, or nil if the script argument was not
@@ -618,6 +620,113 @@ function get_script_args (...)
return unpack(args, 1, select("#", ...))
end
+---Get the best possible hostname for the given host. This can be the target as given on
+-- the commandline, the reverse dns name, or simply the ip address.
+--@param host The host table (or a string that'll simply be returned).
+--@return The best possible hostname, as a string.
+function get_hostname(host)
+ if type(host) == "table" then
+ return host.targetname or ( host.name ~= '' and host.name ) or host.ip
+ else
+ return host
+ end
+end
+
+---Retrieve an item from the registry, checking if each sub-key exists. If any key doesn't
+-- exist, return nil.
+function registry_get(subkeys)
+ local registry = nmap.registry
+ local i = 1
+
+ while(subkeys[i]) do
+ if(not(registry[subkeys[i]])) then
+ return nil
+ end
+
+ registry = registry[subkeys[i]]
+
+ i = i + 1
+ end
+
+ return registry
+end
+
+--Check if the given element exists in the registry. If 'key' is nil, it isn't checked.
+function registry_exists(subkeys, key, value)
+ local subkey = registry_get(subkeys)
+
+ if(not(subkey)) then
+ return false
+ end
+
+ for k, v in pairs(subkey) do
+ if((key == nil or key == k) and (v == value)) then -- TODO: if 'value' is a table, this fails
+ return true
+ end
+ end
+
+ return false
+end
+
+---Add an item to an array in the registry, creating all sub-keys if necessary.
+-- For example, calling:
+-- registry_add_array({'192.168.1.100', 'www', '80', 'pages'}, 'index.html')
+-- Will create nmap.registry['192.168.1.100'] as a table, if necessary, then add a table
+-- under the 'www' key, and so on. 'pages', finally, is treated as an array and the value
+-- given is added to the end.
+function registry_add_array(subkeys, value, allow_duplicates)
+ local registry = nmap.registry
+ local i = 1
+
+ -- Unless the user wants duplicates, make sure there aren't any
+ if(allow_duplicates ~= true) then
+ if(registry_exists(subkeys, nil, value)) then
+ return
+ end
+ end
+
+ while(subkeys[i]) do
+ if(not(registry[subkeys[i]])) then
+ registry[subkeys[i]] = {}
+ end
+ registry = registry[subkeys[i]]
+ i = i + 1
+ end
+
+ -- Make sure the value isn't already in the table
+ for _, v in pairs(registry) do
+ if(v == value) then
+ return
+ end
+ end
+ insert(registry, value)
+end
+
+---Similar to registry_add_array, except instead of adding a value to the
+-- end of an array, it adds a key:value pair to the table.
+function registry_add_table(subkeys, key, value)
+ local registry = nmap.registry
+ local i = 1
+
+ -- Unless the user wants duplicates, make sure there aren't any
+ if(allow_duplicates ~= true) then
+ if(registry_exists(subkeys, key, value)) then
+ return
+ end
+ end
+
+ while(subkeys[i]) do
+ if(not(registry[subkeys[i]])) then
+ registry[subkeys[i]] = {}
+ end
+ registry = registry[subkeys[i]]
+ i = i + 1
+ end
+
+ registry[key] = value
+end
+
+
--- This function allows you to create worker threads that may perform
-- network tasks in parallel with your script thread.
--
diff --git a/scripts/http-enum.nse b/scripts/http-enum.nse
index d70013793..cf8f7f0a8 100644
--- a/scripts/http-enum.nse
+++ b/scripts/http-enum.nse
@@ -1,10 +1,15 @@
description = [[
Enumerates directories used by popular web applications and servers.
-This parses fingerprint files that are properly formatted. Multiple
-files are included with Nmap, including:
-* http-fingerprints: These attempt to find common files and folders.
-* yokoso-fingerprints: These are application-specific fingerprints, designed for finding the presense of specific applications/hardware, including Sharepoint, Forigate's Web interface, Arcsight SmartCollector appliances, Outlook Web Access, etc. These are from the Yokoso project, by InGuardians, and included with permission from Kevin Johnson (http://seclists.org/nmap-dev/2009/q3/0685.html).
+This parses a fingerprint file that's formatted in a way that's compatible with the Nikto Web application
+scanner. This script, however, takes it one step further by building in advanced pattern matching as well
+as having the ability to identify specific versions of Web applications.
+
+Currently, the database can be found under Nmap's directory in the nselib/data folder. The file is called
+http-fingerprints and has a long description of its functionality in the file header.
+
+Many of the finger prints were discovered by me (Ron Bowes), and a number of them are from the Yokoso
+project, used with permission from Kevin Johnson (http://seclists.org/nmap-dev/2009/q3/0685.html).
Initially, this script attempts to access two different random files in order to detect servers
that don't return a proper 404 Not Found status. In the event that they return 200 OK, the body
@@ -17,25 +22,18 @@ this script will also abort. If the root folder has disappeared or requires auth
is little hope of finding anything inside it.
By default, only pages that return 200 OK or 401 Authentication Required are displayed. If the
-displayall script argument is set, however, then all results will be displayed (except
-for 404 Not Found and the status code returned by the random files).
+http-enum.displayall script argument is set, however, then all results will be displayed (except
+for 404 Not Found and the status code returned by the random files). Entries in the http-fingerprints
+database can specify their own criteria for accepting a page as valid.
+
]]
---
--- @args displayall Set to 1 or true to display all status codes
--- that may indicate a valid page, not just 200 OK and 401
--- Authentication Required pages. Although this is more likely to find
--- certain hidden folders, it also generates far more false positives.
--- @args limit Limit the number of folders to check. This option is
--- useful if using a list from, for example, the DirBuster projects
--- which can have more than 80,000 entries.
--- @args fingerprints Specify a different file to read fingerprints
--- from. This will be read instead of the default files.
--- @args path The base path to prepend to each request. Leading/trailing
--- slashes are not required.
--- @args variations Set to 1 or true to
--- attempt variations on the files, adding prefixes and suffixes such as
--- .bak, ~, and Copy of .
+-- @args http-enum.basepath The base path to prepend to each request. Leading/trailing slashes are ignored.
+-- @args http-enum.displayall Set this argument to display all status codes that may indicate a valid page, not
+-- just 200 OK and 401 Authentication Required pages. Although this is more likely
+-- to find certain hidden folders, it also generates far more false positives.
+-- @args http-enum.fingerprintfile Specify a different file to read fingerprints from.
--
-- @output
-- Interesting ports on test.skullsecurity.org (208.81.2.52):
@@ -60,19 +58,17 @@ require 'http'
require 'shortport'
require 'stdnse'
--- List of fingerprint files
-local fingerprint_files = { "http-fingerprints", "yokoso-fingerprints" }
-if(nmap and nmap.registry and nmap.registry.args and nmap.registry.args.fingerprints ~= nil) then
- -- Specifying multiple entries in a table doesn't seem to work
- if(type(nmap.registry.args.fingerprints) == "table") then
- fingerprint_files = nmap.registry.args.fingerprints
- else
- fingerprint_files = { nmap.registry.args.fingerprints }
- end
-end
-
portrule = shortport.http
+-- TODO
+-- o Automatically convert HEAD -> GET if the server doesn't support HEAD
+-- o Add variables for common extensions, common CGI extensions, etc that expand the probes
+
+-- File extensions (TODO: Implement this)
+local cgi_ext = { 'php', 'asp', 'aspx', 'jsp', 'pl', 'cgi' }
+
+local common_ext = { 'php', 'asp', 'aspx', 'jsp', 'pl', 'cgi', 'css', 'js', 'htm', 'html' }
+
---Convert the filename to backup variations. These can be valuable for a number of reasons.
-- First, because they may not have the same access restrictions as the main version (file.php
-- may run as a script, but file.php.bak or file.php~ might not). And second, the old versions
@@ -109,13 +105,6 @@ local function get_variations(filename)
table.insert(variations, bare .. "2" .. extension)
end
- -- Some compressed formats
- table.insert(variations, filename .. ".zip")
- table.insert(variations, filename .. ".tar")
- table.insert(variations, filename .. ".tar.gz")
- table.insert(variations, filename .. ".tgz")
- table.insert(variations, filename .. ".tar.bz2")
-
-- Some Windowsy things
local onlyname = string.sub(filename, 2)
@@ -146,18 +135,25 @@ local function get_variations(filename)
end
end
+ -- Some compressed formats (we don't want a trailing '/' on these, so they go after the loop)
+ table.insert(variations, filename .. ".zip")
+ table.insert(variations, filename .. ".tar")
+ table.insert(variations, filename .. ".tar.gz")
+ table.insert(variations, filename .. ".tgz")
+ table.insert(variations, filename .. ".tar.bz2")
+
+
+
return variations
end
---Get the list of fingerprints from files. The files are defined in fingerprint_files.
--
--@return An array of entries, each of which have a checkdir field, and possibly a checkdesc.
-local function get_fingerprints()
+local function get_fingerprints(fingerprint_file)
local entries = {}
- local PREAUTH = "# Pre-Auth"
- local POSTAUTH = "# Post-Auth"
-
local i
+ local total_count = 0 -- Used for 'limit'
-- Check if we've already read the file
-- There might be a race condition here, where multiple scripts will read the file and set this variable, but the impact
@@ -167,62 +163,165 @@ local function get_fingerprints()
return nmap.registry.http_fingerprints
end
- for i = 1, #fingerprint_files, 1 do
- local count = 0
+ -- Try and find the file; if it isn't in Nmap's directories, take it as a direct path
+ local filename_full = nmap.fetchfile('nselib/data/' .. fingerprint_file)
+ if(not(filename_full)) then
+ filename_full = fingerprint_file
+ end
- -- Try using the root path, if possible
- local filename = fingerprint_files[i]
- local filename_full = nmap.fetchfile(filename)
+ stdnse.print_debug("http-enum: Loading fingerprint database: %s", filename_full)
+ local file = loadfile(filename_full)
+ if(not(file)) then
+ stdnse.print_debug("http-enum: Couldn't load configuration file: %s", filename_full)
+ return false, "Couldn't load fingerprint file: " .. filename_full
+ end
- if(filename_full == nil) then
- -- If the root path fails, try looking in the nselib/data directory
- filename = "nselib/data/" .. fingerprint_files[i]
- filename_full = nmap.fetchfile(filename)
+ setfenv(file, setmetatable({fingerprints = {}; }, {__index = _G}))
+ file()
+
+ local fingerprints = getfenv(file)["fingerprints"]
+
+ -- Sanity check our file to ensure that all the fields were good. If any are bad, we
+ -- stop and don't load the file.
+ for i, fingerprint in pairs(fingerprints) do
+ -- Make sure we have a valid index
+ if(type(i) ~= 'number') then
+ return false, "The 'fingerprints' table is an array, not a table; all indexes should be numeric"
end
-
- if(filename_full == nil) then
- stdnse.print_debug(1, "http-enum: Couldn't find fingerprints file: %s", filename)
- else
- stdnse.print_debug(1, "http-enum: Attempting to parse fingerprint file %s", filename)
- local product = nil
- for line in io.lines(filename_full) do
- -- Ignore "Pre-Auth", "Post-Auth", and blank lines
- if(string.sub(line, 1, #PREAUTH) ~= PREAUTH and string.sub(line, 1, #POSTAUTH) ~= POSTAUTH and #line > 0) then
- -- Commented lines indicate products
- if(string.sub(line, 1, 1) == "#") then
- product = string.sub(line, 3)
- else
- table.insert(entries, {checkdir=line, checkdesc=product})
- count = count + 1
+ -- Make sure they have either a string or a table of probes
+ if(not(fingerprint.probes) or
+ (type(fingerprint.probes) ~= 'table' and type(fingerprint.probes) ~= 'string') or
+ (type(fingerprint.probes) == 'table' and #fingerprint.probes == 0)) then
+ return false, "Invalid path found for fingerprint " .. i
+ end
- -- If the user requested variations, add those as well
- if(nmap.registry.args.variations == '1' or nmap.registry.args.variations == 'true') then
- local variations = get_variations(line)
- for _, variation in ipairs(variations) do
- table.insert(entries, {checkdir=variation, checkdesc=product .. " (variation)"})
- end
- end
- end
- end
+ -- Make sure fingerprint.path is a table
+ if(type(fingerprint.probes) == 'string') then
+ fingerprint.probes = {fingerprint.probes}
+ end
+
+ -- Make sure the elements in the probes array are strings or arrays
+ for i, probe in pairs(fingerprint.probes) do
+ -- Make sure we have a valid index
+ if(type(i) ~= 'number') then
+ return false, "The 'probes' table is an array, not a table; all indexes should be numeric"
end
-
- stdnse.print_debug(1, "http-enum: Added %d entries from file %s", count, filename)
+
+ -- Convert the probe to a table if it's a string
+ if(type(probe) == 'string') then
+ fingerprint.probes[i] = {path=fingerprint.probes[i]}
+ probe = fingerprint.probes[i]
+ end
+
+ -- Make sure the probes table has a 'path'
+ if(not(probe['path'])) then
+ return false, "The 'probes' table requires each element to have a 'path'."
+ end
+
+ -- If they didn't set a method, set it to 'GET'
+ if(not(probe['method'])) then
+ probe['method'] = 'GET'
+ end
+
+ -- Make sure the method's a string
+ if(type(probe['method']) ~= 'string') then
+ return false, "The 'method' in the probes file has to be a string"
+ end
+ end
+
+ -- Ensure that there's a 'matches' field
+ if(not(fingerprint.matches)) then
+ return false, "'matches' field has to be an array for path " .. path
+ end
+
+ -- Ensure that matches is an array
+ if(type(fingerprint.matches) ~= 'table') then
+ return false, "'matches' field has to be a table for path " .. path
+ end
+
+ -- Loop through the matches
+ for i, match in pairs(fingerprint.matches) do
+ -- Make sure we have a valid index
+ if(type(i) ~= 'number') then
+ return false, "The 'path' table is an array, not a table; all indexes should be numeric"
+ end
+
+ -- Check that every element in the table is an array
+ if(type(match) ~= 'table') then
+ return false, "Every element of 'matches' field has to be a table for path " .. path
+ end
+
+ -- Check the output field
+ if(match['output'] == nil or type(match['output']) ~= 'string') then
+ return false, "The 'output' field in 'matches' has to be present and a string"
+ end
+
+ -- Check the 'match' and 'dontmatch' fields, if present
+ if((match['match'] and type(match['match']) ~= 'string') or (match['dontmatch'] and type(match['dontmatch']) ~= 'string')) then
+ return false, "The 'match' and 'dontmatch' fields in 'matches' have to be strings, if they exist"
+ end
+
+ -- Change blank 'match' strings to '.*' so they match everything
+ if(not(match['match']) or match['match'] == '') then
+ match['match'] = '(.*)'
+ end
+ end
+
+ -- Make sure the severity is an integer between 1 and 4. Default it to 1.
+ if(fingerprint.severity and (type(fingerprint.severity) ~= 'number' or fingerprint.severity < 1 or fingerprint.severity > 4)) then
+ return false, "The 'severity' field has to be an integer between 1 and 4 for path " .. path
+ else
+ fingerprint.severity = 1
+ end
+
+ -- Make sure ignore_404 is a boolean. Default it to false.
+ if(fingerprint.ignore_404 and type(fingerprint.ignore_404) ~= 'boolean') then
+ return false, "The 'ignore_404' field has to be a boolean for path " .. path
+ else
+ fingerprint.ignore_404 = false
end
end
+-- -- If the user wants to try variations, add them
+-- if(try_variations) then
+-- -- Get a list of all variations for this directory
+-- local variations = get_variations(entry['checkdir'])
+--
+-- -- Make a copy of the entry for each of them
+-- for _, variation in ipairs(variations) do
+-- new_entry = {}
+-- for k, v in pairs(entry) do
+-- new_entry[k] = v
+-- end
+-- new_entry['checkdesc'] = new_entry['checkdesc'] .. " (variation)"
+-- new_entry['checkdir'] = variation
+-- table.insert(entries, new_entry)
+-- count = count + 1
+-- end
+-- end
+
-- Cache the fingerprints for other scripts, so we aren't reading the files every time
- nmap.registry.http_fingerprints = entries
-
- return entries
+-- nmap.registry.http_fingerprints = fingerprints
+
+ return true, fingerprints
end
action = function(host, port)
-
local response = {}
+ -- Read the script-args, keeping the old ones for reverse compatibility
+ local basepath = stdnse.get_script_args({'http-enum.basepath', 'path'}) or '/'
+ local displayall = stdnse.get_script_args({'http-enum.displayall', 'displayall'}) or false
+ local fingerprint_file = stdnse.get_script_args({'http-enum.fingerprintfile', 'fingerprints'}) or 'http-fingerprints.lua'
+-- local try_variations = stdnse.get_script_args({'http-enum.tryvariations', 'variations'}) or false
+-- local limit = tonumber(stdnse.get_script_args({'http-enum.limit', 'limit'})) or -1
+
-- Add URLs from external files
- local URLs = get_fingerprints()
+ local status, fingerprints = get_fingerprints(fingerprint_file)
+ if(not(status)) then
+ return stdnse.format_output(false, fingerprints)
+ end
-- Check what response we get for a 404
local result, result_404, known_404 = http.identify_404(host, port)
@@ -230,90 +329,111 @@ action = function(host, port)
return stdnse.format_output(false, result_404)
end
- -- Check if we can use HEAD requests
- local use_head = http.can_use_head(host, port, result_404)
-
- -- If we can't use HEAD, make sure we can use GET requests
- if(use_head == false) then
- local result, err = http.can_use_get(host, port)
- if(result == false) then
- return stdnse.format_output(false, err)
- end
- end
-
- -- Get the base path, if the user entered one
- local paths = {''}
- if(nmap.registry.args.path ~= nil) then
- if(type(nmap.registry.args.path) == 'table') then
- paths = nmap.registry.args.path
- else
- paths = { nmap.registry.args.path }
- end
- end
-
-- Queue up the checks
+ local all = {}
- for j = 1, #paths, 1 do
- local all = {}
- local path = paths[j]
+ -- Remove trailing slash, if it exists
+ if(#basepath > 1 and string.sub(basepath, #basepath, #basepath) == '/') then
+ basepath = string.sub(basepath, 1, #basepath - 1)
+ end
- -- Remove trailing slash, if it exists
- if(#path > 1 and string.sub(path, #path, #path) == '/') then
- path = string.sub(path, 1, #path - 1)
+ -- Add a leading slash, if it doesn't exist
+ if(#basepath <= 1) then
+ basepath = ''
+ else
+ if(string.sub(basepath, 1, 1) ~= '/') then
+ basepath = '/' .. basepath
end
+ end
- -- Add a leading slash, if it doesn't exist
- if(#path <= 1) then
- path = ''
- else
- if(string.sub(path, 1, 1) ~= '/') then
- path = '/' .. path
- end
+ -- Loop through the fingerprints
+ stdnse.print_debug(1, "http-enum: Searching for entries under path '%s' (change with 'http-enum.basepath' argument)", basepath)
+ for i = 1, #fingerprints, 1 do
+ -- Add each path. The order very much matters here.
+ for j = 1, #fingerprints[i].probes, 1 do
+ all = http.addPipeline(host, port, basepath .. fingerprints[i].probes[j].path, nil, nil, all, fingerprints[i].probes[j].method or 'GET')
end
+ end
- -- Loop through the URLs
- stdnse.print_debug(1, "http-enum.nse: Searching for entries under path '%s' (change with 'path' argument)", path)
- for i = 1, #URLs, 1 do
- if(nmap.registry.args.limit and i > tonumber(nmap.registry.args.limit)) then
- stdnse.print_debug(1, "http-enum.nse: Reached the limit (%d), stopping", nmap.registry.args.limit)
- break;
- end
+ -- Perform all the requests.
+ local results = http.pipeline(host, port, all, nil)
- if(use_head) then
- all = http.pHead(host, port, path .. URLs[i].checkdir, nil, nil, all)
- else
- all = http.pGet(host, port, path .. URLs[i].checkdir, nil, nil, all)
- end
- end
+ -- Check for http.pipeline error
+ if(results == nil) then
+ stdnse.print_debug(1, "http-enum: http.pipeline encountered an error")
+ return stdnse.format_output(false, "http.pipeline encountered an error")
+ end
- local results = http.pipeline(host, port, all, nil)
-
- -- Check for http.pipeline error
- if(results == nil) then
- stdnse.print_debug(1, "http-enum.nse: http.pipeline returned nil")
- return stdnse.format_output(false, "http.pipeline returned nil")
- end
-
- for i, data in pairs(results) do
- if(http.page_exists(data, result_404, known_404, path .. URLs[i].checkdir, nmap.registry.args.displayall)) then
- -- Build the description
- local description = string.format("%s", path .. URLs[i].checkdir)
- if(URLs[i].checkdesc) then
- description = string.format("%s: %s", path .. URLs[i].checkdir, URLs[i].checkdesc)
+ -- Loop through the fingerprints. Note that for each fingerprint, we may have multiple results
+ local j = 1
+ for i, fingerprint in ipairs(fingerprints) do
+
+ -- Loop through the paths for each fingerprint in the same order we did the requests. Each of these will
+ -- have one result, so increment the result value at each iteration
+ for _, probe in ipairs(fingerprint.probes) do
+ local result = results[j]
+ j = j + 1
+
+ if(result) then
+ local path = basepath .. probe['path']
+ local good = true
+ local output = nil
+ -- Unless this check said to ignore 404 messages, check if we got a valid page back using a known 404 message.
+ if(fingerprint.ignore_404 ~= true and not(http.page_exists(result, result_404, known_404, path, displayall))) then
+ good = false
+ else
+ -- Loop through our matches table and see if anything matches our result
+ for _, match in ipairs(fingerprint.matches) do
+ if(match.match) then
+ local result, matches = http.response_contains(result, match.match)
+ if(result) then
+ output = match.output
+ good = true
+ for k, value in ipairs(matches) do
+ output = string.gsub(output, '\\' .. k, matches[k])
+ end
+ end
+ else
+ output = match.output
+ end
+
+ -- If nothing matched, turn off the match
+ if(not(output)) then
+ good = false
+ end
+
+ -- If we match the 'dontmatch' line, we're not getting a match
+ if(match.dontmatch and match.dontmatch ~= '' and http.response_contains(result, match.dontmatch)) then
+ output = nil
+ good = false
+ end
+
+ -- Break the loop if we found it
+ if(output) then
+ break
+ end
+ end
end
-
- -- Build the status code, if it isn't a 200
- local status = ""
- if(data.status ~= 200) then
- status = " (" .. http.get_status_string(data) .. ")"
- end
-
- stdnse.print_debug("Found a valid page! (%s)%s", description, status)
- table.insert(response, string.format("%s%s", description, status))
+ if(good) then
+ -- Save the path in the registry
+ http.save_path(stdnse.get_hostname(host), port.number, path, result.status)
+
+ -- Add the path to the output
+ output = string.format("%s: %s", path, output)
+
+ -- Build the status code, if it isn't a 200
+ if(result.status ~= 200) then
+ output = output .. " (" .. http.get_status_string(result) .. ")"
+ end
+
+ stdnse.print_debug(1, "Found a valid page! %s", output)
+
+ table.insert(response, output)
+ end
end
end
end
-
+
return stdnse.format_output(true, response)
end
diff --git a/scripts/http-iis-webdav-vuln.nse b/scripts/http-iis-webdav-vuln.nse
index 3ae608d45..4e2900902 100644
--- a/scripts/http-iis-webdav-vuln.nse
+++ b/scripts/http-iis-webdav-vuln.nse
@@ -105,16 +105,16 @@ local function go(host, port)
if(nmap.registry.args.folderdb ~= nil) then
folder_file = nmap.fetchfile(nmap.registry.args.folderdb)
else
- folder_file = nmap.fetchfile('nselib/data/folders.lst')
+ folder_file = nmap.fetchfile('nselib/data/http-folders.txt')
end
if(folder_file == nil) then
- return false, "Couldn't find folders.lst (should be in nselib/data)"
+ return false, "Couldn't find http-folders.txt (should be in nselib/data)"
end
local file = io.open(folder_file, "r")
if not file then
- return false, "Couldn't find folders.lst (should be in nselib/data)"
+ return false, "Couldn't find http-folders.txt (should be in nselib/data)"
end
while true do