From cedb80ff7444ef1192ddd1137068f0f62420e74d Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 4 Jun 2015 16:21:22 -0700 Subject: [PATCH] implement quarantine --- scripts/base/frameworks/pacf/main.bro | 59 ++++++++++++++++++- .../openflow.log | 13 ++++ .../pacf.log | 18 ++++++ .../frameworks/pacf/quarantine-openflow.bro | 19 ++++++ 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/openflow.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log create mode 100644 testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index 3d5041661e..3ba941e4da 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -68,7 +68,7 @@ export { ## Returns: The id of the inserted rule on succes and zero on failure. global shunt_flow: function(f: flow_id, t: interval, location: string &default="") : string; - ## Allows all traffic involving a specific IP address from being forwarded. + ## Allows all traffic involving a specific IP address to be forwarded. ## ## a: The address to be whitelistet. ## @@ -79,6 +79,17 @@ export { ## Returns: The id of the inserted rule on succes and zero on failure. global whitelist_address: function(a: addr, t: interval, location: string &default="") : string; + ## Allows all traffic involving a specific IP subnet to be forwarded. + ## + ## s: The subnet to be whitelistet. + ## + ## t: How long to whitelist it, with 0 being indefinitly. + ## + ## location: An optional string describing whitelist was triddered. + ## + ## Returns: The id of the inserted rule on succes and zero on failure. + global whitelist_subnet: function(s: subnet, t: interval, location: string &default="") : string; + ## Redirects an uni-directional flow to another port. ## ## f: The flow to redirect. @@ -92,6 +103,21 @@ export { ## Returns: The id of the inserted rule on succes and zero on failure. global redirect_flow: function(f: flow_id, out_port: count, t: interval, location: string &default="") : string; + ## Quarantines a host by redirecting rewriting DNS queries to the network dns server dns + ## to the host. Host has to answer to all queries with its own address. Only http communication + ## from infected to quarantinehost is allowed. + ## + ## infected: the host to quarantine + ## + ## dns: the network dns server + ## + ## quarantine: the quarantine server running a dns and a web server + ## + ## t: how long to leave the quarantine in place + ## + ## Returns: Vector of inserted rules on success, empty list on failure. + global quarantine_host: function(infected: addr, dns: addr, quarantine: addr, t: interval, location: string) : vector of string; + ## Flushes all state. global clear: function(); @@ -358,6 +384,14 @@ function whitelist_address(a: addr, t: interval, location: string &default="") : return add_rule(r); } +function whitelist_subnet(s: subnet, t: interval, location: string &default="") : string + { + local e: Entity = [$ty=ADDRESS, $ip=s]; + local r: Rule = [$ty=WHITELIST, $priority=whitelist_priority, $target=FORWARD, $entity=e, $expire=t, $location=location]; + + return add_rule(r); + } + function shunt_flow(f: flow_id, t: interval, location: string &default="") : string { local flow = Pacf::Flow( @@ -386,6 +420,29 @@ function redirect_flow(f: flow_id, out_port: count, t: interval, location: strin return add_rule(r); } +function quarantine_host(infected: addr, dns: addr, quarantine: addr, t: interval, location: string &default="") : vector of string + { + local orules: vector of string = vector(); + local edrop: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected))]; + local rdrop: Rule = [$ty=DROP, $target=FORWARD, $entity=edrop, $expire=t, $location=location]; + orules[|orules|] = add_rule(rdrop); + + local todnse: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected), $dst_h=addr_to_subnet(dns), $dst_p=53/udp)]; + local todnsr = Rule($ty=MODIFY, $target=FORWARD, $entity=todnse, $expire=t, $location=location, $mod=FlowMod($dst_h=quarantine), $priority=+5); + orules[|orules|] = add_rule(todnsr); + + local fromdnse: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(dns), $src_p=53/udp, $dst_h=addr_to_subnet(infected))]; + local fromdnsr = Rule($ty=MODIFY, $target=FORWARD, $entity=fromdnse, $expire=t, $location=location, $mod=FlowMod($src_h=dns), $priority=+5); + orules[|orules|] = add_rule(fromdnsr); + + local wle: Entity = [$ty=FLOW, $flow=Flow($src_h=addr_to_subnet(infected), $dst_h=addr_to_subnet(quarantine), $dst_p=80/tcp)]; + local wlr = Rule($ty=WHITELIST, $target=FORWARD, $entity=wle, $expire=t, $location=location, $priority=+5); + orules[|orules|] = add_rule(wlr); + + return orules; + } + + # Low-level functions that only runs on the manager (or standalone) Bro node. function activate_impl(p: PluginState, priority: int) diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/openflow.log new file mode 100644 index 0000000000..1b4081a31d --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/openflow.log @@ -0,0 +1,13 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2015-06-04-23-21-03 +#fields ts dpid match.in_port match.dl_src match.dl_dst match.dl_vlan match.dl_vlan_pcp match.dl_type match.nw_tos match.nw_proto match.nw_src match.nw_dst match.tp_src match.tp_dst flow_mod.cookie flow_mod.table_id flow_mod.command flow_mod.idle_timeout flow_mod.hard_timeout flow_mod.priority flow_mod.out_port flow_mod.out_group flow_mod.flags flow_mod.actions.out_ports flow_mod.actions.vlan_vid flow_mod.actions.vlan_pcp flow_mod.actions.vlan_strip flow_mod.actions.dl_src flow_mod.actions.dl_dst flow_mod.actions.nw_tos flow_mod.actions.nw_src flow_mod.actions.nw_dst flow_mod.actions.tp_src flow_mod.actions.tp_dst +#types time count count string string count count count count count subnet subnet count count count count enum count count count count count count vector[count] count count bool string string count addr addr count count +1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511108 - OpenFlow::OFPFC_ADD 0 36000 0 - - 1 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - 17 10.10.1.4/32 8.8.8.8/32 - 53 4398046511110 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - - 192.169.18.1 - - +1254722767.875996 42 - - - - - 2048 - 17 8.8.8.8/32 10.10.1.4/32 53 - 4398046511112 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - 8.8.8.8 - - - +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 192.169.18.1/32 - 80 4398046511114 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - - - - - +#close 2015-06-04-23-21-03 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log new file mode 100644 index 0000000000..0bcb99fd48 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-06-04-23-18-56 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->*/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->8.8.8.8/32/53 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 8.8.8.8/32/53->10.10.1.4/32/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->192.169.18.1/32/80 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->*/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->8.8.8.8/32/53 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 8.8.8.8/32/53->10.10.1.4/32/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->192.169.18.1/32/80 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +#close 2015-06-04-23-18-56 diff --git a/testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro b/testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro new file mode 100644 index 0000000000..eff863b684 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro @@ -0,0 +1,19 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff pacf.log +# @TEST-EXEC: btest-diff openflow.log + +@load base/frameworks/pacf + +global of_controller: OpenFlow::Controller; + +event bro_init() + { + of_controller = OpenFlow::log_new(42); + local pacf_of = Pacf::create_openflow(of_controller); + Pacf::activate(pacf_of, 0); + } + +event connection_established(c: connection) + { + Pacf::quarantine_host(c$id$orig_h, 8.8.8.8, 192.169.18.1, 10hrs); + }