Exploit the possiblities

Traceroute-Like HTTP Scanner

Traceroute-Like HTTP Scanner
Posted Nov 21, 2011
Authored by Nicolas Gregoire

This is a python script that uses the Max-Forwards header in HTTP and SIP to perform a traceroute-like scanning functionality.

tags | tool, web, scanner, python
systems | unix
MD5 | ae56d53ec6967cafda77f5544aeaabba

Traceroute-Like HTTP Scanner

Change Mirror Download
#!/usr/bin/env python

import getopt, sys, re, urllib2, urllib, BaseHTTPServer
from urllib2 import Request, urlopen, URLError, HTTPError

################## HEADER ###################################

#
# Traceroute-like HTTP scanner
# Using the "Max-Forwards" header
# RFC 2616 - HTTP/1.1 - Section 14.31
# RFC 3261 - SIP - Section 8.1.1.6
#

#
# By Nicolas Gregoire (nicolas.gregoire@agarri.fr)
#
# 0.5 : First public release
# 0.4 : Private release, looking for bugs - More heuristics
# 0.3 : A lot more options - More verbosity levels - Some heuristics
#
# By Julien Cayssol (tools@aqwz.com)
#
# 0.2 : Add extract of headers
# 0.1 : Initial version
#

#
# Heuristics :
# - Status Codes :
# - HTTP Status Code == 502
# - HTTP Status Code == 483
# - Specific data in body or headers :
# - X-Forwarded-For in body when using TRACE
# - Via or X-Via in headers
# - Differences between hops :
# - HTTP Status Codes
# - Server headers
# - Content-Type headers
# - Via headers
# - HTML titles
# - HTML <address> tags
# - X-Forwarded-For values when using TRACE
#

############## GLOBAL VARIABLES ###################################

global_data = { 'StatusCode':{}, 'Server':{} , 'Content-Type':{}, 'Title':{}, 'Address':{}, 'X-Fwd':{}, 'Via':{} }
score = 0
verbosity = 0
scheme = 'http'
host = '127.0.0.1'
port = '80'
path = '/'
method = 'TRACE'
body_content = None
max_fwds = 3
userAgent = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.2) Gecko/20060502 Firefox/1.5.0.2'
contentType = 'text/html'

############## FUNCTIONS ###################################

# Pretty printing
def zprint(string, flag = '=='):
print '[' + flag + '] ' + string

# Increment the heuristic score
def inc_score():
global score
score = score + 1
if verbosity:
zprint('Score : ' + str(score), '!!')

# Help
def showUsage():
print 'Usage : ' + sys.argv[0] + ' [-h] [-m method] [-s scheme] [-t target] [-p port] [-P path] [-v 0|1|2] [-f forwards]'
print '\t[-h] Help (this text)'
print '\t[-m] HTTP Method : default is "TRACE"'
print '\t[-s] Scheme : default is "http"'
print '\t[-t] Target host : default is "127.0.0.1"'
print '\t[-p] Port : default is "80"'
print '\t[-P] Path : default is "/"'
print '\t[-f] Max # of forwards : default is "3"'
print '\t[-v] Verbosity : 0 = default, 1 = verbose, 2 = debug'
print 'Examples :'
print sys.argv[0] + ' -t www.example.org'
print ' => TRACE /'
print sys.argv[0] + ' -t www.example.org -m GET -s https -p 443 -v 1'
print ' => GET / on a SSL host'
print sys.argv[0] + ' -t www.example.org -m POST -P /axis2/checkacc -v 2 -f 5'
print ' => Debug mode on a specific end-point'
sys.exit(1)

# Parse CLI args
def getArguments():
try:
if len(sys.argv) < 2:
zprint('No arguments ? Probably a bad choice. Use "-h" ...', '!!')
sys.exit(1)
optlist, list = getopt.getopt(sys.argv[1:], 'hm:s:t:p:P:v:f:')
except getopt.GetoptError:
showUsage()
for opt in optlist:
if opt[0] == '-h':
showUsage()
if opt[0] == '-m':
global method
method = opt[1]
if opt[0] == '-s':
global scheme
scheme = opt[1]
if opt[0] == '-t':
global host
host = opt[1]
if opt[0] == '-p':
global port
port = opt[1]
if opt[0] == '-P':
global path
path = opt[1]
if opt[0] == '-v':
global verbosity
verbosity = int(opt[1])
if opt[0] == '-f':
global max_fwds
max_fwds = int(opt[1])

# Extract some interesting data from the headers
def analyse_headers(data):

if verbosity:
print
zprint('Analyzing headers', '**')

wanted_headers = [
'Server',
'Via',
'X-Via',
'Set-Cookie',
'X-Forwarded-For',
'Content-Type',
'Content-Length',
'Last-Modified',
'Location',
'Date',
]

for h_name in wanted_headers:
h_value = data.getheader(h_name)
if h_value != None:
# Print the value
if verbosity:
zprint(h_value, h_name)
# Add it to the global structure if needed
if h_name == 'Server' or h_name == 'Content-Type':
global_data[h_name][hop] = h_value
# Some heuristics
if h_name == 'Via' or h_name == 'X-Via':
zprint('"Via" header : Probably a reverse proxy', '++')
global_data['Via'][hop] = h_value
inc_score()

# Extract some interesting data from the body
def analyse_body(data):

