203 lines
7.0 KiB
Markdown
203 lines
7.0 KiB
Markdown
## Vulnerable Application
|
|
|
|
This module creates a mock SMTP server which accepts credentials or unauthenticated email
|
|
before throwing a `503` error.
|
|
|
|
## Verification Steps
|
|
|
|
1. Start msfconsole
|
|
2. Do: ```use auxiliary/server/capture/smtp```
|
|
3. Do: ```run```
|
|
|
|
## Options
|
|
|
|
### AUTHPROMPT
|
|
|
|
If the client should be prompted for credentials or not. When set to `false` credentials can still be
|
|
accepted, but the client isn't prompted outright to give them. Some systems will only provide crednetials
|
|
if prompted. Defaults to `false`
|
|
|
|
## Scenarios
|
|
|
|
### Testing Script
|
|
|
|
The following script should test the following:
|
|
|
|
1. Auth Plain
|
|
2. Auth Login
|
|
3. Auth CRAM-MD5
|
|
4. Sending an email w/o auth
|
|
5. RSET is implemented (https://github.com/rapid7/metasploit-framework/issues/11980)
|
|
|
|
```
|
|
require 'net/smtp'
|
|
require 'socket'
|
|
|
|
puts 'Testing: plain'
|
|
begin
|
|
Net::SMTP.start('127.0.0.1', 25, 'localhost', 'username_plain', 'password_plain', :plain)
|
|
rescue => e
|
|
puts "Error: #{e}"
|
|
end
|
|
|
|
puts 'Testing: login'
|
|
begin
|
|
Net::SMTP.start('127.0.0.1', 25, 'localhost', 'username_login', 'password_login', :login)
|
|
rescue => e
|
|
puts "Error: #{e}"
|
|
end
|
|
|
|
puts 'Testing: cram md5'
|
|
begin
|
|
Net::SMTP.start('127.0.0.1', 25, 'localhost', 'username_cram', 'password_cram', :cram_md5)
|
|
rescue => e
|
|
puts "Error: #{e}"
|
|
end
|
|
|
|
puts 'Testing: DATA'
|
|
begin
|
|
Net::SMTP.start('127.0.0.1') do |smtp|
|
|
smtp.send_message 'test', 'from@test.com', 'to@test.com'
|
|
end
|
|
rescue => e
|
|
puts "Error: #{e}"
|
|
end
|
|
|
|
|
|
# test for https://github.com/rapid7/metasploit-framework/issues/11980
|
|
puts 'Testing: RSET during DATA'
|
|
begin
|
|
t = TCPSocket.open('127.0.0.1', 25)
|
|
t.gets
|
|
t.print("EHLO localhost \r\n")
|
|
t.gets
|
|
t.print("MAIL FROM:<from@test.com>\r\n")
|
|
t.gets
|
|
t.print("MAIL TO:<to@test.com>\r\n")
|
|
t.gets
|
|
t.print("DATA\r\n")
|
|
t.gets
|
|
t.print("RSET\r\n")
|
|
puts " Response: #{t.gets.chop}"
|
|
rescue => e
|
|
puts "Error: #{e}"
|
|
end
|
|
|
|
puts 'Testing: RSET during middle of DATA'
|
|
begin
|
|
t = TCPSocket.open('127.0.0.1', 25)
|
|
t.gets
|
|
t.print("EHLO localhost \r\n")
|
|
t.gets
|
|
t.print("MAIL FROM:<from@test.com>\r\n")
|
|
t.gets
|
|
t.print("MAIL TO:<to@test.com>\r\n")
|
|
t.gets
|
|
t.print("DATA\r\n")
|
|
t.gets
|
|
t.print("testing a message which gets cancelled\r\n")
|
|
t.print("RSET\r\n")
|
|
puts " Response: #{t.gets.chop}"
|
|
rescue => e
|
|
puts "Error: #{e}"
|
|
end
|
|
```
|
|
|
|
### Output from testing script
|
|
|
|
When this script is run from the Metasploit console, it intermingles with the commands, which is great!
|
|
|
|
```
|
|
$ sudo ./msfconsole -qx 'use auxiliary/server/capture/smtp; set srvhost 127.0.0.1;run;ruby tools/dev/test_capture_smtp.rb'
|
|
srvhost => 127.0.0.1
|
|
[*] Auxiliary module running as background job 0.
|
|
[*] exec: ruby tools/dev/test_capture_smtp.rb
|
|
|
|
[*] Started service listener on 127.0.0.1:25
|
|
[*] Server started.
|
|
Testing: plain
|
|
[*] SMTP: 127.0.0.1:46212 Command: EHLO localhost
|
|
[*] SMTP: 127.0.0.1:46212 Command: AUTH PLAIN AHVzZXJuYW1lX3BsYWluAHBhc3N3b3JkX3BsYWlu
|
|
[+] SMTP LOGIN 127.0.0.1:46212 username_plain / password_plain
|
|
Testing: login
|
|
[*] SMTP: 127.0.0.1:46214 Command: EHLO localhost
|
|
[*] SMTP: 127.0.0.1:46214 Command: AUTH LOGIN
|
|
[*] SMTP: 127.0.0.1:46214 Command: dXNlcm5hbWVfbG9naW4=
|
|
[*] SMTP: 127.0.0.1:46214 Command: cGFzc3dvcmRfbG9naW4=
|
|
[+] SMTP LOGIN 127.0.0.1:46214 username_login / password_login
|
|
Testing: cram md5
|
|
[*] SMTP: 127.0.0.1:46216 Command: EHLO localhost
|
|
[*] SMTP: 127.0.0.1:46216 Command: AUTH CRAM-MD5
|
|
[*] SMTP: 127.0.0.1:46216 Command: dXNlcm5hbWVfY3JhbSA3YjA2NzUyMjVhM2FjMmI5MjMxYzJlOTM5OTg2Y2U0Mg==
|
|
Testing: DATA
|
|
[+] SMTP LOGIN 127.0.0.1:46216 username_cram / <12345@127.0.0.1>#7b0675225a3ac2b9231c2e939986ce42
|
|
[*] SMTP: 127.0.0.1:46218 Command: EHLO localhost
|
|
[*] SMTP: 127.0.0.1:46218 Command: MAIL FROM:<from@test.com>
|
|
[*] SMTP: 127.0.0.1:46218 Command: RCPT TO:<to@test.com>
|
|
[*] SMTP: 127.0.0.1:46218 Command: DATA
|
|
[*] SMTP: 127.0.0.1:46218 Command: test
|
|
.
|
|
[*] SMTP: 127.0.0.1:46218 EMAIL: test
|
|
[*] SMTP: 127.0.0.1:46218 Command: QUIT
|
|
Testing: RSET during DATA
|
|
[*] SMTP: 127.0.0.1:46220 Command: EHLO localhost
|
|
[*] SMTP: 127.0.0.1:46220 Command: MAIL FROM:<from@test.com>
|
|
[*] SMTP: 127.0.0.1:46220 Command: MAIL TO:<to@test.com>
|
|
[*] SMTP: 127.0.0.1:46220 Command: DATA
|
|
[*] SMTP: 127.0.0.1:46220 Command: RSET
|
|
Response: 250 OK
|
|
Testing: RSET during middle of DATA
|
|
[*] SMTP: 127.0.0.1:46222 Command: EHLO localhost
|
|
[*] SMTP: 127.0.0.1:46222 Command: MAIL FROM:<from@test.com>
|
|
[*] SMTP: 127.0.0.1:46222 Command: MAIL TO:<to@test.com>
|
|
[*] SMTP: 127.0.0.1:46222 Command: DATA
|
|
[*] SMTP: 127.0.0.1:46222 Command: testing a message which gets cancelled
|
|
RSET
|
|
[*] SMTP: 127.0.0.1:46222 EMAIL: testing a message which gets cancelled
|
|
Response: 250 OK
|
|
msf auxiliary(server/capture/smtp) > creds
|
|
Credentials
|
|
===========
|
|
|
|
host origin service public private realm private_type JtR Format
|
|
---- ------ ------- ------ ------- ----- ------------ ----------
|
|
127.0.0.1 127.0.0.1 25/tcp (smtp) username_cram <12345@127.0.0.1>#7b0675225a3ac2b9231c2e939986ce42 Nonreplayable hash hmac-md5
|
|
127.0.0.1 127.0.0.1 25/tcp (smtp) username_login password_login Password
|
|
127.0.0.1 127.0.0.1 25/tcp (smtp) username_plain password_plain Password
|
|
|
|
msf auxiliary(server/capture/smtp) > notes
|
|
|
|
Notes
|
|
=====
|
|
|
|
Time Host Service Port Protocol Type Data
|
|
---- ---- ------- ---- -------- ---- ----
|
|
2020-04-17 15:11:24 UTC 127.0.0.1 smtp_message "testing a message which gets cancelled\r\n"
|
|
|
|
|
|
```
|
|
|
|
### Cracking Cram-md5 (hmac-md5)
|
|
|
|
Metasploit currently doesn't have a cracker for `hmac-md5`, however the output is pre-formatted to JTR standards,
|
|
and `creds -o /tmp/file.jtr` will export it correctly for John. It is also possible to export to hashcat format
|
|
with `creds -o /tmp/file.hcat` and mode `10200`.
|
|
|
|
```
|
|
user@kali:~/metasploit-framework$ sudo cat /tmp/cram
|
|
username_cram:<12345@127.0.0.1>#7b0675225a3ac2b9231c2e939986ce42
|
|
user@kali:~/metasploit-framework$ sudo cat /tmp/wordlist
|
|
password_cram
|
|
user@kali:~/metasploit-framework$ sudo john --wordlist=/tmp/wordlist --format=hmac-md5 /tmp/cram
|
|
Using default input encoding: UTF-8
|
|
Loaded 1 password hash (HMAC-MD5 [password is key, MD5 256/256 AVX2 8x3])
|
|
Warning: poor OpenMP scalability for this hash type, consider --fork=8
|
|
Will run 8 OpenMP threads
|
|
Press 'q' or Ctrl-C to abort, almost any other key for status
|
|
Warning: Only 1 candidate left, minimum 192 needed for performance.
|
|
password_cram (username_cram)
|
|
1g 0:00:00:00 DONE (2020-04-17 11:32) 50.00g/s 50.00p/s 50.00c/s 50.00C/s password_cram
|
|
Use the "--show --format=HMAC-MD5" options to display all of the cracked passwords reliably
|
|
Session completed
|
|
```
|