Common Vulnerability Check Examples

The Nexpose Writing Vulnerability Checks tutorial takes you through a simple example of how to write an HTTP-based vulnerability check and run it in Nexpose. This page contains more examples of different types of checks you can do in Nexpose.

Service banner checks

The <NetworkService> element checks for the presence of a certain service running on the network. The type attribute indicates the protocol. Multiple OR'd types are separated by a | (pipe) character. The example below uses "HTTP|HTTPS" to indicate HTTP or HTTPS.

The <Product> element indicates a fingerprinted product found running on that service. The <version> element checks for a range of product version numbers. NOTE: The <high> version number is exclusive -- in other words <high> should be equal to the next NON-vulnerable version of that product. In the example below, Apache 2.0.45 contains the patch.

http-apache-excessive-newline-dos.vck

<VulnerabilityCheck id="http-apache-excessive-newline-dos" scope="endpoint">
   <NetworkService type="HTTP|HTTPS">
      <Product name="Apache">
         <version>
            <range><low>2.0.0</low><high>2.0.45</high></range>
         </version>
      </Product>
   </NetworkService>
</VulnerabilityCheck>

ftp-proftpd-cwd-format-string.vck, which tests for the existence of a vulnerability using a FTP banner version test:

<VulnerabilityCheck id="ftp-proftpd-cwd-format-string" version="1.0" scope="endpoint">
   <NetworkService type="FTP">
      <Product name="ProFTPD">
         <version><range><high>1.2.0rc3</high></range></version>
      </Product>
   </NetworkService>
</VulnerabilityCheck>

ftp-servu-directory-traversal.vck, which connects to an FTP server with any available credentials, executes a directory change command, and checks the result code and text.

<VulnerabilityCheck id="ftp-servu-directory-traversal" version="1.0" scope="endpoint">
   <NetworkService type="FTP"/>
   <FTPCheck login="1">
      <FTPRequestResponse>
         <FTPRequest>CWD \\..%20.</FTPRequest>
         <FTPResponse code="250">
            <regex>Directory changed to /..</regex>
         </FTPResponse>
      </FTPRequestResponse>
   </FTPCheck>
</VulnerabilityCheck>

http-website-long-options-bof.vck, example version check for two different product editions in one check file.

<VulnerabilityCheck id="http-website-long-options-bof" scope="endpoint">
   <NetworkService type="HTTP|HTTPS">
      <Product name="WebSite">
         <version><range><high>3.5.15</high></range></version>
      </Product>
      <Product name="WebSitePro">
         <version><range><high>3.5.15</high></range></version>
      </Product>
   </NetworkService>
</VulnerabilityCheck>

Sometimes you want to check for the version of a particular <Component> of a <Product>, for example PHP.

php-ecalloc-integer-overflow.vck

<VulnerabilityCheck id="php-ecalloc-integer-overflow" scope="endpoint">
   <NetworkService type="HTTP|HTTPS">
      <Product name="Apache">
         <Component name="PHP">
            <version><range><low>4.0.0</low><high>4.3.0</high></range></version>
            <version><range><low>5.0.0</low><high>5.2.0</high></range></version>
         </Component>
      </Product>
   </NetworkService>
</VulnerabilityCheck>

Authenticated Windows checks

In order for Nexpose to execute authenticated Windows checks, it must have access to either WMI or the Remote Registry service, which is usually discovered using a default account check (known default passwords) or administrative credentials specified in the site configuration of the Nexpose web interface.

ActiveXControlInstalled - Checks for the presence of an ActiveX control

The <ActiveXControlInstalled> element allows you to test for the presence of ActiveX control on a Windows system (by GUID). By default, this element does honor the kill-bit. In other words, if the ActiveX control is installed but the kill-bit is set, the check will report "not vulnerable". If you want to report the vulnerability even if the kill-bit is set, specify <ActiveXControlInstalled honorKillBit="0">

ibm-access-support-activex-bof.vck

