bsd.rb 2.56 KB
Newer Older
1 2 3 4 5 6 7
# encoding: UTF-8
=begin

BETTERCAP

Author : Simone 'evilsocket' Margaritelli
Email  : evilsocket@gmail.com
Sophie Brun's avatar
Sophie Brun committed
8
Blog   : https://www.evilsocket.net/
9 10 11 12 13 14 15 16 17

This project is released under the GPL 3 license.

=end

module BetterCap
module Firewalls
# *BSD and OSX Firewall class.
class BSD < Base
Sophie Brun's avatar
Sophie Brun committed
18 19 20 21
  def initialize
    @filename = "/tmp/bettercap_pf_#{Process.pid}.conf"
  end

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
  # If +enabled+ is true will enable packet forwarding, otherwise it will
  # disable it.
  def enable_forwarding(enabled)
    Shell.execute("sysctl -w net.inet.ip.forwarding=#{enabled ? 1 : 0}")
  end

  # If +enabled+ is true will enable packet icmp_echo_ignore_broadcasts, otherwise it will
  # disable it.
  def enable_icmp_bcast(enabled)
    Shell.execute("sysctl -w net.inet.icmp.bmcastecho=#{enabled ? 1 : 0}")
  end

  # Return true if packet forwarding is currently enabled, otherwise false.
  def forwarding_enabled?
    Shell.execute('sysctl net.inet.ip.forwarding').strip.split(' ')[1] == '1'
  end

  # This method is ignored on OSX.
  def enable_send_redirects(enabled); end

  # If +enabled+ is true, the PF firewall will be enabled, otherwise it will
  # be disabled.
  def enable(enabled)
45 46
    Shell.execute("pfctl -#{enabled ? 'e' : 'd'} >/dev/null 2>&1")
  rescue
47 48 49 50 51
  end

  # Apply the +r+ BetterCap::Firewalls::Redirection port redirection object.
  def add_port_redirection( r )
    # create the pf config file
Sophie Brun's avatar
Sophie Brun committed
52 53
    File.open( @filename, 'a+t' ) do |f|
      f.write "#{gen_rule(r)}\n"
54 55
    end
    # load the rule
Sophie Brun's avatar
Sophie Brun committed
56
    Shell.execute("pfctl -f #{@filename} >/dev/null 2>&1")
57 58 59 60 61 62
    # enable pf
    enable true
  end

  # Remove the +r+ BetterCap::Firewalls::Redirection port redirection object.
  def del_port_redirection( r )
Sophie Brun's avatar
Sophie Brun committed
63 64 65 66
    # remove the redirection rule from the existing file
    rule = gen_rule(r)
    rules = File.readlines(@filename).collect(&:strip).reject(&:empty?)
    rules.delete(rule)
67

Sophie Brun's avatar
Sophie Brun committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81
    # no other rules, delete file and disable firewall.
    if rules.empty?
      File.delete(@filename)
      enable false
    # other rules are present in the file, update it
    else
      File.open( @filename, 'w+t' ) do |f|
        rules.each do |rule|
          f.write "#{rule}\n"  
        end
      end
      # let the firewall know we updated the file
      Shell.execute("pfctl -f #{@filename} >/dev/null 2>&1")
    end
82
  rescue
83
  end
Sophie Brun's avatar
Sophie Brun committed
84 85 86 87 88 89 90 91 92 93

  private

  # Convert +r+ to BSD firewall rule
  def gen_rule( r )
    "rdr pass on #{r.interface} " +
      "proto #{r.protocol} " +
      "from any to #{r.src_address.nil? ? 'any' : r.src_address} " +
      "port #{r.src_port} -> #{r.dst_address} port #{r.dst_port}"
  end
94 95 96
end
end
end