if verbosity:
print
zprint('Analyzing body', '**')

wanted_patterns = [
'<title>(.*)</title>',
'<address>(.*)</address>',
'Reason: <strong>(.*)</strong>',
'X-Forwarded-For: (.*)',
]

for p_name in wanted_patterns:
# Case insensitive search
p_value = re.search(p_name, data, re.IGNORECASE)
if p_value != None:
# Only the 1st group, without newlines
value = p_value.groups()[0].strip('\r\n')
if verbosity:
zprint(value, p_name)
# Add it to the global structure if needed
if p_name == '<title>(.*)</title>':
global_data['Title'][hop] = value
if p_name == '<address>(.*)</address>':
global_data['Address'][hop] = value
# Some heuristics
if re.search('X-Forwarded-For:' , p_name):
global_data['X-Fwd'][hop] = value
if method == 'TRACE':
zprint('"X-Forwarded-For" in body when using TRACE : Probably a reverse proxy', '++')
inc_score()

# Analyse the data returned by urllib2.*open()
def debug_and_parse(data):

# Get data
headers = data.info()
body = data.read()

# Debug
if verbosity == 2:
zprint(str(headers), 'DEBUG HEADERS')
zprint(str(body), 'DEBUG BODY')

# Extract some intersting info
codes = BaseHTTPServer.BaseHTTPRequestHandler.responses
global_data['StatusCode'][hop] = str(data.code) + ' ' + codes[data.code][0]
analyse_headers(headers)
analyse_body(body)

############## SCAN ###################################

# Init
getArguments()

# Current target
url = scheme + '://' + host + ':' + port + path
zprint('Target URL : ' + url)
zprint('Used method : ' + method)
zprint('Max number of hops : ' + str(max_fwds))

# Scan
for hop in range(0, max_fwds):

# Create the request object
request = urllib2.Request(url)
request.get_method = lambda: method
request.add_data(body_content)
request.add_header('Content-Type', contentType)
request.add_header('User-agent', userAgent)

# Add the 'Max-Forwards' header
request.add_header('Max-Forwards', hop)
if verbosity:
print('-' * 80)
zprint('Current value of "Max-Forwards" = ' + str(hop) + ' [' + '-' * 20 + ']', '-' * 19)
print('-' * 80)

try:
# Do the HTTP request
opener = urllib2.build_opener(urllib2.HTTPHandler)
result = opener.open(request)

# Found something
if verbosity:
zprint('Status Code => HTTP 200: OK', '**')

# Analyse it
debug_and_parse(result)

# Not a 200 OK
except HTTPError, e:
if verbosity:
zprint('Status Code => ' + str(e), '**')
# Some heuristics
if e.code == 502:
zprint('HTTP 502 : Probably a reverse proxy', '++')
inc_score()
if e.code == 483:
zprint('HTTP 483 : Probably a reverse proxy (SIP ?)', '++')
inc_score()

# Analyse it
debug_and_parse(e)

# Network problem
except URLError, e:
zprint('Network problem !', '!!')
zprint('Reason : ' + str(e.reason), '!!')
break

############## REPORT ###################################

print('-' * 80)
zprint('Heuristic Report [' + '-' * 31 + ']', '-' * 27)
print('-' * 80)

# For each key
for k in global_data.keys():
string = k + ':\n'
previous = 'Undef'
# For each hop
ok = 0
for i in range(0, max_fwds):
# Try this key
try:
current = global_data[k][i]
# We got a value !
ok = 1
except KeyError:
current = 'Undef'

# Some heuristics
if previous != current and i > 0:
inc_score()

# Then add it to the current string
string = string + '\tHop #' + str(i) + " : " + current + '\n'
previous = current

# Display this key only if values were found
if ok:
print string

# Final score
if score == 0:
zprint('No reverse proxy', '--')
else:
zprint('Found a reverse proxy, score is ' + str(score), '++')

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

November 2017

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Nov 1st
    22 Files
  • 2
    Nov 2nd
    28 Files
  • 3
    Nov 3rd
    10 Files
  • 4
    Nov 4th
    1 Files
  • 5
    Nov 5th
    5 Files
  • 6
    Nov 6th
    15 Files
  • 7
    Nov 7th
    15 Files
  • 8
    Nov 8th
    13 Files
  • 9
    Nov 9th
    9 Files
  • 10
    Nov 10th
    9 Files
  • 11
    Nov 11th
    3 Files
  • 12
    Nov 12th
    2 Files
  • 13
    Nov 13th
    15 Files
  • 14
    Nov 14th
    17 Files
  • 15
    Nov 15th
    19 Files
  • 16
    Nov 16th
    15 Files
  • 17
    Nov 17th
    19 Files
  • 18
    Nov 18th
    4 Files
  • 19
    Nov 19th
    2 Files
  • 20
    Nov 20th
    9 Files
  • 21
    Nov 21st
    15 Files
  • 22
    Nov 22nd
    23 Files
  • 23
    Nov 23rd
    0 Files
  • 24
    Nov 24th
    0 Files
  • 25
    Nov 25th
    0 Files
  • 26
    Nov 26th
    0 Files
  • 27
    Nov 27th
    0 Files
  • 28
    Nov 28th
    0 Files
  • 29
    Nov 29th
    0 Files
  • 30
    Nov 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2016 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close