summaryrefslogtreecommitdiffstats
path: root/scripts/http-icloud-findmyiphone.nse
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/http-icloud-findmyiphone.nse')
-rw-r--r--scripts/http-icloud-findmyiphone.nse87
1 files changed, 87 insertions, 0 deletions
diff --git a/scripts/http-icloud-findmyiphone.nse b/scripts/http-icloud-findmyiphone.nse
new file mode 100644
index 0000000..beed634
--- /dev/null
+++ b/scripts/http-icloud-findmyiphone.nse
@@ -0,0 +1,87 @@
+local mobileme = require "mobileme"
+local datetime = require "datetime"
+local stdnse = require "stdnse"
+local tab = require "tab"
+
+description = [[
+Retrieves the locations of all "Find my iPhone" enabled iOS devices by querying
+the MobileMe web service (authentication required).
+]]
+
+---
+-- @usage
+-- nmap -sn -Pn --script http-icloud-findmyiphone --script-args='username=<user>,password=<pass>'
+--
+-- @output
+-- Pre-scan script results:
+-- | http-icloud-findmyiphone:
+-- | name location accuracy date type
+-- | Patrik Karlsson's MacBook Air -,- - - -
+-- | Patrik Karlsson's iPhone 40.690,-74.045 65 04/10/12 16:56:37 Wifi
+-- |_ Mac mini 40.690,-74.045 65 04/10/12 16:56:36 Wifi
+--
+-- @args http-icloud-findmyiphone.username the Apple Id username
+-- @args http-icloud-findmyiphone.password the Apple Id password
+--
+
+author = "Patrik Karlsson"
+license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
+categories = {"discovery", "safe", "external"}
+
+
+local arg_username = stdnse.get_script_args(SCRIPT_NAME .. ".username")
+local arg_password = stdnse.get_script_args(SCRIPT_NAME .. ".password")
+
+prerule = function() return true end
+
+-- decode basic UTF8 encoded strings
+-- iOS devices are commonly named after the user eg:
+-- * Patrik Karlsson's Macbook Air
+-- * Patrik Karlsson's iPhone
+--
+-- This function decodes the single quote as a start and should really
+-- be replaced with a proper UTF-8 decoder in the future
+local function decodeString(str)
+ return str:gsub("\226\128\153", "'")
+end
+
+local function fail(err) return stdnse.format_output(false, err) end
+
+action = function()
+
+ if ( not(arg_username) or not(arg_password) ) then
+ return fail("No username or password was supplied")
+ end
+
+ local mobileme = mobileme.Helper:new(arg_username, arg_password)
+ local status, response = mobileme:getLocation()
+
+ if ( not(status) ) then
+ stdnse.debug2("%s", response)
+ return fail("Failed to retrieve location information")
+ end
+
+ local output = tab.new(4)
+ tab.addrow(output, "name", "location", "accuracy", "date", "type")
+ for name, info in pairs(response) do
+ local loc
+ if ( info.latitude and info.longitude ) then
+ loc = ("%.3f,%.3f"):format(
+ tonumber(info.latitude) or "-",
+ tonumber(info.longitude) or "-")
+ else
+ loc = "-,-"
+ end
+ local ts
+ if ( info.timestamp and 1000 < info.timestamp ) then
+ ts = datetime.format_timestamp(info.timestamp//1000)
+ else
+ ts = "-"
+ end
+ tab.addrow(output, decodeString(name), loc, info.accuracy or "-", ts, info.postype or "-")
+ end
+
+ if ( 1 < #output ) then
+ return stdnse.format_output(true, tab.dump(output))
+ end
+end