<?xml version='1.0' encoding='UTF-8'?>
<VulnerabilityCheck id="ibm-access-support-activex-bof" scope="node" version="1.0">
   <ActiveXControlInstalled guid="74FFE28D-2378-11D5-990C-006094235084"/>
</VulnerabilityCheck>

WindowsRegistry - Checks for registry keys/values in the Windows registry

Windows registry check tests are tests which check for the existence of certain keys, values, or value data in a windows registry service found by Nexpose during a scan

w32-protoride-b-worm.vck

<VulnerabilityCheck id="w32-protoride-b-worm" scope="node">
   <WindowsRegistry>
      <registryKey name="HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run" mustNotBePresent="1">
         <registryValue name="Windows Taskbar Manager"><regex cflags="REG_ICASE">.*</regex></registryValue>
      </registryKey>
   </WindowsRegistry>
</VulnerabilityCheck>

The <WindowsRegistry> element is the top-level element of a windows registry test. This element must contain at least one <registryKey> sub-element. No other elements are allowed.

The <registryKey> element is the top-level element describing a registry key and value to test for. It has two attributes: name and mustNotBePresent. The name is the name of the registry key to check for. The mustNotBePresent attribute is worded a backwards. If mustNotBePresent="1", it means "Fire this check if the key is present, otherwise return not vulnerable".

The <registryValue> element specifies the expected data assigned to a specific registry value. It contains three attributes: name, type and default.

  • The name attribute specifies the name of the registry value (under the parent key).
  • The type attribute specifies the expected type of the registry value, which must be one of: REG_SZ, REG_EXPAND_SZ, REG_BINARY, REG_DWORD, REG_DWORD_LITTLE_ENDIAN,, REG_DWORD_BIG_ENDIAN, REG_LINK, REG_MULTI_SZ, REG_RESOURCE_LIST, REG_FULL_RESOURCE_DESCRIPTOR, REG_RESOURCE_REQUIREMENTS_LIST, REG_QWORD, REG_QWORD_LITTLE_ENDIAN. See http://msdn.microsoft.com/en-us/library/ms724884%28VS.85%29.aspx for more information on different value types.
  • The default attribute is used when you want to check for the registry "default value" under a key without specifying the name attribute.

If you want to test for existence of registry keys and registry values, use the <registryKeyExists> and <registryValueExists> elements.

trojan-gimmiv.vck

<VulnerabilityCheck id="trojan-gimmiv" scope="node">
  <or>
    <!-- created by the dropper component (Gimmiv.A) -->
    <WindowsRegistry>
      <registryKeyExists name="HKLM\SYSTEM\CurrentControlSet\Services\sysmgr\Parameters">
        <registryValueExists name="ServiceDll"/>
        <registryValueExists name="ServiceMain"/>
      </registryKeyExists>
      <registryKeyExists name="HKLM\SYSTEM\CurrentControlSet\Services\sysmgr">
        <registryValueExists name="DisplayName"/>
        <registryValueExists name="ImagePath"/>
      </registryKeyExists>
    </WindowsRegistry>
    <WindowsFileExists>
      <!-- created by the dropper component (Gimmiv.A) -->
      <fileExists name="%CSIDL_SYSTEM%\wbem\sysmgr.dll"/>
      <!-- created by the worm component (Gimmiv.B) -->
      <fileExists name="%CSIDL_SYSTEM%\wbem\winbaseInst.exe"/>
      <fileExists name="%CSIDL_SYSTEM%\wbem\winbase.dll"/>
      <fileExists name="%CSIDL_SYSTEM%\wbem\basesvc.dll"/>
      <fileExists name="%CSIDL_SYSTEM%\wbem\syicon.dll"/>
    </WindowsFileExists>
  </or>
</VulnerabilityCheck>

WindowsFileExists - check for existence of files

