Coder Social home page Coder Social logo

libinjection's Introduction

CI license

SQL / SQLI tokenizer parser analyzer. For

See https://www.client9.com/ for details and presentations.

Simple example:

#include <stdio.h>
#include <strings.h>
#include <errno.h>
#include "libinjection.h"
#include "libinjection_sqli.h"

int main(int argc, const char* argv[])
{
    struct libinjection_sqli_state state;
    int issqli;

    const char* input = argv[1];
    size_t slen = strlen(input);

    /* in real-world, you would url-decode the input, etc */

    libinjection_sqli_init(&state, input, slen, FLAG_NONE);
    issqli = libinjection_is_sqli(&state);
    if (issqli) {
        fprintf(stderr, "sqli detected with fingerprint of '%s'\n", state.fingerprint);
    }
    return issqli;
}
$ gcc -Wall -Wextra examples.c libinjection_sqli.c
$ ./a.out "-1' and 1=1 union/* foo */select load_file('/etc/passwd')--"
sqli detected with fingerprint of 's&1UE'

More advanced samples:

VERSION INFORMATION

See CHANGELOG for details.

Versions are listed as "major.minor.point"

Major are significant changes to the API and/or fingerprint format. Applications will need recompiling and/or refactoring.

Minor are C code changes. These may include

  • logical change to detect or suppress
  • optimization changes
  • code refactoring

Point releases are purely data changes. These may be safely applied.

QUALITY AND DIAGNOSITICS

The continuous integration results at GitHub tests the following:

LICENSE

Copyright (c) 2012-2016 Nick Galbreath

Licensed under the standard BSD 3-Clause open source license. See COPYING for details.

BUILD TARGETS

Some of the previous help runners have been merged into the Makefile. E.g.:

  • run-clang-asan.sh -> make clan-asan
  • make-ci.sh -> make ci

If you run make cppcheck you will see this warning printed:

nofile:0 information missingIncludeSystem Cppcheck cannot find all the include files (use --check-config for details)

You can safely ignore it as it is just saying that standard include files are being ignored (which is the recommended option):

example1.c:1:0: information: Include file: <stdio.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]

EMBEDDING

The src directory contains everything, but you only need to copy the following into your source tree:

Usually the new autoconf build system takes care of the LIBINJECTION_VERSION definition. But that might now be available when you are embedding the above files.

This is solved by manually defining the version you are embedding to your CFLAGS.

E.g.: CFLAGS="-DLIBINJECTION_VERSION=\"3.9.2.65-dfe6-dirty\""

An easy way to get the version tag is to execute git describe in this directory.

libinjection's People

Contributors

andrewkahn avatar b1v1r avatar bizonix avatar blackyoup avatar client9 avatar diversario avatar dvershinin avatar fzipi avatar ihacku avatar ivannardi avatar ivanr avatar lloydw93 avatar maage avatar marpaia avatar migueldemoura avatar mirkodziadzka avatar mtourne avatar ngalbreath avatar ngo avatar p0pr0ck5 avatar qerub avatar raz0r avatar testforwebpentest avatar veeshi avatar victorhora avatar wenchuan avatar wgh- avatar zimmerle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libinjection's Issues

False-Positive with fingerprint sos (OWASP CoreRuleSet Rule 942100)

Hi,

we are currently running mod_security2 with the OWASP CoreRuleSet (CRS) in version 3.3.4.
And we get false-positive matches because of a user-defined XML-Filter for a GIS application.
It's somehow detected as an SQL-injection attack.

The full GET-Request from the ModSecurity AuditLog is as follows:

