Each rule set is found in a file under the rules directory. The rules are written using standard PERL operators and regular expressions. See a PERL manual or the examples below if you are unfamiliar with PERL.
The cve rule set contains rules that map vulnerability records to the corresponding CVE numbers, encoded DOD-CERT Information Assurance Vulnerability Alert (IAVA) numbers, and other standards if necessary. Each rule is applied once for each SAINT record that contains a vulnerability. (See the Database Format section.)
The rule format is:
condition TAB [yes|no] TAB CVE number(s) TAB IAVA number(s) TAB other
Each condition is applied to the text field of each vulnerability record. If there is a match, then the corresponding CVE number(s) and/or IAVA number(s), if present and non-zero, are assigned to the vulnerability. If a record does not match any of the conditions in rules/cve, then no CVE/IAVA number is associated with the vulnerability. The second field indicates whether or not the vulnerability is one of the SANS Top 20 Internet Security Vulnerabilities. The word "yes" in this field indicates that the vulnerability is on the list.
For instance, suppose CVE 1999-2501 and IAVA 1999-A-0101 correspond to the vulnerability whose output is myservice is vulnerable, which is on the Top 20 list. Therefore, the rule is:
/myservice is vulnerable/i yes CVE-1999-2501 a7B93kGia90Xhpx
The random string of characters at the end of the line is the encoded IAVA number. The IAVA plug-in is required to decode this vulnerability. If this plug-in is present, the IAVA number will be decoded to IAVA 1999-A-0101. Otherwise, the IAVA field will be empty.
The fifth field, "other", is an optional value which can be used to map SAINT's vulnerability checks to a user-defined index. The value in this field, if present, is included in the scan results, and can be included in an optional column in SAINTwriter reports. By default, this field is empty.
This rule set specifies what data-collection tool output SAINT should ignore. This can be used to prevent SAINT from saving certain facts which are not important. (Note that this is not the same as an exclusion, which allows saved facts to be hidden from view.) Each rule is applied once for each SAINT record that has an "a" in the status field, meaning the host is available. (See Database Format.)
For instance, SAINT may detect what it thinks is an RDS vulnerability on myhost.com, even though you know for a fact that the patch has already been applied. In this case, we would tell SAINT not to report the RDS vulnerability for myhost.com:
$target eq "myhost.com" && $text =~ /RDS/
The $target variable holds the name of the target host (or the IP address if the name couldn't be resolved), and the $text variable holds the output of the SAINT probe, which in this case was http.saint. Any of the global SAINT variables can be used. Note that eq with quotes around the expression looks for an exact match, while the =~ operator with slashes around the expression will catch any string containing the expression. Other options are ne (not equal to) and !~ (does not contain).
The facts rule set deduces potential vulnerabilities from existing data. For example, several versions of the FTP daemon are known to have problems on certain operating systems. Daemon versions can be recognized by their greeting banners.
Each rule is executed once for each SAINT record that has an "a" in the status field, meaning that the host is available. (See Database Format.)
The rule format is:
condition TAB fact
(Note: TAB represents the tab character.)
For example, if we want to assume that if a host is running rexd it is insecure without trying to probe it further, we would put:
/runs rexd/
$target|rexd|a|us|ANY@$target|ANY@ANY|REXD access|rexd vulnerable
In order to understand the rules/facts file, you have to understand the Database Format. There are four macros which can appear in the condition part of the facts rule set:
The format of this file is:
CLASS class_name
condition TAB hosttype TAB certainty
(Note: TAB represents the tab character.)
The class_name is used for the first rough breakdown by host type in reports. It should be a major software category, such as SUN or WINDOWS. For example, here is the code for recognizing a SUN and its major OS revision:
CLASS SUN
UNKNOWN && /SunOS/ "SunOS 4"
/4.1\/SMI-4.1/ "SunOS 4"
/SMI-SVR4/ "SunOS 5"
While the code above may look fairly complex, it isn't really. Simply study the examples, and then modify the code in the examples to create your own rules.
The certainty field is a number from 1 to 10 which conveys the level of certainty that the inferred host type is actually correct. If multiple facts match different hosttype rules resulting in conflicting host types for the same target, the rule with the higher certainty is used. If this field is omitted, a value of 5 is assumed.
The information rule set instructs the SAINT engine to remember a particular piece of information about a target. The information can be recalled later in a facts rule. This allows SAINT to infer new facts based upon known information about a target in conjunction with other facts.
The format of this file is:
condition TAB identifier TAB value
(Note: TAB represents the tab character.)
When there is a fact which matches the condition, then the value is stored in memory, and can be recalled later using the identifier. If the value is omitted, then $1 (the first group marked by parentheses in the condition) is implied.
An example information rule is:
/Internet Explorer version: ([\d\.]+)/ ie_versionThis rule tells SAINT that when it finds, for example, a fact containing Internet Explorer version: 6.0, then it should remember the number 6.0. Later in the scan, the expression INFO(ie_version) can be used in a fact rule to infer a new fact based on the Internet Explorer version number.
The format of this file is:
class_name
condition TAB service_name TAB host
(Note: TAB represents the tab character.)
If host is omitted, the host in the target field of the fact is implied.
The class_name is one of the following:
For instance, to classify a host as an NNTP server, you'd simply do this in the SERVERS section:
$service eq "nntp" NNTP (Usenet news)
This rule set classifies services according to the software providing the service. For example, WWW service might be provided by Apache or IIS software. These rules are applied to SAINT records for the identified service.
The format of this file is:
SERVICE service_name
condition TAB software_name TAB host
(Note: TAB represents the tab character.)
The service name should match the beginning of one of the service names in the rules/services file. The condition is a PERL expression, with full access to the standard global SAINT variables (e.g., $target..$text). The software name specifies a name to identify the software, such as "Apache" or "IIS". If this field is not specified, the default is the first string captured by the pattern match with the condition (i.e., $1). The host field specifies the host that takes or provides the service. When no host is specified, the host in the target field of the fact ($target) is assumed.
For example, to classify Qualcomm as software type for the POP service, you might have a section:
SERVICE POP
/QPOP/i Qualcomm
Each rule is executed once for each SAINT record that has an "a" in the status field. (See Database Format)
The format of this file is:
condition TAB target tool tool-arguments
(Note: TAB represents the tab character.)
The condition is a logical expression, with the usual internal SAINT variables, that has to be satisfied in order for SAINT to run the probe specified. When the condition is satisfied, and the tool is allowed to be run conditionally at the current attack level (see SAINT Configuration), the tool is executed as:
tool tool-arguments target
SAINT keeps track of which tools have already been executed against which targets.
For instance, if a host is running ypserv, we would typically run the ypbind.saint probe against it. This would be done as follows:
$service eq "ypserv" $target "ypbind.saint"
It's easy to put in a probe that depends on the type of system that you're looking at. For instance, SGI/IRIX hosts have guest, lp, and other accounts with no password when taken out-of-the-box from SGI. Here's how you could check to see if this is a problem:
/IRIX/ $target "rsh.saint" "-u guest"
This rule would tell SAINT to run rsh.saint against every IRIX target. The "-u guest" argument tells rsh.saint to do an rsh as user guest to see if commands can be executed remotely. SAINT would then record this fact in the results. The todo rule set recognizes two macros. HOSTTTYPE is expanded to the host type of the target. SHORT_HOSTTYPE is expanded to a shortened version of the host type, stripped of OS revision and release numbers.
This rule set helps SAINT classify the data that was collected by the tools on NFS service, DNS, NIS, and other cases of trust. Each rule is executed once for each SAINT record that has an "a" in the status field. (See Database Format.)
The format of this file is:
condition TAB name of relationship
(Note: TAB represents the tab character.)
With the currrent rules/trust file, SAINT only begins to scratch the surface. It handles only the most easily detected forms of trust:
$severity eq "l" remote login
$text =~ /exports \S+ to/ file sharing
$text =~ / mounts \S+/ file sharing