153 lines
5.4 KiB
Plaintext
153 lines
5.4 KiB
Plaintext
|
|
-----------------
|
|
1. Introduction
|
|
-----------------
|
|
|
|
With skipfish signatures it is possible to find interesting content,
|
|
or even vulnerabilities, in server responses. The signatures follow
|
|
a Snort-like syntax and most keywords behave similarly as well.
|
|
|
|
Signatures focus on detecting web application vulnerabilities, information
|
|
leaks and can recognize interesting web applications, such as phpmyadmin
|
|
or phpinfo() pages.
|
|
|
|
Signatures could also detect vulnerable software packages (e.g. old
|
|
WordPress instances) but this is a task that fits vulnerability scanners,
|
|
like Nessus and Nikto, better.
|
|
|
|
-----------------
|
|
2. Contributing
|
|
-----------------
|
|
|
|
The current signature list is nice but far from complete. If you have
|
|
new signatures or can optimize existing ones, please help out by reporting
|
|
this via our issue tracker:
|
|
|
|
https://code.google.com/p/skipfish/issues/entry?template=Content%20signatures
|
|
|
|
-----------------------
|
|
3. Signature keywords
|
|
-----------------------
|
|
|
|
=== content:[!]"<string>"
|
|
|
|
The content keyword is used to specify a string that we try to match
|
|
against the server response. The value can either be a static string or
|
|
a regular expression (the latter requires the type:regex; modifier).
|
|
|
|
Multiple content strings can be specified per signature and, unless the
|
|
signature specifies a mime type, there should be at least one.
|
|
|
|
Modifiers can be specified per content keyword to influence how the string
|
|
is matches against the payload. For example, with the 'depth' keyword
|
|
you can specify how far in the payload we should look for the string.
|
|
|
|
When ! is specified before the content string, the test is positive when
|
|
the string is NOT present. This is mainly useful in case your signature
|
|
has multiple content values.
|
|
|
|
Note: content string modifiers should be specified _after_ the content
|
|
string to which they apply.
|
|
|
|
=== content modifier: depth:<int>
|
|
|
|
With depth you can limit the amount of bytes we should search for the
|
|
string. Initially the depth is relative to the beginning of the
|
|
payload. However, when multiple 'content' strings are used, the depth
|
|
is relative to the first byte after the previous content match.
|
|
|
|
Using the depth keyword has two advantages: increase performance and
|
|
increase signature accuracy.
|
|
|
|
1) Performance: A signature that matches on a <title> tag doesn't need
|
|
to be applied to the whole payload. Instead, a depth of 512 or even
|
|
1024 bytes will help to improve performance.
|
|
|
|
2) Accuracy: In a signature with two 'content' keywords, you can force the
|
|
second keyword to be searched within a very short depth of the previous
|
|
content match.
|
|
|
|
=== content modifier: offset:<int>
|
|
|
|
The content string searching will start at the given offset value. For
|
|
the first content string this is relative to the beginning of the
|
|
payload. For the following content strings, this is relative to the
|
|
first byte of the last match.
|
|
|
|
=== content modifier: type:["regex|static"]
|
|
|
|
Indicates whether the content string should be treated as a regular
|
|
expression or a static string. Content strings are treated as static by
|
|
default so you can leave this keyword out unless you're using a regular
|
|
expression.
|
|
|
|
In a signature that has multiple content strings, static strings can be
|
|
mixed with regular expressions. You'll likely get the best performance
|
|
by starting with a static string before applying a regular expression.
|
|
|
|
=== mime:"<string>"
|
|
|
|
The given value will be compared with the MIME type specified by the
|
|
server. This is a "begins with" comparison so a partial MIME string,
|
|
like "javascript/" will match with a server value of "javascript/foo".
|
|
|
|
=== memo:"<string>"
|
|
|
|
The memo message is displayed in the report when the signature
|
|
matches. The content should be a short but meaningful problem title.
|
|
|
|
=== sev:[1-4]
|
|
|
|
The severity with which a signature match should be reported where:
|
|
|
|
- 1 is High
|
|
- 2 is Medium
|
|
- 3 is Low
|
|
- 4 is Info (default)
|
|
|
|
=== prob:"<string>"
|
|
|
|
All issue types are defined in database.h and, by default, signature
|
|
matches are reported with generic (signature) issue types.
|
|
|
|
Using the prob keyword, a signature match can be reported as any other
|
|
known issue. For example, issue 40401 stands for interesting files and
|
|
is already used for several signatures.
|
|
|
|
The advantage of using an existing issue ID is that it's severity and
|
|
description will be used to report the signature match.
|
|
|
|
=== check:<int>
|
|
|
|
Injection tests have their own ID which are specified in checks.h. Using
|
|
the "check" keyword, it is possible to bind a signature to a specific
|
|
injection test.
|
|
|
|
The idea is to allow context specific signatures to be written. Take the
|
|
following scenario as an example: During a scan, file disclosure tests
|
|
might not fully succeed to highlight a vulnerability. Errors thrown
|
|
during these tests can still reveal that there is more than likely a
|
|
file disclosure problem. While generic server error detection will
|
|
highlight these errors, it is more useful if we can detect that these
|
|
errors are related to our tests and report them as such.
|
|
|
|
=== id:<int>
|
|
|
|
The unique signature ID. Currently this is for documentation purpose only
|
|
but in the future we'll probably add signature chaining which requires
|
|
unique ID's as well.
|
|
|
|
|
|
|
|
-----------------------
|
|
3. Upcoming keywords
|
|
-----------------------
|
|
|
|
Amongst other changes, it's likely that the next release will have the
|
|
following keywords implemented:
|
|
|
|
1) nocase - for case insensitive matching
|
|
2) ssl - match against SSL responses only
|
|
3) header - match against a specific header
|
|
|