From c9d5b74896dd6fdf4581847c57455c774d272cdf Mon Sep 17 00:00:00 2001
From: Steve Pinkham
Date: Wed, 12 Sep 2012 17:06:51 -0400
Subject: [PATCH] Version 2.08b: Many changes including dir refactor
- Added Host header XSS testing.
- Added HTML encoding XSS tests to detect scenarios where our
injection string ends up in an attributes that execute HTML encoded
Javascript. For example: onclick.
- Bruteforcing is now disabled for URLs that gave a directory listing.
- Added subject alternate name checking for SSL certificates (cheers
to Matt Caroll for his feedback)
- Added signature matching (see doc/signatures.txt) which means a lot
of the content based issues are no longer hardcoded.
- Added active XSSI test. The passive XSSI stays (for now) but this
active check is more acurate and will remove issues detected by the
passive one if they cannot be confirmed. This reduces false
positives
- Added HTML tag XSS test which triggers when our payload is used
as a tag attribute value but without quotes (courtesy of wavsep).
- Added javascript: scheme XSS testing (courtesy of wavsep).
- Added form based authentication. During these authenticated
scans, skipfish will check if the session has ended and re-authenticates
if necessary.
- Fixed a bug where in slow scans the console output could mess up
due to the high(er) refresh rate.
- Fixed a bug where a missed response during the injection tests could
result in a crash. (courtesy of Sebastian Roschke)
- Restructure the source package a bit by adding a src/, doc/ and
tools/ directory.
---
ChangeLog | 38 ++
Makefile | 36 +-
README | 29 +-
assets/index.html | 8 +-
dictionaries/extensions-only.wl | 2 -
doc/authentication.txt | 98 +++
.../README-FIRST => doc/dictionaries.txt | 0
doc/signatures.txt | 152 +++++
skipfish.1 => doc/skipfish.1 | 0
signatures/apps.sigs | 13 +
signatures/context.sigs | 24 +
signatures/files.sigs | 42 ++
signatures/messages.sigs | 45 ++
signatures/mime.sigs | 13 +
signatures/signatures.conf | 28 +
alloc-inl.h => src/alloc-inl.h | 0
analysis.c => src/analysis.c | 395 ++++--------
analysis.h => src/analysis.h | 17 +
src/auth.c | 279 +++++++++
src/auth.h | 74 +++
checks.c => src/checks.c | 532 +++++++++++++---
checks.h => src/checks.h | 41 +-
config.h => src/config.h | 9 +-
crawler.c => src/crawler.c | 27 +-
crawler.h => src/crawler.h | 1 +
database.c => src/database.c | 67 +-
database.h => src/database.h | 23 +-
debug.h => src/debug.h | 2 +-
http_client.c => src/http_client.c | 98 ++-
http_client.h => src/http_client.h | 12 +
report.c => src/report.c | 12 +-
report.h => src/report.h | 0
same_test.c => src/same_test.c | 0
src/signatures.c | 570 ++++++++++++++++++
src/signatures.h | 148 +++++
skipfish.c => src/skipfish.c | 225 ++++---
string-inl.h => src/string-inl.h | 35 +-
types.h => src/types.h | 0
sfscandiff => tools/sfscandiff | 0
39 files changed, 2551 insertions(+), 544 deletions(-)
create mode 100644 doc/authentication.txt
rename dictionaries/README-FIRST => doc/dictionaries.txt (100%)
create mode 100644 doc/signatures.txt
rename skipfish.1 => doc/skipfish.1 (100%)
create mode 100644 signatures/apps.sigs
create mode 100644 signatures/context.sigs
create mode 100644 signatures/files.sigs
create mode 100644 signatures/messages.sigs
create mode 100644 signatures/mime.sigs
create mode 100644 signatures/signatures.conf
rename alloc-inl.h => src/alloc-inl.h (100%)
rename analysis.c => src/analysis.c (87%)
rename analysis.h => src/analysis.h (94%)
create mode 100644 src/auth.c
create mode 100644 src/auth.h
rename checks.c => src/checks.c (75%)
rename checks.h => src/checks.h (65%)
rename config.h => src/config.h (97%)
rename crawler.c => src/crawler.c (99%)
rename crawler.h => src/crawler.h (99%)
rename database.c => src/database.c (96%)
rename database.h => src/database.h (95%)
rename debug.h => src/debug.h (99%)
rename http_client.c => src/http_client.c (96%)
rename http_client.h => src/http_client.h (97%)
rename report.c => src/report.c (98%)
rename report.h => src/report.h (100%)
rename same_test.c => src/same_test.c (100%)
create mode 100644 src/signatures.c
create mode 100644 src/signatures.h
rename skipfish.c => src/skipfish.c (73%)
rename string-inl.h => src/string-inl.h (88%)
rename types.h => src/types.h (100%)
rename sfscandiff => tools/sfscandiff (100%)
diff --git a/ChangeLog b/ChangeLog
index 46161ee..0355fde 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+Version 2.08b:
+
+ - Added Host header XSS testing.
+
+ - Added HTML encoding XSS tests to detect scenarios where our
+ injection string ends up in an attributes that execute HTML encoded
+ Javascript. For example: onclick.
+
+ - Bruteforcing is now disabled for URLs that gave a directory listing.
+
+ - Added subject alternate name checking for SSL certificates (cheers
+ to Matt Caroll for his feedback)
+
+ - Added signature matching (see doc/signatures.txt) which means a lot
+ of the content based issues are no longer hardcoded.
+
+ - Added active XSSI test. The passive XSSI stays (for now) but this
+ active check is more acurate and will remove issues detected by the
+ passive one if they cannot be confirmed. This reduces false positives
+
+ - Added HTML tag XSS test which triggers when our payload is used
+ as a tag attribute value but without quotes (courtesy of wavsep).
+
+ - Added javascript: scheme XSS testing (courtesy of wavsep).
+
+ - Added form based authentication. During these authenticated
+ scans, skipfish will check if the session has ended and re-authenticates
+ if necessary.
+
+ - Fixed a bug where in slow scans the console output could mess up
+ due to the high(er) refresh rate.
+
+ - Fixed a bug where a missed response during the injection tests could
+ result in a crash. (courtesy of Sebastian Roschke)
+
+ - Restructure the source package a bit by adding a src/, doc/ and
+ tools/ directory.
+
Version 2.07b:
--------------
diff --git a/Makefile b/Makefile
index 039065f..b824797 100644
--- a/Makefile
+++ b/Makefile
@@ -20,45 +20,49 @@
#
PROGNAME = skipfish
-VERSION = 2.07b
+VERSION = 2.08b
-OBJFILES = http_client.c database.c crawler.c analysis.c report.c \
- checks.c
-INCFILES = alloc-inl.h string-inl.h debug.h types.h http_client.h \
+SRCDIR = src
+SFILES = http_client.c database.c crawler.c analysis.c report.c \
+ checks.c signatures.c auth.c
+IFILES = alloc-inl.h string-inl.h debug.h types.h http_client.h \
database.h crawler.h analysis.h config.h report.h \
- checks.h
+ checks.h signatures.h auth.h
+
+OBJFILES = $(patsubst %,$(SRCDIR)/%,$(SFILES))
+INCFILES = $(patsubst %,$(SRCDIR)/%,$(IFILES))
CFLAGS_GEN = -Wall -funsigned-char -g -ggdb -I/usr/local/include/ \
-I/opt/local/include/ $(CFLAGS) -DVERSION=\"$(VERSION)\"
CFLAGS_DBG = -DLOG_STDERR=1 -DDEBUG_ALLOCATOR=1 $(CFLAGS_GEN)
-CFLAGS_OPT = -O3 -Wno-format $(CFLAGS_GEN)
+CFLAGS_OPT = -O3 -Wno-format $(CFLAGS_GEN)
LDFLAGS += -L/usr/local/lib/ -L/opt/local/lib
-LIBS += -lcrypto -lssl -lidn -lz
+LIBS += -lcrypto -lssl -lidn -lz -lpcre
all: $(PROGNAME)
-$(PROGNAME): $(PROGNAME).c $(OBJFILES) $(INCFILES)
- $(CC) $(LDFLAGS) $(PROGNAME).c -o $(PROGNAME) $(CFLAGS_OPT) \
- $(OBJFILES) $(LIBS)
+$(PROGNAME): $(SRCDIR)/$(PROGNAME).c $(OBJFILES) $(INCFILES)
+ $(CC) $(LDFLAGS) $(SRCDIR)/$(PROGNAME).c -o $(PROGNAME) \
+ $(CFLAGS_OPT) $(OBJFILES) $(LIBS)
@echo
- @echo "See dictionaries/README-FIRST to pick a dictionary for the tool."
+ @echo "See doc/dictionaries.txt to pick a dictionary for the tool."
@echo
@echo "Having problems with your scans? Be sure to visit:"
@echo "http://code.google.com/p/skipfish/wiki/KnownIssues"
@echo
-debug: $(PROGNAME).c $(OBJFILES) $(INCFILES)
- $(CC) $(LDFLAGS) $(PROGNAME).c -o $(PROGNAME) $(CFLAGS_DBG) \
- $(OBJFILES) $(LIBS)
+debug: $(SRCDIR)/$(PROGNAME).c $(OBJFILES) $(INCFILES)
+ $(CC) $(LDFLAGS) $(SRCDIR)/$(PROGNAME).c -o $(PROGNAME) \
+ $(CFLAGS_DBG) $(OBJFILES) $(LIBS)
clean:
rm -f $(PROGNAME) *.exe *.o *~ a.out core core.[1-9][0-9]* *.stackdump \
LOG same_test
rm -rf tmpdir
-same_test: same_test.c $(OBJFILES) $(INCFILES)
- $(CC) same_test.c -o same_test $(CFLAGS_DBG) $(OBJFILES) $(LDFLAGS) \
+same_test: $(SRCDIR)/same_test.c $(OBJFILES) $(INCFILES)
+ $(CC) $(SRCDIR)/same_test.c -o same_test $(CFLAGS_DBG) $(OBJFILES) $(LDFLAGS) \
$(LIBS)
publish: clean
diff --git a/README b/README
index 569cabd..f068618 100644
--- a/README
+++ b/README
@@ -85,6 +85,9 @@ associated with web security scanners. Specific advantages include:
stored XSS (path, parameters, headers), blind SQL or XML injection,
or blind shell injection.
+ * Snort style content signatures which will highlight server errors,
+ information leaks or potentially dangerous web applications.
+
* Report post-processing drastically reduces the noise caused by any
remaining false positives or server gimmicks by identifying repetitive
patterns.
@@ -274,23 +277,15 @@ report will be non-destructively annotated by adding red background to all
new or changed nodes; and blue background to all new or changed issues
found.
-Some sites may require authentication; for simple HTTP credentials, you can
-try:
+Some sites may require authentication for which our support is described
+in docs/authentication.txt. In most cases, you'll be wanting to use the
+form authentication method which is capable of detecting broken sessions
+in order to re-authenticate.
-$ ./skipfish -A user:pass ...other parameters...
-
-Alternatively, if the site relies on HTTP cookies instead, log in in your
-browser or using a simple curl script, and then provide skipfish with a
-session cookie:
-
-$ ./skipfish -C name=val ...other parameters...
-
-Other session cookies may be passed the same way, one per each -C option.
-
-Certain URLs on the site may log out your session; you can combat this in two
-ways: by using the -N option, which causes the scanner to reject attempts to
-set or delete cookies; or with the -X parameter, which prevents matching URLs
-from being fetched:
+Once authenticated, certain URLs on the site may log out your session;
+you can combat this in two ways: by using the -N option, which causes
+the scanner to reject attempts to set or delete cookies; or with the -X
+parameter, which prevents matching URLs from being fetched:
$ ./skipfish -X /logout/logout.aspx ...other parameters...
@@ -544,8 +539,6 @@ know:
* Scheduling and management web UI.
- * A database for banner / version checks or other configurable rules?
-
-------------------------------------
9. Oy! Something went horribly wrong!
-------------------------------------
diff --git a/assets/index.html b/assets/index.html
index f50e54c..ce036f9 100644
--- a/assets/index.html
+++ b/assets/index.html
@@ -278,6 +278,7 @@ var issue_desc= {
"10804": "Conflicting MIME / charset info (low risk)",
"10901": "Numerical filename - consider enumerating",
"10902": "OGNL-like parameter behavior",
+ "10909": "Signature match (informational)",
"20101": "Resource fetch failed",
"20102": "Limits exceeded, fetch suppressed",
@@ -294,6 +295,7 @@ var issue_desc= {
"30203": "SSL certificate host name mismatch",
"30204": "No SSL certificate data found",
"30205": "Weak SSL cipher negotiated",
+ "30206": "Host name length mismatch (name string has null byte)",
"30301": "Directory listing restrictions bypassed",
"30401": "Redirection to attacker-supplied URLs",
"30402": "Attacker-supplied URLs in embedded content (lower risk)",
@@ -305,11 +307,13 @@ var issue_desc= {
"30701": "Incorrect caching directives (lower risk)",
"30801": "User-controlled response prefix (BOM / plugin attacks)",
"30901": "HTTP header injection vector",
+ "30909": "Signature match detected",
"40101": "XSS vector in document body",
"40102": "XSS vector via arbitrary URLs",
"40103": "HTTP response header splitting",
"40104": "Attacker-supplied URLs in embedded content (higher risk)",
+ "40105": "XSS vector via injected HTML tag attribute",
"40201": "External content embedded on a page (higher risk)",
"40202": "Mixed content embedded on a page (higher risk)",
"40301": "Incorrect or missing MIME type (higher risk)",
@@ -321,6 +325,7 @@ var issue_desc= {
"40501": "Directory traversal / file inclusion possible",
"40601": "Incorrect caching directives (higher risk)",
"40701": "Password form submits from or to non-HTTPS page",
+ "40909": "Signature match detected (higher risk)",
"50101": "Server-side XML injection vector",
"50102": "Shell injection vector",
@@ -329,7 +334,8 @@ var issue_desc= {
"50105": "Integer overflow vector",
"50106": "File inclusion",
"50201": "SQL query or similar syntax in parameters",
- "50301": "PUT request accepted"
+ "50301": "PUT request accepted",
+ "50909": "Signature match detected (high risk)"
};
diff --git a/dictionaries/extensions-only.wl b/dictionaries/extensions-only.wl
index 16605ed..45c183f 100644
--- a/dictionaries/extensions-only.wl
+++ b/dictionaries/extensions-only.wl
@@ -86,7 +86,6 @@ e 1 1 1 sql
e 1 1 1 stackdump
e 1 1 1 svn-base
e 1 1 1 swf
-e 1 1 1 swp
e 1 1 1 tar
e 1 1 1 tar.bz2
e 1 1 1 tar.gz
@@ -107,4 +106,3 @@ e 1 1 1 xsl
e 1 1 1 xslt
e 1 1 1 yml
e 1 1 1 zip
-e 1 1 1 ~
diff --git a/doc/authentication.txt b/doc/authentication.txt
new file mode 100644
index 0000000..b06210a
--- /dev/null
+++ b/doc/authentication.txt
@@ -0,0 +1,98 @@
+
+
+This document describes 3 different methods you can use to run
+authenticated skipfish scans.
+
+ 1) Form authentication
+ 2) Cookie authentication
+ 3) Basic HTTP authentication
+
+
+
+-----------------------
+1. Form authentication
+----------------------
+
+With form authentication, skipfish will submit credentials using the
+given login form. The server is expected to reply with authenticated
+cookies which will than be used during the rest of the scan.
+
+An example to login using this feature:
+
+$ ./skipfish --auth-form http://example.org/login \
+ --auth-user myuser \
+ --auth-pass mypass \
+ --auth-verify-url http://example.org/profile \
+ [...other options...]
+
+This is how it works:
+
+1. Upon start of the scan, the authentication form at /login will be
+ fetched by skipfish. We will try to complete the username and password
+ fields and submit the form.
+
+2. Once a server response is obtained, skipfish will fetch the
+ verification URL twice: once with the new session cookies and once
+ without any cookies. Both responses are expected to be different.
+
+3. During the scan, the verification URL will be used many times to
+ test whether we are authenticated. If at some point our session has
+ been terminated server-side, skipfish will re-authenticate using the
+ --auth-form (/login in our example) .
+
+Verifying whether the session is still active requires a good verification
+URL where an authenticated request is going to get a different response
+than an anonymous request. For example a 'profile' or 'my account' page.
+
+Troubleshooting:
+----------------
+
+1. Login field names not recognized
+
+ If the username and password form fields are not recognized, skipfish
+ will complain. In this case, you should specify the field names using
+ the --auth-user-field and --auth-pass-field flags.
+
+2. The form is not submitted to the right location
+
+ If the login form doesn't specify an action="" location, skipfish
+ will submit the form's content to the form URL. This will fail in some
+ occasions. For example, when the login page uses Javascript to submit
+ the form to a different location.
+
+ Use the --auth-form-target flag to specify the URL where you want skipfish
+ to submit the form to.
+
+3. Skipfish keeps getting logged out
+
+ Make sure you blacklist any URLs that will log you out. For example,
+ using the " -X /logout"
+
+
+-------------------------
+2. Cookie authentication
+-------------------------
+
+Alternatively, if the site relies on HTTP cookies you can also feed these
+to skipfish manually. To do this log in using your browser or using a
+simple curl script, and then provide skipfish with a session cookie:
+
+$ ./skipfish -C name=val [...other options...]
+
+Other session cookies may be passed the same way, one per each -C option.
+
+The -N option, which causes new cookies to be rejected by skipfish,
+is almost always a good choice when running cookie authenticated scans
+(e.g. to avoid your precious cookies from being overwritten).
+
+$ ./skipfish -N -C name=val [...other options...]
+
+-----------------------------
+3. Basic HTTP authentication
+-----------------------------
+
+For simple HTTP credentials, you can use the -A option to pass the
+credentials.
+
+$ ./skipfish -A user:pass [...other options...]
+
diff --git a/dictionaries/README-FIRST b/doc/dictionaries.txt
similarity index 100%
rename from dictionaries/README-FIRST
rename to doc/dictionaries.txt
diff --git a/doc/signatures.txt b/doc/signatures.txt
new file mode 100644
index 0000000..c648bb7
--- /dev/null
+++ b/doc/signatures.txt
@@ -0,0 +1,152 @@
+
+-----------------
+ 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:[!]""
+
+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:
+
+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 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:
+
+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:""
+
+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:""
+
+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:""
+
+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:
+
+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:
+
+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
+
diff --git a/skipfish.1 b/doc/skipfish.1
similarity index 100%
rename from skipfish.1
rename to doc/skipfish.1
diff --git a/signatures/apps.sigs b/signatures/apps.sigs
new file mode 100644
index 0000000..663855f
--- /dev/null
+++ b/signatures/apps.sigs
@@ -0,0 +1,13 @@
+
+# ##############################################
+# Detect interesting apps / pages that leak info
+# and where their exposure is a security risk by
+# default.
+
+# A phpinfo() page
+id:11001; sev:3; content:"phpinfo()phpMyAdmin '; depth:1024; content:''; depth:2048; memo:"phpMyAdmin";
+
+id:11003; sev:3; content:"Parallels Plesk Panel"; depth:1024; content:'action="/login_up.php3" method="post"'; memo:"Plesk administrative interface";
diff --git a/signatures/context.sigs b/signatures/context.sigs
new file mode 100644
index 0000000..240bcf6
--- /dev/null
+++ b/signatures/context.sigs
@@ -0,0 +1,24 @@
+
+###############################
+# CONTEXT SPECIFIC SIGNATURES
+#
+# During some injection tests we might not be able to determine that
+# the server is vulnerable. However, some server messages can give away
+# the fact that the underlying logic can likely be abused. The signatures
+# in this file look for such messages and are all linked to individual
+# injection tests. For example: we look for I/O errors during local file
+# disclosure attacks.
+
+#####################################################
+# Signatures for check 8: File inclusion / disclosure
+
+# PHP errors for include(), fopen(), include_once(), file_get_contents(), etc
+id:51001; sev:2; check:8; content:"["; depth:512; memo:"Flash crossdomain file";
+id:31009; sev:3; content:""; depth:512; memo:"Silverlight cross-domain policy";
+
+# Web.xml config file
+id:31010; sev:3; content:"" content:!""; memo:"PHP source";
+id:32005; sev:3; content:"<%@"; content:"%>"; memo:"JSP source";
+id:32006; sev:3; content:"<%"; content:"%>"; memo:"ASP source";
+# These two need to be improved!
+id:32007; sev:3; content:"@echo "; depth:256; memo:"DOS batch script";
+id:32008; sev:3; content:"(\"Wscript."; depth:256; memo:"Windows shell script";
+
+
diff --git a/signatures/messages.sigs b/signatures/messages.sigs
new file mode 100644
index 0000000..02b0a45
--- /dev/null
+++ b/signatures/messages.sigs
@@ -0,0 +1,45 @@
+
+#####################################
+# INTERESTING SERVER ERRORS
+
+# SQL related error strings
+id:21001; prob:40402; content:"Warning: MySQL: "; memo:"MySQL error string";
+id:21002; prob:40402; content:"Unclosed quotation mark"; memo:"SQL error string";
+id:21003; prob:40402; content:"java.sql.SQLException:"; memo:"Java SQL exception";
+id:21004; prob:40402; content:"SqlClient.SqlException: Syntax error"; memo:"SqlClient exception";
+id:21005; prob:40402; content:"PostgreSQL query failed"; memo:"PostgreSQL query failed";
+id:21006; prob:40402; content:"Dynamic SQL Error"; memo:"SQL error string";
+id:21007; prob:40402; content:"unable to perform query"; memo:"Possible SQL error string";
+id:21008; prob:40402; content:"Microsoft OLE DB Provider for ODBC Drivers"; memo:"OLE SQL error";
+id:21009; prob:40402; content:"[Microsoft][ODBC SQL Server Driver]"; memo:"Microsoft SQL error";
+id:21010; prob:40402; content:"Syntax error in string in query expression"; memo:"SQL syntax string";
+id:21011; prob:40402; content:"You have an error in your SQL syntax; "; memo:"SQL syntax error";
+id:21012; prob:40402; content:"Incorrect syntax near"; memo:"SQL syntax error";
+id:21013; prob:40402; content:"[DM_QUERY_E_SYNTAX]"; memo:"SQL syntax error";
+
+# Stacktraces and server errors
+id:22001; prob:40402; content:"