Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

first commit

  • Loading branch information...
commit b1de0ee9582cc5cea97155ab16f1610e3016237c 0 parents
Josep M. Bach authored
3  .gitignore
@@ -0,0 +1,3 @@
+pkg/*
+*.gem
+.bundle
2  .rspec
@@ -0,0 +1,2 @@
+--color
+--format documentation
1  .rvmrc
@@ -0,0 +1 @@
+rvm --create use ruby-1.9.2@micetrap
4 Gemfile
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in micetrap.gemspec
+gemspec
43 Gemfile.lock
@@ -0,0 +1,43 @@
+PATH
+ remote: .
+ specs:
+ micetrap (0.0.1)
+ trollop
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ configuration (1.2.0)
+ diff-lcs (1.1.2)
+ guard (0.2.2)
+ open_gem (~> 1.4.2)
+ thor (~> 0.14.3)
+ guard-rspec (0.1.9)
+ guard (>= 0.2.2)
+ launchy (0.3.7)
+ configuration (>= 0.0.5)
+ rake (>= 0.8.1)
+ open_gem (1.4.2)
+ launchy (~> 0.3.5)
+ rake (0.8.7)
+ rspec (2.3.0)
+ rspec-core (~> 2.3.0)
+ rspec-expectations (~> 2.3.0)
+ rspec-mocks (~> 2.3.0)
+ rspec-core (2.3.1)
+ rspec-expectations (2.3.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.3.0)
+ thor (0.14.6)
+ trollop (1.16.2)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ bundler (~> 1.0.7)
+ guard
+ guard-rspec
+ micetrap!
+ rspec (~> 2.3.0)
+ trollop
8 Guardfile
@@ -0,0 +1,8 @@
+# A sample Guardfile
+# More info at http://github.com/guard/guard#readme
+
+guard 'rspec', :version => 2 do
+ watch('^spec/(.*)_spec.rb')
+ watch('^lib/(.*)\.rb') { |m| "spec/#{m[1]}_spec.rb" }
+ watch('^spec/spec_helper.rb') { "spec" }
+end
10 Rakefile
@@ -0,0 +1,10 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
+
+require 'rspec/core'
+require 'rspec/core/rake_task'
+RSpec::Core::RakeTask.new(:spec) do |spec|
+ spec.pattern = FileList['spec/**/*_spec.rb']
+end
+
+task :default => :spec
46 Readme.md
@@ -0,0 +1,46 @@
+#micetrap
+ ___
+ _.-| | |\__/,| (`\
+ { | | |o o |__ _) )
+ "-.|___| _.( T ) ` /
+ .--'-`-. _((_ `^--' /_< \
+ .+|______|__.-||__)`-'(((/ (((/
+
+Catch hackers on the fly with micetrap!
+
+Micetrap opens a server on either a given or random port, emulating fake
+vulnerable services. Port scanners such as Nmap, when fingerprinting ports
+to discover service names and versions, will get apparently legitimate
+responses from common services such as FTP, HTTP or MySQL servers,
+therefore misleading potential attackers with false information.
+
+Depending on the operating system you are using, micetrap will try its best
+to +look feasible+ by choosing the appropriate fake services and versions
+to emulate. Whenever possible, micetrap will provide a bit outdated versions
+which are more likely to be vulnerable, and thus making the attacker focus
+on those ports. While the attacker tries to exploit these ports, she is
+essentially sending certain packets -- which get properly captured and
+logged my micetrap. This information might be useful to discover what kind
+of attacks are being tried against your machine, therefore giving you time
+and the opportunity to defend appropriately.
+
+Running micetrap with sudo will allow it to use default, unsuspicious ports,
+which may give you advantage at tricking a smart attacker.
+
+Micetrap is currently under intensive development, and hopefully a first
+version will be soon available.
+
+##Note on Patches/Pull Requests
+
+* Fork the project.
+* Make your feature addition or bug fix.
+* Add specs for it. This is important so I don't break it in a
+ future version unintentionally.
+* Commit, do not mess with rakefile, version, or history.
+ If you want to have your own version, that is fine but bump version
+ in a commit by itself I can ignore when I pull.
+* Send me a pull request. Bonus points for topic branches.
+
+## Copyright
+
+Copyright (c) 2011 Josep M. Bach. See LICENSE for details.
50 bin/micetrap
@@ -0,0 +1,50 @@
+#!/usr/bin/env ruby -w
+$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
+
+require 'micetrap'
+require 'micetrap/version'
+
+SERVICES = Micetrap.services
+
+opts = Trollop::options do
+ version "micetrap #{Micetrap::VERSION} (c) 2011 Josep M. Bach"
+ banner <<-EOS
+ Micetrap opens a server on either a given or random port, emulating fake
+ vulnerable services. Port scanners such as Nmap, when fingerprinting ports
+ to discover service names and versions, will get apparently legitimate
+ responses from common services such as FTP, HTTP or MySQL servers,
+ therefore misleading potential attackers with false information.
+
+ Depending on the operating system you are using, micetrap will try its best
+ to +look feasible+ by choosing the appropriate fake services and versions
+ to emulate. Whenever possible, micetrap will provide a bit outdated versions
+ which are more likely to be vulnerable, and thus making the attacker focus
+ on those ports. While the attacker tries to exploit these ports, she is
+ essentially sending certain packets -- which get properly captured and
+ logged my micetrap. This information might be useful to discover what kind
+ of attacks are being tried against your machine, therefore giving you time
+ and the opportunity to defend appropriately.
+
+ Fire up a simple ftp micetrap like this:
+
+ sudo micetrap ftp
+
+ Running it with sudo will allow you to use default, unsuspicious ports,
+ which may give you advantage at tricking a smart attacker.
+
+ The available options are are:
+ #{SERVICES.join('\n')}
+
+ Usage:
+ [sudo] micetrap <service> [options]
+
+ where [options] are:
+EOS
+ opt :port, "A specific port to use", :default => nil
+ stop_on SERVICES
+end
+
+service = ARGV.shift
+Trollop::die "You need to specify a service, which must be one of the following: #{SERVICES.join(', ')}\n\nMaybe you just feel a bit lost.." unless SERVICES.include?(service)
+
+Micetrap::Server.new(opts).fire!
11 lib/micetrap.rb
@@ -0,0 +1,11 @@
+require 'micetrap/services/exceptions'
+require 'micetrap/logger'
+require 'micetrap/server'
+
+module Micetrap
+ class << self
+ def services
+ []
+ end
+ end
+end
24 lib/micetrap/logger.rb
@@ -0,0 +1,24 @@
+module Micetrap
+ class Logger
+ TIMESTAMP_FORMAT = "%Y-%m-%d__%H-%M"
+
+ attr_reader :filename
+
+ def initialize(service_name)
+ @service_name = service_name
+ @filename = ['micetrap',
+ service_name,
+ Time.now.strftime(TIMESTAMP_FORMAT)
+ ].join('_') + '.log'
+ end
+
+ def file
+ @file ||= File.open(@filename, 'w')
+ end
+
+ def log(line, remote_host, remote_port)
+ file.write "\n#{Time.now} #{@service_name.upcase} fake server recorded probes coming from #{remote_host}:#{remote_port} containing the following:\n\t\t#{line}"
+ end
+
+ end
+end
28 lib/micetrap/server.rb
@@ -0,0 +1,28 @@
+require 'socket'
+
+module Micetrap
+ class Server
+ attr_reader :service
+ attr_reader :port
+ attr_reader :logger
+
+ def initialize(options)
+ raise StandardError.new("Service cannot be empty!") unless options[:service]
+ @service =
+ eval("Micetrap::Services::#{options[:service].to_s.capitalize}").new
+ @logger = Logger.new
+ @port = options[:port] # Optional
+ rescue NameError
+ raise Services::UnrecognizedServiceException.new("Service #{options[:service].to_s.capitalize} is not recognized")
+ end
+
+ def fire!
+ @service.fire port
+ end
+
+ def log(*args)
+ @logger.log(*args)
+ end
+
+ end
+end
5 lib/micetrap/services/exceptions.rb
@@ -0,0 +1,5 @@
+module Micetrap
+ module Services
+ class UnrecognizedServiceException < StandardError; end;
+ end
+end
3  lib/micetrap/version.rb
@@ -0,0 +1,3 @@
+module Micetrap
+ VERSION = "0.0.1"
+end
29 micetrap.gemspec
@@ -0,0 +1,29 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "micetrap/version"
+
+Gem::Specification.new do |s|
+ s.name = "micetrap"
+ s.version = Micetrap::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["Josep M. Bach"]
+ s.email = ["josep.m.bach@gmail.com"]
+ s.homepage = "http://github.com/txus/micetrap"
+ s.summary = %q{Catch evil hackers on the fly by placing open-port traps emulating fake vulnerable services!}
+ s.description = %q{Catch evil hackers on the fly by placing open-port traps emulating fake vulnerable services!}
+
+ s.rubyforge_project = "micetrap"
+
+ s.add_runtime_dependency 'trollop'
+ s.default_executable = "micetrap"
+
+ s.add_development_dependency 'bundler', '~> 1.0.7'
+ s.add_development_dependency 'rspec', '~> 2.3.0'
+ s.add_development_dependency 'guard'
+ s.add_development_dependency 'guard-rspec'
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+end
46 spec/micetrap/logger_spec.rb
@@ -0,0 +1,46 @@
+require 'spec_helper'
+
+module Micetrap
+
+ describe Logger do
+
+ describe "#initialize" do
+ it 'initializes the filename' do
+ Time.stub_chain('now.strftime')
+ .and_return "2011-01-03__20-30"
+ logger = Logger.new :ftp
+ logger.filename.should == "micetrap_ftp_2011-01-03__20-30.log"
+ end
+ end
+
+ describe "instance methods" do
+
+ subject { Logger.new :ftp }
+
+ describe "#file" do
+ it 'returns the log file' do
+ file = double('file')
+ File.stub(:open).and_return file
+ subject.file.should be(file)
+ end
+ end
+
+ describe "#log" do
+ it 'logs a scanned service along with the scanner info' do
+ file = double('file')
+ now = Time.now
+ Time.stub(:now).and_return now
+ File.stub(:open).and_return file
+
+ expected_string = "\n#{time} FTP fake server recorded probes coming from hackerz.com:5978 containing the following:\n\t\t###EVILPROBE###"
+
+ subject.file.should_receive(:write)
+ .with expected_string
+
+ subject.log "###EVILPROBE###", "hackerz.com", 5978
+ end
+ end
+ end
+
+ end
+end
66 spec/micetrap/server_spec.rb
@@ -0,0 +1,66 @@
+require 'spec_helper'
+
+module Micetrap
+
+ module Services
+ class Test
+ end
+ end
+
+ describe Server do
+ describe "#initialize" do
+ it 'initializes the service' do
+ server = Server.new :service => :test
+ server.service.should be_a(Services::Test)
+ end
+ it 'assigns a custom port if given' do
+ server = Server.new :service => :test,
+ :port => 80
+ server.port.should be(80)
+ end
+ it 'assigns a new logger' do
+ server = Server.new :service => :test
+ server.logger.should be_a(Logger)
+ end
+
+ context 'when given an invalid service' do
+ it 'raises' do
+ expect {
+ Server.new :service => :foo
+ }.to raise_error(Services::UnrecognizedServiceException)
+ end
+ end
+ context 'when service is blank' do
+ it 'raises' do
+ expect {
+ Server.new :service => nil
+ }.to raise_error(StandardError, "Service cannot be empty!")
+ end
+ end
+ end
+
+ describe "#fire!" do
+ it 'fires the service' do
+ test_service = double('service')
+ Services::Test.should_receive(:new).and_return test_service
+ server = Server.new :service => :test
+ server.stub(:port).and_return 80
+ test_service.should_receive(:fire).with(80)
+
+ server.fire!
+ end
+ end
+
+ describe "#log" do
+ it 'delegates to its logger' do
+ test_service = double('service')
+ my_args = [1,2,3]
+ Services::Test.should_receive(:new).and_return test_service
+ server = Server.new :service => :test
+ server.logger.should_receive(:log).with(*my_args)
+
+ server.log(*my_args)
+ end
+ end
+ end
+end
17 spec/spec_helper.rb
@@ -0,0 +1,17 @@
+require 'bundler'
+begin
+ Bundler.setup(:default, :development)
+rescue Bundler::BundlerError => e
+ $stderr.puts e.message
+ $stderr.puts "Run `bundle install` to install missing gems"
+ exit e.status_code
+end
+$LOAD_PATH.unshift(File.dirname(__FILE__))
+$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+
+require 'micetrap'
+require 'rspec'
+
+# Requires supporting files with custom matchers and macros, etc,
+# in ./support/ and its subdirectories.
+Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
Please sign in to comment.
Something went wrong with that request. Please try again.