connect7: Rewrite ShellExecute code for bypassing Windows Defender

main
remittor 1 day ago
parent fa53d71028
commit 7518d5d084

@ -59,80 +59,18 @@ def is_root():
else:
raise RuntimeError('Unsupported os: {!r}'.format(os.name))
if os.name != 'nt':
winapi = None
else:
from ctypes.wintypes import *
windll = ctypes.windll
WinError = ctypes.WinError
get_last_error = ctypes.get_last_error
class winapi:
class SHELLEXECUTEINFO(ctypes.Structure):
_fields_ = [
('cbSize', DWORD),
('fMask', ULONG),
('hwnd', HWND),
('lpVerb', LPCWSTR),
('lpFile', LPCWSTR),
('lpParameters', LPCWSTR),
('lpDirectory', LPCWSTR),
('nShow', ctypes.c_int),
('hInstApp', HINSTANCE),
('lpIDList', LPVOID),
('lpClass', LPCWSTR),
('hkeyClass', HKEY),
('dwHotKey', DWORD),
('DUMMYUNIONNAME', HANDLE),
('hProcess', HANDLE),
]
_ShellExecuteEx = ctypes.windll.shell32.ShellExecuteExW
_ShellExecuteEx.restype = BOOL
_ShellExecuteEx.argtypes = [ ctypes.POINTER(SHELLEXECUTEINFO) ]
SW_HIDE = 0
SW_SHOW = 5
@staticmethod
def ShellExecuteEx(file, params, directory, verb = None, show = SW_SHOW, mask = 0, hwnd = None):
data = winapi.SHELLEXECUTEINFO()
data.cbSize = ctypes.sizeof(data)
data.fMask = mask
data.hwnd = hwnd
data.lpVerb = verb if verb else None
data.lpFile = file
data.lpParameters = params
data.lpDirectory = directory
data.nShow = show
data.hInstApp = None
data.lpIDList = None
data.lpClass = None
data.hkeyClass = None
data.dwHotKey = 0
data.DUMMYUNIONNAME = None
data.hProcess = None
rc = winapi._ShellExecuteEx(ctypes.byref(data))
if not rc:
raise WinError(get_last_error())
return { 'hInstApp': data.hInstApp, 'hProcess': data.hProcess }
def get_firewall_rule(rule_name):
cmd = [ 'netsh.exe', 'advfirewall', 'firewall', 'show', 'rule', f'name={rule_name}' ]
res = subprocess.run(cmd, capture_output = True, text = True, encoding = 'utf-8', errors = "replace")
return res.stdout if res else None
def add_firewall_rule(rule_name, program):
import base64
import shexec
exename = 'netsh.exe'
params = f'advfirewall firewall add rule name={rule_name} dir=in action=allow "program={program}" enable=yes protocol=TCP'
try:
res = winapi.ShellExecuteEx(
file = 'netsh.exe',
params = f'advfirewall firewall add rule name={rule_name} dir=in action=allow "program={program}" enable=yes protocol=TCP',
directory = None,
verb = base64.b64decode( 'cnVu0XM='.replace('0', 'Y') ).decode(), # decoding RUNAS
mask = 0x40,
show = winapi.SW_HIDE
)
print(f'Rule "{rule_name}" added to Firewal settings')
res = shexec.run(exename, params, directory = None)
print(f'Rule "{rule_name}" added to Firewall settings')
return res
except OSError as e:
print('ERROR: cannot execute NETSH.EXE')
@ -161,7 +99,8 @@ if os.name == 'nt':
rule_name = gen_rule_name(srv_fw_rule, rule_app)
txt = get_firewall_rule(rule_name)
if not txt or f' {rule_name}\n' not in txt:
print('WARN: Firewall rule for XMiR not founded! Try add new rule to Windows Firewall...')
print('WARN: Firewall rule for XMiR-Patcher not founded!')
print('INFO: Try add new rule to Windows Firewall...')
add_firewall_rule(rule_name, rule_app)
time.sleep(0.5)

