How to make web scanners to stuck in an infinite false positives loop: Test with Nikto and Skipfish

In this post I’ll create a custom “404 not found” page in order to generate many false positives when a web scanner trying to guess hidden files or directories

theMiddle
theMiddle
Aug 22, 2017 · 2 min read

The very first problem that I met writing a web scanner, was handling false positives. The first source of false positives is when a non-existent page doesn’t return a 404 status. What I’ve done in order to handle this kind of situation, is to “collect” many responses from non-existent requests, make a md5 hash of them and compare it with all following responses.

When you need a md5 hash of an HTML response, you need to replace many things like timestamps, tokens, the pathname you requested, etc… In other words, all dynamic contents that could change. For example, my code does the following replacements:

# generating random strings
randomstring = 'blabla1234.html'
# make a request
conn.request('GET', '/'+randomstring)
# getting the response
orig_response = conn.getresponse().read()
# start replacing
respdata = orig_response.replace('/'+randomstring, '') #1
respdata = re.sub("\n", ' ', dst_respdata) #2
respdata = re.sub('[a-fA-F0-9]{10,}', '', respdata) #3
respdata = re.sub('\d+', '', respdata) #4
# hash
resphash = str(hashlib.md5(respdata.strip()).hexdigest())

#1 removes the current pathname requested.
#2 removes all “new lines”
#3 removes all hexadecimal string that are >= then 10 chars
#4 removes all numbers

Obviously this way has many flaws. A random string that includes numbers, letters and special chars could make my scanner goes crazy, finding a huge number of files that don’t exist. This kind of problem seems present on others web scanners like Nikto or SkipFish, let’s do a test!

Creating a custom 404 page

We need a 404 response body that contains random string with numbers, letters, special chars, spaces, etc… So, we need to start from Nginx:

server {
...
error_page 404 = /error.php;
...
}

Now, create the error.php file that could be something like this:

<?php   header('HTTP/1.1 200 OK');   echo '<!-- '.random_string(2000).' -->';
echo "404 Not Found\n";
echo '<!-- '.random_string(2000).' -->';
function random_string($length=100) {
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
'abcdefghijklmnopqrstuvwxyz'.
'0123456789,.-;:_ ';
return substr(
str_shuffle(
str_repeat($chars, $length)
),
0, $length);
}

This PHP page return always a 200 status code with two HTML comment that contains the random strings. The response will be like the following:

response body

Now we can test it with Nikto or Skipfish!

Test 1: Nikto

Test 2: SkipFish

)
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade