mailpot 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+