Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions MITMsmtp/SMTPHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ def init(self):
""" Reads a line from TCP Stream
@return: Read line
"""
def readLine(self):
line = self.rfile.readline().strip()
if (self.server.printLines):
def readLine(self, skipBlank=True):
while True:
line = self.rfile.readline().strip()
if line or not skipBlank:
break
if self.server.printLines:
print("C:" + line)
return line

Expand Down Expand Up @@ -180,7 +183,7 @@ def sendIntermediate(self):
def readMSG(self):
message = ""
while True:
line = self.readLine()
line = self.readLine(skipBlank=False)
if (line == '.'):
self.message.setMessage(message)
return
Expand Down
13 changes: 6 additions & 7 deletions MITMsmtp/SMTPServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""
SMTPServer wrapper class for TCPServer
"""
class SMTPServer(TCPServer):
class SMTPServer(ThreadingMixIn, TCPServer):
""" Creates a new SMTPServer object
@param server_address: The address to listen on
@type server_address: str
Expand Down Expand Up @@ -79,11 +79,10 @@ def get_request(self):
@return: Returns encrypted connection
"""
def wrapSSL(self, socket):
connstream = ssl.wrap_socket(socket,
server_side=True,
certfile = self.certfile,
keyfile = self.keyfile,
ssl_version = self.ssl_version)
context = ssl.SSLContext(self.ssl_version)
if self.certfile:
context.load_cert_chain(certfile=self.certfile, keyfile=self.keyfile)
connstream = context.wrap_socket(socket, server_side=True)

return connstream

class SMTPServer(ThreadingMixIn, SMTPServer): pass
7 changes: 5 additions & 2 deletions MITMsmtp/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def loginCallback(self, message, username, password):
@type message: Message
"""
def messageCallback(self, message):
output = """=== Complete Message ===%s\nIP : %s\n\nUsername : %s\nPassword : %s\nClient : %s\nSender : %s\n""" % (message.clientIP,
output = """=== Complete Message ===\nIP : %s\n\nUsername : %s\nPassword : %s\nClient : %s\nSender : %s\n""" % (message.clientIP,
message.username,
message.password,
message.client_name,
Expand All @@ -72,7 +72,7 @@ def messageCallback(self, message):
log.write(output + "\n\n")
log.write(message.message)

def main(args=None):
def main():
# Parse arguments
parser=argparse.ArgumentParser(description="MITMsmtp is an Evil SMTP Server for pentesting SMTP clients to catch login credentials and mails sent over plain or SSL encrypted connections.")
parser.add_argument('--server_address', default="0.0.0.0", help='IP Address to listen on (default: all)')
Expand Down Expand Up @@ -118,3 +118,6 @@ def main(args=None):
except KeyboardInterrupt:
pass
server.stop() #Stop SMTPServer

if __name__ == "__main__":
main()
4 changes: 2 additions & 2 deletions MITMsmtp/auth/authLogin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ class authLogin (authMethod):
@returns: The authMethods name
"""
def __init__(self, SMTPHandler, authLine):
super().__init__(SMTPHandler, authLine)

self.SMTPHandler = SMTPHandler
self.authLine = authLine
self.username = None
self.password = None

self.requestUsername()
self.readUsername()
Expand Down
3 changes: 3 additions & 0 deletions MITMsmtp/auth/authMethod.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class authMethod(ABC):
def __init__(self, SMTPHandler, authLine):
super().__init__()

self.username = None
self.password = None

""" Returns the authMethods name

Has to be overwritten, otherwise authentication method can't be advertised to client!
Expand Down
5 changes: 2 additions & 3 deletions MITMsmtp/auth/authPlain.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ class authPlain(authMethod):
@returns: The authMethods name
"""
def __init__(self, SMTPHandler, authLine):
super().__init__(SMTPHandler, authLine)

self.SMTPHandler = SMTPHandler
self.authLine = authLine
self.username = None
self.password = None

match = re.match("AUTH PLAIN$", authLine)
if (match != None):
Expand Down Expand Up @@ -85,7 +85,6 @@ def auth(self):
self.authSuccess()
self.username = auth[-2]
self.password = auth[-1]
authSuccess()

"""
Sends success reply
Expand Down
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,32 @@ MITMsmtp supports the following login methods:
Challenge-Response based authentication methods like CRAM-MD5, NTLM or Kerberos can't be supported as these methods require the server to know the cleartext password.

## Setup
MITMsmtp requires Python3 and setuptools. You might want to install git as well. Use the following command on Debian:
MITMsmtp requires at least Python 3.6. You might want to install git and setuptools as well. Use the following command on Debian:

`apt install python3 python3-setuptools git`

Now just clone the MITMsmtp repository:

`git clone https://github.com/RobinMeis/MITMsmtp.git`

Change into MITMsmtp directory and start the installation:
Change into MITMsmtp directory. From there you can run the program as a module with:

`sudo python3 setup.py install`
`python -m MITMsmtp`

That's it!
or install it with setuptools by running:

`pip install .`

After installation, you will be able to use the `MITMsmtp` command directly from your terminal.

### Updating
`git pull`

`sudo python3 setup.py install`
From within the MITMsmtp directory run:

```
git pull`
pip install .
```

## Usage
*MITMsmtp can be used as standalone command line application and offers an easy to use Python3 API to integrate in your own project*
Expand Down
25 changes: 25 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "MITMsmtp"
version = "0.0.3-dev"
authors = [
{name = "Robin Meis", email = "blog@smartnoob.de"},
]
description = "An evil SMTP Server for client pentesting"
readme = "README.md"
license = "GPL-3.0-only"
license-files = ["LICENSE"]
requires-python = ">= 3.6"
classifiers = [
"Programming Language :: Python :: 3",
"Topic :: Security"
]

[project.urls]
GitHub = "https://github.com/RobinMeis/MITMsmtp"

[project.scripts]
MITMsmtp = "MITMsmtp.__main__:main"
28 changes: 0 additions & 28 deletions setup.py

This file was deleted.