--22b76f48-B--
GET /ogc-free-data.ows?REQUEST=GetFeature&SERVICE=WFS&MAXFEATURES=1001&VERSION=1.1.0&TYPENAME=flst&srsName=EPSG:25832&FILTER=%3CFilter%3E%3CAnd%3E%3CPropertyIsEqualTo+escape%3D%27%2F%27%3E%3CPropertyName%3EFS_GKNR%3C%2FPropertyName%3E%3CLiteral%3E2730%3C%2FLiteral%3E%3C%2FPropertyIsEqualTo%3E%3CPropertyIsEqualTo+escape%3D%27%2F%27%3E%3CPropertyName%3EGK_GKBEZ%3C%2FPropertyName%3E%3CLiteral%3ELingelbach%3C%2FLiteral%3E%3C%2FPropertyIsEqualTo%3E%3CPropertyIsEqualTo+escape%3D%27%2F%27%3E%3CPropertyName%3EFS_FLNR%3C%2FPropertyName%3E%3CLiteral%3E4%3C%2FLiteral%3E%3C%2FPropertyIsEqualTo%3E%3CPropertyIsEqualTo+escape%3D%27%2F%27%3E%3CPropertyName%3EFS_FSZ%3C%2FPropertyName%3E%3CLiteral%3E1%3C%2FLiteral%3E%3C%2FPropertyIsEqualTo%3E%3C%2FAnd%3E%3C%2FFilter%3E HTTP/1.1
Content-Type: application/xml; charset=ISO-8859-1
User-Agent: Jakarta Commons-HttpClient/3.1
Host: host.tld

And the ModSecurity message is:

Message: Warning. detected SQLi using libinjection with fingerprint 'sos' [file "/etc/apache2/mod_security2.d/crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "66"] [id "942100"] [msg "SQL Injection Attack Detected via libinjection"] [data "Matched Data: sos found within ARGS:FILTER: <Filter><And><PropertyIsEqualTo escape='/'><PropertyName>FS_GKNR</PropertyName><Literal>2730</Literal></PropertyIsEqualTo><PropertyIsEqualTo escape='/'><PropertyName>GK_GKBEZ</PropertyName><Literal>Lingelbach</Literal></PropertyIsEqualTo><PropertyIsEqualTo escape='/'><PropertyName>FS_FLNR</PropertyName><Literal>4</Literal></PropertyIsEqualTo><PropertyIsEqualTo escape='/'><PropertyName>FS_FSZ</PropertyName><Literal>1</Literal></PropertyIsEqualTo></And></Filter>"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.4"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-sqli"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/248/66"] [tag "PCI/6.5.2"]

fingerprints2sqli.py says the fingerprint sos equals the following string:

user@host:~/git/libinjection/src (main)$ ./fingerprints2sqli.py | grep '^sos \"'
sos "1" * "1"

But the string "1" * "1" isn't found in the GET-Request.

Switching to the v3.10.0 tag, compiling libinjection_sqli.c with gcc -Wall -Wextra example1.c libinjection_sqli.c and running the decoded Filter from the GET-Request against it, indeed returns: sqli with fingerprint of 'sos'

user@host:~/git/libinjection/src (main)$ git checkout v3.10.0
user@host:~/git/libinjection/src ((v3.10.0))$ gcc -Wall -Wextra example1.c libinjection_sqli.c
user@host:~/git/libinjection/src ((v3.10.0))$ ./a.out "<Filter><And><PropertyIsEqualTo escape='/'><PropertyName>FS_GKNR</PropertyName><Literal>2730</Literal></PropertyIsEqualTo><PropertyIsEqualTo escape='/'><Pro
pertyName>GK_GKBEZ</PropertyName><Literal>Lingelbach</Literal></PropertyIsEqualTo><PropertyIsEqualTo escape='/'><PropertyName>FS_FLNR</PropertyName><Literal>4</Literal></PropertyIsEqualTo><PropertyIsEqualTo escape='/'><PropertyName>FS_FS
Z</PropertyName><Literal>1</Literal></PropertyIsEqualTo></And></Filter>"
sqli with fingerprint of 'sos'

Currently I defined an exemption rule for the affected URIs. But it would be great if this could be fixed in libinjection.

Detection Bypass

Hi,

While testing the SQLi technique outlined here, I discovered a bypass in libinjection. So, this is the payload I'm trying to inject:

0); set @q=0x53454c45435420534c454550283129; prepare stmt from @q; execute stmt;#

Which is correctly detected by libinjection:

$ ./test "0); set @q=0x53454c45435420534c454550283129; prepare stmt from @q; execute stmt;#"
sqli with fingerprint of '1);Ev'

