class Analyzer::Asp::Classic

Overview

Classic ASP (VBScript) attack surface.

Classic ASP has no route table: an .asp file's path under the web root is its URL, the same shape as plain PHP or JSP. The work is therefore (a) deciding which .asp files are actually requestable and (b) recovering the request keys the page reads.

global.asa and .inc are never served (IIS refuses the former and does not map the latter to the ASP engine), so only .asp is walked.

Defined in:

analyzer/analyzers/asp/classic.cr

Constant Summary

BINARY_READ_RE = /\brequest\s*\.\s*(?:binaryread|totalbytes)\b/i
CONTINUATION_RE = /_[ \t]*\r?\n/
DIRECTORY_INDEXES = Set {"default.asp", "index.asp"}

IIS default documents: also reachable as the bare directory URL.

FORM_ACTION_RE = /\baction\s*=\s*["']?([^"'\s>]*)/i
FORM_TAG_RE = /<form\b([^>]*)>/i

A form only makes this page a POST target when it submits back to itself. Treating any <form> as a self-post gave every page hosting a search or login box that posts to a dedicated handler a phantom POST endpoint.

INCLUDE_DIR_RE = /\/(?:includes?|inc)\//i

Fragments that are included rather than requested. The include graph below is the real filter; these catch the conventional cases it can miss (a fragment nobody includes statically).

INCLUDE_NAME_RE = /\A(?:lib|partial)\./i
INCLUDE_RE = /<!--\s*#include\s+(file|virtual)\s*=\s*["']([^"']+)["']\s*-->/i

<!-- #include file="..." -->. Most real code puts a space after <!--, and virtual= is web-root-absolute while file= is relative to the including file.

POST_METHOD_RE = /request\s*\.\s*servervariables\s*\(\s*"request_method"\s*\)\s*=\s*"post"/i

Only an equality test is evidence the page handles POST; <> is the opposite guard.

REQUEST_RE = /\brequest\s*(?:\.\s*(form|querystring|cookies|servervariables)\s*)?\(\s*"([^"]*)"\s*\)/i

Intrinsic collection reads. The name must be a double-quoted literal closed immediately by )Request("prefix" & id) is a runtime-built key, and capturing prefix from it would be wrong. Whitespace before ( is not optional decoration: it appears in over half of real form reads (Request.Form ("x")).

SERVER_SCRIPT_RE = /(<script\b[^>]*\brunat\s*=\s*["']?server["']?[^>]*>)([\s\S]*?)(<\/script>)/i

Server code lives in <% %> / <%= %> or a runat="server" script block; <%@ %> is a page directive, not code.

WEBROOT_MARKERS = ["wwwroot/", "inetpub/"]

IIS-specific roots only. Generic names like public/ are deliberately absent — they collide with build output, the false positive FileHelper documents.

WRAPPER_RE = /\b(?:getRequest|Easp\s*\.\s*[GPR])\s*\(\s*"([^"]*)"\s*\)/i

Framework wrappers that merge the collections. Without these a real CMS loses most of its surface: QuickerSite routes nearly every dynamic param through aspLite's getRequest.

Instance Method Summary

Instance methods inherited from class Analyzer

analyze analyze, base_path : String base_path, base_paths : Array(String) base_paths, callees_needed? : Bool callees_needed?, http_header_name(name : String) : String | Nil http_header_name, line_number_for_index(content : String, char_index : Int32) : Int32 line_number_for_index, logger : NoirLogger logger, parallel_analyze(files : Array(String), &block : String -> Nil) parallel_analyze, read_file_content(path : String) : String read_file_content, result : Array(Endpoint) result, unique_params(params : Array(Param)) : Array(Param) unique_params, url : String url, web_root_path(path : String, markers : Array(String)) : String web_root_path

Constructor methods inherited from class Analyzer

new(options : Hash(String, YAML::Any)) new

Instance methods inherited from module FileHelper

all_files : Array(String) all_files, get_files_by_extension(extension : String) : Array(String) get_files_by_extension, get_files_by_extensions(extensions : Array(String)) : Array(String) get_files_by_extensions, get_files_by_prefix(prefix : String) : Array(String) get_files_by_prefix, get_files_by_prefix_and_extension(prefix : String, extension : String) : Array(String) get_files_by_prefix_and_extension, get_public_dir_files(base_path : String, folder : String) : Array(String) get_public_dir_files, get_public_files(base_path : String, anchors : Array(String) = ["shard.yml", "Gemfile"]) : Array(String) get_public_files

Instance Method Detail

def analyze #

[View source]