Tracking a stolen laptop…

To track an eventually stolen laptop, I try to set it up to periodically send a security e-mail to myself.
This should happen as invisible and with the least intervention possible.
The following script assembles a message containing (thanks to jj!) the machine’s SN and current WAN IP number.
How could that be sent, regardless the kind of e-mail client, and without user intervention…?

set the_sn to text 2 thru -2 of (do shell script "ioreg -l | grep serial-number | awk '{print $4}'")
set {t, IPnr} to {do shell script "curl -s http://checkip.dyndns.org/ | grep 62 | awk '{print $6}'", ""}
repeat with i in characters of t
	if "<" is in (i as string) then exit repeat
	set IPnr to IPnr & i
end repeat
repeat
	set inputText to (the_sn as Unicode text)
	set exitOK to true
	if (inputText's length) mod 2 ≠ 0 then inputText to "0" & inputText
	set hexchars to "0123456789ABCDEFabcdef"
	copy inputText to temp
	repeat with i in inputText
		if (offset of i in hexchars) = 0 then
			set exitOK to false
			exit repeat
		end if
	end repeat
	if exitOK then
		exit repeat
	else
		display dialog "Invalid data!" & return & return & "You must enter an even quantity of hex digits..." with icon stop buttons "OK" default button 1
	end if
end repeat

set rr to my hextoString(inputText)
set sn to ""
repeat with i from 1 to count of characters of rr
	if character i of rr is in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" then set sn to (sn & character i of rr) as string
end repeat
set cpu_name to do shell script "hostname | awk -F. '{print $1}'"
open location ("mailto:abc@def.net?subject=StatusMsg?body=" & cpu_name & "__" & sn & "__now_at__" & IPnr) as string

on hextoString(t)
	set z to ""
	repeat with i from 1 to t's length by 252
		try
			set z to z & (run script "«data cstr" & ¬
				text from character i of t to character (i + 251) of t & "00» as string")
		on error
			set z to z & (run script "«data cstr" & ¬
				text from character i of t to character -1 of t & "00» as string")
		end try
	end repeat
	z
end hextoString

Hi Eelco,

some “shortcuts” to get the machine informations (with Panther and Tiger):

set WAN_ip to word -7 of (do shell script "curl http://checkip.dyndns.org") -- Tiger
set WAN_ip to word -6 of (do shell script "curl http://checkip.dyndns.org") -- Panther (I don't know why, it's the same command)
set serial_number to word -1 of (do shell script "ioreg -l | grep IOPlatformSerialNumber")
set host_name to do shell script "uname -n" -- Bonjour name 

PS: Probably it’s possible to send the mail with the UNIX mail program, hope this helps:
http://www.helpdesk.umd.edu/documentation/unix/mail.shtml

hi eelco,

i agree with stephan that you’d be well served by the built in mail program, but i think one problem you may run into is how to find an email server that will forward your email along the line (SMTP server). what you may need to look into is a DNS query, specifically for MX (mail exchange) records for whatever location the laptop is in and then use that information to send an email.

i’ll look into this a bit later and see if i can suggest some specifics. it’s a difficult problem.

cheers.

NOTE: there must be some way to do it as there is software already made to accomplish this. it’s worth checking out, i suppose:

http://homepage.mac.com/sweetcocoa/lapcop/

EDITED to add: this program sends an email whenever the network settings change–Clever!

SECOND EDIT: here’s another. may be associated with the one above:

http://orbicule.com/undercover/

apparently this one will simulate a hardware failure if it is stolen and can’t send the email.

THIRD EDIT: apparently there are a TON of these out here. this website lists some. there are some good ideas in here also:

http://contactsheet.org/articles/2004/02/26/computer_crimes_of_another_kind.html

i particularly like the idea of using a web browser to access a unique page or using wget before the system even boots up completely.

cheers.

I like the original idea a lot. The way I envision setting it up is by creating a guest login option that doesn’t require a password. A startup program for this account would then execute the above script. As the thief is likely to try various login options with only one not requiring a password I think this might work perfectly (especially when it is named ‘guest’). As I don’t know how to script unix mail as well, a bit of help would be appreciated. Or did Eelco find a way to do that already? Additionally, wouldn’t it be great to have iSight make a snapshot and attach that to the email (no clue how to do that either)

As for the abovementioned mail server problem, wouldn’t it be easiest to use an provider-independent SMTP server, like Gmail?

PS. Eelco, are you a fellow Dutchie?

Stadsman,

Yep, I am!
(not from Amsterdam anymore, so the issue is slightly less pertinent…)
However, I found the way to use Unix sendmail that does work for me.
Did not check if it also works from a new (clean) account, though.


set WAN_ip to word -7 of (do shell script "curl http://checkip.dyndns.org") -- Tiger
set sn to word -1 of (do shell script "ioreg -l | grep IOPlatformSerialNumber")
set host_name to do shell script "uname -n  | awk -F.  '{print $1}'" -- Bonjour name 

send_mail_sbr("Status of " & host_name, ("At " & (current date) & return & host_name & " (" & sn & ") was at " & WAN_ip), "yourname@yourISP.com")

do shell script "sleep 2"
tell application "System Events" to keystroke return -- to eventually "OK" Little Snitch outgoing

on send_mail_sbr(subj, body, addr)
	do shell script ("echo \"" & body & "\" | mail -s \"" & subj & "\" " & addr)
end send_mail_sbr

Te camera idea is OK, you may take a look for the shell script at:
http://slappingturtle.com/home/index.php?option=com_content&task=view&id=20&Itemid=1
I am interested if the camera lamp remains dimmed, though.

Hi,

a similar CLI is isightcapture
http://www.intergalactic.de/hacks.html

I already found iSightCaptur too :slight_smile: and came up with the following script which seems to work fine here.
If only I could keep Mail.app hidden throughout the process…

-- This script sends an email to a specified address either through Unix mail or through Mail.app (or you can use both too)
-- When using Mail.app, an iSight image capture will be added as attachment
-- This script requires iSightCapture which can be downloaded from http://www.intergalactic.de/hacks.html
-- For this to work, the script requires that the shell script 'iSightCapture' to be located in the same folder as the script
-- This script must be saved as an application to work properly


set WAN_ip to word -7 of (do shell script "curl http://checkip.dyndns.org") -- Tiger
set Serial_Number to word -1 of (do shell script "ioreg -l | grep IOPlatformSerialNumber")
set host_name to do shell script "uname -n  | awk -F.  '{print $1}'" -- Bonjour name 
set theName to "John Doe" -- change to whatever name
set theAddress to "john.doe@provider.com" -- change to preferred email address 
set theSubject to "Status of " & host_name -- change as preferred
set theBody to "At " & (current date) & return & host_name & " (" & Serial_Number & ") was at IP address " & WAN_ip
set theSender to "jane.doe@provider.com" -- change to preferred email address

tell application "Finder"
	set thePath to container of (path to me) as string
	set theAttachment to thePath & "isightimage.jpg"
	set shPath to POSIX path of thePath
end tell


--send email through Unix mail; doesn't attach iSight capture
do shell script ("echo \"" & theBody & "\" | mail -s \"" & theSubject & "\" " & theAddress)
do shell script "sleep 2"
tell application "System Events" to keystroke return -- to "OK" Little Snitch outgoing in case it is installed


--send email through Mail.app; includes iSight photo as attachment
do shell script "cd " & shPath & "; ./isightcapture isightimage.jpg" -- Take iSight photo

tell application "Mail"
	set newMessage to make new outgoing message with properties {subject:theSubject, content:theBody & return & return}
	tell newMessage
		set visible to false
		set sender to theSender
		make new to recipient at end of to recipients with properties {name:theName, address:theAddress}
		tell content to make new attachment with properties {file name:theAttachment as alias} at after the last paragraph
	end tell
	send newMessage
end tell

Stadsman,

To include attachments in Unix mail you may check:
http://www.panix.com/~kylet/unix-att.html

(rather than me, not being a Unix guy.)

I had been looking into a Unix mail attachment solution as well, unfortunately I think that the Unix program(s?) under OSX do not support this.

hi stadsman,

while i do think you could mail an attachment, it seems complicated. however, nothing is stopping you from sending an email and then following up with a “put” FTP command to a write only drop box for the screenshot. a good solution might include attempts to use multiple services in case of firewall blockage. perhaps a file could be sent to a .mac account…

cheers.

After some experiments based on the existing iSight snap script, it works. What I tried:


do shell script ("UUencode " & fpath & " | sendmail  " & addr)

→ the iSight picture was sent. However, the attachment received is only 0.1 kB and cannot be decoded with uudecode in Terminal.


do shell script ("uuencode " & quoted form of fpath & " jpg.sit  | mail -s \"" & subj & "\" " & addr)

→ attachment can not be decoded by either Stuffit (format unrecognized) or uudecode (“Does not start with “Begin””)

However:


do shell script ("uuencode " & quoted form of fpath & " x.jpg  | mail -s \"" & subj & "\" " & addr)

→ Mail attachment now indeed is the iSight snapshot, 43kB x.jpg readable in Preview, it apparently never got uunencoded or Stuffed anyway. The picture is quite dark though (making myself an even better suspect than intended :wink:

This is on a plain OSX 10.4.8 machine with no Unix frills - apart from Apple’s.

It did get uuencoded, but most email programs are capable of decoding it on the fly.

Just solved my last hurdle with help from Kel.

Here is my latest script. Though it’s not needed at all, I left in the Mail.app routine, just in case someone likes to use it.

The script sends an email through Unix containing both a logentry and a uuencoded snapshit from iSight. For most email programs uuencoded files is not a problem, they often automatically decode them so it seems as if the image is an attachment. There are probably some smarter routines to use, but for me this works as I want it too.

The main features:

  • checks whether an internet connection is available, if not, just logs the time and location
  • if connected, takes a pic from iSight, logs the location and time and sends this by emaill to specified address (using either Unix mail or Mail.app). Time and location are also logged on the computer
  • once sent, the culprit/finder gets to see himself in preview, a warning is read out and appears on screen.
  • if (s)he clicks OK on last dialogue box, an email to the owner is generated for a save return

(Edit: cleaned it up quite a bit)

-- This script sends an email to a specified address either through Unix mail or through Mail.app (or you can use both too)
-- This script requires iSightCapture which can be downloaded from http://www.intergalactic.de/hacks.html
-- For this to work, the script requires that the shell script 'iSightCapture' to be located in the same folder as the script
-- This script must be saved as an application to work properly
-- You can use this script to track the theft of your laptop
-- I suggest to create a login account "guest" without password protection and use the script as a startup program for that login account
-- For the Mail.app script it is necessary that a working mail aount has been set up for the user


-- Change these variable to fit your needs
property UseMailApp : false -- if True, both Apple Mail and Unix mail will be used. If False, only Unix mail will be used
property ShowPicPreview : false -- if True, a preview of the image will be shown to the 'finder' of the computer
property ShowWarning : false -- If True an audio warning will be displayed and a warning message appears on screen
property PrepareMail : false -- if True, an email message to you from the lost computer willl be prepared.
property WAN_ip : word -7 of (do shell script "curl http://checkip.dyndns.org") -- Tiger
property Serial_Number : word -1 of (do shell script "ioreg -l | grep IOPlatformSerialNumber")
property host_name : do shell script "uname -n  | awk -F.  '{print $1}'" -- Bonjour name 
property theName : "John Doe" -- change to whatever name
property theAddress : "john.doe@provider.com" -- change to preferred email address 
property theSubject : "Status of " & host_name -- Header for mail message; change as preferred
property theMessage : "At " & (current date) & return & host_name & " (" & Serial_Number & ") was located at IP address " & WAN_ip -- Body for mail message
property theSender : "john.doe@provider.com" -- change to preferred email address
property AlertMessage : "A picture of you was made and the location of this Macintosh has been recorded. These were sent to a central location. Please return this Macintosh to its owner. A finder's fee will be given to you in return. If not, the police will be alerted" as string --Any text here
property Found_Header : "Found your computer" -- header text for email from finder
property Found_Body : "I have found your computer and would like to make sure you get it back safely. Please contact me at (insert contact infomation)."
property TheReturnKey : ASCII character 13
global thePath
global PosixPath

--log all events in eventlog.txt
tell application "Finder"
	set thePath to container of (path to me) as string
	set PosixPath to POSIX path of thePath
	set MessageEntry to theMessage & TheReturnKey
	do shell script "echo " & quoted form of MessageEntry & " >> " & quoted form of PosixPath & "eventlog.txt"
end tell


-- Test connection status; if not connected script won't run
set testIP to chkUP("http://www.apple.com") or chkUP("http://www.google.com")
if testIP then
	SendAlert()
end if

to chkUP(theURL)
	return (count (get ((theURL as URL)'s host & {dotted decimal form:""})'s dotted decimal form)) > 0
end chkUP

-- The actual alert script
on SendAlert()
	tell application "Finder"
		set thePath to container of (path to me) as string
		set theAttachment to thePath & "isightimage.jpg"
		set old_Image to thePath & "isightimage.jpg"
		if exists file old_Image then
			do shell script "rm " & PosixPath & "isightimage.jpg"
		end if
		set old_Event to thePath & "concat.txt"
		if exists file old_Event then
			do shell script "rm " & PosixPath & "concat.txt"
			do shell script "touch " & PosixPath & "concat.txt"
		end if
	end tell
	
	
	do shell script "cd " & PosixPath & "; ./isightcapture isightimage.jpg" -- Take iSight photo	

	set LogEntry to theMessage & TheReturnKey & TheReturnKey
	
	--send email through Unix mail
	do shell script "uuencode -o " & PosixPath & "camcapture.jpg " & PosixPath & "isightimage.jpg camcapture.jpg" --encodes the image for Unix mail
	do shell script ("echo " & quoted form of LogEntry & " >> " & quoted form of PosixPath & "concat.txt")
	do shell script ("cat " & quoted form of PosixPath & "camcapture.jpg >> " & quoted form of PosixPath & "concat.txt")
	do shell script ("cat " & quoted form of PosixPath & "concat.txt" & " | mail -s \"" & theSubject & "\" " & theAddress)
	do shell script "sleep 2"
	tell application "System Events" to keystroke return -- to "OK" Little Snitch outgoing in case it is installed
	
	if UseMailApp is true then MailApp()
	if ShowPicPreview is true then ShowPreview()
	if ShowWarning is true then ShowAlert()
	if PrepareMail is true then MailHome()
end SendAlert


-- send email through Mail.app; includes iSight photo as attachment
on MailApp()
	tell application "Mail"
		set newMessage to make new outgoing message with properties {subject:theSubject, content:theMessage & return & return}
		tell newMessage
			set visible to false
			set sender to theSender
			make new to recipient at end of to recipients with properties {name:theName, address:theAddress}
			tell content to make new attachment with properties {file name:theAttachment as alias} at after the last paragraph
		end tell
		send newMessage
	end tell
end MailApp

--Shows the captured image in Preview on screen
on ShowPreview()
	tell application "Preview"
		activate
		open theAttachment as alias
	end tell
end ShowPreview

--alert the finder/culprit that information and a picture was sent to a central location"
on ShowAlert()
	say AlertMessage
	display dialog AlertMessage
end ShowAlert


-- Predefines an email to be sent to the owner by the finder
on MailHome()
	tell application "Mail"
		set newMessage to make new outgoing message with properties {subject:Found_Header, content:Found_Body & return & return}
		tell newMessage
			set visible to true
			make new to recipient at end of to recipients with properties {name:theName, address:theAddress}
		end tell
		activate
	end tell
end MailHome

Edit: cleaned it up quite a bit

Sorry to dig up an old thread.

I am currently in the middle of doing this myself and the easiest way I found to send an email is php. If you work for a company they likely have a web server running php so you can easily have a txt file containing the serials of all the stolen laptops and have curl read it like so:

do shell script "curl http://www.website.com/stolen.txt

read out each paragraph and if the serial variable is in there then have it collect system information & post it to a php page on the same web server ie:

do shell script "curl [url=http://www.website.com/theftmail.php?ip=]http://www.website.com/theftmail.php?ip="[/url] & _ip

adding in as many variables as you want.

<?php
//gets the variables passed from the URL
$mac = $_GET ['MAC']; 
$ip = $_GET['ip']; 
$anc = $_GET['anc'];
$serial = $_GET['serial']; 
$hostname = $_GET['hostname'];
$vip = $_SERVER['REMOTE_ADDR'];

// mail function
$to = "me@website.com";
$subject = "Stolen Laptop Recovery System";
$message = "The following information has been emailed to you because the laptop with serial number " . $serial . " has been found in the database of stolen Laptops \n
The machines ethernet mac address is: " . $mac . "\n
The machines current external IP address according to dydns.com is: " . $ip . "\n
The machines active network connection is: " . $anc . "\n
The machines serial number is: " . $serial . "\n
The machines hostname is: " .$hostname . "\n
The machines current external IP address according to visitor IP lookup is: " . $vip ;

$from = "me@website.com";
mail($to,$subject,$message);

// prints it on the webpage if visited
echo "The following information has been emailed to you because the laptop with serial number " . $serial . " has been found in the database of stolen Laptops \n
The machines ethernet mac address is: " . $mac . "\n
The machines current external IP address according to dydns.com is: " . $ip . "\n
The machines active network connection is: " . $anc . "\n
The machines serial number is: " . $serial . "\n
The machines hostname is: " .$hostname . "\n
The machines current external IP address according to visitor IP lookup is: " . $vip ;
?> 

this is 100% silent and doesn’t require you to setup any mail functions and it also has the added benifit of being able to use the $vip = $_SERVER[‘REMOTE_ADDR’]; which gives you their external ip address without having to query dydns.org and read it out form the html.

Hope this helps someone and if anyone wants a copy of my finished thing feel free to contact me

Dave Maltby