The <fileExists> element is used to determine whether or not a file is available on a system. The trojan-gimmiv.vck example above shows an example of how this check works. The name attribute is the name of the file. Certain well-known Windows paths can be specified using percent substitution. For example, it is not always known where the Windows directory is. Usually, this is ‘C:\WINDOWS’, however it may vary depending on the configuration of the device. During runtime (scanning), Nexpose will discover the windows root for the device under test and replace the ‘%windir%’ string in the path for the fileVersion test with the actual windows root directory on the device. The following substitution strings are supported:

  • %SystemDrive%
  • %windir%
  • %CSIDL_SYSTEM%
  • %CSIDL_SYSTEMX86%
  • %ProgramFiles%
  • %ProgramFiles(x86)%
  • %CommonProgramFiles%
  • %CSIDL_PROGRAM_FILES_COMMONX86%
  • %SQLPath%
  • %ExchangePath%
  • %OfficePath%

WindowsFileVersion - check for version of a Windows .EXE or .DLL

<WindowsFileVersion> tests allow testing of versions retrieved from files on the file system of the endpoint under test during a scan. If a file versioning service is found during a scan, Nexpose will use them to execute these tests.

A file version check test would resemble the following:

<WindowsFileVersion>
  <fileVersion name="%windir%\system32\scesrv.dll" mustExist="1">
    <version><range><high inclusive="0">5.0.2195.3649</high></range></version>
  </fileVersion>
</WindowsFileVersion>

Here is a more complex check which contains tests for a specific file version only on Windows XP SP2 (a combination of system and windows file version check tests).

<VulnerabilityCheck id="acme-windows-file-check-1" scope="node" version="1.0">
  <System>
    <OS minCertainty="1.0" name="Windows XP Professional" vendor="Microsoft">
      <version>
        <value>SP2</value>
      </version>
    </OS>
  </System>
  <WindowsFileVersion>
    <fileVersion name="%windir%\system32\shsvcs.dll" mustExist="1">
      <version><range><high inclusive="0">6.0.2900.3051</high></range></version>
    </fileVersion>
  </WindowsFileVersion>
</VulnerabilityCheck>

Here is an example check for a particular version of Internet Explorer which tests multiple registry values for that specific product.

<VulnerabilityCheck id="acme-windows-registry-check-1" scope="node" version="1.0">
  <InstalledSoftware>
    <Product minCertainty="1.0" name="Internet Explorer" vendor="Microsoft">
      <version>
        <value>5.01 SP4</value>
      </version>
    </Product>
  </InstalledSoftware>
  <WindowsRegistry>
    <registryKey name="HKLM\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{D9998BD0-7957-11D2-8FED-00606730D3AA}">
      <registryValue name="Compatibility Flags" type="REG_DWORD">
        <value>1024</value>
      </registryValue>
    </registryKey>
    <registryKey name="HKLM\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{BE4191FB-59EF-4825-AEFC-109727951E42}">
      <registryValue name="Compatibility Flags" type="REG_DWORD">
        <value>1024</value>
      </registryValue>
    </registryKey>
  </WindowsRegistry>
</VulnerabilityCheck>

InstalledSoftware - checks for version of installed software

<InstalledSoftware>
    <Product minCertainty="1.0" name="Exchange 2000 Server" vendor="Microsoft">
      <version>
        <value>SP3</value>
      </version>
    </Product>
  </InstalledSoftware>

Default account checks

In Nexpose, all username/password checks work basically the same way. You have a <NetworkService> element with the type of service, followed by a <DefaultAccount> element. The <uid> and <password> elements should be self-explanatory. The optional <realm> element can be used to specify either a domain name (for CIFS), a database or schema (for database authentication), or an authentication realm (for HTTP).