However, if I put a random string and a semicolon before the SET statement, the payload will not be detected anymore. But this won't do the trick, because the stacked queries are not executed when an error is encountered. So, instead of the random string I chose the "SHOW WARNINGS" MySQL statement, and this payload bypasses libinjection detection:

$ ./test "0); show warnings; set @q=0x53454c45435420534c454550283129; prepare stmt from @q; execute stmt;#"
not sqli

XSS vs SQLI: NULL bytes

Since 991433e it is clear that the input of libinjection_xss() MUST be something like s, strlen(s). In other words, we can't have NULL bytes in the input string (see also the discussion in client9/libinjection#150)
Does the same constrain apply to libinjection_sqli()?

Having Python 3 workable

libInjection uses Python in two different circumstances:

  • Build and test utilities - Build and test utilities are mostly used during library development (vide misc folder).
  • Python Bindings - Export the library functionalities to Python.

The support for Python is currently targeting Python 2 using swig. This issue is meant to track the progress of having the bindings working all right on Python 3.

Reference:

libinjection/libinjection_wrap.c: libinjection/libinjection.i libinjection/libinjection.h libinjection/libinjection_sqli.h
swig -version
swig -python -builtin -Wall -Wextra libinjection/libinjection.i

The motivation for this issue was: client9/libinjection#108

Latest changes on generating version.h breaks embedding

Hello, the latest changes (bd86522) completely break embedding the files into other projects, like naxsi.

I have been using this lib for a loooong time within naxsi (an NGINX FOSS WAF) and the latest changes completely break the compatibility with other software using this library source code without actually building the .so/.a library.

i would suggest to create a default version.h file which gets overwritten by the configure script.
The issue with building this without actually building the library is due how NGINX plugins build system is done which does not simply allow to build the lib first and then link to it easily like any other good build system.

Feature: document how to mimic old build for easier migration from client9/libinjection

The old makefile would build libinjection.a but with the new autotools system the ability to create a static lib build seems to be missing?

I tried configure --enable-static but that didn't seem to generate libinjection.a

Either this is broken, or I don't understand autotools (which is more likely).

Some documentation around the new autotools system would be much appreciated.

Add fuzzing

We should evaluate if fuzz testing can be added to the library.

result ask

I use the example and find "select c1 from t1 order by c2" is marked. Why?

the result is "sqli detected with fingerprint of 'EnknB'"

I can't understand, I think the sql is ok

False negative on no whitespace before and/or after "*" or delimited identifier in SELECT list

Created by @srutzky at client9/libinjection#152


Little known fact, but at least some SQL dialects, such as T-SQL, don't require whitespace before or after certain characters in the SELECT list:

  • *
  • [
  • ]
  • (
  • )

The following are all completely valid T-SQL and I just confirmed that they all return the expected results without any errors:

SELECT*FROM sys.objects
SELECT *FROM sys.objects
SELECT* FROM sys.objects

SELECT[name]FROM sys.objects
SELECT [name]FROM sys.objects
SELECT[name] FROM sys.objects

SELECT*,[name]FROM sys.objects
SELECT[name],*FROM sys.objects

SELECT([name])FROM sys.objects

P.S. I'm not sure if this behavior relates to Issue client9/libinjection#100 or not (in terms of how the * is handled).

Take care,
Solomon...
https://SqlQuantumLift.com/
https://SqlQuantumLeap.com/
https://SQLsharp.com/

Packaged in Fedora

Hi,

As of today I'm the maintainer of the libinjection RPM package in Redhat Fedora (and EPEL) and I just wanted you to know this. My reason for packaging libinjection is to "unbundle" it from mod_security and naxsi to make future updates like security fixes easier to apply and deal with.

I wrote a nicer Makefile that you could use if so desired: https://src.fedoraproject.org/rpms/libinjection/raw/rawhide/f/Makefile-libinjection

The correct way to generate the makefile would be to use autoconf, automake and libool but that requires an autopoo wizzard.

Cheers,

False positive on "!@#"

Hi,

I have an LUA script that checks with libinjection if a string contains SQL injection and I get a false positive on strings that contain "!@#".
I resolve this by prechecking strings. Is there another way? Can I specify in libinjection to "pass" if it contains something or create a whitelist?

project migration request

