Triangulate A Phone's Location Using Python
How to approximately triangulate a phone's location using Python.
Hello there!
This tutorial will teach you how to approximately triangulate a phone's location using Python, GSM modem (and a computer lol).
Requirements
- Python 3 installed
- pygsm smpplib geopy Python Packages
- GSM Modem
Install Dependencies
We can install the dependencies using pip, python's package manager.
pip install smpplib geopy
Install pygsm
pip install git+https://github.com/adammck/pygsm.git
Sending a "silent" SMS
A silent SMS, also known as a stealth SMS, ping SMS, or Type 0 SMS, is a special type of text message that is sent to a mobile phone but does not alert the recipient in any way. These messages are invisible to the user as they do not produce any notification sound, vibration, or display a message on the screen.
import smpplib.client
import smpplib.gsm
import smpplib.consts
def send_silent_sms(target_number, message=""):
client = smpplib.client.Client("localhost", 2775)
client.set_message_sent_handler(
lambda pdu: sys.stdout.write('sent {} {}\n'.format(pdu.sequence, pdu.message_id)))
)
client.connect()
client.bind_transmitter(system_id="username", password="password")
message_parts, encoding, esm_class = smpplib.gsm.make_parts(message)
for part in message_parts:
pdu = client.send_message(
source_addr_ton=smpplib.consts.SMPP_TON_ALNUM,
source_addr_npi=smpplib.consts.SMPP_NPI_UNK,
source_addr="SilentSMS",
dest_addr_ton=smpplib.consts.SMPP_TON_INTL,
dest_addr_npi=smpplib.consts.SMPP_NPI_ISDN,
destination_addr=target_number,
short_message=part,
data_coding=encoding,
esm_class=esm_class,
registered_delivery=True,
)
print(f'PDU: {pdu.sequence}')
client.unbind()
client.disconnect()
# Replace with your phone number (country code + phone number)
send_silent_sms("+1234567890")
Process SMS Data
Now we need a code that would process the data we get back.
import pygsm
def process_received_sms(modem):
while True:
sms = modem.next_message()
if sms is None:
continue
print(f"Received: {sms}")
# Process the SMS data here
process_sms_data(sms)
def process_sms_data(sms):
# Extract relevant information from the SMS
# This is where you'd implement your specific processing logic
# Example: print the sender and message content
print(f"Sender: {sms.sender}")
print(f"Message: {sms.text}")
# Set up the GSM modem
try:
modem = pygsm.GsmModem(port="/dev/ttyUSB0", baudrate=115200)
modem.connect()
print("Modem connected successfully.")
# Start processing received messages
process_received_sms(modem)
except Exception as e:
print(f"Error: {e}")
finally:
modem.disconnect()
print("Modem disconnected.")
Basic Triangulation Code
Now we need to find some celltowers in our area & copy their coordinates.
from geopy import distance
def triangulate(tower1, tower2, tower3, dist1, dist2, dist3):
"""
Basic triangulation using three cell towers.
tower1, tower2, tower3 are tuples of (latitude, longitude)
dist1, dist2, dist3 are distances from each tower to the target
"""
def get_third_point(p1, d1, p2, d2):
# Calculate the two possible points
bearing = distance.distance(kilometers=d1).destination(p1, 0)
c1 = distance.distance(kilometers=d2).destination(p2, bearing)
c2 = distance.distance(kilometers=d2).destination(p2, bearing + 180)
return c1, c2
# Get two possible points from the first two towers
c1, c2 = get_third_point(tower1, dist1, tower2, dist2)
# Check which point is closer to the third tower
if abs(
distance.distance(c1, tower3).kilometers - dist3
) < abs(
distance.distance(c2, tower3).kilometers - dist3
):
return c1
else:
return c2
# Example usage
tower1 = (40.7128, -74.0060) # New York
tower2 = (34.0522, -118.2437) # Los Angeles
tower3 = (41.8781, -87.6298) # Chicago
dist1 = 100 # km
dist2 = 200 # km
dist3 = 150 # km
estimated_location = triangulate(tower1, tower2, tower3, dist1, dist2, dist3)
print(f"Estimated location: {estimated_location}")
Put it all together!
Here's the final code:
import threading
import time
def main():
# Set up the GSM modem
modem = pygsm.GsmModem(port="/dev/ttyUSB0", baudrate=115200)
modem.connect()
# Start a thread for processing received messages
receive_thread = threading.Thread(target=process_received_sms, args=(modem,))
receive_thread.start()
# Main loop for sending Silent SMS and performing triangulation
while True:
target_number = "+1234567890" # Replace with actual target number
send_silent_sms(target_number)
time.sleep(60) # Wait for 60 seconds before next ping
# Perform triangulation (assuming you have the necessary data)
# estimated_location = triangulate(tower1, tower2, tower3, dist1, dist2, dist3)
# print(f"Estimated location: {estimated_location}")
# Clean up
receive_thread.join()
modem.disconnect()
if __name__ == "__main__":
main()
NOTE: This code is a simplified version made for educational purposes. A real-world implementation would require better error handling, secure communication protocols, and actual cellular network infrastructure integration.