The following type attribute values can be used for <NetworkService> with a <DefaultAccount> check:

  • "IBM AS400 PortMapper"
  • "pcAnywhere-control"
  • "CIFS" (optional <realm> specifies Windows domain name)
  • "DB2" (<realm> specifies database name, e.g. SAMPLE)
  • "FTP"
  • "HTTP"
  • "MySQL" (<realm> specifies database name, e.g. mysql)
  • "Novell Netware"
  • "Oracle" (<realm> specifies database name)
  • "Postgres" (<realm> specifies database name, e.g. template1)
  • "Remote Execution" (rexec i.e. port 512/tcp)
  • "SNMP" (specify only the <password> element which will be the SNMP community name, e.g. private)
  • "SSH"
  • "TDS" (Microsoft SQL Server, <realm> specifies database name, e.g. master)
  • "Sybase" (<realm> specifies database name, e.g. master)
  • "Telnet"

cifs-default-password-administrator-password.vck (checks for Administrator/password on CIFS)

<VulnerabilityCheck id="CIFS-GENERIC-0002" scope="node">
   <NetworkService type="CIFS"/>
   <DefaultAccount>
      <uid>Administrator</uid>
      <password>password</password>
   </DefaultAccount>
</VulnerabilityCheck>

ssh-default-account-root-password-password.vck (checks for root/password on SSH)

<VulnerabilityCheck id="ssh-default-account-root-password-password" scope="endpoint">
   <NetworkService type="SSH"/>
   <DefaultAccount>
      <uid>root</uid>
      <password>password</password>
   </DefaultAccount>
</VulnerabilityCheck>

telnet-default-account-root-password-password.vck (checks for root/password on Telnet)

<VulnerabilityCheck id="telnet-default-account-root-password-password" scope="endpoint">
   <NetworkService type="Telnet"/>
   <DefaultAccount>
      <uid>root</uid>
      <password>password</password>
      <realm></realm>
   </DefaultAccount>
</VulnerabilityCheck>

mysql-default-account-admin-nopassword.vck (checks for admin with no password on MySQL)

<VulnerabilityCheck id="mysql-default-account-admin-nopassword" scope="endpoint">
   <NetworkService type="MySQL"/>
   <DefaultAccount>
      <uid>admin</uid>
      <password></password>
      <realm>mysql</realm>
   </DefaultAccount>
</VulnerabilityCheck>

Operating System fingerprint checks

<System>
    <OS minCertainty="1.0" name="Windows NT Server" vendor="Microsoft">
      <version>
        <value>4.0 SP5</value>
      </version>
      <version>
        <value>4.0 SP6a</value>
      </version>
      <version>
        <value>4.0 SP4</value>
      </version>
    </OS>
  </System>

Denial-of-service checks

Sometimes you want to do an unsafe check, for example a denial-of-service. In this case, set the safe attribute of <VulnerabilityCheck> to "0". This will cause this check to be skipped unless the user explicitly enables unsafe checks in their scan template.

<VulnerabilityCheck id="http-jrun-long-url-bof" safe="0" scope="endpoint">
   <NetworkService type="HTTP|HTTPS">
      <Product name="JRun"/>
   </NetworkService>
   <HTTPCheck retries="3">
      <HTTPRequest method="GET">
         <URI>/<garbage length="5200">R7</garbage>.jsp</URI>
      </HTTPRequest>
      <HTTPResponse><thrownException class="java.io.IOException"/></HTTPResponse>
   </HTTPCheck>
   <TCPStatusCheck wait="2500" status="closed"/>
</VulnerabilityCheck>

Boolean expressions

Sometimes you may want to group a set of checks with <and> or <or> (or either in combination) to form complex boolean tests. For example:

VulnerabilityCheck id=”example-http-sensitive-data” scope=”endpoint”>
<NetworkService type=”HTTP|HTTPS”/>
<HTTPCheck>
   <HTTPRequest method=”GET”><URI>/</URI>
   <HTTPResponse code=”200”>
      <or>
         <regex>secret password</regex>
         <regex>SSN: [0-9]{3}-[0-9]{2}-[0-9]{4}</regex>
      </or>
   </HTTPResponse>
</HTTPCheck>
</VulnerabilityCheck>

Common Vulnerability Check Examples