Init WFuzz state

This commit is contained in:
Jan Stárek
2019-10-09 13:24:01 +02:00
parent 7c3ed5ef0b
commit a5eb2a97e1
114 changed files with 6221 additions and 0 deletions

View 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

View File

@@ -0,0 +1,2 @@
./fuzz_and_grep_logs.sh "$(dirname "${BASH_SOURCE[0]}")" "Timeout or closed connection"
exit $?

View 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

View File

@@ -0,0 +1,2 @@
./fuzz_and_grep_logs.sh "$(dirname "${BASH_SOURCE[0]}")" "Status code higher or equal than 500!"
exit $?

View 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

View 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
View 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

View 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
View 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()

View 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

View File

@@ -0,0 +1,2 @@
./fuzz_and_grep_logs.sh "$(dirname "${BASH_SOURCE[0]}")" "application/json body is not valid JSON structure"
exit $?

View 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"]
}
}

View 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
View 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

View 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

View 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()

View 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()

View File

@@ -0,0 +1,2 @@
./fuzz_and_grep_logs.sh "$(dirname "${BASH_SOURCE[0]}")" "Bad HTTP header"
exit $?