mirror of
https://github.com/ysoftdevs/wapifuzz.git
synced 2026-05-10 01:43:49 +02:00
Init WFuzz state
This commit is contained in:
25
tests/command_injection/handler.py
Normal file
25
tests/command_injection/handler.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import os
|
||||
import urllib.parse
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
|
||||
class RequestHandler(BaseHTTPRequestHandler):
|
||||
def _set_headers(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'plain/text')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
self._get_path_parameters()
|
||||
self._set_headers()
|
||||
self.wfile.write(b'OK')
|
||||
|
||||
def _get_path_parameters(self):
|
||||
path = urllib.parse.unquote(self.path)[len("/pets?attributeName="):]
|
||||
if path.startswith("sleep "):
|
||||
self._try_to_execute_command(path)
|
||||
|
||||
def _try_to_execute_command(self, path):
|
||||
os.system(path)
|
||||
|
||||
def send_error(self, code, message=None, explain=None):
|
||||
pass
|
||||
2
tests/command_injection/test.sh
Normal file
2
tests/command_injection/test.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
./fuzz_and_grep_logs.sh "$(dirname "${BASH_SOURCE[0]}")" "Timeout or closed connection"
|
||||
exit $?
|
||||
14
tests/detect_internal_server_error/handler.py
Normal file
14
tests/detect_internal_server_error/handler.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
|
||||
class RequestHandler(BaseHTTPRequestHandler):
|
||||
def _set_headers(self):
|
||||
self.send_response(500)
|
||||
self.send_header('Content-type', 'text/plain')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
self._set_headers()
|
||||
self.wfile.write(b'Internal server error')
|
||||
|
||||
def send_error(self, code, message=None, explain=None):
|
||||
pass
|
||||
2
tests/detect_internal_server_error/test.sh
Normal file
2
tests/detect_internal_server_error/test.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
./fuzz_and_grep_logs.sh "$(dirname "${BASH_SOURCE[0]}")" "Status code higher or equal than 500!"
|
||||
exit $?
|
||||
9
tests/detect_timeout/handler.py
Normal file
9
tests/detect_timeout/handler.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
|
||||
|
||||
class RequestHandler(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
pass
|
||||
|
||||
def send_error(self, code, message=None, explain=None):
|
||||
pass
|
||||
2
tests/detect_timeout/test.sh
Normal file
2
tests/detect_timeout/test.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
./fuzz_and_grep_logs.sh "$(dirname "${BASH_SOURCE[0]}")" "Timeout or closed connection"
|
||||
exit $?
|
||||
62
tests/documentation.yaml
Normal file
62
tests/documentation.yaml
Normal file
@@ -0,0 +1,62 @@
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
version: 1.0.0
|
||||
title: Swagger Petstore
|
||||
license:
|
||||
name: MIT
|
||||
servers:
|
||||
- url: http://petstore.swagger.io/v1
|
||||
paths:
|
||||
/pets?attributeName={attributeValue}:
|
||||
get:
|
||||
summary: List all pets
|
||||
operationId: listPets
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: attributeValue
|
||||
in: query
|
||||
description: How many items to return at one time (max 100)
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: A paged array of pets
|
||||
headers:
|
||||
x-next:
|
||||
description: A link to the next page of responses
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
components:
|
||||
schemas:
|
||||
Pet:
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
Pets:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
Error:
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
message:
|
||||
type: string
|
||||
38
tests/fuzz_and_grep_logs.sh
Normal file
38
tests/fuzz_and_grep_logs.sh
Normal file
@@ -0,0 +1,38 @@
|
||||
FOLDER=$1
|
||||
MATCH_MESSAGE=$2
|
||||
|
||||
# Start server
|
||||
python3 ./httpd.py "${FOLDER}" &
|
||||
SERVER_PID=`echo $!`
|
||||
|
||||
function trap_sigint()
|
||||
{
|
||||
kill -9 $SERVER_PID
|
||||
exit 2
|
||||
}
|
||||
|
||||
trap "trap_sigint" 2
|
||||
|
||||
cd ../
|
||||
|
||||
# Run fuzzer
|
||||
./run.sh ./tests/localhost_config.json ./tests/documentation.yaml
|
||||
|
||||
# Check logs, if there are tests with failures
|
||||
cat fuzzing.log | grep "${MATCH_MESSAGE}"
|
||||
IS_MATCH1=`echo $?`
|
||||
|
||||
cat ./reporter/reports.junit.xml | grep "${MATCH_MESSAGE}"
|
||||
IS_MATCH2=`echo $?`
|
||||
|
||||
cat ./reporter/reports.html | grep "${MATCH_MESSAGE}"
|
||||
IS_MATCH3=`echo $?`
|
||||
|
||||
# Kill server
|
||||
kill -9 $SERVER_PID
|
||||
|
||||
if [ $IS_MATCH1 -eq 0 -a $IS_MATCH2 -eq 0 -a $IS_MATCH3 -eq 0 ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
exit 1
|
||||
15
tests/httpd.py
Normal file
15
tests/httpd.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import sys
|
||||
import importlib
|
||||
from http.server import HTTPServer
|
||||
from pprint import pprint
|
||||
|
||||
handler_class = importlib.import_module(sys.argv[1][2:] + ".handler").RequestHandler
|
||||
|
||||
def run(server_class=HTTPServer, handler_class=handler_class, port=5000):
|
||||
server_address = ('', port)
|
||||
httpd = server_class(server_address, handler_class)
|
||||
httpd.serve_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
14
tests/invalid_json/handler.py
Normal file
14
tests/invalid_json/handler.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
|
||||
class RequestHandler(BaseHTTPRequestHandler):
|
||||
def _set_headers(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'application/json')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
self._set_headers()
|
||||
self.wfile.write(b'invalid json')
|
||||
|
||||
def send_error(self, code, message=None, explain=None):
|
||||
pass
|
||||
2
tests/invalid_json/test.sh
Normal file
2
tests/invalid_json/test.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
./fuzz_and_grep_logs.sh "$(dirname "${BASH_SOURCE[0]}")" "application/json body is not valid JSON structure"
|
||||
exit $?
|
||||
19
tests/localhost_config.json
Normal file
19
tests/localhost_config.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"fixed_url_attributes": {},
|
||||
"headers": {},
|
||||
"polling_interval": 0.05,
|
||||
"response_timeout": 1,
|
||||
"reporting_interval": 10,
|
||||
"skipping_endpoints_keywords": [],
|
||||
"http_fuzzing": false,
|
||||
"target": {
|
||||
"hostname": "127.0.0.1",
|
||||
"port": 5000,
|
||||
"ssl": false
|
||||
},
|
||||
"payloads_to_json_primitives_mapping": {
|
||||
"boolean": ["numeric", "os-command-injection", "path-traversal", "special-chars-generic", "sql-injection", "unicode", "xml"],
|
||||
"number": ["numeric", "os-command-injection", "path-traversal", "special-chars-generic", "sql-injection", "unicode", "xml"],
|
||||
"string": ["numeric", "os-command-injection", "path-traversal", "special-chars-generic", "sql-injection", "unicode", "xml"]
|
||||
}
|
||||
}
|
||||
11
tests/non_existing_target/test.sh
Normal file
11
tests/non_existing_target/test.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
cd ../
|
||||
|
||||
# Run fuzzer
|
||||
./run.sh ./tests/localhost_config.json ./tests/documentation.yaml 2>&1 | grep "Fuzzing hangs on test case number: 1. See log file for an error message."
|
||||
RET_VAL=`echo $?`
|
||||
|
||||
if [ $RET_VAL -eq 0 ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
exit 1
|
||||
54
tests/run_tests.sh
Normal file
54
tests/run_tests.sh
Normal file
@@ -0,0 +1,54 @@
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
ORANGE='\033[0;33m'
|
||||
NO_COLOR='\033[0m'
|
||||
|
||||
TEST_SCRIPTS=`find . -regex ".*\(test.sh\)"`
|
||||
TEST_SCRIPTS_COUNT=`find . -regex ".*\(test.sh\)" | wc -l`
|
||||
|
||||
SUCCESSFULL=0
|
||||
FAILED=0
|
||||
|
||||
TEST_LOG_FILE=e2e_tests.log
|
||||
|
||||
# Clear or create log file
|
||||
> $TEST_LOG_FILE
|
||||
|
||||
echo "Founded ${TEST_SCRIPTS_COUNT} tests. Starting test session. Some tests may wait for some kind of timeout, so please be patient."
|
||||
for SCRIPT in $TEST_SCRIPTS
|
||||
do
|
||||
echo ${SCRIPT} >> $TEST_LOG_FILE
|
||||
printf "${ORANGE} Started testing: ${SCRIPT} ${NO_COLOR}\n"
|
||||
$SCRIPT >> $TEST_LOG_FILE 2>&1
|
||||
RET_VAL=$?
|
||||
if [ $RET_VAL -eq 0 ] ; then
|
||||
SUCCESSFULL=$((SUCCESSFULL+1))
|
||||
printf "${GREEN} Test ${SCRIPT} was successfull.${NO_COLOR}\n"
|
||||
else
|
||||
FAILED=$((FAILED+1))
|
||||
printf "${RED} Test ${SCRIPT} was NOT successfull.${NO_COLOR}\n"
|
||||
fi
|
||||
|
||||
# Clean generated files
|
||||
cd ../
|
||||
make clean > /dev/null 2>&1
|
||||
cd - > /dev/null 2>&1
|
||||
|
||||
# Make a newline
|
||||
echo ""
|
||||
echo "" >> $TEST_LOG_FILE
|
||||
done
|
||||
|
||||
# Print summary
|
||||
echo ""
|
||||
echo "--- Summary ---"
|
||||
echo "Failed: ${FAILED}"
|
||||
echo "Successfull: ${SUCCESSFULL}"
|
||||
echo "Total: ${TEST_SCRIPTS_COUNT}"
|
||||
echo "Success rate: $((100*SUCCESSFULL/TEST_SCRIPTS_COUNT))%"
|
||||
|
||||
if [ $SUCCESSFULL -eq $TEST_SCRIPTS_COUNT ] ; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
35
tests/sql_blind_injection/test.sh
Normal file
35
tests/sql_blind_injection/test.sh
Normal file
@@ -0,0 +1,35 @@
|
||||
# Start server which does not send any response
|
||||
python3 "$(dirname "${BASH_SOURCE[0]}")/web_and_sql_server.py" &
|
||||
SERVER_PID=`echo $!`
|
||||
|
||||
function trap_sigint()
|
||||
{
|
||||
kill -9 $SERVER_PID
|
||||
exit 2
|
||||
}
|
||||
|
||||
trap "trap_sigint" 2
|
||||
|
||||
cd ../
|
||||
|
||||
# Run fuzzer
|
||||
./run.sh ./tests/localhost_config.json ./tests/documentation.yaml
|
||||
|
||||
# Check logs, if there are tests with failure
|
||||
cat fuzzing.log | grep "Timeout or closed connection"
|
||||
IS_MATCH1=`echo $?`
|
||||
|
||||
cat ./reporter/reports.junit.xml | grep "Timeout or closed connection"
|
||||
IS_MATCH2=`echo $?`
|
||||
|
||||
cat ./reporter/reports.html | grep "Timeout or closed connection"
|
||||
IS_MATCH3=`echo $?`
|
||||
|
||||
# Kill server
|
||||
kill -9 $SERVER_PID
|
||||
|
||||
if [ $IS_MATCH1 -eq 0 -a $IS_MATCH2 -eq 0 -a $IS_MATCH3 -eq 0 ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
exit 1
|
||||
63
tests/sql_blind_injection/web_and_sql_server.py
Normal file
63
tests/sql_blind_injection/web_and_sql_server.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import os
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
import urllib.parse
|
||||
import time
|
||||
import sqlite3
|
||||
from sqlite3 import Error
|
||||
|
||||
|
||||
def create_in_memory_connection():
|
||||
try:
|
||||
conn = sqlite3.connect(':memory:')
|
||||
except Error as e:
|
||||
print(e)
|
||||
return conn
|
||||
|
||||
|
||||
class RequestHandler(BaseHTTPRequestHandler):
|
||||
def _set_headers(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'plain/text')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
self._get_path_parameters()
|
||||
self._set_headers()
|
||||
self.wfile.write(b'OK')
|
||||
|
||||
def _get_path_parameters(self):
|
||||
path = urllib.parse.unquote(self.path)[len("/pets?attributeName="):]
|
||||
if path.startswith("sleep("):
|
||||
try:
|
||||
self.cursor.execute("SELECT " + path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def _try_to_execute_command(self, path):
|
||||
os.system(path)
|
||||
|
||||
def send_error(self, code, message=None, explain=None):
|
||||
pass
|
||||
|
||||
|
||||
def run(server_class=HTTPServer, handler_class=RequestHandler, port=5000):
|
||||
server_address = ('', port)
|
||||
httpd = server_class(server_address, handler_class)
|
||||
httpd.serve_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from sys import argv
|
||||
|
||||
conn = create_in_memory_connection()
|
||||
|
||||
# Define custom sleep function
|
||||
# On different DB engines it can be predefined
|
||||
conn.create_function("sleep", 1, time.sleep)
|
||||
|
||||
RequestHandler.cursor = conn.cursor()
|
||||
|
||||
if len(argv) == 2:
|
||||
run(port=int(argv[1]))
|
||||
else:
|
||||
run()
|
||||
29
tests/wrong_http_response/handler.py
Normal file
29
tests/wrong_http_response/handler.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
|
||||
|
||||
class RequestHandler(BaseHTTPRequestHandler):
|
||||
def _set_headers(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/plain')
|
||||
|
||||
def do_GET(self):
|
||||
self._set_headers()
|
||||
self.wfile.write(b'OK')
|
||||
|
||||
def send_error(self, code, message=None, explain=None):
|
||||
pass
|
||||
|
||||
|
||||
def run(server_class=HTTPServer, handler_class=RequestHandler, port=5000):
|
||||
server_address = ('', port)
|
||||
httpd = server_class(server_address, handler_class)
|
||||
httpd.serve_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from sys import argv
|
||||
|
||||
if len(argv) == 2:
|
||||
run(port=int(argv[1]))
|
||||
else:
|
||||
run()
|
||||
2
tests/wrong_http_response/test.sh
Normal file
2
tests/wrong_http_response/test.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
./fuzz_and_grep_logs.sh "$(dirname "${BASH_SOURCE[0]}")" "Bad HTTP header"
|
||||
exit $?
|
||||
Reference in New Issue
Block a user