Hi, this is the golang version of libinjection, I want to migrate it to the libinjection project group so that users of golang can use it, is it possible? *_test.go is my test file for xss and sqli detection. Thank you very much!

Space in REQUEST_COOKIE is triggering 941100 XSS attack rule

From ModSecurity created by danielwrayois: owasp-modsecurity/ModSecurity#2426

Hi,

The following userid cookie rXXAAl OnJK6gwAXXXXeAg== generated by Nginx appears to trigger the xss rule 941100, the uuid is generated per user session so it is intermittent, however the only consistent pattern is that the userid cookies that are blocked contain a space " ", rather than a plus "+" character.

[client xxx.xxx.xxx.xxx] ModSecurity: Access denied with code 403 (phase 2). detected XSS using libinjection. [file "/etc/nginx/conf.d/modsecurity/rules/3.0.2/REQUEST-941-APPLICATION-ATTACK-XSS.conf"] [line "37"] [id "941100"] [rev "2"] [msg "XSS Attack Detected via libinjection"] [data "Matched Data: rXXAAl OnJK6gwAXXXXeAg== found within REQUEST_COOKIES:id: rXXAAl OnJK6gwAXXXXeAg=="] [severity "2"] [ver "OWASP_CRS/3.0.0"] [maturity "1"] [accuracy "9"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-xss"] [tag "OWASP_CRS/WEB_ATTACK/XSS"] [tag "WASCTC/WASC-8"] [tag "WASCTC/WASC-22"] [tag "OWASP_TOP_10/A3"] [tag "OWASP_AppSensor/IE1"] [tag "CAPEC-242"] [hostname "xxx.xxx.xxx.xxx"] [uri "/summary"] [unique_id "160319605595.840815"] [ref "v668,24t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls"]

Nginx: 1.17.9
CRS ruleset: 3.0.2
ModSecurity: v3/master from around 29th April 2020

From testing it appears to be related to the space, which I believe with base64 encoded is a legal character, but typically ignored during parsing. I am not sure if this space is triggering a rule that would normally detect something like a CRLF-type attack i.e. if a space, page return, et al are in a value it is automatically assumed to be an XSS?

fatal error: version.h: No such file or directory

I build modsecurity with git submodule update --init --remote and the latest liibinjection build fails:

#0 28.14 Making all in others
#0 28.15 make[1]: Entering directory '/src/ModSecurity/others'
#0 28.17 depbase=`echo libinjection/src/libinjection_html5.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
#0 28.17 /bin/bash ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I../src     -g -O2 -MT libinjection/src/libinjection_html5.lo -MD -MP -MF $depbase.Tpo -c -o libinjection/src/libinjection_html5.lo libinjection/src/libinjection_html5.c &&\
#0 28.17 mv -f $depbase.Tpo $depbase.Plo
#0 28.24 libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../src -g -O2 -MT libinjection/src/libinjection_html5.lo -MD -MP -MF libinjection/src/.deps/libinjection_html5.Tpo -c libinjection/src/libinjection_html5.c  -fPIC -DPIC -o libinjection/src/.libs/libinjection_html5.o
#0 28.39 libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../src -g -O2 -MT libinjection/src/libinjection_html5.lo -MD -MP -MF libinjection/src/.deps/libinjection_html5.Tpo -c libinjection/src/libinjection_html5.c -o libinjection/src/libinjection_html5.o >/dev/null 2>&1
#0 28.54 depbase=`echo libinjection/src/libinjection_sqli.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
#0 28.54 /bin/bash ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I../src     -g -O2 -MT libinjection/src/libinjection_sqli.lo -MD -MP -MF $depbase.Tpo -c -o libinjection/src/libinjection_sqli.lo libinjection/src/libinjection_sqli.c &&\
#0 28.54 mv -f $depbase.Tpo $depbase.Plo
#0 28.56 libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../src -g -O2 -MT libinjection/src/libinjection_sqli.lo -MD -MP -MF libinjection/src/.deps/libinjection_sqli.Tpo -c libinjection/src/libinjection_sqli.c  -fPIC -DPIC -o libinjection/src/.libs/libinjection_sqli.o
#0 28.58 libinjection/src/libinjection_sqli.c:17:10: fatal error: version.h: No such file or directory
#0 28.58    17 | #include "version.h"
#0 28.58       |          ^~~~~~~~~~~
#0 28.58 compilation terminated.
#0 28.58 make[1]: *** [Makefile:590: libinjection/src/libinjection_sqli.lo] Error 1
#0 28.58 make[1]: Leaving directory '/src/ModSecurity/others'
#0 28.58 make: *** [Makefile:1048: all-recursive] Error 1

... seems related to 75e55bc#diff-0f741da44ae0ce50ac8603c2760f696753aca8eb77e974fc791b8981c1d7a98cR17

Hackity-hack-hack I created the version.h manually and it builds ok:

echo "#define LIBINJECTION_VERSION \"0.0.0\"" > others/libinjection/src/version.h

Stack overflow (via infinite loop) in XSS code

While fuzzing an unrelated project using libinjection, I found a reproducible way to trigger a stack overflow (because of an infinite loop) in the XSS code.

You can trivially reproduce the bug with current master, simply calling something like that

libinjection_xss(str, strlen(str));

Is that the right place where to discuss/share this kind of information?

false negative (bypass) with square bracket

Almost any kind of injection, when surrounded by square brackets, can bypass the check.
For example:

1337 INTO OUTFILE ‘xxx’--
vs
[1337 INTO OUTFILE ‘xxx’--]

makes its fingerprint become 'n',

111=@`\'`)%20UnIon%20seleCt%201,2,3,4,5,6,7,8,9,10,userid,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,pwd,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42%20from%20`%23@__admin`%23@`\'`%20
vs
[111=@`\'`)%20UnIon%20seleCt%201,2,3,4,5,6,7,8,9,10,userid,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,pwd,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42%20from%20`%23@__admin`%23@`\'`%20]