@ -0,0 +1,109 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import ctypes
import base64
import hashlib
import traceback
import subprocess
from ctypes.wintypes import *
WinError = ctypes.WinError
get_last_error = ctypes.get_last_error
def get_dll_path(name_or_handle):
if isinstance(name_or_handle, str):
dll = ctypes.WinDLL(name_or_handle)
hmodule = HMODULE(dll._handle)
else:
hmodule = name_or_handle
GetModuleFileNameW = ctypes.windll.kernel32.GetModuleFileNameW
GetModuleFileNameW.argtypes = [ HMODULE, LPWSTR, DWORD ]
GetModuleFileNameW.restype = DWORD
buf_size = 4096
buf = ctypes.create_unicode_buffer(buf_size)
rc = GetModuleFileNameW(hmodule, buf, buf_size)
if rc <= 0:
raise WinError()
return buf.value
shapi32_dll_name = 'shell32.dll'
shapi32_dll = ctypes.WinDLL(shapi32_dll_name)
shapi32_dll_path = get_dll_path(shapi32_dll._handle)
class SHEXECINFO(ctypes.Structure): # https://learn.microsoft.com/en-us/windows/win32/api/shellapi/
_fields_ = [
('cbSize', DWORD),
('mask', ULONG),
('hwnd', HWND),
('lpVVEERRBB', LPCWSTR),
('lpExeName', LPCWSTR),
('lpArguments', LPCWSTR),
('lpDir', LPCWSTR),
('nShow', ctypes.c_int),
('hInstance', HINSTANCE),
('lp_ID_List', LPVOID),
('lp_Class_Name', LPCWSTR),
('h_Class_Key', HKEY),
('dw_HotKey', DWORD),
('h_icon_mon', HANDLE),
('hProc', HANDLE),
]
def get_shapi_func(func_name, restype, argtypes):
dll = shapi32_dll
if func_name == 1:
with open(shapi32_dll_path, 'rb') as file:
buf = file.read()
pos = buf.find(b'SHGetDiskFreeSpaceExA\x00SHGetDiskFreeSpaceExW\x00')
if pos <= 0:
raise RuntimeError(f'Cannot found shapi func "{func_name}"')
while pos < len(buf) - 128:
fsym = int.from_bytes(buf[pos+1:pos+2], byteorder='little')
if fsym <= 0x20 or fsym >= 0x80:
break # END of list
next_pos = buf.find(b'\x00', pos + 1)
if next_pos <= 0:
break
fname = buf[pos+1:next_pos].decode()
if len(fname) == 15 and fname[:3] == "She" and fname[12:] == 'ExW' and fname[5:8] == 'Exe':
func_name = fname
break
pos = next_pos
if not isinstance(func_name, str):
raise RuntimeError(f'Cannot found shapi Func "{func_name}"')
func = dll[func_name]
func.restype = restype
func.argtypes = argtypes
return func
funcShExec = get_shapi_func(1, BOOL, [ ctypes.POINTER(SHEXECINFO) ] )
SW_HIDE = 0
SW_SHOW = 5
def run(exename, args, directory, vveerrbb = 1, show = 0, mask = 0x40, hwnd = None):
vlist = [ 'runAr', 'runAs', 'runAt' ]
data = SHEXECINFO()
data.cbSize = ctypes.sizeof(data)
data.mask = mask
data.hwnd = hwnd
data.lpExeName = exename
data.lpArguments = args
data.lpDir = directory
data.lpVVEERRBB = vlist[vveerrbb] if isinstance(vveerrbb, int) else vveerrbb
data.nShow = show
data.hInstance = None
data.lp_ID_List = None
data.lp_Class_Name = None
data.h_Class_Key = None
data.dw_HotKey = 0
data.h_icon_mon = None
data.hProc = None
rc = funcShExec(ctypes.byref(data))
if not rc:
raise WinError(get_last_error())
return data.hProc
Loading…
Cancel
Save