diff --git a/NOTICE b/NOTICE index 553a3efc34..0501be9f03 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ ModSecurity (www.modsecurity.org) -    Copyright [2004-2011] Trustwave Holdings, Inc +    Copyright [2004-2013] Trustwave Holdings, Inc     This product includes software developed at     Trustwave Holdings, Inc (http://www.trustwave.com/). diff --git a/README.TXT b/README.TXT index ff2a0beef3..3647d08f9d 100644 --- a/README.TXT +++ b/README.TXT @@ -1,5 +1,5 @@ ModSecurity for Apache 2.x, http://www.modsecurity.org/ -Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) You may not use this file except in compliance with the License.  You may obtain a copy of the License at diff --git a/alp2/alp2.c b/alp2/alp2.c index fd2d6ba8b2..8a40272cc2 100755 --- a/alp2/alp2.c +++ b/alp2/alp2.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/alp2/alp2.h b/alp2/alp2.h index 332e3ca3df..2a159d5627 100644 --- a/alp2/alp2.h +++ b/alp2/alp2.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/alp2/alp2_pp.c b/alp2/alp2_pp.c index d88d636cf7..5649dc1854 100755 --- a/alp2/alp2_pp.c +++ b/alp2/alp2_pp.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/alp2/alp2_pp.h b/alp2/alp2_pp.h index 8ccdaeac16..ba5c090946 100644 --- a/alp2/alp2_pp.h +++ b/alp2/alp2_pp.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/Makefile.am b/apache2/Makefile.am index 38211f9b9d..b7bde26671 100644 --- a/apache2/Makefile.am +++ b/apache2/Makefile.am @@ -11,7 +11,7 @@ mod_security2_la_SOURCES = mod_security2.c \ re_variables.c msc_logging.c msc_xml.c \ msc_multipart.c modsecurity.c msc_parsers.c \ msc_util.c msc_pcre.c persist_dbm.c msc_reqbody.c \ - msc_geo.c msc_gsb.c msc_crypt.c msc_tree.c msc_unicode.c acmp.c msc_lua.c msc_release.c + msc_geo.c msc_gsb.c msc_crypt.c msc_tree.c msc_unicode.c acmp.c msc_lua.c msc_release.c libinjection/sqlparse.c mod_security2_la_CFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \ @PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @LUA_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @CURL_CFLAGS@ diff --git a/apache2/Makefile.win b/apache2/Makefile.win index c6c4bb6bc8..51e355a690 100644 --- a/apache2/Makefile.win +++ b/apache2/Makefile.win @@ -46,7 +46,7 @@ OBJS = mod_security2.obj apache2_config.obj apache2_io.obj apache2_util.obj \ msc_logging.obj msc_xml.obj msc_multipart.obj modsecurity.obj \ msc_parsers.obj msc_util.obj msc_pcre.obj persist_dbm.obj \ msc_reqbody.obj msc_geo.obj msc_gsb.obj msc_crypt.obj msc_tree.obj msc_unicode.obj acmp.obj msc_lua.obj \ - msc_release.obj + msc_release.obj libinjection\sqlparse.obj all: $(DLL) diff --git a/apache2/acmp.c b/apache2/acmp.c index 5f55b8e1df..6e796b38db 100644 --- a/apache2/acmp.c +++ b/apache2/acmp.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/acmp.h b/apache2/acmp.h index bc5f5b2f9b..6566516770 100644 --- a/apache2/acmp.h +++ b/apache2/acmp.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/apache2.h b/apache2/apache2.h index c658da3465..87a17ed2e9 100644 --- a/apache2/apache2.h +++ b/apache2/apache2.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/apache2_config.c b/apache2/apache2_config.c index c2ccc78779..71d955e273 100644 --- a/apache2/apache2_config.c +++ b/apache2/apache2_config.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/apache2_io.c b/apache2/apache2_io.c index e6f28b75fb..b961197ed3 100644 --- a/apache2/apache2_io.c +++ b/apache2/apache2_io.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ - * Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/apache2_util.c b/apache2/apache2_util.c index 11879b21e0..2f33c87e39 100644 --- a/apache2/apache2_util.c +++ b/apache2/apache2_util.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/libinjection/COPYING.txt b/apache2/libinjection/COPYING.txt new file mode 100644 index 0000000000..772b05624f --- /dev/null +++ b/apache2/libinjection/COPYING.txt @@ -0,0 +1,36 @@ +/* Copyright 2012, 2013 + * Nick Galbreath -- nickg [at] client9 [dot] com + * http://www.client9.com/projects/libinjection/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of libinjection nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This is the standard "new" BSD license: + * http://www.opensource.org/licenses/bsd-license.php + */ diff --git a/apache2/libinjection/sqli_fingerprints.h b/apache2/libinjection/sqli_fingerprints.h new file mode 100644 index 0000000000..4d6359870b --- /dev/null +++ b/apache2/libinjection/sqli_fingerprints.h @@ -0,0 +1,2163 @@ +#ifndef _SQLPARSE_FINGERPRINTS_H +#define _SQLPARSE_FINGERPRINTS_H + +static const char* patmap[] = { + "&1o1U", + "&1osU", + "&1ovU", + "&f()o", + "&f(1)", + "&f(1o", + "&f(s)", + "&f(v)", + "&so1U", + "&sovU", + "&vo1U", + "&vosU", + "&vovU", + "1&((f", + "1&((k", + "1&(1)", + "1&(1,", + "1&(1o", + "1&(f(", + "1&(k(", + "1&(k1", + "1&(kf", + "1&(kk", + "1&(kn", + "1&(ko", + "1&(ks", + "1&(kv", + "1&(s)", + "1&(s,", + "1&(so", + "1&(v)", + "1&(v,", + "1&(vo", + "1&1", + "1&1Bf", + "1&1Uk", + "1&1c", + "1&1f(", + "1&1o(", + "1&1o1", + "1&1of", + "1&1ok", + "1&1on", + "1&1oo", + "1&1os", + "1&1ov", + "1&f((", + "1&f()", + "1&f(1", + "1&f(f", + "1&f(k", + "1&f(n", + "1&f(s", + "1&f(v", + "1&k(1", + "1&k(f", + "1&k(s", + "1&k(v", + "1&k1k", + "1&kUk", + "1&kk1", + "1&kks", + "1&kkv", + "1&ksk", + "1&kvk", + "1&n()", + "1&no1", + "1&nos", + "1&nov", + "1&o(1", + "1&o(s", + "1&o(v", + "1&o1o", + "1&oso", + "1&ovo", + "1&sBf", + "1&sU(", + "1&sUk", + "1&sf(", + "1&so(", + "1&so1", + "1&sof", + "1&sok", + "1&son", + "1&soo", + "1&sos", + "1&sov", + "1&vBf", + "1&vU(", + "1&vUk", + "1&vf(", + "1&vo(", + "1&vo1", + "1&vof", + "1&vok", + "1&von", + "1&voo", + "1&vos", + "1&vov", + "1)&(1", + "1)&(f", + "1)&(k", + "1)&(n", + "1)&(s", + "1)&(v", + "1)&1B", + "1)&1U", + "1)&1f", + "1)&1o", + "1)&f(", + "1)&o(", + "1)&sB", + "1)&sU", + "1)&sf", + "1)&so", + "1)&vB", + "1)&vU", + "1)&vf", + "1)&vo", + "1)()s", + "1)()v", + "1))&(", + "1))&1", + "1))&f", + "1))&o", + "1))&s", + "1))&v", + "1)))&", + "1))))", + "1)));", + "1)))B", + "1)))U", + "1)))k", + "1)))o", + "1));k", + "1))B1", + "1))Bs", + "1))Bv", + "1))Uk", + "1))Un", + "1))k1", + "1))kk", + "1))ks", + "1))kv", + "1))o(", + "1))o1", + "1))of", + "1))ok", + "1))on", + "1))os", + "1))ov", + "1),(1", + "1),(s", + "1),(v", + "1);k&", + "1);k(", + "1);kf", + "1);kk", + "1);kn", + "1);ko", + "1)B1", + "1)B1&", + "1)B1c", + "1)B1o", + "1)Bs", + "1)Bs&", + "1)Bsc", + "1)Bso", + "1)Bv", + "1)Bv&", + "1)Bvc", + "1)Bvo", + "1)U(k", + "1)Uk(", + "1)Uk1", + "1)Ukf", + "1)Ukk", + "1)Ukn", + "1)Uko", + "1)Uks", + "1)Ukv", + "1)Unk", + "1)k1", + "1)k1c", + "1)k1o", + "1)kks", + "1)kkv", + "1)knk", + "1)ks", + "1)ksc", + "1)kso", + "1)kv", + "1)kvc", + "1)kvo", + "1)o(1", + "1)o(k", + "1)o(n", + "1)o(s", + "1)o(v", + "1)o1)", + "1)o1B", + "1)o1U", + "1)o1f", + "1)o1k", + "1)o1o", + "1)of(", + "1)ok(", + "1)ok1", + "1)oks", + "1)okv", + "1)on&", + "1)ono", + "1)os)", + "1)osB", + "1)osU", + "1)osf", + "1)osk", + "1)oso", + "1)ov)", + "1)ovB", + "1)ovU", + "1)ovf", + "1)ovk", + "1)ovo", + "1,(f(", + "1,(k(", + "1,(k1", + "1,(kf", + "1,(ks", + "1,(kv", + "1,1),", + "1,1)o", + "1,1B1", + "1,1Bs", + "1,1Bv", + "1,1Uk", + "1,f(1", + "1,f(s", + "1,f(v", + "1,s),", + "1,s)o", + "1,sB1", + "1,sBv", + "1,sUk", + "1,v),", + "1,v)o", + "1,vB1", + "1,vBs", + "1,vBv", + "1,vUk", + "1;k&k", + "1;k((", + "1;k(1", + "1;k(o", + "1;k(s", + "1;k(v", + "1;k1,", + "1;kf(", + "1;kks", + "1;kkv", + "1;kn(", + "1;kn,", + "1;knc", + "1;ko(", + "1;kok", + "1;ks,", + "1;kv,", + "1B1", + "1B1,1", + "1B1,n", + "1B1,s", + "1B1,v", + "1B1Uk", + "1B1c", + "1B1k1", + "1B1ks", + "1B1kv", + "1Bf(1", + "1Bf(f", + "1Bf(s", + "1Bf(v", + "1Bk(1", + "1Bk(s", + "1Bk(v", + "1Bn,n", + "1Bnk1", + "1Bnks", + "1Bnkv", + "1Bs", + "1Bs,1", + "1Bs,n", + "1Bs,v", + "1BsUk", + "1Bsc", + "1Bsk1", + "1Bsks", + "1Bskv", + "1Bv", + "1Bv,1", + "1Bv,n", + "1Bv,s", + "1Bv,v", + "1BvUk", + "1Bvc", + "1Bvk1", + "1Bvks", + "1Bvkv", + "1U", + "1U((k", + "1U(k1", + "1U(kf", + "1U(kn", + "1U(ks", + "1U(kv", + "1U1,1", + "1U1,s", + "1U1,v", + "1Uc", + "1Uk", + "1Uk(1", + "1Uk(k", + "1Uk(n", + "1Uk(s", + "1Uk(v", + "1Uk1", + "1Uk1,", + "1Uk1c", + "1Uk1f", + "1Uk1k", + "1Uk1n", + "1Uk1o", + "1Ukf", + "1Ukf(", + "1Ukf,", + "1Ukk(", + "1Ukk,", + "1Ukk1", + "1Ukkk", + "1Ukkn", + "1Ukks", + "1Ukkv", + "1Ukn&", + "1Ukn(", + "1Ukn,", + "1Ukn1", + "1Uknc", + "1Uknk", + "1Ukno", + "1Ukns", + "1Uknv", + "1Uko1", + "1Ukok", + "1Ukos", + "1Ukov", + "1Uks", + "1Uks,", + "1Uksc", + "1Uksf", + "1Uksk", + "1Uksn", + "1Ukso", + "1Ukv", + "1Ukv,", + "1Ukvc", + "1Ukvf", + "1Ukvk", + "1Ukvn", + "1Ukvo", + "1Un,1", + "1Un,s", + "1Un,v", + "1Un1,", + "1Unk(", + "1Unk1", + "1Unkf", + "1Unks", + "1Unkv", + "1Uns,", + "1Unv,", + "1Uon1", + "1Uons", + "1Uonv", + "1Us,1", + "1Us,v", + "1Uv,1", + "1Uv,s", + "1Uv,v", + "1c", + "1f()k", + "1k1U(", + "1k1Uk", + "1k1c", + "1kU1,", + "1kUs,", + "1kUv,", + "1kf(1", + "1kf(s", + "1kf(v", + "1kk(1", + "1kk(s", + "1kk(v", + "1kksc", + "1kkvc", + "1knkn", + "1kno1", + "1kokn", + "1ksU(", + "1ksUk", + "1ksc", + "1kvU(", + "1kvUk", + "1kvc", + "1n&f(", + "1n)Uk", + "1nUk1", + "1nUkn", + "1nUks", + "1nUkv", + "1nk1c", + "1nkf(", + "1nksc", + "1nkvc", + "1o(((", + "1o((1", + "1o((f", + "1o((s", + "1o((v", + "1o(1)", + "1o(1o", + "1o(f(", + "1o(k(", + "1o(k1", + "1o(kf", + "1o(kn", + "1o(ks", + "1o(kv", + "1o(n)", + "1o(o1", + "1o(os", + "1o(s)", + "1o(so", + "1o(v)", + "1o(vo", + "1o1)&", + "1o1)o", + "1o1Bf", + "1o1Uk", + "1o1f(", + "1o1kf", + "1o1o(", + "1o1o1", + "1o1of", + "1o1oo", + "1o1os", + "1o1ov", + "1of()", + "1of(1", + "1of(f", + "1of(n", + "1of(s", + "1of(v", + "1ok(1", + "1ok(k", + "1ok(s", + "1ok(v", + "1ok)U", + "1ok)o", + "1ok1", + "1ok1,", + "1ok1c", + "1ok1k", + "1okUk", + "1okf(", + "1oks", + "1oks,", + "1oksc", + "1oksk", + "1okv", + "1okv,", + "1okvc", + "1okvk", + "1onov", + "1os)&", + "1os)U", + "1os)o", + "1osBf", + "1osUk", + "1osf(", + "1oskf", + "1oso(", + "1oso1", + "1osof", + "1osoo", + "1osos", + "1osov", + "1ov)&", + "1ov)U", + "1ov)o", + "1ovBf", + "1ovUk", + "1ovf(", + "1ovkf", + "1ovo(", + "1ovo1", + "1ovof", + "1ovoo", + "1ovos", + "1ovov", + ";kknc", + "Uk1,1", + "Uk1,f", + "Uk1,n", + "Uk1,s", + "Uk1,v", + "Ukkkn", + "Uks,1", + "Uks,f", + "Uks,n", + "Uks,v", + "Ukv,1", + "Ukv,f", + "Ukv,n", + "Ukv,s", + "Ukv,v", + "f((k(", + "f((kf", + "f()&f", + "f()of", + "f(1)&", + "f(1)U", + "f(1)o", + "f(1,1", + "f(1,f", + "f(1,s", + "f(1,v", + "f(1o1", + "f(1os", + "f(1ov", + "f(f()", + "f(f(1", + "f(f(f", + "f(f(s", + "f(f(v", + "f(k()", + "f(k,(", + "f(k,n", + "f(n()", + "f(s)&", + "f(s)U", + "f(s)o", + "f(s,1", + "f(s,f", + "f(s,v", + "f(so1", + "f(sov", + "f(v)&", + "f(v)U", + "f(v)o", + "f(v,1", + "f(v,f", + "f(v,s", + "f(v,v", + "f(vo1", + "f(vos", + "f(vov", + "k()ok", + "k(1)U", + "k(ok(", + "k(s)U", + "k(sv)", + "k(v)U", + "k(vs)", + "k(vv)", + "k1,1,", + "k1,1c", + "k1,1k", + "k1,f(", + "k1,n,", + "k1,s,", + "k1,sc", + "k1,sk", + "k1,v,", + "k1,vc", + "k1,vk", + "k1k(k", + "k1o(s", + "k1o(v", + "k;non", + "kf(1)", + "kf(1,", + "kf(f(", + "kf(n,", + "kf(o)", + "kf(s)", + "kf(s,", + "kf(s:", + "kf(v)", + "kf(v,", + "kf(v:", + "kk(f(", + "kk1f(", + "kk1fn", + "kk1kk", + "kk1nk", + "kk1sk", + "kk1sn", + "kk1vk", + "kk1vn", + "kksf(", + "kksfn", + "kkskk", + "kksnk", + "kksvk", + "kksvn", + "kkvf(", + "kkvfn", + "kkvkk", + "kkvnk", + "kkvsk", + "kkvsn", + "kkvvk", + "kkvvn", + "kn1kk", + "kn1sk", + "kn1sn", + "kn1vk", + "kn1vn", + "knk(k", + "knskk", + "knsvk", + "knsvn", + "knvkk", + "knvsk", + "knvsn", + "knvvk", + "knvvn", + "ko(k(", + "ko(kf", + "kok(k", + "ks)", + "ks,1,", + "ks,1c", + "ks,1k", + "ks,f(", + "ks,v,", + "ks,vc", + "ks,vk", + "ksf(1", + "ksf(v", + "ksk(1", + "ksk(k", + "ksk(v", + "kso(s", + "kso(v", + "kv)", + "kv,1,", + "kv,1c", + "kv,1k", + "kv,f(", + "kv,s,", + "kv,sc", + "kv,sk", + "kv,v,", + "kv,vc", + "kv,vk", + "kvf(1", + "kvf(s", + "kvf(v", + "kvk(1", + "kvk(k", + "kvk(s", + "kvk(v", + "kvo(s", + "kvo(v", + "n&(1)", + "n&(1,", + "n&(k1", + "n&(ks", + "n&(kv", + "n&(o1", + "n&(os", + "n&(ov", + "n&(s)", + "n&(s,", + "n&(v)", + "n&(v,", + "n&1Bf", + "n&1f(", + "n&1o(", + "n&1o1", + "n&1of", + "n&1oo", + "n&1os", + "n&1ov", + "n&f(1", + "n&f(f", + "n&f(s", + "n&f(v", + "n&k(1", + "n&k(s", + "n&k(v", + "n&o1o", + "n&oso", + "n&ovo", + "n&sf(", + "n&so(", + "n&so1", + "n&sof", + "n&soo", + "n&sov", + "n&vf(", + "n&vo(", + "n&vo1", + "n&vof", + "n&voo", + "n&vos", + "n&vov", + "n)&(k", + "n)&1f", + "n)&1o", + "n)&f(", + "n)&sf", + "n)&so", + "n)&vf", + "n)&vo", + "n))&(", + "n))&1", + "n))&f", + "n))&s", + "n))&v", + "n)))&", + "n)));", + "n)))k", + "n)))o", + "n));k", + "n))kk", + "n))o(", + "n))o1", + "n))of", + "n))ok", + "n))os", + "n))ov", + "n);k&", + "n);k(", + "n);kf", + "n);kk", + "n);kn", + "n);ko", + "n)k1o", + "n)kks", + "n)kkv", + "n)kso", + "n)kvo", + "n)o(k", + "n)o1&", + "n)o1f", + "n)o1o", + "n)of(", + "n)ok(", + "n)os&", + "n)osf", + "n)oso", + "n)ov&", + "n)ovf", + "n)ovo", + "n,(f(", + "n,(k(", + "n,(k1", + "n,(kf", + "n,(ks", + "n,(kv", + "n,f(1", + "n,f(s", + "n,f(v", + "n:o1U", + "n:osU", + "n:ovU", + "n;k&k", + "n;k((", + "n;k(1", + "n;k(s", + "n;k(v", + "n;kf(", + "n;kks", + "n;kkv", + "n;kn(", + "n;ko(", + "n;kok", + "nUk(k", + "nUk1,", + "nUkf(", + "nUkn,", + "nUks,", + "nUkv,", + "nUnk(", + "nk1Uk", + "nk1o1", + "nkf(1", + "nkf(s", + "nkf(v", + "nkksc", + "nkkvc", + "nksUk", + "nkvUk", + "nnn)U", + "nno1U", + "nnosU", + "nnovU", + "no(k1", + "no(ks", + "no(kv", + "no(o1", + "no(os", + "no(ov", + "no1&1", + "no1&s", + "no1&v", + "no1Uk", + "no1f(", + "no1o(", + "no1of", + "no1oo", + "no1os", + "no1ov", + "nof(1", + "nof(s", + "nof(v", + "nok(f", + "nok(k", + "nok(s", + "nok(v", + "nono1", + "nos&1", + "nos&v", + "nosUk", + "nosf(", + "noso(", + "noso1", + "nosof", + "nosoo", + "nosov", + "nov&1", + "nov&s", + "nov&v", + "novUk", + "novf(", + "novo(", + "novo1", + "novof", + "novoo", + "novos", + "novov", + "o1kf(", + "oUk1,", + "oUks,", + "oUkv,", + "of()o", + "of(1)", + "of(s)", + "of(v)", + "ok1o1", + "ok1os", + "ok1ov", + "okkkn", + "okso1", + "oksov", + "okvo1", + "okvos", + "okvov", + "ook1,", + "ooks,", + "ookv,", + "oskf(", + "ovkf(", + "s&((f", + "s&((k", + "s&(1)", + "s&(1,", + "s&(1o", + "s&(f(", + "s&(k(", + "s&(k)", + "s&(k1", + "s&(kf", + "s&(kk", + "s&(kn", + "s&(ko", + "s&(ks", + "s&(kv", + "s&(s)", + "s&(s,", + "s&(so", + "s&(v)", + "s&(v,", + "s&(vo", + "s&1", + "s&1Bf", + "s&1Uk", + "s&1c", + "s&1f(", + "s&1o(", + "s&1o1", + "s&1of", + "s&1ok", + "s&1on", + "s&1oo", + "s&1os", + "s&1ov", + "s&f((", + "s&f()", + "s&f(1", + "s&f(f", + "s&f(k", + "s&f(n", + "s&f(s", + "s&f(v", + "s&k&s", + "s&k&v", + "s&k(1", + "s&k(f", + "s&k(o", + "s&k(s", + "s&k(v", + "s&k1k", + "s&k1o", + "s&kUk", + "s&kc", + "s&kk1", + "s&kkv", + "s&knk", + "s&ko(", + "s&ko1", + "s&kok", + "s&kos", + "s&kov", + "s&kso", + "s&kvk", + "s&kvo", + "s&n&s", + "s&n&v", + "s&n()", + "s&no1", + "s&nos", + "s&nov", + "s&o(1", + "s&o(k", + "s&o(s", + "s&o(v", + "s&o1o", + "s&okc", + "s&oko", + "s&os", + "s&oso", + "s&ov", + "s&ovo", + "s&s", + "s&s:o", + "s&sBf", + "s&sU(", + "s&sUk", + "s&sc", + "s&sf(", + "s&so(", + "s&so1", + "s&sof", + "s&son", + "s&soo", + "s&sos", + "s&sov", + "s&sso", + "s&svo", + "s&v:o", + "s&vBf", + "s&vU(", + "s&vUk", + "s&vc", + "s&vf(", + "s&vo(", + "s&vo1", + "s&vof", + "s&vok", + "s&von", + "s&voo", + "s&vos", + "s&vov", + "s&vso", + "s&vvo", + "s)&(1", + "s)&(f", + "s)&(k", + "s)&(n", + "s)&(s", + "s)&(v", + "s)&1B", + "s)&1U", + "s)&1f", + "s)&1o", + "s)&f(", + "s)&o(", + "s)&sB", + "s)&sf", + "s)&so", + "s)&vB", + "s)&vU", + "s)&vf", + "s)&vo", + "s)()s", + "s)()v", + "s))&(", + "s))&1", + "s))&f", + "s))&n", + "s))&o", + "s))&s", + "s))&v", + "s)))&", + "s))))", + "s)));", + "s)))B", + "s)))U", + "s)))k", + "s)))o", + "s));k", + "s))B1", + "s))Bs", + "s))Bv", + "s))Uk", + "s))Un", + "s))k1", + "s))kk", + "s))ks", + "s))kv", + "s))o(", + "s))o1", + "s))of", + "s))ok", + "s))on", + "s))os", + "s))ov", + "s),(1", + "s),(s", + "s),(v", + "s);k&", + "s);k(", + "s);kf", + "s);kk", + "s);kn", + "s);ko", + "s)B1", + "s)B1&", + "s)B1c", + "s)B1o", + "s)Bs", + "s)Bs&", + "s)Bsc", + "s)Bso", + "s)Bv", + "s)Bv&", + "s)Bvc", + "s)Bvo", + "s)U(k", + "s)Uk(", + "s)Uk1", + "s)Ukf", + "s)Ukk", + "s)Ukn", + "s)Uko", + "s)Uks", + "s)Ukv", + "s)Unk", + "s)k1", + "s)k1c", + "s)k1o", + "s)kks", + "s)kkv", + "s)ks", + "s)ksc", + "s)kso", + "s)kv", + "s)kvc", + "s)kvo", + "s)o(1", + "s)o(k", + "s)o(n", + "s)o(s", + "s)o(v", + "s)o1B", + "s)o1f", + "s)o1k", + "s)o1o", + "s)of(", + "s)ok(", + "s)ok1", + "s)oks", + "s)okv", + "s)on&", + "s)os)", + "s)osB", + "s)osU", + "s)osf", + "s)osk", + "s)oso", + "s)ov)", + "s)ovB", + "s)ovf", + "s)ovk", + "s)ovo", + "s,(f(", + "s,(k(", + "s,(k1", + "s,(kf", + "s,(kv", + "s,1),", + "s,1)o", + "s,1B1", + "s,1Bv", + "s,1Uk", + "s,f(1", + "s,f(v", + "s,s),", + "s,v),", + "s,v)o", + "s,vB1", + "s,vBv", + "s,vUk", + "s:o1)", + "s:ov)", + "s;k&k", + "s;k((", + "s;k(1", + "s;k(o", + "s;k(s", + "s;k(v", + "s;k1,", + "s;k1o", + "s;k;", + "s;k[k", + "s;k[n", + "s;kf(", + "s;kkn", + "s;kks", + "s;kkv", + "s;kn(", + "s;kn,", + "s;knc", + "s;knk", + "s;knn", + "s;ko(", + "s;kok", + "s;ks,", + "s;ksc", + "s;ksk", + "s;kso", + "s;kv,", + "s;kvc", + "s;kvk", + "s;kvo", + "s;n:k", + "sB1", + "sB1&s", + "sB1&v", + "sB1,1", + "sB1,n", + "sB1,v", + "sB1Uk", + "sB1c", + "sB1k1", + "sB1ks", + "sB1kv", + "sB1os", + "sB1ov", + "sBf(1", + "sBf(f", + "sBf(v", + "sBk(1", + "sBk(v", + "sBn,n", + "sBnk1", + "sBnkv", + "sBs", + "sBs&s", + "sBs&v", + "sBsUk", + "sBsc", + "sBsos", + "sBsov", + "sBv", + "sBv&s", + "sBv&v", + "sBv,1", + "sBv,n", + "sBv,v", + "sBvUk", + "sBvc", + "sBvk1", + "sBvks", + "sBvkv", + "sBvos", + "sBvov", + "sU((k", + "sU(k(", + "sU(k1", + "sU(kf", + "sU(kk", + "sU(kn", + "sU(ks", + "sU(kv", + "sU1,1", + "sU1,v", + "sUc", + "sUk", + "sUk(1", + "sUk(k", + "sUk(n", + "sUk(v", + "sUk1", + "sUk1&", + "sUk1,", + "sUk1c", + "sUk1f", + "sUk1k", + "sUk1n", + "sUk1o", + "sUkf", + "sUkf(", + "sUkf,", + "sUkk(", + "sUkk,", + "sUkk1", + "sUkkk", + "sUkkn", + "sUkks", + "sUkkv", + "sUkn&", + "sUkn(", + "sUkn,", + "sUkn1", + "sUknc", + "sUknk", + "sUkno", + "sUkns", + "sUknv", + "sUko1", + "sUkok", + "sUkov", + "sUks", + "sUks&", + "sUks,", + "sUksc", + "sUksk", + "sUkso", + "sUkv", + "sUkv&", + "sUkv,", + "sUkvc", + "sUkvf", + "sUkvk", + "sUkvn", + "sUkvo", + "sUn(k", + "sUn,1", + "sUn,v", + "sUn1,", + "sUnk(", + "sUnk1", + "sUnkf", + "sUnks", + "sUnkv", + "sUno1", + "sUnos", + "sUnov", + "sUnv,", + "sUon1", + "sUonv", + "sUv,1", + "sUv,v", + "sc", + "sf()k", + "sf(1)", + "sf(n,", + "sf(s)", + "sf(v)", + "sk)&(", + "sk)&1", + "sk)&f", + "sk)&s", + "sk)&v", + "sk);k", + "sk)B1", + "sk)Bs", + "sk)Bv", + "sk)Uk", + "sk)Un", + "sk)k1", + "sk)kk", + "sk)ks", + "sk)kv", + "sk)o(", + "sk)o1", + "sk)of", + "sk)ok", + "sk)os", + "sk)ov", + "sk1&1", + "sk1&s", + "sk1&v", + "sk1U(", + "sk1Uk", + "sk1c", + "sk1o1", + "sk1os", + "sk1ov", + "skU1,", + "skUs,", + "skUv,", + "skf(1", + "skf(v", + "skk(1", + "skk(v", + "skks", + "skksc", + "skkv", + "skkvc", + "sknkn", + "sks&1", + "sks&v", + "sksUk", + "sksc", + "skso1", + "sksos", + "sksov", + "skv&1", + "skv&s", + "skv&v", + "skvU(", + "skvUk", + "skvc", + "skvo1", + "skvos", + "skvov", + "sn&f(", + "sn,f(", + "snUk1", + "snUkn", + "snUkv", + "snk1c", + "snkf(", + "snkvc", + "sno(s", + "sno1U", + "snosU", + "snovU", + "so(((", + "so((1", + "so((f", + "so((k", + "so((s", + "so((v", + "so(1)", + "so(1o", + "so(f(", + "so(k(", + "so(k)", + "so(k1", + "so(kf", + "so(kk", + "so(kn", + "so(ko", + "so(ks", + "so(kv", + "so(n)", + "so(o1", + "so(os", + "so(ov", + "so(s)", + "so(so", + "so(v)", + "so(vo", + "so1&1", + "so1&o", + "so1&s", + "so1&v", + "so1)&", + "so1)o", + "so1Bf", + "so1Uk", + "so1c", + "so1f(", + "so1kf", + "so1o(", + "so1o1", + "so1of", + "so1ok", + "so1oo", + "so1os", + "so1ov", + "sof()", + "sof(1", + "sof(f", + "sof(k", + "sof(n", + "sof(s", + "sof(v", + "sok&s", + "sok&v", + "sok(1", + "sok(k", + "sok(o", + "sok(s", + "sok(v", + "sok1", + "sok1,", + "sok1c", + "sok1k", + "sok1o", + "sokUk", + "sokc", + "sokf(", + "sokn,", + "soknk", + "soko(", + "soko1", + "sokok", + "sokos", + "sokov", + "soks", + "soks,", + "soksc", + "sokso", + "sokv", + "sokv,", + "sokvc", + "sokvk", + "sokvo", + "sonk1", + "sonks", + "sonkv", + "sonos", + "sonov", + "sos", + "sos&(", + "sos&1", + "sos&o", + "sos&s", + "sos&v", + "sos:o", + "sosBf", + "sosUk", + "sosc", + "sosf(", + "soskf", + "soso(", + "soso1", + "sosof", + "sosok", + "sosoo", + "sosos", + "sosov", + "sosso", + "sosvo", + "sov", + "sov&(", + "sov&1", + "sov&o", + "sov&s", + "sov&v", + "sov)&", + "sov)o", + "sov:o", + "sovBf", + "sovUk", + "sovc", + "sovf(", + "sovkf", + "sovo(", + "sovo1", + "sovof", + "sovok", + "sovoo", + "sovos", + "sovov", + "sovso", + "sovvo", + "v&((f", + "v&((k", + "v&(1)", + "v&(1,", + "v&(1o", + "v&(f(", + "v&(k(", + "v&(k)", + "v&(k1", + "v&(kf", + "v&(kk", + "v&(kn", + "v&(ko", + "v&(ks", + "v&(kv", + "v&(s)", + "v&(s,", + "v&(so", + "v&(v)", + "v&(v,", + "v&(vo", + "v&1Bf", + "v&1Uk", + "v&1c", + "v&1f(", + "v&1o(", + "v&1o1", + "v&1of", + "v&1ok", + "v&1on", + "v&1oo", + "v&1os", + "v&1ov", + "v&f((", + "v&f()", + "v&f(1", + "v&f(f", + "v&f(k", + "v&f(n", + "v&f(s", + "v&f(v", + "v&k&s", + "v&k&v", + "v&k(1", + "v&k(f", + "v&k(o", + "v&k(s", + "v&k(v", + "v&k1k", + "v&k1o", + "v&kUk", + "v&kc", + "v&kk1", + "v&kks", + "v&kkv", + "v&knk", + "v&ko(", + "v&ko1", + "v&kok", + "v&kos", + "v&kov", + "v&ksk", + "v&kso", + "v&kvk", + "v&kvo", + "v&n&s", + "v&n&v", + "v&n()", + "v&no1", + "v&nos", + "v&nov", + "v&o(1", + "v&o(k", + "v&o(s", + "v&o(v", + "v&o1o", + "v&okc", + "v&oko", + "v&os", + "v&oso", + "v&ov", + "v&ovo", + "v&s:o", + "v&sBf", + "v&sU(", + "v&sUk", + "v&sc", + "v&sf(", + "v&so(", + "v&so1", + "v&sof", + "v&sok", + "v&son", + "v&soo", + "v&sos", + "v&sov", + "v&sso", + "v&svo", + "v&v:o", + "v&vBf", + "v&vU(", + "v&vUk", + "v&vc", + "v&vf(", + "v&vo(", + "v&vo1", + "v&vof", + "v&vok", + "v&von", + "v&voo", + "v&vos", + "v&vov", + "v&vso", + "v&vvo", + "v)&(1", + "v)&(f", + "v)&(k", + "v)&(n", + "v)&(s", + "v)&(v", + "v)&1B", + "v)&1U", + "v)&1f", + "v)&1o", + "v)&f(", + "v)&o(", + "v)&sB", + "v)&sU", + "v)&sf", + "v)&so", + "v)&vB", + "v)&vU", + "v)&vf", + "v)&vo", + "v)()s", + "v)()v", + "v))&(", + "v))&1", + "v))&f", + "v))&n", + "v))&o", + "v))&s", + "v))&v", + "v)))&", + "v))))", + "v)));", + "v)))B", + "v)))U", + "v)))k", + "v)))o", + "v));k", + "v))B1", + "v))Bs", + "v))Bv", + "v))Uk", + "v))Un", + "v))k1", + "v))kk", + "v))ks", + "v))kv", + "v))o(", + "v))o1", + "v))of", + "v))ok", + "v))on", + "v))os", + "v))ov", + "v),(1", + "v),(s", + "v),(v", + "v);k&", + "v);k(", + "v);kf", + "v);kk", + "v);kn", + "v);ko", + "v)B1", + "v)B1&", + "v)B1c", + "v)B1o", + "v)Bs", + "v)Bs&", + "v)Bsc", + "v)Bso", + "v)Bv", + "v)Bv&", + "v)Bvc", + "v)Bvo", + "v)U(k", + "v)Uk(", + "v)Uk1", + "v)Ukf", + "v)Ukk", + "v)Ukn", + "v)Uko", + "v)Uks", + "v)Ukv", + "v)Unk", + "v)k1", + "v)k1c", + "v)k1o", + "v)kks", + "v)kkv", + "v)ks", + "v)ksc", + "v)kso", + "v)kv", + "v)kvc", + "v)kvo", + "v)o(1", + "v)o(k", + "v)o(n", + "v)o(s", + "v)o(v", + "v)o1B", + "v)o1U", + "v)o1f", + "v)o1k", + "v)o1o", + "v)of(", + "v)ok(", + "v)ok1", + "v)oks", + "v)okv", + "v)on&", + "v)ono", + "v)os)", + "v)osB", + "v)osU", + "v)osf", + "v)osk", + "v)oso", + "v)ovB", + "v)ovU", + "v)ovf", + "v)ovk", + "v)ovo", + "v,(f(", + "v,(k(", + "v,(k1", + "v,(kf", + "v,(ks", + "v,(kv", + "v,1),", + "v,1)o", + "v,1B1", + "v,1Bs", + "v,1Bv", + "v,1Uk", + "v,f(1", + "v,f(s", + "v,f(v", + "v,s),", + "v,s)o", + "v,sB1", + "v,sBv", + "v,sUk", + "v,v),", + "v,v)o", + "v,vB1", + "v,vBs", + "v,vBv", + "v,vUk", + "v:o1)", + "v:os)", + "v:ov)", + "v;k&k", + "v;k((", + "v;k(1", + "v;k(o", + "v;k(s", + "v;k(v", + "v;k1,", + "v;k1o", + "v;k;", + "v;k[k", + "v;k[n", + "v;kf(", + "v;kkn", + "v;kks", + "v;kkv", + "v;kn(", + "v;kn,", + "v;knc", + "v;knk", + "v;knn", + "v;ko(", + "v;kok", + "v;ks,", + "v;ksc", + "v;ksk", + "v;kso", + "v;kv,", + "v;kvc", + "v;kvk", + "v;kvo", + "v;n:k", + "vB1", + "vB1&s", + "vB1&v", + "vB1,1", + "vB1,n", + "vB1,s", + "vB1,v", + "vB1Uk", + "vB1c", + "vB1k1", + "vB1ks", + "vB1kv", + "vB1os", + "vB1ov", + "vBf(1", + "vBf(f", + "vBf(s", + "vBf(v", + "vBk(1", + "vBk(s", + "vBk(v", + "vBn,n", + "vBnk1", + "vBnks", + "vBnkv", + "vBs", + "vBs&s", + "vBs&v", + "vBs,1", + "vBs,n", + "vBs,v", + "vBsUk", + "vBsc", + "vBsk1", + "vBsks", + "vBskv", + "vBsos", + "vBsov", + "vBv", + "vBv&s", + "vBv&v", + "vBv,1", + "vBv,n", + "vBv,s", + "vBv,v", + "vBvUk", + "vBvc", + "vBvk1", + "vBvks", + "vBvkv", + "vBvos", + "vBvov", + "vU((k", + "vU(k(", + "vU(k1", + "vU(kf", + "vU(kk", + "vU(kn", + "vU(ks", + "vU(kv", + "vU1,1", + "vU1,s", + "vU1,v", + "vUc", + "vUk", + "vUk(1", + "vUk(k", + "vUk(n", + "vUk(s", + "vUk(v", + "vUk1", + "vUk1&", + "vUk1,", + "vUk1c", + "vUk1f", + "vUk1k", + "vUk1n", + "vUk1o", + "vUkf", + "vUkf(", + "vUkf,", + "vUkk(", + "vUkk,", + "vUkk1", + "vUkkk", + "vUkkn", + "vUkks", + "vUkkv", + "vUkn&", + "vUkn(", + "vUkn,", + "vUkn1", + "vUknc", + "vUknk", + "vUkno", + "vUkns", + "vUknv", + "vUko1", + "vUkok", + "vUkos", + "vUkov", + "vUks", + "vUks&", + "vUks,", + "vUksc", + "vUksf", + "vUksk", + "vUksn", + "vUkso", + "vUkv", + "vUkv&", + "vUkv,", + "vUkvc", + "vUkvf", + "vUkvk", + "vUkvn", + "vUkvo", + "vUn(k", + "vUn,1", + "vUn,s", + "vUn,v", + "vUn1,", + "vUnk(", + "vUnk1", + "vUnkf", + "vUnks", + "vUnkv", + "vUno1", + "vUnos", + "vUnov", + "vUns,", + "vUnv,", + "vUon1", + "vUons", + "vUonv", + "vUs,1", + "vUs,v", + "vUv,1", + "vUv,s", + "vUv,v", + "vc", + "vf()k", + "vf(1)", + "vf(n,", + "vf(s)", + "vf(v)", + "vk)&(", + "vk)&1", + "vk)&f", + "vk)&s", + "vk)&v", + "vk);k", + "vk)B1", + "vk)Bs", + "vk)Bv", + "vk)Uk", + "vk)Un", + "vk)k1", + "vk)kk", + "vk)ks", + "vk)kv", + "vk)o(", + "vk)o1", + "vk)of", + "vk)ok", + "vk)os", + "vk)ov", + "vk1&1", + "vk1&s", + "vk1&v", + "vk1U(", + "vk1Uk", + "vk1c", + "vk1o1", + "vk1os", + "vk1ov", + "vkU1,", + "vkUs,", + "vkUv,", + "vkf(1", + "vkf(s", + "vkf(v", + "vkk(1", + "vkk(s", + "vkk(v", + "vkks", + "vkksc", + "vkkv", + "vkkvc", + "vknkn", + "vks&1", + "vks&v", + "vksU(", + "vksUk", + "vksc", + "vkso1", + "vksos", + "vksov", + "vkv&1", + "vkv&s", + "vkv&v", + "vkvU(", + "vkvUk", + "vkvc", + "vkvo1", + "vkvos", + "vkvov", + "vn&f(", + "vn,f(", + "vnUk1", + "vnUkn", + "vnUks", + "vnUkv", + "vnk1c", + "vnkf(", + "vnksc", + "vnkvc", + "vno1U", + "vnosU", + "vnovU", + "vo(((", + "vo((1", + "vo((f", + "vo((k", + "vo((s", + "vo((v", + "vo(1)", + "vo(1o", + "vo(f(", + "vo(k(", + "vo(k)", + "vo(k1", + "vo(kf", + "vo(kk", + "vo(kn", + "vo(ko", + "vo(ks", + "vo(kv", + "vo(n)", + "vo(o1", + "vo(os", + "vo(ov", + "vo(s)", + "vo(so", + "vo(v)", + "vo(vo", + "vo1&1", + "vo1&o", + "vo1&s", + "vo1&v", + "vo1)&", + "vo1)o", + "vo1Bf", + "vo1Uk", + "vo1c", + "vo1f(", + "vo1kf", + "vo1o(", + "vo1o1", + "vo1of", + "vo1ok", + "vo1oo", + "vo1os", + "vo1ov", + "vof()", + "vof(1", + "vof(f", + "vof(k", + "vof(n", + "vof(s", + "vof(v", + "vok&s", + "vok&v", + "vok(1", + "vok(k", + "vok(o", + "vok(s", + "vok(v", + "vok1", + "vok1,", + "vok1c", + "vok1k", + "vok1o", + "vokUk", + "vokc", + "vokf(", + "vokn,", + "voknk", + "voko(", + "voko1", + "vokok", + "vokos", + "vokov", + "voks", + "voks,", + "voksc", + "voksk", + "vokso", + "vokv", + "vokv,", + "vokvc", + "vokvk", + "vokvo", + "vonk1", + "vonks", + "vonkv", + "vono1", + "vonos", + "vonov", + "vos", + "vos&(", + "vos&1", + "vos&o", + "vos&s", + "vos&v", + "vos)&", + "vos)o", + "vos:o", + "vosBf", + "vosUk", + "vosc", + "vosf(", + "voskf", + "voso(", + "voso1", + "vosof", + "vosok", + "vosoo", + "vosos", + "vosov", + "vosso", + "vosvo", + "vov", + "vov&(", + "vov&1", + "vov&o", + "vov&s", + "vov&v", + "vov)&", + "vov)o", + "vov:o", + "vovBf", + "vovUk", + "vovc", + "vovf(", + "vovkf", + "vovo(", + "vovo1", + "vovof", + "vovok", + "vovoo", + "vovos", + "vovov", + "vovso", + "vovvo", +}; +static const size_t patmap_sz = 2135; + + +/* Simple binary search */ +int is_sqli_pattern(const char *key) +{ + int left = 0; + int right = (int)patmap_sz - 1; + + while (left <= right) { + int pos = (left + right) / 2; + int cmp = strcmp(patmap[pos], key); + if (cmp == 0) { + return 1; /* TRUE */ + } else if (cmp < 0) { + left = pos + 1; + } else { + right = pos - 1; + } + } + return 0; /* FALSE */ +} +#endif diff --git a/apache2/libinjection/sqlparse.c b/apache2/libinjection/sqlparse.c new file mode 100644 index 0000000000..05f35ab705 --- /dev/null +++ b/apache2/libinjection/sqlparse.c @@ -0,0 +1,1075 @@ +/** + * Copyright 2012,2013 Nick Galbreath + * nickg@client9.com + * BSD License -- see COPYING.txt for details + * + * (setq-default indent-tabs-mode nil) + * (setq c-default-style "k&r" + * c-basic-offset 4) + * indent -kr -nut + */ + +#include +#include +#include +#include +#include + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#if 0 +#define FOLD_DEBUG printf("%d: Fold state = %d, current=%c, last=%c\n", __LINE__, sf->fold_state, current->type, last->type == CHAR_NULL ? '~': last->type) +#else +#define FOLD_DEBUG +#endif + +// order is important here +#include "sqlparse_private.h" +#include "sqlparse_data.h" + +// memmem is a linux function +// may not exist in Windows, and doesn't exist +// in Mac OS X < 10.8 and FreeBSD < 6.0 +// Define our own. Modified to use 'const char*' +// instead of (void *) +// + +/*- + * Copyright (c) 2005 Pascal Gloor + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +const char * +my_memmem(const char *cl, size_t l_len, const char *cs, size_t s_len) +{ + register const char *cur, *last; + + /* we need something to compare */ + if (l_len == 0 || s_len == 0) + return NULL; + + /* "s" must be smaller or equal to "l" */ + if (l_len < s_len) + return NULL; + + /* special case where s_len == 1 */ + if (s_len == 1) + return (const char*) memchr(cl, (int)*cs, l_len); + + /* the last position where its possible to find "s" in "l" */ + last = cl + l_len - s_len; + + for (cur = cl; cur <= last; cur++) + if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) + return cur; + + return NULL; +} + + +size_t strlenspn(const char *s, size_t len, const char *accept) +{ + size_t i; + for (i = 0; i < len; ++i) { + /* likely we can do better by inlining this function + * but this works for now + */ + if (strchr(accept, s[i]) == NULL) { + return i; + } + } + return len; +} + +/* + * ASCII case insenstive compare only! + */ +int cstrcasecmp(const char *a, const char *b) +{ + int ca, cb; + + do { + ca = *a++ & 0xff; + cb = *b++ & 0xff; + if (ca >= 'a' && ca <= 'z') + ca -= 0x20; + if (cb >= 'a' && cb <= 'z') + cb -= 0x20; + } while (ca == cb && ca != '\0'); + + return ca - cb; +} + +int streq(const char *a, const char *b) +{ + return cstrcasecmp(a, b) == 0; +} + +void st_clear(stoken_t * st) +{ + st->type = CHAR_NULL; + st->str_open = CHAR_NULL; + st->str_close = CHAR_NULL; + st->val[0] = CHAR_NULL; +} + +int st_is_empty(const stoken_t * st) +{ + return st->type == CHAR_NULL; +} + +void st_assign_char(stoken_t * st, const char stype, const char value) +{ + st->type = stype; + st->val[0] = value; + st->val[1] = CHAR_NULL; +} + +void st_assign(stoken_t * st, const char stype, const char *value, + size_t len) +{ + size_t last = len < (ST_MAX_SIZE - 1) ? len : (ST_MAX_SIZE - 1); + st->type = stype; + strncpy(st->val, value, last); + st->val[last] = CHAR_NULL; +} + +void st_assign_cstr(stoken_t * st, const char stype, const char *value) +{ + st->type = stype; + strncpy(st->val, value, ST_MAX_SIZE - 1); + st->val[ST_MAX_SIZE - 1] = CHAR_NULL; +} + +int st_equals_cstr(const stoken_t * st, const char stype, + const char *value) +{ + return st->type == stype && !cstrcasecmp(value, st->val); +} + +void st_copy(stoken_t * dest, const stoken_t * src) +{ + memcpy(dest, src, sizeof(stoken_t)); +} + +const char *bsearch_cstrcase(const char *key, const char *base[], size_t nmemb) +{ + int left = 0; + int right = (int) nmemb - 1; + + while (left <= right) { + int pos = (left + right) / 2; + int cmp = cstrcasecmp(base[pos], key); + if (cmp == 0) { + return base[pos]; + } else if (cmp < 0) { + left = pos + 1; + } else { + right = pos - 1; + } + } + return NULL; +} + +const char *bsearch_cstr(const char *key, const char *base[], size_t nmemb) +{ + int left = 0; + int right = (int) nmemb - 1; + + while (left <= right) { + int pos = (left + right) / 2; + int cmp = strcmp(base[pos], key); + if (cmp == 0) { + return base[pos]; + } else if (cmp < 0) { + left = pos + 1; + } else { + right = pos - 1; + } + } + return NULL; +} + +char bsearch_keyword_type(const char *key, const keyword_t * keywords, + size_t numb) +{ + int left = 0; + int right = (int) numb - 1; + + while (left <= right) { + int pos = (left + right) / 2; + int cmp = cstrcasecmp(keywords[pos].word, key); + if (cmp == 0) { + return keywords[pos].type; + } else if (cmp < 0) { + left = pos + 1; + } else { + right = pos - 1; + } + } + return CHAR_NULL; +} + +int is_operator2(const char *key) +{ + return bsearch_cstrcase(key, operators2, operators2_sz) != NULL; +} + +int st_is_multiword_start(const stoken_t * st) +{ + return bsearch_cstrcase(st->val, + multikeywords_start, + multikeywords_start_sz) != NULL; +} + +int st_is_unary_op(const stoken_t * st) +{ + return (st->type == 'o' && !(strcmp(st->val, "+") && + strcmp(st->val, "-") && + strcmp(st->val, "!") && + strcmp(st->val, "!!") && + cstrcasecmp(st->val, "NOT") && + strcmp(st->val, "~"))); +} + +int st_is_arith_op(const stoken_t * st) +{ + return (st->type == 'o' && !(strcmp(st->val, "-") && + strcmp(st->val, "+") && + strcmp(st->val, "~") && + strcmp(st->val, "!") && + strcmp(st->val, "/") && + strcmp(st->val, "%") && + strcmp(st->val, "*") && + strcmp(st->val, "|") && + strcmp(st->val, "&") && + cstrcasecmp(st->val, "MOD") && + cstrcasecmp(st->val, "DIV"))); +} + +size_t parse_white(sfilter * sf) +{ + return sf->pos + 1; +} + +size_t parse_operator1(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + size_t pos = sf->pos; + + st_assign_char(current, 'o', cs[pos]); + return pos + 1; +} + +size_t parse_other(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + size_t pos = sf->pos; + + st_assign_char(current, '?', cs[pos]); + return pos + 1; +} + +size_t parse_char(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + size_t pos = sf->pos; + + st_assign_char(current, cs[pos], cs[pos]); + return pos + 1; +} + +size_t parse_eol_comment(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + const char *endpos = + (const char *) memchr((const void *) (cs + pos), '\n', slen - pos); + if (endpos == NULL) { + st_assign_cstr(current, 'c', cs + pos); + return slen; + } else { + st_assign(current, 'c', cs + pos, endpos - cs - pos); + return (endpos - cs) + 1; + } +} + +size_t parse_dash(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + + size_t pos1 = pos + 1; + if (pos1 < slen && cs[pos1] == '-') { + return parse_eol_comment(sf); + } else { + st_assign_char(current, 'o', '-'); + return pos1; + } +} + +size_t is_mysql_comment(const char *cs, const size_t len, size_t pos) +{ + size_t i; + + if (pos + 2 >= len) { + return 0; + } + if (cs[pos + 2] != '!') { + return 0; + } + // this is a mysql comment + // got "/*!" + if (pos + 3 >= len) { + return 3; + } + + if (!isdigit(cs[pos + 3])) { + return 3; + } + // handle odd case of /*!0SELECT + if (!isdigit(cs[pos + 4])) { + return 4; + } + + if (pos + 7 >= len) { + return 4; + } + + for (i = pos + 5; i <= pos + 7; ++i) { + if (!isdigit(cs[i])) { + return 3; + } + } + return 8; +} + +size_t parse_slash(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + const char* cur = cs + pos; + size_t inc = 0; + + size_t pos1 = pos + 1; + if (pos1 == slen || cs[pos1] != '*') { + return parse_operator1(sf); + } + + inc = is_mysql_comment(cs, slen, pos); + if (inc == 0) { + + // skip over initial '/*' + const char *ptr = + (const char *) my_memmem(cur + 2, slen - (pos + 2), "*/", 2); + if (ptr == NULL) { + // unterminated comment + st_assign_cstr(current, 'c', cs + pos); + return slen; + } else { + // postgresql allows nested comments which makes + // this is incompatible with parsing so + // if we find a '/*' inside the coment, then + // make a new token. + char ctype = 'c'; + const size_t clen = (ptr + 2) - (cur); + if (my_memmem(cur + 2, ptr - (cur + 2), "/*", 2) != + NULL) { + ctype = 'X'; + } + st_assign(current, ctype, cs + pos, clen); + + return pos + clen; + } + } else { + // MySQL Comment + sf->in_comment = TRUE; + st_clear(current); + return pos + inc; + } +} + +size_t parse_backslash(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + if (pos + 1 < slen && cs[pos + 1] == 'N') { + st_assign_cstr(current, '1', "NULL"); + return pos + 2; + } else { + return parse_other(sf); + } +} + +size_t parse_operator2(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + char op2[3]; + size_t pos = sf->pos; + + if (pos + 1 >= slen) { + return parse_operator1(sf); + } + + op2[0] = cs[pos]; + op2[1] = cs[pos + 1]; + op2[2] = CHAR_NULL; + + // Special Hack for MYSQL style comments + // instead of turning: + // /*! FOO */ into FOO by rewriting the string, we + // turn it into FOO */ and ignore the ending comment + if (sf->in_comment && op2[0] == '*' && op2[1] == '/') { + sf->in_comment = FALSE; + st_clear(current); + return pos + 2; + } else if (pos + 2 < slen && op2[0] == '<' && op2[1] == '=' + && cs[pos + 2] == '>') { + // special 3-char operator + + st_assign_cstr(current, 'o', "<=>"); + return pos + 3; + } else if (is_operator2(op2)) { + if (streq(op2, "&&") || streq(op2, "||")) { + st_assign_cstr(current, '&', op2); + } else { + // normal 2 char operator + st_assign_cstr(current, 'o', op2); + } + return pos + 2; + } else { + // must be a single char operator + return parse_operator1(sf); + } +} + +size_t parse_string_core(const char *cs, const size_t len, size_t pos, + stoken_t * st, char delim, size_t offset) +{ + // offset is to skip the perhaps first quote char + const char *qpos = + (const char *) memchr((const void *) (cs + pos + offset), delim, + len - pos - offset); + + // then keep string open/close info + if (offset == 1) { + // this is real quote + st->str_open = delim; + } else { + // this was a simulated quote + st->str_open = CHAR_NULL; + } + + while (TRUE) { + if (qpos == NULL) { + // string ended with no trailing quote + // assign what we have + st_assign_cstr(st, 's', cs + pos + offset); + st->str_close = CHAR_NULL; + return len; + } else if (*(qpos - 1) != '\\') { + // ending quote is not escaped.. copy and end + st_assign(st, 's', cs + pos + offset, + qpos - (cs + pos + offset)); + st->str_close = delim; + return qpos - cs + 1; + } else { + qpos = + (const char *) memchr((const void *) (qpos + 1), delim, + (cs + len) - (qpos + 1)); + } + } +} + +/** + * Used when first char is a ' or " + */ +size_t parse_string(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + // assert cs[pos] == single or double quote + return parse_string_core(cs, slen, pos, current, cs[pos], 1); +} + +size_t parse_word(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + size_t pos = sf->pos; + + size_t slen = + strlenspn(cs + pos, sf->slen - pos, + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$"); + + st_assign(current, 'n', cs + pos, slen); + if (slen < ST_MAX_SIZE) { + char ch = bsearch_keyword_type(current->val, sql_keywords, + sql_keywords_sz); + if (ch == CHAR_NULL) { + ch = 'n'; + } + current->type = ch; + } + return pos + slen; +} + +size_t parse_var(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + size_t xlen = 0; + + size_t pos1 = pos + 1; + + // move past optional other '@' + if (pos1 < slen && cs[pos1] == '@') { + pos1 += 1; + } + + xlen = strlenspn(cs + pos1, slen - pos1, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$"); + if (xlen == 0) { + st_assign(current, 'v', cs + pos, (pos1 - pos)); + return pos1; + } else { + st_assign(current, 'v', cs + pos, xlen + (pos1 - pos)); + return pos1 + xlen; + } +} + +size_t parse_number(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + size_t xlen = 0; + size_t start = 0; + + if (pos + 1 < slen && cs[pos] == '0' && (cs[pos + 1] == 'X' || cs[pos + 1] == 'x')) { + // TBD compare if isxdigit + xlen = strlenspn(cs + pos + 2, slen - pos - 2, "0123456789ABCDEFabcdef"); + if (xlen == 0) { + st_assign_cstr(current, 'n', "0X"); + return pos + 2; + } else { + st_assign(current, '1', cs + pos, 2 + xlen); + return pos + 2 + xlen; + } + } + start = pos; + + while (isdigit(cs[pos])) { + pos += 1; + } + if (cs[pos] == '.') { + pos += 1; + while (pos < slen && isdigit(cs[pos])) { + pos += 1; + } + if (pos - start == 1) { + st_assign_char(current, 'n', '.'); + return pos; + } + } + + if (cs[pos] == 'E' || cs[pos] == 'e') { + pos += 1; + if (pos < slen && (cs[pos] == '+' || cs[pos] == '-')) { + pos += 1; + } + while (isdigit(cs[pos])) { + pos += 1; + } + } else if (isalpha(cs[pos])) { + // oh no, we have something like '6FOO' + // use microsoft style parsing and take just + // the number part and leave the rest to be + // parsed later + st_assign(current, '1', cs + start, pos - start); + return pos; + } + + st_assign(current, '1', cs + start, pos - start); + return pos; +} + +int parse_token(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *s = sf->s; + const size_t slen = sf->slen; + size_t *pos = &sf->pos; + pt2Function fnptr; + + st_clear(current); + + if (*pos == 0 && sf->delim != CHAR_NULL) { + *pos = parse_string_core(s, slen, 0, current, sf->delim, 0); + return TRUE; + } + + while (*pos < slen) { + const int ch = (int) (s[*pos]); + if (ch < 0 || ch > 127) { + *pos += 1; + continue; + } + fnptr = char_parse_map[ch]; + *pos = (*fnptr) (sf); + if (current->type != CHAR_NULL) { + return TRUE; + } + } + return FALSE; +} + +void sfilter_reset(sfilter * sf, const char *s, size_t len) +{ + memset(sf, 0, sizeof(sfilter)); + sf->s = s; + sf->slen = len; +} + +int syntax_merge_words(stoken_t * a, stoken_t * b) +{ + size_t sz1 = 0; + size_t sz2 = 0; + size_t sz3 = 0; + char tmp[ST_MAX_SIZE]; + char ch; + + if (! + (a->type == 'k' || a->type == 'n' || a->type == 'o' + || a->type == 'U')) { + return FALSE; + } + + sz1 = strlen(a->val); + sz2 = strlen(b->val); + sz3 = sz1 + sz2 + 1; + + if (sz3 >= ST_MAX_SIZE) { + return FALSE; + } + // oddly annoying last.val + ' ' + current.val + memcpy(tmp, a->val, sz1); + tmp[sz1] = ' '; + memcpy(tmp + sz1 + 1, b->val, sz2); + tmp[sz3] = CHAR_NULL; + + ch = bsearch_keyword_type(tmp, multikeywords, multikeywords_sz); + if (ch != CHAR_NULL) { + // -1, don't copy the null byte + st_assign(a, ch, tmp, sz3); + return TRUE; + } else { + return FALSE; + } +} + +int sqli_tokenize(sfilter * sf, stoken_t * sout) +{ + stoken_t *last = &sf->syntax_last; + stoken_t *current = &sf->syntax_current; + + while (parse_token(sf)) { + char ttype = current->type; + if (ttype == 'c') { + st_copy(&sf->syntax_comment, current); + continue; + } + st_clear(&sf->syntax_comment); + + // + // If we don't have a saved token + // + if (last->type == CHAR_NULL) { + switch (ttype) { + + // items that have special needs + case 's': + st_copy(last, current); + continue; + case 'n': + case 'k': + case 'U': + case '&': + case 'o': + if (st_is_multiword_start(current)) { + st_copy(last, current); + continue; + } else if (current->type == 'o' || current->type == '&') { + //} else if (st_is_unary_op(current)) { + st_copy(last, current); + continue; + } else { + // copy to out + st_copy(sout, current); + return TRUE; + } + default: + // copy to out + st_copy(sout, current); + return TRUE; + } + } + // + // We have a saved token + // + + switch (ttype) { + case 's': + if (last->type == 's') { + // "FOO" "BAR" == "FOO" (skip second string) + continue; + } else { + st_copy(sout, last); + st_copy(last, current); + return TRUE; + } + break; + + case 'o': + // first case to handle "IS" + "NOT" + if (syntax_merge_words(last, current)) { + continue; + } else if (st_is_unary_op(current) + && (last->type == 'o' || last->type == '&' + || last->type == 'U')) { + // if an operator is followed by a unary operator, skip it. + // 1, + ==> "+" is not unary, it's arithmetic + // AND, + ==> "+" is unary + continue; + } else { + // no match + st_copy(sout, last); + st_copy(last, current); + return TRUE; + } + break; + + case 'n': + case 'k': + if (syntax_merge_words(last, current)) { + continue; + } else { + // total no match + st_copy(sout, last); + st_copy(last, current); + return TRUE; + } + break; + + default: + // fix up for ambigous "IN" + // handle case where IN is typically a function + // but used in compound "IN BOOLEAN MODE" jive + if (last->type == 'n' && !cstrcasecmp(last->val, "IN")) { + st_copy(last, current); + st_assign_cstr(sout, 'f', "IN"); + return TRUE; + } else { + // no match at all + st_copy(sout, last); + st_copy(last, current); + return TRUE; + } + break; + } + } + + // final cleanup + if (last->type) { + st_copy(sout, last); + st_clear(last); + return TRUE; + } else if (sf->syntax_comment.type) { + st_copy(sout, &sf->syntax_comment); + st_clear(&sf->syntax_comment); + return TRUE; + } else { + return FALSE; + } +} + +int filter_fold(sfilter * sf, stoken_t * sout) +{ + stoken_t *last = &sf->fold_last; + stoken_t *current = &sf->fold_current; + + if (sf->fold_state == 4 && !st_is_empty(last)) { + st_copy(sout, last); + sf->fold_state = 2; + st_clear(last); + return TRUE; + } + + while (sqli_tokenize(sf, current)) { + // 0 = start of statement + // skip ( and unary ops + if (sf->fold_state == 0) { + if (current->type == '(') { + continue; + } + if (st_is_unary_op(current)) { + continue; + } + sf->fold_state = 1; + } + + if (st_is_empty(last)) { + FOLD_DEBUG; + if (current->type == '1' || current->type == 'n' + || current->type == '(') { + sf->fold_state = 2; + st_copy(last, current); + } + st_copy(sout, current); + return TRUE; + } else if (last->type == '(' && st_is_unary_op(current)) { + // similar to beginning of statement + // an opening '(' resets state, and we should skip all + // unary operators + continue; + } else if (last->type == '(' && current->type == '(') { + // if we get another '(' after another + // emit 1, but keep state + st_copy(sout, current); + return TRUE; + } else if ((last->type == '1' || last->type == 'n') + && st_is_arith_op(current)) { + FOLD_DEBUG; + st_copy(last, current); + } else if (last->type == 'o' + && (current->type == '1' || current->type == 'n')) { + FOLD_DEBUG; + st_copy(last, current); + } else { + if (sf->fold_state == 2) { + if (last->type != '1' && last->type != '(' + && last->type != 'n') { + FOLD_DEBUG; + st_copy(sout, last); + st_copy(last, current); + sf->fold_state = 4; + } else { + FOLD_DEBUG; + st_copy(sout, current); + st_clear(last); + } + return TRUE; + } else { + if (last->type == 'o') { + st_copy(sout, last); + st_copy(last, current); + sf->fold_state = 4; + } else { + sf->fold_state = 2; + st_copy(sout, current); + st_clear(last); + } + return TRUE; + } + } + } + + if (!st_is_empty(last)) { + if (st_is_arith_op(last)) { + st_copy(sout, last); + st_clear(last); + return TRUE; + } else { + st_clear(last); + } + } + + return FALSE; +} + +int is_string_sqli(sfilter * sql_state, const char *s, size_t slen, + const char delim, ptr_fingerprints_fn fn) +{ + int all_done = 0; + int tlen = 0; + int patmatch = 0; + sfilter_reset(sql_state, s, slen); + sql_state->delim = delim; + + while (tlen < MAX_TOKENS) { + all_done = filter_fold(sql_state, &(sql_state->tokenvec[tlen])); + if (!all_done) { + break; + } + + sql_state->pat[tlen] = sql_state->tokenvec[tlen].type; + tlen += 1; + } + sql_state->pat[tlen] = CHAR_NULL; + + // if token 5 (last) looks like a functino word (such as ABS or ASCII) + // then check token 6 to see if it's a "(". + // if NOT then, it's not a function. + + if (tlen == MAX_TOKENS && !all_done + && sql_state->pat[MAX_TOKENS - 1] == 'f') { + + stoken_t tmp; + all_done = filter_fold(sql_state, &tmp); + if (!all_done && tmp.type != '(') { + sql_state->reason = __LINE__; + return FALSE; + } + } + // check for 'X' in pattern + // this means parsing could not be done + // accurately due to pgsql's double comments + // or other syntax that isn't consistent + // should be very rare false positive + if (strchr(sql_state->pat, 'X')) { + return TRUE; + } + + patmatch = fn(sql_state->pat); + + if (!patmatch) { + sql_state->reason = __LINE__; + return FALSE; + } + switch (tlen) { + case 2:{ + // if 'comment' is '#' ignore.. too many FP + if (sql_state->tokenvec[1].val[0] == '#') { + sql_state->reason = __LINE__; + return FALSE; + } + // detect obvious sqli scans.. many people put '--' in plain text + // so only detect if input ends with '--', e.g. 1-- but not 1-- foo + if ((strlen(sql_state->tokenvec[1].val) > 2) + && sql_state->tokenvec[1].val[0] == '-') { + sql_state->reason = __LINE__; + return FALSE; + } + break; + } + case 3:{ + // ...foo' + 'bar... + // no opening quote, no closing quote + // and each string has data + if (streq(sql_state->pat, "sos") + || streq(sql_state->pat, "s&s")) { + if ((sql_state->tokenvec[0].str_open == CHAR_NULL) + && (sql_state->tokenvec[2].str_close == CHAR_NULL)) { + + // if ....foo" + "bar.... + return TRUE; + } else { + // not sqli + sql_state->reason = __LINE__; + return FALSE; + } + break; + } + } /* case 3 */ + } /* end switch */ + return TRUE; +} + +int is_sqli(sfilter * sql_state, const char *s, size_t slen, + ptr_fingerprints_fn fn) +{ + + if (slen == 0) { + return FALSE; + } + + if (is_string_sqli(sql_state, s, slen, CHAR_NULL, fn)) { + return TRUE; + } + + if (memchr(s, CHAR_SINGLE, slen) + && is_string_sqli(sql_state, s, slen, CHAR_SINGLE, fn)) { + return TRUE; + } + + if (memchr(s, CHAR_DOUBLE, slen) + && is_string_sqli(sql_state, s, slen, CHAR_DOUBLE, fn)) { + return TRUE; + } + + return FALSE; +} + +/* + not used yet + +// [('o', 228), ('k', 220), ('1', 217), (')', 157), ('(', 156), ('s', 154), ('n', 77), ('f', 73), (';', 59), (',', 35), ('v', 17), ('c', 15), +int char2int(char c) +{ + const char *map = "ok1()snf;,"; + const char *pos = strchr(map, c); + if (pos == NULL) { + return 15; + } else { + return (int) (pos - map) + 1; + } +} + +unsigned long long pat2int(const char *pat) +{ + unsigned long long val = 0; + while (*pat) { + val = (val << 4) + char2int(*pat); + pat += 1; + } + return val; +} +*/ diff --git a/apache2/libinjection/sqlparse.h b/apache2/libinjection/sqlparse.h new file mode 100644 index 0000000000..f6a0d1889b --- /dev/null +++ b/apache2/libinjection/sqlparse.h @@ -0,0 +1,83 @@ +/** + * Copyright 2012, Nick Galbreath + * nickg@client9.com + * BSD License -- see COPYING.txt for details + * + * + * HOW TO USE: + * + * // Normalize query or postvar value + * // ATTENTION: this modifies user_string... make copy if that is not ok + * size_t new_len = qs_normalize(user_string, user_string_len); + * + * sfilter s; + * bool sqli = is_sqli(&s, user_string, new_len); + * + * // That's it! sfilter s has some data on how it matched or not + * // details to come! + * + */ + +#ifndef _SQLPARSE_H +#define _SQLPARSE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define ST_MAX_SIZE 32 +#define MAX_TOKENS 5 + +typedef struct { + char type; + char str_open; + char str_close; + char val[ST_MAX_SIZE]; +} stoken_t; + +typedef struct { + /* input */ + const char *s; + size_t slen; + + /* current tokenize state */ + size_t pos; + int in_comment; + + /* syntax fixups state */ + stoken_t syntax_current; + stoken_t syntax_last; + stoken_t syntax_comment; + + /* constant folding state */ + stoken_t fold_current; + stoken_t fold_last; + int fold_state; + + /* final sqli data */ + stoken_t tokenvec[MAX_TOKENS]; + + // +1 for possible ending null + char pat[MAX_TOKENS + 1]; + char delim; + int reason; +} sfilter; + +/** + * Pointer to function, takes cstr input, return true/false + */ +typedef int (*ptr_fingerprints_fn)(const char*); + +/** + * + * + * \return TRUE if SQLi, FALSE is benign + */ +int is_sqli(sfilter * sql_state, const char *s, size_t slen, + ptr_fingerprints_fn fn); + +#ifdef __cplusplus +} +#endif + +#endif /* _SQLPARSE_H */ diff --git a/apache2/libinjection/sqlparse_data.h b/apache2/libinjection/sqlparse_data.h new file mode 100644 index 0000000000..a76af56de3 --- /dev/null +++ b/apache2/libinjection/sqlparse_data.h @@ -0,0 +1,682 @@ +#ifndef _SQLPARSE_DATA_H +#define _SQLPARSE_DATA_H +#include "sqlparse.h" + +static const char* operators2[] = { + "!!", + "!<", + "!=", + "!>", + "!~", + "%=", + "&&", + "&=", + "*=", + "+=", + "-=", + "/=", + ":=", + "<<", + "<=", + "<>", + "<@", + ">=", + ">>", + "@>", + "^=", + "|/", + "|=", + "||", + "~*", +}; +static const size_t operators2_sz = 25; + +static const keyword_t sql_keywords[] = { + {"ABS", 'f'}, + {"ACCESSIBLE", 'k'}, + {"ACOS", 'f'}, + {"ADD", 'k'}, + {"ADDDATE", 'f'}, + {"ADDTIME", 'f'}, + {"AES_DECRYPT", 'f'}, + {"AES_ENCRYPT", 'f'}, + {"AGAINST", 'k'}, + {"ALL_USERS", 'k'}, + {"ALTER", 'k'}, + {"ANALYZE", 'k'}, + {"AND", '&'}, + {"AS", 'k'}, + {"ASC", 'k'}, + {"ASCII", 'f'}, + {"ASENSITIVE", 'k'}, + {"ASIN", 'f'}, + {"ATAN", 'f'}, + {"ATAN2", 'f'}, + {"AVG", 'f'}, + {"BEFORE", 'k'}, + {"BEGIN", 'k'}, + {"BENCHMARK", 'f'}, + {"BETWEEN", 'k'}, + {"BIGINT", 'k'}, + {"BIN", 'f'}, + {"BINARY", 'k'}, + {"BINARY_DOUBLE_INFINITY", '1'}, + {"BINARY_DOUBLE_NAN", '1'}, + {"BINARY_FLOAT_INFINITY", '1'}, + {"BINARY_FLOAT_NAN", '1'}, + {"BINBINARY", 'f'}, + {"BIT_AND", 'f'}, + {"BIT_COUNT", 'f'}, + {"BIT_LENGTH", 'f'}, + {"BIT_OR", 'f'}, + {"BIT_XOR", 'f'}, + {"BLOB", 'k'}, + {"BOOLEAN", 'k'}, + {"BOTH", 'k'}, + {"BY", 'n'}, + {"CALL", 'k'}, + {"CASCADE", 'k'}, + {"CASE", 'o'}, + {"CAST", 'f'}, + {"CEIL", 'f'}, + {"CEILING", 'f'}, + {"CHANGE", 'k'}, + {"CHAR", 'f'}, + {"CHARACTER", 'k'}, + {"CHARACTER_LENGTH", 'f'}, + {"CHARSET", 'f'}, + {"CHAR_LENGTH", 'f'}, + {"CHECK", 'k'}, + {"CHR", 'f'}, + {"COALESCE", 'k'}, + {"COERCIBILITY", 'f'}, + {"COLLATE", 'k'}, + {"COLLATION", 'f'}, + {"COLUMN", 'k'}, + {"COMPRESS", 'f'}, + {"CONCAT", 'f'}, + {"CONCAT_WS", 'f'}, + {"CONDITION", 'k'}, + {"CONNECTION_ID", 'f'}, + {"CONSTRAINT", 'k'}, + {"CONTINUE", 'k'}, + {"CONV", 'f'}, + {"CONVERT", 'f'}, + {"CONVERT_TZ", 'f'}, + {"COS", 'f'}, + {"COT", 'f'}, + {"COUNT", 'f'}, + {"CRC32", 'f'}, + {"CREATE", 'k'}, + {"CTXSYS.DRITHSX.SN", 'f'}, + {"CURDATE", 'f'}, + {"CURRENT_DATE", 'k'}, + {"CURRENT_DATECURRENT_TIME", 'f'}, + {"CURRENT_TIME", 'k'}, + {"CURRENT_TIMESTAMP", 'k'}, + {"CURRENT_USER", 'k'}, + {"CURSOR", 'k'}, + {"CURTIME", 'f'}, + {"DATABASE", 'k'}, + {"DATABASES", 'k'}, + {"DATE", 'f'}, + {"DATEDIFF", 'f'}, + {"DATE_ADD", 'f'}, + {"DATE_FORMAT", 'f'}, + {"DATE_SUB", 'f'}, + {"DAY", 'f'}, + {"DAYNAME", 'f'}, + {"DAYOFMONTH", 'f'}, + {"DAYOFWEEK", 'f'}, + {"DAYOFYEAR", 'f'}, + {"DAY_HOUR", 'k'}, + {"DAY_MICROSECOND", 'k'}, + {"DAY_MINUTE", 'k'}, + {"DAY_SECOND", 'k'}, + {"DBMS_PIPE.RECEIVE_MESSAGE", 'f'}, + {"DEC", 'k'}, + {"DECIMAL", 'k'}, + {"DECLARE", 'k'}, + {"DECODE", 'f'}, + {"DEFAULT", 'k'}, + {"DEGREES", 'f'}, + {"DELAY", 'k'}, + {"DELAYED", 'k'}, + {"DELETE", 'k'}, + {"DESC", 'k'}, + {"DESCRIBE", 'k'}, + {"DES_DECRYPT", 'f'}, + {"DES_ENCRYPT", 'f'}, + {"DETERMINISTIC", 'k'}, + {"DISTINCROW", 'k'}, + {"DISTINCT", 'k'}, + {"DIV", 'o'}, + {"DROP", 'k'}, + {"DUAL", 'k'}, + {"EACH", 'k'}, + {"ELSE", 'k'}, + {"ELSEIF", 'k'}, + {"ELT", 'f'}, + {"ENCLOSED", 'k'}, + {"ENCODE", 'f'}, + {"ENCRYPT", 'f'}, + {"ESCAPED", 'k'}, + {"EXEC", 'k'}, + {"EXECUTE", 'k'}, + {"EXISTS", 'k'}, + {"EXIT", 'k'}, + {"EXP", 'f'}, + {"EXPLAIN", 'k'}, + {"EXPORT_SET", 'f'}, + {"EXTRACT", 'f'}, + {"EXTRACTVALUE", 'f'}, + {"EXTRACT_VALUE", 'f'}, + {"FALSE", '1'}, + {"FETCH", 'k'}, + {"FIELD", 'f'}, + {"FIND_IN_SET", 'f'}, + {"FLOOR", 'f'}, + {"FOR", 'n'}, + {"FORCE", 'k'}, + {"FOREIGN", 'k'}, + {"FORMAT", 'f'}, + {"FOUND_ROWS", 'f'}, + {"FROM", 'k'}, + {"FROM_DAYS", 'f'}, + {"FROM_UNIXTIME", 'f'}, + {"FULLTEXT", 'k'}, + {"GENERATE_SERIES", 'f'}, + {"GET_FORMAT", 'f'}, + {"GET_LOCK", 'f'}, + {"GOTO", 'k'}, + {"GRANT", 'k'}, + {"GREATEST", 'f'}, + {"GROUP", 'n'}, + {"GROUP_CONCAT", 'f'}, + {"HAVING", 'k'}, + {"HEX", 'f'}, + {"HIGH_PRIORITY", 'k'}, + {"HOST_NAME", 'f'}, + {"HOUR", 'f'}, + {"HOUR_MICROSECOND", 'k'}, + {"HOUR_MINUTE", 'k'}, + {"HOUR_SECOND", 'k'}, + {"IF", 'k'}, + {"IFF", 'f'}, + {"IFNULL", 'f'}, + {"IGNORE", 'k'}, + {"IIF", 'f'}, + {"IN", 'n'}, + {"INDEX", 'k'}, + {"INET_ATON", 'f'}, + {"INET_NTOA", 'f'}, + {"INFILE", 'k'}, + {"INNER", 'k'}, + {"INOUT", 'k'}, + {"INSENSITIVE", 'k'}, + {"INSERT", 'k'}, + {"INSTR", 'f'}, + {"INT", 'k'}, + {"INT1", 'k'}, + {"INT2", 'k'}, + {"INT3", 'k'}, + {"INT4", 'k'}, + {"INT8", 'k'}, + {"INTEGER", 'k'}, + {"INTERVAL", 'k'}, + {"INTO", 'k'}, + {"IS", 'o'}, + {"ISNULL", 'f'}, + {"IS_FREE_LOCK", 'f'}, + {"IS_MEMBERIS_SRVROLEMEMBER", 'f'}, + {"IS_USED_LOCK", 'f'}, + {"ITERATE", 'k'}, + {"JOIN", 'k'}, + {"KEYS", 'k'}, + {"KILL", 'k'}, + {"LAST_INSERT_ID", 'f'}, + {"LCASE", 'f'}, + {"LEADING", 'k'}, + {"LEAST", 'f'}, + {"LEAVE", 'k'}, + {"LEFT", 'n'}, + {"LENGTH", 'f'}, + {"LIKE", 'o'}, + {"LIMIT", 'k'}, + {"LINEAR", 'k'}, + {"LINES", 'k'}, + {"LN", 'f'}, + {"LOAD", 'k'}, + {"LOAD_FILE", 'f'}, + {"LOCALTIME", 'k'}, + {"LOCALTIMESTAMP", 'k'}, + {"LOCATE", 'f'}, + {"LOCK", 'n'}, + {"LOG", 'f'}, + {"LOG10", 'f'}, + {"LOG2", 'f'}, + {"LONGBLOB", 'k'}, + {"LONGTEXT", 'k'}, + {"LOOP", 'k'}, + {"LOWER", 'f'}, + {"LOW_PRIORITY", 'k'}, + {"LPAD", 'f'}, + {"LTRIM", 'f'}, + {"MAKEDATE", 'f'}, + {"MAKE_SET", 'f'}, + {"MASTER_BIND", 'k'}, + {"MASTER_POS_WAIT", 'f'}, + {"MASTER_SSL_VERIFY_SERVER_CERT", 'k'}, + {"MATCH", 'k'}, + {"MAX", 'f'}, + {"MAXVALUE", 'k'}, + {"MD5", 'f'}, + {"MEDIUMBLOB", 'k'}, + {"MEDIUMINT", 'k'}, + {"MEDIUMTEXT", 'k'}, + {"MERGE", 'k'}, + {"MICROSECOND", 'f'}, + {"MID", 'f'}, + {"MIDDLEINT", 'k'}, + {"MIN", 'f'}, + {"MINUTE", 'f'}, + {"MINUTE_MICROSECOND", 'k'}, + {"MINUTE_SECOND", 'k'}, + {"MOD", 'o'}, + {"MODE", 'n'}, + {"MODIFIES", 'k'}, + {"MONTH", 'f'}, + {"MONTHNAME", 'f'}, + {"NAME_CONST", 'f'}, + {"NOT", 'o'}, + {"NOW", 'f'}, + {"NO_WRITE_TO_BINLOG", 'k'}, + {"NULL", '1'}, + {"NULLIF", 'f'}, + {"NUMERIC", 'k'}, + {"OCT", 'f'}, + {"OCTET_LENGTH", 'f'}, + {"OFFSET", 'k'}, + {"OLD_PASSWORD", 'f'}, + {"ONE_SHOT", 'k'}, + {"OPEN", 'k'}, + {"OPENDATASOURCE", 'f'}, + {"OPENQUERY", 'f'}, + {"OPENROWSET", 'f'}, + {"OPENXML", 'f'}, + {"OPTIMIZE", 'k'}, + {"OPTION", 'k'}, + {"OPTIONALLY", 'k'}, + {"OR", '&'}, + {"ORD", 'f'}, + {"ORDER", 'n'}, + {"OUT", 'k'}, + {"OUTFILE", 'k'}, + {"OWN3D", 'k'}, + {"PARTITION", 'k'}, + {"PASSWORD", 'k'}, + {"PERIOD_ADD", 'f'}, + {"PERIOID_DIFF", 'f'}, + {"PG_ADVISORY_LOCK", 'f'}, + {"PG_SLEEP", 'f'}, + {"PI", 'f'}, + {"POSITION", 'f'}, + {"POW", 'f'}, + {"POWER", 'f'}, + {"PRECISION", 'k'}, + {"PRIMARY", 'k'}, + {"PROCEDURE", 'k'}, + {"PURGE", 'k'}, + {"QUARTER", 'f'}, + {"QUOTE", 'f'}, + {"RADIANS", 'f'}, + {"RAND", 'f'}, + {"RANDOMBLOB", 'f'}, + {"RANGE", 'k'}, + {"READ", 'k'}, + {"READS", 'k'}, + {"READ_WRITE", 'k'}, + {"REAL", 'n'}, + {"REFERENCES", 'k'}, + {"REGEXP", 'o'}, + {"RELEASE", 'k'}, + {"RELEASE_LOCK", 'f'}, + {"RENAME", 'k'}, + {"REPEAT", 'k'}, + {"REPLACE", 'k'}, + {"REQUIRE", 'k'}, + {"RESIGNAL", 'k'}, + {"RESTRICT", 'k'}, + {"RETURN", 'k'}, + {"REVERSE", 'f'}, + {"REVOKE", 'k'}, + {"RIGHT", 'n'}, + {"RLIKE", 'o'}, + {"ROUND", 'f'}, + {"ROW", 'f'}, + {"ROW_COUNT", 'f'}, + {"RPAD", 'f'}, + {"RTRIM", 'f'}, + {"SCHEMA", 'k'}, + {"SCHEMAS", 'k'}, + {"SECOND_MICROSECOND", 'k'}, + {"SEC_TO_TIME", 'f'}, + {"SELECT", 'k'}, + {"SENSITIVE", 'k'}, + {"SEPARATOR", 'k'}, + {"SESSION_USER", 'f'}, + {"SET", 'k'}, + {"SHA", 'f'}, + {"SHA1", 'f'}, + {"SHA2", 'f'}, + {"SHOW", 'n'}, + {"SHUTDOWN", 'k'}, + {"SIGN", 'f'}, + {"SIGNAL", 'k'}, + {"SIMILAR", 'k'}, + {"SIN", 'f'}, + {"SLEEP", 'f'}, + {"SMALLINT", 'k'}, + {"SOUNDEX", 'f'}, + {"SOUNDS", 'o'}, + {"SPACE", 'f'}, + {"SPATIAL", 'k'}, + {"SPECIFIC", 'k'}, + {"SQL", 'k'}, + {"SQLEXCEPTION", 'k'}, + {"SQLSTATE", 'k'}, + {"SQLWARNING", 'k'}, + {"SQL_BIG_RESULT", 'k'}, + {"SQL_CALC_FOUND_ROWS", 'k'}, + {"SQL_SMALL_RESULT", 'k'}, + {"SQRT", 'f'}, + {"SSL", 'k'}, + {"STARTING", 'k'}, + {"STDDEV", 'f'}, + {"STDDEV_POP", 'f'}, + {"STDDEV_SAMP", 'f'}, + {"STRAIGHT_JOIN", 'k'}, + {"STRCMP", 'f'}, + {"STR_TO_DATE", 'f'}, + {"SUBDATE", 'f'}, + {"SUBSTR", 'f'}, + {"SUBSTRING", 'f'}, + {"SUBSTRING_INDEX", 'f'}, + {"SUBTIME", 'f'}, + {"SUM", 'f'}, + {"SYS.STRAGG", 'f'}, + {"SYSCOLUMNS", 'k'}, + {"SYSDATE", 'f'}, + {"SYSOBJECTS", 'k'}, + {"SYSTEM_USER", 'f'}, + {"SYSUSERS", 'k'}, + {"TABLE", 'k'}, + {"TAN", 'f'}, + {"TERMINATED", 'k'}, + {"THEN", 'k'}, + {"TIME", 'k'}, + {"TIMEDIFF", 'f'}, + {"TIMESTAMP", 'f'}, + {"TIMESTAMPADD", 'f'}, + {"TIME_FORMAT", 'f'}, + {"TIME_TO_SEC", 'f'}, + {"TINYBLOB", 'k'}, + {"TINYINT", 'k'}, + {"TINYTEXT", 'k'}, + {"TOP", 'k'}, + {"TO_CHAR", 'f'}, + {"TO_DAYS", 'f'}, + {"TO_SECONDS", 'f'}, + {"TRAILING", 'n'}, + {"TRIGGER", 'k'}, + {"TRIM", 'f'}, + {"TRUE", '1'}, + {"TRUNCATE", 'f'}, + {"UCASE", 'f'}, + {"UNCOMPRESS", 'f'}, + {"UNCOMPRESS_LENGTH", 'f'}, + {"UNDO", 'k'}, + {"UNHEX", 'f'}, + {"UNION", 'U'}, + {"UNIQUE", 'n'}, + {"UNIX_TIMESTAMP", 'f'}, + {"UNI_ON", 'U'}, + {"UNLOCK", 'k'}, + {"UNSIGNED", 'k'}, + {"UPDATE", 'k'}, + {"UPDATEXML", 'f'}, + {"UPPER", 'f'}, + {"USAGE", 'k'}, + {"USE", 'k'}, + {"USING", 'f'}, + {"UTC_DATE", 'k'}, + {"UTC_TIME", 'k'}, + {"UTC_TIMESTAMP", 'k'}, + {"UTL_INADDR.GET_HOST_ADDRESS", 'f'}, + {"UUID", 'f'}, + {"UUID_SHORT", 'f'}, + {"VALUES", 'k'}, + {"VARBINARY", 'k'}, + {"VARCHAR", 'k'}, + {"VARCHARACTER", 'k'}, + {"VARIANCE", 'f'}, + {"VARYING", 'k'}, + {"VAR_POP", 'f'}, + {"VAR_SAMP", 'f'}, + {"VERSION", 'f'}, + {"WAITFOR", 'k'}, + {"WEEK", 'f'}, + {"WEEKDAY", 'f'}, + {"WEEKOFYEAR", 'f'}, + {"WHEN", 'k'}, + {"WHERE", 'k'}, + {"WHILE", 'k'}, + {"WITH", 'k'}, + {"XMLELEMENT", 'f'}, + {"XMLFOREST", 'f'}, + {"XMLFORMAT", 'f'}, + {"XMLTYPE", 'f'}, + {"XOR", 'o'}, + {"XP_EXECRESULTSET", 'k'}, + {"YEAR", 'f'}, + {"YEARWEEK", 'f'}, + {"YEAR_MONTH", 'k'}, + {"ZEROFILL", 'k'}, +}; +static const size_t sql_keywords_sz = 450; +static const char* multikeywords_start[] = { + "ALTER", + "CROSS", + "FULL", + "GROUP", + "IN", + "IN BOOLEAN", + "INTERSECT", + "IS", + "LEFT", + "LOCK", + "NATURAL", + "NOT", + "NOT SIMILAR", + "ORDER", + "OWN3D", + "READ", + "RIGHT", + "SELECT", + "SIMILAR", + "SOUNDS", + "UNION", +}; +static const size_t multikeywords_start_sz = 21; +static const keyword_t multikeywords[] = { + {"ALTER DOMAIN", 'k'}, + {"ALTER TABLE", 'k'}, + {"CROSS JOIN", 'k'}, + {"FULL OUTER", 'k'}, + {"GROUP BY", 'B'}, + {"IN BOOLEAN", 'n'}, + {"IN BOOLEAN MODE", 'k'}, + {"INTERSECT ALL", 'o'}, + {"IS NOT", 'o'}, + {"LEFT JOIN", 'k'}, + {"LEFT OUTER", 'k'}, + {"LOCK TABLE", 'k'}, + {"LOCK TABLES", 'k'}, + {"NATURAL FULL", 'k'}, + {"NATURAL INNER", 'k'}, + {"NATURAL JOIN", 'k'}, + {"NATURAL LEFT", 'k'}, + {"NATURAL OUTER", 'k'}, + {"NATURAL RIGHT", 'k'}, + {"NOT BETWEEN", 'o'}, + {"NOT IN", 'o'}, + {"NOT LIKE", 'o'}, + {"NOT REGEXP", 'o'}, + {"NOT RLIKE", 'o'}, + {"NOT SIMILAR", 'o'}, + {"NOT SIMILAR TO", 'o'}, + {"ORDER BY", 'B'}, + {"OWN3D BY", 'B'}, + {"READ WRITE", 'k'}, + {"RIGHT JOIN", 'k'}, + {"RIGHT OUTER", 'k'}, + {"SELECT ALL", 'k'}, + {"SIMILAR TO", 'o'}, + {"SOUNDS LIKE", 'o'}, + {"UNION ALL", 'U'}, +}; +static const size_t multikeywords_sz = 35; + +typedef size_t (*pt2Function)(sfilter *sf); +static const pt2Function char_parse_map[] = { + &parse_white, /* 0 */ + &parse_white, /* 1 */ + &parse_white, /* 2 */ + &parse_white, /* 3 */ + &parse_white, /* 4 */ + &parse_white, /* 5 */ + &parse_white, /* 6 */ + &parse_white, /* 7 */ + &parse_white, /* 8 */ + &parse_white, /* 9 */ + &parse_white, /* 10 */ + &parse_white, /* 11 */ + &parse_white, /* 12 */ + &parse_white, /* 13 */ + &parse_white, /* 14 */ + &parse_white, /* 15 */ + &parse_white, /* 16 */ + &parse_white, /* 17 */ + &parse_white, /* 18 */ + &parse_white, /* 19 */ + &parse_white, /* 20 */ + &parse_white, /* 21 */ + &parse_white, /* 22 */ + &parse_white, /* 23 */ + &parse_white, /* 24 */ + &parse_white, /* 25 */ + &parse_white, /* 26 */ + &parse_white, /* 27 */ + &parse_white, /* 28 */ + &parse_white, /* 29 */ + &parse_white, /* 30 */ + &parse_white, /* 31 */ + &parse_white, /* 32 */ + &parse_operator2, /* 33 */ + &parse_string, /* 34 */ + &parse_eol_comment, /* 35 */ + &parse_white, /* 36 */ + &parse_operator1, /* 37 */ + &parse_operator2, /* 38 */ + &parse_string, /* 39 */ + &parse_char, /* 40 */ + &parse_char, /* 41 */ + &parse_operator2, /* 42 */ + &parse_operator1, /* 43 */ + &parse_char, /* 44 */ + &parse_dash, /* 45 */ + &parse_number, /* 46 */ + &parse_slash, /* 47 */ + &parse_number, /* 48 */ + &parse_number, /* 49 */ + &parse_number, /* 50 */ + &parse_number, /* 51 */ + &parse_number, /* 52 */ + &parse_number, /* 53 */ + &parse_number, /* 54 */ + &parse_number, /* 55 */ + &parse_number, /* 56 */ + &parse_number, /* 57 */ + &parse_char, /* 58 */ + &parse_char, /* 59 */ + &parse_operator2, /* 60 */ + &parse_operator2, /* 61 */ + &parse_operator2, /* 62 */ + &parse_other, /* 63 */ + &parse_var, /* 64 */ + &parse_word, /* 65 */ + &parse_word, /* 66 */ + &parse_word, /* 67 */ + &parse_word, /* 68 */ + &parse_word, /* 69 */ + &parse_word, /* 70 */ + &parse_word, /* 71 */ + &parse_word, /* 72 */ + &parse_word, /* 73 */ + &parse_word, /* 74 */ + &parse_word, /* 75 */ + &parse_word, /* 76 */ + &parse_word, /* 77 */ + &parse_word, /* 78 */ + &parse_word, /* 79 */ + &parse_word, /* 80 */ + &parse_word, /* 81 */ + &parse_word, /* 82 */ + &parse_word, /* 83 */ + &parse_word, /* 84 */ + &parse_word, /* 85 */ + &parse_word, /* 86 */ + &parse_word, /* 87 */ + &parse_word, /* 88 */ + &parse_word, /* 89 */ + &parse_word, /* 90 */ + &parse_other, /* 91 */ + &parse_backslash, /* 92 */ + &parse_other, /* 93 */ + &parse_operator1, /* 94 */ + &parse_word, /* 95 */ + &parse_word, /* 96 */ + &parse_word, /* 97 */ + &parse_word, /* 98 */ + &parse_word, /* 99 */ + &parse_word, /* 100 */ + &parse_word, /* 101 */ + &parse_word, /* 102 */ + &parse_word, /* 103 */ + &parse_word, /* 104 */ + &parse_word, /* 105 */ + &parse_word, /* 106 */ + &parse_word, /* 107 */ + &parse_word, /* 108 */ + &parse_word, /* 109 */ + &parse_word, /* 110 */ + &parse_word, /* 111 */ + &parse_word, /* 112 */ + &parse_word, /* 113 */ + &parse_word, /* 114 */ + &parse_word, /* 115 */ + &parse_word, /* 116 */ + &parse_word, /* 117 */ + &parse_word, /* 118 */ + &parse_word, /* 119 */ + &parse_word, /* 120 */ + &parse_word, /* 121 */ + &parse_word, /* 122 */ + &parse_other, /* 123 */ + &parse_operator2, /* 124 */ + &parse_other, /* 125 */ + &parse_operator1, /* 126 */ + &parse_white, /* 127 */ +}; + +#endif diff --git a/apache2/libinjection/sqlparse_private.h b/apache2/libinjection/sqlparse_private.h new file mode 100644 index 0000000000..0d16c033e6 --- /dev/null +++ b/apache2/libinjection/sqlparse_private.h @@ -0,0 +1,109 @@ +/** + * Copyright 2012, Nick Galbreath + * nickg@client9.com + * BSD License - see COPYING.txt for details + * + * (setq-default indent-tabs-mode nil) + * (setq c-default-style "k&r" + * c-basic-offset 4) + * indent -kr -nut + */ +#ifndef _SQLPARSE_PRIVATE_H +#define _SQLPARSE_PRIVATE_H + +#include "sqlparse.h" + +#define CHAR_NULL '\0' +#define CHAR_SINGLE '\'' +#define CHAR_DOUBLE '"' + +/*** + * The stdlib function 'strspn' assumes input to null-delimited. + * This allows us to specifying and input length and allows + * embedded nulls + */ +size_t strlenspn(const char *s, size_t len, const char *accept); + +int streq(const char *a, const char *b); + +void st_clear(stoken_t * st); +void st_assign_char(stoken_t * st, const char stype, const char value); +void st_set_type(stoken_t * st, const char stype); +void st_assign(stoken_t * st, const char stype, const char *value, + size_t len); +void st_assign_cstr(stoken_t * st, const char stype, const char *value); +void st_copy(stoken_t * dest, const stoken_t * src); + +int st_equals_cstr(const stoken_t * src, const char stype, + const char *value); + +int st_is_empty(const stoken_t * st); +int st_is_arith_op(const stoken_t * st); +int st_is_unary_op(const stoken_t * st); +int st_is_english_op(const stoken_t * st); +int st_is_logical_op(const stoken_t * st); +int st_is_multiword_start(const stoken_t * st); + +const char *bsearch_cstr(const char *key, const char *base[], + size_t nmemb); + +typedef struct { + const char *word; + char type; +} keyword_t; + +char bsearch_keyword_type(const char *key, const keyword_t keywords[], + size_t len); + +int is_operator2(const char *key); + +int is_sqli_pattern(const char *key); + +size_t parse_none(sfilter * sf); +size_t parse_other(sfilter * sf); +size_t parse_white(sfilter * sf); +size_t parse_operator1(sfilter *sf); +size_t parse_char(sfilter *sf); +size_t parse_eol_comment(sfilter *sf); +size_t parse_dash(sfilter *sf); +size_t is_mysql_comment(const char *cs, const size_t len, size_t pos); +size_t parse_slash(sfilter *sf); +size_t parse_backslash(sfilter * sf); +size_t parse_operator2(sfilter *sf); +size_t parse_string_core(const char *cs, const size_t len, size_t pos, + stoken_t * st, char delim, size_t offset); +size_t parse_string(sfilter *sf); +size_t parse_word(sfilter * sf); +size_t parse_var(sfilter * sf); + +size_t parse_number(sfilter * sf); + +int parse_token(sfilter * sf); + +/** + * Looks at syntax_last and syntax_current to see + * if they can be merged into a multi-keyword + */ +int syntax_merge_words(stoken_t * a, stoken_t * b); + +void sfilter_reset(sfilter * sf, const char *s, size_t slen); + +/** + * Takes a raw stream of SQL tokens and does the following: + * * Merge mutliple strings into one "foo", "bar" --> "foo bar" + * * Remove comments except last one 1, +, -- foo, 1 ->> 1,+,1 + * * Merge multi-word keywords and operators into one + * e.g. "UNION", "ALL" --> "UNION ALL" + */ +int sqli_tokenize(sfilter * sf, stoken_t * sout); + +int filter_fold(sfilter * sf, stoken_t * sout); + +int is_string_sqli(sfilter * sql_state, const char *s, size_t slen, + const char delim, + ptr_fingerprints_fn fn); + +int char2int(char c); +unsigned long long pat2int(const char *pat); + +#endif /* _SQLPARSE_PRIVATE_H */ diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c index 849ca9dc42..6ad6b1a0ad 100644 --- a/apache2/mod_security2.c +++ b/apache2/mod_security2.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/modsecurity.c b/apache2/modsecurity.c index a7a5bb18de..a6891711be 100644 --- a/apache2/modsecurity.c +++ b/apache2/modsecurity.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/modsecurity.h b/apache2/modsecurity.h index cb1a8d188e..9f001523cd 100644 --- a/apache2/modsecurity.h +++ b/apache2/modsecurity.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_crypt.c b/apache2/msc_crypt.c index 5699c83248..3b251c4bf9 100644 --- a/apache2/msc_crypt.c +++ b/apache2/msc_crypt.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ - * Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_crypt.h b/apache2/msc_crypt.h index 54a6dc7fb5..3b3aa6da44 100644 --- a/apache2/msc_crypt.h +++ b/apache2/msc_crypt.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_geo.c b/apache2/msc_geo.c index 400dd9041e..49cf292c7d 100644 --- a/apache2/msc_geo.c +++ b/apache2/msc_geo.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_geo.h b/apache2/msc_geo.h index 8b64cb0d10..1293614608 100644 --- a/apache2/msc_geo.h +++ b/apache2/msc_geo.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_gsb.c b/apache2/msc_gsb.c index d3449e2f43..49b1ff4e5d 100644 --- a/apache2/msc_gsb.c +++ b/apache2/msc_gsb.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_gsb.h b/apache2/msc_gsb.h index 7bff4c4a81..87399d16d5 100644 --- a/apache2/msc_gsb.h +++ b/apache2/msc_gsb.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_logging.c b/apache2/msc_logging.c index b2f2e445a2..66d204f7b5 100644 --- a/apache2/msc_logging.c +++ b/apache2/msc_logging.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_logging.h b/apache2/msc_logging.h index 308b09b693..75af9da7ae 100644 --- a/apache2/msc_logging.h +++ b/apache2/msc_logging.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_lua.c b/apache2/msc_lua.c index 6450e7784b..f4482ae7e5 100644 --- a/apache2/msc_lua.c +++ b/apache2/msc_lua.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_lua.h b/apache2/msc_lua.h index 1f8e50eebe..a60697ce90 100644 --- a/apache2/msc_lua.h +++ b/apache2/msc_lua.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_multipart.c b/apache2/msc_multipart.c index d0b3242bc0..4afd5c757b 100644 --- a/apache2/msc_multipart.c +++ b/apache2/msc_multipart.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_multipart.h b/apache2/msc_multipart.h index fcc85a4ceb..a0f6a08ddf 100644 --- a/apache2/msc_multipart.h +++ b/apache2/msc_multipart.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_parsers.c b/apache2/msc_parsers.c index ffa6d4692d..57f291ec2a 100644 --- a/apache2/msc_parsers.c +++ b/apache2/msc_parsers.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_parsers.h b/apache2/msc_parsers.h index 41a9e392be..2be96dc666 100644 --- a/apache2/msc_parsers.h +++ b/apache2/msc_parsers.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_pcre.c b/apache2/msc_pcre.c index 3393493b41..8534a20914 100644 --- a/apache2/msc_pcre.c +++ b/apache2/msc_pcre.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_pcre.h b/apache2/msc_pcre.h index af58133270..bbaa818b29 100644 --- a/apache2/msc_pcre.h +++ b/apache2/msc_pcre.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_release.c b/apache2/msc_release.c index 291c756b5c..4c06a8cef0 100644 --- a/apache2/msc_release.c +++ b/apache2/msc_release.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_release.h b/apache2/msc_release.h index d87b185d83..e0c08089f2 100644 --- a/apache2/msc_release.h +++ b/apache2/msc_release.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_reqbody.c b/apache2/msc_reqbody.c index 55e2e6dc29..384e4578a8 100644 --- a/apache2/msc_reqbody.c +++ b/apache2/msc_reqbody.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_tree.c b/apache2/msc_tree.c index ec1da0d058..ce0e70afc8 100644 --- a/apache2/msc_tree.c +++ b/apache2/msc_tree.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ - * Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_tree.h b/apache2/msc_tree.h index a6df488fdb..c82ffbc124 100644 --- a/apache2/msc_tree.h +++ b/apache2/msc_tree.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_unicode.c b/apache2/msc_unicode.c index 1090efcf35..3b85f519da 100644 --- a/apache2/msc_unicode.c +++ b/apache2/msc_unicode.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_unicode.h b/apache2/msc_unicode.h index d37cbed54e..1eaf3d6625 100644 --- a/apache2/msc_unicode.h +++ b/apache2/msc_unicode.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_util.c b/apache2/msc_util.c index a46312211f..3641b27089 100644 --- a/apache2/msc_util.c +++ b/apache2/msc_util.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_util.h b/apache2/msc_util.h index 06fa26c5af..ea716d336c 100644 --- a/apache2/msc_util.h +++ b/apache2/msc_util.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_xml.c b/apache2/msc_xml.c index 87ab967e7e..a31decb5e1 100644 --- a/apache2/msc_xml.c +++ b/apache2/msc_xml.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_xml.h b/apache2/msc_xml.h index a3183212a6..f239068672 100644 --- a/apache2/msc_xml.h +++ b/apache2/msc_xml.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/persist_dbm.c b/apache2/persist_dbm.c index ba7f5c79fa..f212774ccb 100644 --- a/apache2/persist_dbm.c +++ b/apache2/persist_dbm.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/persist_dbm.h b/apache2/persist_dbm.h index 2ad68e4758..57d85bddca 100644 --- a/apache2/persist_dbm.h +++ b/apache2/persist_dbm.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/re.c b/apache2/re.c index 70956dbbf2..975d7e09f2 100644 --- a/apache2/re.c +++ b/apache2/re.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/re.h b/apache2/re.h index c17aecd737..dec78067ac 100644 --- a/apache2/re.h +++ b/apache2/re.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/re_actions.c b/apache2/re_actions.c index ca6d59054c..e71b35d70e 100644 --- a/apache2/re_actions.c +++ b/apache2/re_actions.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/re_operators.c b/apache2/re_operators.c index 25657f7834..0e46e91550 100644 --- a/apache2/re_operators.c +++ b/apache2/re_operators.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -27,6 +27,9 @@ #include #endif +#include "libinjection/sqlparse.h" +#include "libinjection/sqli_fingerprints.h" + /** * */ @@ -2129,6 +2132,38 @@ static int msre_op_contains_execute(modsec_rec *msr, msre_rule *rule, msre_var * return 0; } +/** libinjection detectSQLi +* links against files in libinjection directory + * See www.client9.com/libinjection for details + * `is_sqli_pattern` right now is a hardwired set of sqli fingerprints. + * In future, change to read from file. +*/ +static int msre_op_detectSQLi_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, + char **error_msg) { + sfilter sf; + int issqli = is_sqli(&sf, var->value, var->value_len, is_sqli_pattern); + int capture = apr_table_get(rule->actionset->actions, "capture") ? 1 : 0; + + if (issqli) { + set_match_to_tx(msr, capture, sf.pat, 0); + + *error_msg = apr_psprintf(msr->mp, "detected SQLi using libinjection fingerprint '%s'", + sf.pat); + if (msr->txcfg->debuglog_level >= 9) { + msr_log(msr, 9, "ISSQL: libinjection fingerprint '%s' matched input '%s'", + sf.pat, + log_escape_ex(msr->mp, var->value, var->value_len)); + } + } else { + if (msr->txcfg->debuglog_level >= 9) { + msr_log(msr, 9, "ISSQL: not sqli, no libinjection sqli fingerprint matched input '%s'", + log_escape_ex(msr->mp, var->value, var->value_len)); + } + } + + return issqli; +} + /* containsWord */ static int msre_op_containsWord_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) { @@ -4502,7 +4537,14 @@ void msre_engine_register_default_operators(msre_engine *engine) { msre_op_containsWord_execute ); - /* is */ + /* detectSQLi */ + msre_engine_op_register(engine, + "detectSQLi", + NULL, + msre_op_detectSQLi_execute + ); + + /* streq */ msre_engine_op_register(engine, "streq", NULL, /* ENH init function to flag var substitution */ diff --git a/apache2/re_tfns.c b/apache2/re_tfns.c index 133bfe2333..63068dae8c 100644 --- a/apache2/re_tfns.c +++ b/apache2/re_tfns.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/re_variables.c b/apache2/re_variables.c index f1dd074413..26669734ff 100644 --- a/apache2/re_variables.c +++ b/apache2/re_variables.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/utf8tables.h b/apache2/utf8tables.h index 9b975868d1..28140ffadb 100644 --- a/apache2/utf8tables.h +++ b/apache2/utf8tables.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/configure.ac b/configure.ac index 78ca88f83a..59b40cebe0 100644 --- a/configure.ac +++ b/configure.ac @@ -374,7 +374,7 @@ AC_ARG_ENABLE(htaccess-config, # Enable phase-1 in post_read_request AC_ARG_ENABLE(request-early, AS_HELP_STRING([--enable-request-early], - [Place phase1 into post_read_request hook.]), + [Place phase1 into post_read_request hook. default is hook_request_early]), [ if test "$enableval" != "no"; then request_early="-DREQUEST_EARLY" diff --git a/ext/mod_op_strstr.c b/ext/mod_op_strstr.c index cd4f298cc3..53c5138a55 100644 --- a/ext/mod_op_strstr.c +++ b/ext/mod_op_strstr.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/ext/mod_reqbody_example.c b/ext/mod_reqbody_example.c index 133e320f33..8b4abb60ab 100644 --- a/ext/mod_reqbody_example.c +++ b/ext/mod_reqbody_example.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/ext/mod_tfn_reverse.c b/ext/mod_tfn_reverse.c index 17048b66fb..1a5b814352 100644 --- a/ext/mod_tfn_reverse.c +++ b/ext/mod_tfn_reverse.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/ext/mod_var_remote_addr_port.c b/ext/mod_var_remote_addr_port.c index 0fda2553d1..4bd81ee9db 100644 --- a/ext/mod_var_remote_addr_port.c +++ b/ext/mod_var_remote_addr_port.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/main.cpp b/iis/main.cpp index f7ed1fe657..f761609a40 100644 --- a/iis/main.cpp +++ b/iis/main.cpp @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/moduleconfig.cpp b/iis/moduleconfig.cpp index 53e6ba1210..a92d51ffb1 100644 --- a/iis/moduleconfig.cpp +++ b/iis/moduleconfig.cpp @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/moduleconfig.h b/iis/moduleconfig.h index 70bae0ef04..83b7517d34 100644 --- a/iis/moduleconfig.h +++ b/iis/moduleconfig.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/mymodule.cpp b/iis/mymodule.cpp index c2b63b4179..9b8ce7459f 100644 --- a/iis/mymodule.cpp +++ b/iis/mymodule.cpp @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/mymodule.h b/iis/mymodule.h index 9a53f4e696..efc11f9872 100644 --- a/iis/mymodule.h +++ b/iis/mymodule.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/mymodulefactory.h b/iis/mymodulefactory.h index 9934ab6148..f8870da6b9 100644 --- a/iis/mymodulefactory.h +++ b/iis/mymodulefactory.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/mlogc/mlogc-batch-load.pl.in b/mlogc/mlogc-batch-load.pl.in index 662df3db98..53da8786a7 100755 --- a/mlogc/mlogc-batch-load.pl.in +++ b/mlogc/mlogc-batch-load.pl.in @@ -1,7 +1,7 @@ #!@PERL@ # # ModSecurity for Apache 2.x, http://www.modsecurity.org/ -# Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +# Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) # # You may not use this file except in compliance with # the License.  You may obtain a copy of the License at diff --git a/mlogc/mlogc.c b/mlogc/mlogc.c index edb5b962cc..4163230999 100644 --- a/mlogc/mlogc.c +++ b/mlogc/mlogc.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/nginx/modsecurity/ngx_http_modsecurity.c b/nginx/modsecurity/ngx_http_modsecurity.c index 272b46c91a..ed9c9559e6 100644 --- a/nginx/modsecurity/ngx_http_modsecurity.c +++ b/nginx/modsecurity/ngx_http_modsecurity.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/Makefile.am b/standalone/Makefile.am index dc6cb70e58..c470376a59 100644 --- a/standalone/Makefile.am +++ b/standalone/Makefile.am @@ -13,7 +13,7 @@ standalone_la_SOURCES = ../apache2/mod_security2.c \ ../apache2/msc_util.c ../apache2/msc_pcre.c ../apache2/persist_dbm.c ../apache2/msc_reqbody.c \ ../apache2/msc_geo.c ../apache2/msc_gsb.c ../apache2/msc_unicode.c \ ../apache2/acmp.c ../apache2/msc_lua.c ../apache2/msc_release.c \ - ../apache2/msc_crypt.c ../apache2/msc_tree.c \ + ../apache2/msc_crypt.c ../apache2/msc_tree.c ../apache2/libinjection/sqlparse.c \ api.c buckets.c \ config.c filters.c \ hooks.c \ diff --git a/standalone/api.c b/standalone/api.c index 09158f5014..c787589661 100644 --- a/standalone/api.c +++ b/standalone/api.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/api.h b/standalone/api.h index 15c326c637..eec55a31c9 100644 --- a/standalone/api.h +++ b/standalone/api.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/buckets.c b/standalone/buckets.c index 7beb6918b0..755581d6db 100644 --- a/standalone/buckets.c +++ b/standalone/buckets.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/config.c b/standalone/config.c index f26f7ad926..1552c6fabf 100644 --- a/standalone/config.c +++ b/standalone/config.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/filters.c b/standalone/filters.c index fb8c2b1c8b..ef0825e8dc 100644 --- a/standalone/filters.c +++ b/standalone/filters.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/hooks.c b/standalone/hooks.c index dbb4b96750..2390f558fc 100644 --- a/standalone/hooks.c +++ b/standalone/hooks.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/main.cpp b/standalone/main.cpp index 912b96f9e8..30c3e67e92 100644 --- a/standalone/main.cpp +++ b/standalone/main.cpp @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/regex.c b/standalone/regex.c index e356144eaa..495a18eb97 100644 --- a/standalone/regex.c +++ b/standalone/regex.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/server.c b/standalone/server.c index 2893d81280..be6c72ca56 100644 --- a/standalone/server.c +++ b/standalone/server.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/tests/Makefile.am b/tests/Makefile.am index 2b2b6f4686..c0209daa7b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -21,7 +21,8 @@ msc_test_SOURCES = msc_test.c \ $(top_srcdir)/apache2/msc_gsb.c \ $(top_srcdir)/apache2/acmp.c \ $(top_srcdir)/apache2/msc_lua.c \ - $(top_srcdir)/apache2/msc_release.c + $(top_srcdir)/apache2/msc_release.c \ + $(top_srcdir)/apache2/libinjection/sqlparse.c msc_test_CFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \ @PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @LUA_CFLAGS@ msc_test_CPPFLAGS = -I$(top_srcdir)/apache2 \ diff --git a/tests/msc_test.c b/tests/msc_test.c index f6637f506a..4085a17e7c 100644 --- a/tests/msc_test.c +++ b/tests/msc_test.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/tests/op/detectSQLi.t b/tests/op/detectSQLi.t new file mode 100644 index 0000000000..8bd9b8c9b4 --- /dev/null +++ b/tests/op/detectSQLi.t @@ -0,0 +1,18 @@ +{ + type => "op", + name => "detectSQLi", + input => "", + ret => 0 +}, +{ + type => "op", + name => "detectSQLi", + input => "this is not isqli", + ret => 0 +}, +{ + type => "op", + name => "detectSQLi", + input => "ascii(substring(version() from 1 for 1))", + ret => 1 +}