its fingerprint becomes 's'.

By a quick look into lexer I found following handling of []:

/**
 * This handles MS SQLSERVER bracket words
 * http://stackoverflow.com/questions/3551284/sql-serverwhat-do-brackets-mean-around-column-name
 *
 */
static size_t parse_bword(struct libinjection_sqli_state * sf)

I do understand in some dialect it's a word and if we treat it as separate words it creates another risk of bypass. But to treat it as bracket words also can be a defeat.

I've tested the example with 3.9.2 and 3.10.0 from /client9/libinjection and latest source from this fork.

XSS: False positive

Any string that starts with on and ends with == is matching for XSS.
Examples: online== , onAAAAA== , onfoobar==

These strings can occur in case of receiving legitimate content encoded in base64

Address the static analysis complains

Current the QA is failing due:

  • src/libinjection_sqli.c:528 nullPointerArithmeticRedundantCheck warning Either the condition 'ptr==(const char*)NULL' is redundant or there is overflow in pointer subtraction.
  • src/testdriver.c:65 unreadVariable style Variable 'slen' is assigned a value that is never used.

if (memchr2(cur + 2, (size_t)(ptr - (cur + 1)), '/', '*') != NULL) {
ctype = TYPE_EVIL;
} else if (is_mysql_comment(cs, slen, pos)) {
ctype = TYPE_EVIL;
}

size_t print_var(char* buf, size_t len, stoken_t* t)
{
int slen = 0;
if (t->count >= 1) {
slen = sprintf(buf + len, "%c", '@');
assert(slen >= 0);
len += (size_t) slen;
}
if (t->count == 2) {
slen = sprintf(buf + len, "%c", '@');
assert(slen >= 0);
len += (size_t) slen;
}
return print_string(buf, len, t);
}

Evasion mitigation

On 2020-Sep-13, @theMiddleBlue has published on SecJuice an excellent write-up on possible evasions for libInjection.

This issue was created to track the mitigation for such evasions.

The fixes are planned to be shipped altogether on v3.11.0.

SQLi:false postive which occurs very posibbily

image/*;q=0.8 string is positive sqli by libinjection.

and image/*;q=0.8 is usually the value of http header 'Accept'.

solution

libinjection will be convert image/*;q=0.8 to tokens "nc" what means a 'word' and a 'sql comment' , i think 'nc' pattern should not be removed by in sql_keywords list.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.