SQLChop - SQL Injection Detection Engine

ID KITPLOIT:7343951545452956548
Type kitploit
Reporter KitPloit
Modified 2015-08-25T21:12:00


SQLChop is a novel SQL injection detection engine built on top of SQL tokenizing and syntax analysis. Web input (URLPath, body, cookie, etc.) will be first decoded to the raw payloads that web app accepts, then syntactical analysis will be performed on payload to classify result. The algorithm behind SQLChop is based on compiler knowledge and automata theory, and runs at a time complexity of O(N).




The SQLChop alpha testing release includes the c++ header and shared object, a python library, and also some sample usages. The release has been tested on most linux distributions.
If using python, you need to install protobuf-python , e.g.:

$ sudo pip install protobuf

If using c++, you need to install protobuf , protobuf-compiler and protobuf-devel , e.g.:

$ sudo yum install protobuf protobuf-compiler protobuf-devel


SQLChop Python API

The current alpha testing release is provided as a python library. C++ headers and examples will be released soon.
The following APIs are the main interfaces SQLChop export.


Given a raw payload, determine whether the payload is an SQL injection payload.

  • Parameter: string
  • Return value: bool, return True for SQLi payload, return False for normal case.

    >>> from sqlchop import SQLChop >>> detector = SQLChop() >>> detector.is_sqli('SELECT 1 From users') True >>> detector.is_sqli("' or '1'='1") True >>> detector.is_sqli('select the best student from classes as the student union representative') False >>> detector.is_sqli('''(select(0)from(select(sleep(0)))v)/'+(select(0)from(select(sleep(12)))v)+'"+(select(0)from(select(sleep(0)))v)+"/''') True


Given a web application input, classify API will decode the input and find possible SQL injection payload inside. If SQLi payload found, payloads will be listed.

  • Parameter 1: object with following keys
    1. urlpath : string, the urlpath of web request
    2. body : string, the http body of POST/PUT request
    3. cookie : string, the cookie content of web request
    4. raw : string, other general field that needs general decoding.
  • Parameter 2: detail, if detail is True , detailed payload list will be returned, if False , only result will be returned, which runs faster.
  • Return: an object contains result and payloads

    1. result : int, positive value indicates the web request contains sql injection payload
    2. payloads : list of objects containing key , score , value and source
    3. key : string, reserved
    4. source : string, shows where this payload is embed in original web request and how the payload is decoded
    5. value : decoded sqli payload
    6. score : the score of the decoded sqli payload Examples here:

    >>> from sqlchop import SQLChop >>> detector = SQLChop() >>> detector.classify({'urlpath': '/tag/sr/news.asp?d=LTElMjBhbmQlMjAxPTIlMjB1bmlvbiUyMHNlbGVjdCUyMDEsMiwzLGNocigxMDYpLDUsNiw3LDgsOSwxMCwxMSwxMiUyMGZyb20lMjBhZG1pbg==' }, True) >>> { 'payloads': [{ 'key': '', 'score': 4.070000171661377, 'source': 'urlpath: querystring_decode b64decode url_decode ', 'value': '-1 and 1=2 union select 1,2,3,chr(106),5,6,7,8,9,10,11,12 from admin' }], 'result': 1 }

    >>> detector.classify({'body': 'opt=saveedit&arrs1[]=83&arrs1[]=69&arrs1[]=76&arrs1[]=69&arrs1[]=67&arrs1[]=84&arrs1[]=32&arrs1[]=42&arrs1[]=32&arrs1[]=70&arrs1[]=114&arrs1[]=111&arrs1[]=109&arrs1[]=32&arrs1[]=84&arrs1[]=97&arrs1[]=98&arrs1[]=108&arrs1[]=101&arrs1[]=32&arrs1[]=87&arrs1[]=72&arrs1[]=69&arrs1[]=82&arrs1[]=69&arrs1[]=32&arrs1[]=78&arrs1[]=97&arrs1[]=109&arrs1[]=101&arrs1[]=61&arrs1[]=39&arrs1[]=83&arrs1[]=81&arrs1[]=76&arrs1[]=32&arrs1[]=105&arrs1[]=110&arrs1[]=106&arrs1[]=101&arrs1[]=99&arrs1[]=116&arrs1[]=39&arrs1[]=32&arrs1[]=97&arrs1[]=110&arrs1[]=100&arrs1[]=32&arrs1[]=80&arrs1[]=97&arrs1[]=115&arrs1[]=115&arrs1[]=119&arrs1[]=111&arrs1[]=114&arrs1[]=100&arrs1[]=61&arrs1[]=39&arrs1[]=39&arrs1[]=32&arrs1[]=97&arrs1[]=110&arrs1[]=100&arrs1[]=32&arrs1[]=67&arrs1[]=111&arrs1[]=114&arrs1[]=112&arrs1[]=61&arrs1[]=39&arrs1[]=39&arrs1[]=32&arrs1[]=111&arrs1[]=114&arrs1[]=32&arrs1[]=49&arrs1[]=61&arrs1[]=40&arrs1[]=83&arrs1[]=69&arrs1[]=76&arrs1[]=69&arrs1[]=67&arrs1[]=84&arrs1[]=32&arrs1[]=64&arrs1[]=64&arrs1[]=86&arrs1[]=69&arrs1[]=82&arrs1[]=83&arrs1[]=73&arrs1[]=79&arrs1[]=78&arrs1[]=41&arrs1[]=45&arrs1[]=45&arrs1[]=32&arrs1[]=39'}, True) >>> { 'payloads': [{ 'key': '', 'score': 3.9800000190734863, 'source': 'body: querystring_decode ', 'value': "SELECT * From Table WHERE Name='SQL inject' and Password='' and Corp='' or 1=(SELECT @@VERSION)-- '" }, { 'key': '', 'score': 2.0899999141693115, 'source': 'body: querystring_decode ', 'value': "'SQL inject' and Password" }, { 'key': '', 'score': 2.180000066757202, 'source': 'body: querystring_decode ', 'value': "(SELECT @@VERSION)-- '" }, { 'key': '', 'score': 0.0, 'source': 'body: querystring_decode ', 'value': 'saveedit' }], 'result': 1 }


The is_sqli API (in sqlchop.py) detects SQLi using score 2.1 as threshold, you can adjust this threshold according to your usage scenario.

    def is_sqli(self, payload):
        ret = self.score_sqli(payload)
        return ret > 2.1  # here you can modify and test this threshold

    def classify(self, request, detail=False):

Download SQLChop