mailpot 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011-2012 Matt Jezorek
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ # MailPot
2
+
3
+ MailPot is a simple SMTP honeypot that will catch email and save it to a database
4
+ MailPot works to gain some automatic analysis and probe detection
5
+
6
+ ## Features
7
+ * Catches all email and stores it
8
+ * Works with Attachements
9
+ * Runs as a daemon in the background
10
+ * Written in EventMachine
11
+
12
+ ## How
13
+ 1. `gem install mailpot`
14
+ 2. `mailpot`
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "bundler/setup"
4
+ require 'mailpot'
5
+ Mailpot.run!
@@ -0,0 +1,100 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require 'active_support/all'
4
+ require 'eventmachine'
5
+ require 'optparse'
6
+ require 'rbconfig'
7
+
8
+ module Mailpot extend ActiveSupport::Autoload
9
+ autoload :Smtp
10
+ autoload :Mail
11
+
12
+ module_function
13
+
14
+ @@defaults = {
15
+ :smtp_ip => '127.0.0.1',
16
+ :smtp_port => '1025',
17
+ :verbose => false,
18
+ :daemon => true,
19
+ :key_file => '/etc/mailpot/keys.yml'
20
+ }
21
+
22
+ def parse! arguments=ARGV, defaults=@@defaults
23
+ @@defaults.dup.tap do |options|
24
+ OptionParser.new do |parser|
25
+ parser.banner = "Usage: mailpot [options]"
26
+ parser.version = File.read(File.expand_path("../../VERSION", __FILE__))
27
+
28
+ parser.on("--ip IP", "Set the ip address of the smtp server") do |ip|
29
+ options[:smtp_ip] = ip
30
+ end
31
+
32
+ parser.on("--keys KEYFILE", "Set the key file that contains AWS creds") do |f|
33
+ options[:key_file] = f
34
+ end
35
+
36
+ parser.on("--port PORT", Integer, "Set the port of the smtp server") do |port|
37
+ options[:smtp_port] = port
38
+ end
39
+
40
+ parser.on('-f', '--foreground', 'Run in forground') do
41
+ options[:daemon] = false
42
+ end
43
+
44
+ parser.on('-v', '--verbose', 'Be more verbose') do
45
+ options[:verbose] = true
46
+ end
47
+
48
+ parser.on('-h', '--help', 'Display help information') do
49
+ puts parser
50
+ exit!
51
+ end
52
+ end.parse!
53
+ end
54
+ end
55
+
56
+ def get_config
57
+ options &&= @@defaults.merge options
58
+ options ||= parse!
59
+ end
60
+
61
+ def run! options=nil
62
+ #options &&= @@defaults.merge options
63
+ #options ||= parse!
64
+ #@config = options
65
+ options = get_config
66
+ puts "Starting MailPot"
67
+ EventMachine.run do
68
+ rescue_port options[:smtp_port] do
69
+ EventMachine.start_server options[:smtp_ip], options[:smtp_port], Smtp
70
+ puts "==> smtp://#{options[:smtp_ip]}:#{options[:smtp_port]}"
71
+ end
72
+
73
+ if options[:daemon]
74
+ EventMachine.next_tick do
75
+ puts "*** Mailpot now runs as a daemon by default"
76
+ Process.daemon
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def quit!
83
+ EventMachine.next_tick {EventMachine.stop_event_loop}
84
+ end
85
+
86
+ protected
87
+ module_function
88
+ def rescue_port port
89
+ begin
90
+ yield
91
+ rescue RuntimeError
92
+ if $!.to_s =~ /\bno acceptor\b/
93
+ puts "~~> ERROR: Somethings using port #{port}. Are you already running MailPot"
94
+ exit -1
95
+ else
96
+ raise
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,4 @@
1
+ require 'eventmachine'
2
+ module Mailpot::Events
3
+ MessageAdded = EventMachine::Channel.new
4
+ end
@@ -0,0 +1,54 @@
1
+ require 'eventmachine'
2
+ require 'yaml'
3
+ require 'base64'
4
+ require 'socket'
5
+ require 'zlib'
6
+ require 'digest/md5'
7
+ require 'aws'
8
+
9
+ module Mailpot::Mail
10
+ module_function
11
+
12
+ @initialized = false
13
+ # setup connections etc
14
+ def initialize
15
+ config = Mailpot.get_config
16
+ yml = YAML.load_file config[:key_file]
17
+ @bucket = yml['bucket']
18
+ @queue = yml['queue']
19
+ @s3 = AWS::S3.new(yml)
20
+ @sqs = AWS::SQS.new(yml)
21
+ @initialized = true
22
+ end
23
+
24
+ def add_message(message)
25
+ if !@initialized
26
+ initialize
27
+ end
28
+ msg = Hash.new
29
+ msg[:source] = message[:source]
30
+ msg[:sender] = message[:sender]
31
+ msg[:source_ip] = message[:ip]
32
+ msg[:recipients] = message[:recipients]
33
+ # worried about dedupe here and need to come up with a way at 1M messages
34
+ # a day this could be a lot of storage
35
+ encoded_message = Base64.encode64(msg.to_json)
36
+ deflate_encoded_message = gzdeflate(encoded_message)
37
+ digest = Digest::MD5.hexdigest(deflate_encoded_message)
38
+ store_message(digest, deflate_encoded_message)
39
+ end
40
+
41
+ def store_message(key, value)
42
+ Thread.new {
43
+ mail = @s3.buckets[@bucket].objects[key]
44
+ mail.write(value)
45
+ q = @sqs.queues[@queue]
46
+ msg = q.send_message(key)
47
+ }
48
+ end
49
+
50
+ def gzdeflate(s)
51
+ Zlib::Deflate.new(nil, -Zlib::MAX_WBITS).deflate(s, Zlib::FINISH)
52
+ end
53
+
54
+ end
@@ -0,0 +1,57 @@
1
+ require 'eventmachine'
2
+ require 'socket'
3
+ class Mailpot::Smtp < EventMachine::Protocols::SmtpServer
4
+ def current_message
5
+ @current_message ||= {}
6
+ end
7
+
8
+ def receive_reset
9
+ @current_message = nil
10
+ true
11
+ end
12
+
13
+ def get_server_greeting
14
+ "ESMTP Sendmail 8.12.9/8.12.9;"
15
+ end
16
+
17
+ def get_server_domain
18
+ Socket.gethostbyname(Socket.gethostname).first
19
+ end
20
+
21
+ def receive_sender(sender)
22
+ current_message[:sender] = sender
23
+ end
24
+
25
+ def receive_recipient(recipient)
26
+ current_message[:recipients] ||= []
27
+ current_message[:recipients] << recipient
28
+ true
29
+ end
30
+
31
+ def receive_data_chunk(lines)
32
+ current_message[:source] ||= ""
33
+ current_message[:source] += lines.join("\n")
34
+ true
35
+ end
36
+
37
+ def receive_message
38
+ port, ip = Socket.unpack_sockaddr_in(get_peername)
39
+ current_message[:ip] = ip
40
+ current_message[:port] = port
41
+ Mailpot::Mail.add_message current_message
42
+ puts "==> SMTP: Received message from '#{current_message[:sender]}' (#{current_message[:source].length} bytes)"
43
+ true
44
+ rescue
45
+ puts "*** Error receiving message: #{current_message.inspect}"
46
+ puts " Exception: #{$!}"
47
+ puts " Backtrace:"
48
+ $!.backtrace.each do |line|
49
+ puts " #{line}"
50
+ end
51
+ puts " Please submit this as an issue at https://github.com/mjezorek/Mailpot/issues"
52
+ false
53
+ ensure
54
+ @current_message = nil
55
+ end
56
+
57
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mailpot
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Matt Jezorek
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-02-15 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 7
29
+ segments:
30
+ - 3
31
+ - 0
32
+ version: "3.0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: eventmachine
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 19
44
+ segments:
45
+ - 0
46
+ - 12
47
+ version: "0.12"
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: aws-sdk
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ type: :runtime
63
+ version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: rake
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ type: :development
77
+ version_requirements: *id004
78
+ - !ruby/object:Gem::Dependency
79
+ name: rdoc
80
+ prerelease: false
81
+ requirement: &id005 !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ type: :development
91
+ version_requirements: *id005
92
+ description: " MailPot is a simple SMTP server honeypot that will catch emails and store\n them deduplicated in a database. This will extract links from emails and do \n other analysis on it. Once probes can be identified they will be passed.\n"
93
+ email: mjezorek@gmail.com
94
+ executables:
95
+ - mailpot
96
+ extensions: []
97
+
98
+ extra_rdoc_files:
99
+ - README.md
100
+ - LICENSE
101
+ files:
102
+ - README.md
103
+ - LICENSE
104
+ - VERSION
105
+ - bin/mailpot
106
+ - lib/mailpot/events.rb
107
+ - lib/mailpot/mail.rb
108
+ - lib/mailpot/smtp.rb
109
+ - lib/mailpot.rb
110
+ homepage: http://mattjezorek.com/
111
+ licenses: []
112
+
113
+ post_install_message:
114
+ rdoc_options: []
115
+
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ hash: 57
124
+ segments:
125
+ - 1
126
+ - 8
127
+ - 7
128
+ version: 1.8.7
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ hash: 3
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ requirements: []
139
+
140
+ rubyforge_project:
141
+ rubygems_version: 1.7.2
142
+ signing_key:
143
+ specification_version: 3
144
+ summary: Runs an SMTP Server and catches emails, will pass probes when identified as a probe
145
+ test_files: []
146
+