Stability fuzzing PoC

This commit is contained in:
toneillcodes
2026-06-09 20:30:48 -04:00
parent 9946e8c51b
commit 1f0f14b974
4 changed files with 176 additions and 15 deletions
+28 -14
View File
@@ -6,10 +6,13 @@ LOG_FILE = "active_telemetry.jsonl"
# TOGGLE FLAG: Set to True for Chrome/Browsers, False for Notepad++/Single apps
ENABLE_CHILD_GATING = False
# CONNECTION MODE: Set to a running PID (e.g., 1234) to attach, or None to spawn fresh
TARGET_PID = 10032
# The JavaScript instrumentation payload to inject
JS_CODE = """
const seenFunctions = new Set();
const moduleName = "wininet.dll";
const moduleName = "uxtheme.dll";
function instrumentModule() {
try {
@@ -81,35 +84,46 @@ def on_child_added(child):
# Initialize device manager
device = frida.get_local_device()
# Configure target binary path and flags
# TARGET_PATH = r"C:\Program Files\Google\Chrome\Application\chrome.exe"
# Configure fallback spawn target path and flags
TARGET_PATH = r"C:\Program Files\Notepad++\notepad++.exe"
TARGET_FLAGS = [TARGET_PATH]
try:
print(f"[*] Bootstrapping instrumentation loop for {TARGET_PATH}...")
print(f"[*] Child Gating Status: {'ENABLED' if ENABLE_CHILD_GATING else 'DISABLED'}")
# 1. Conditionally register the device-level callback
# 1. Conditionally register child gating callbacks if enabled
if ENABLE_CHILD_GATING:
device.on('child-added', on_child_added)
# 2. Spawn the process with the configured gating flag
pid = device.spawn(TARGET_FLAGS, child_gating=ENABLE_CHILD_GATING)
session = device.attach(pid)
# 2. Establish Session based on connection mode (Attach vs Spawn)
if TARGET_PID is not None:
print(f"[*] Attaching to existing process PID: {TARGET_PID}...")
session = device.attach(TARGET_PID)
pid = TARGET_PID
should_resume = False
else:
print(f"[*] Bootstrapping fresh instance for {TARGET_PATH}...")
pid = device.spawn(TARGET_FLAGS, child_gating=ENABLE_CHILD_GATING)
session = device.attach(pid)
should_resume = True
print(f"[*] Child Gating Status: {'ENABLED' if ENABLE_CHILD_GATING else 'DISABLED'}")
# 3. Conditionally enable session-level child tracking
if ENABLE_CHILD_GATING:
session.enable_child_gating()
# Load script into the primary parent process
# Load script into the target process session
script = session.create_script(JS_CODE)
script.on('message', on_message)
script.load()
device.resume(pid)
print(f"[+] Root process running at PID {pid}. Press Ctrl+C to stop tracking.\n" + "="*80)
# 4. Only resume if we spawned it suspended
if should_resume:
device.resume(pid)
print(f"[+] Root process spawned and running at PID {pid}.")
else:
print(f"[+] Successfully attached to running PID {pid}.")
print("[*] Telemetry active. Press Ctrl+C to stop tracking.\n" + "="*80)
sys.stdin.read()
except KeyboardInterrupt:
@@ -3,7 +3,8 @@
## Module Testing Table
| Process | Version Tested | Target Module | Target Function | Payload Size | Beacon Result | Notes |
|----|----|----|----|----|----|----|
| notepad++.exe | 8.9.3 | wininet.dll | InternetSetOptionW | 287930 | execution | Crashed on 'Open File' operation |
| Code.exe | 1.105.1 | wininet.dll | ShowCertificate | 287930 | success | Stable during typical usage |
| notepad++.exe | 8.9.3 | wininet.dll | InternetSetOptionW | 287930 | execution, unstable | Crashed on 'Open File' operation |
| notepad++.exe | 8.9.3 | wininet.dll | ShowCertificate | 287930 | success | Stable during normal browsing |
| sublime_text.exe | Build 4200 | wininet.dll | InternetSetOptionW | 287930 | success | Stable during typical usage |
| sublime_text.exe | Build 4200 | wininet.dll | ShowCertificate | 287930 | success | Stable during typical usage |
@@ -0,0 +1,44 @@
[
{
"target_executable": "C:\\Program Files\\Sublime Text\\sublime_text.exe",
"trigger_dll": "comctl32.dll",
"secondary_tool": "C:\\Users\\Administrator\\Desktop\\git\\windows-process-injection\\module-stomping\\remote-stomp.exe",
"tool_arguments": ["-p", "{pid}", "-d", "wininet.dll", "-f", "InternetSetOptionW"],
"timeout_seconds": 60
},
{
"target_executable": "C:\\Program Files\\Sublime Text\\sublime_text.exe",
"trigger_dll": "comctl32.dll",
"secondary_tool": "C:\\Users\\Administrator\\Desktop\\git\\windows-process-injection\\module-stomping\\remote-stomp.exe",
"tool_arguments": ["-p", "{pid}", "-d", "wininet.dll", "-f", "DeleteUrlCacheEntry"],
"timeout_seconds": 60
},
{
"target_executable": "C:\\Program Files\\Sublime Text\\sublime_text.exe",
"trigger_dll": "comctl32.dll",
"secondary_tool": "C:\\Users\\Administrator\\Desktop\\git\\windows-process-injection\\module-stomping\\remote-stomp.exe",
"tool_arguments": ["-p", "{pid}", "-d", "wininet.dll", "-f", "DeleteUrlCacheEntryA"],
"timeout_seconds": 60
},
{
"target_executable": "C:\\Program Files\\Sublime Text\\sublime_text.exe",
"trigger_dll": "comctl32.dll",
"secondary_tool": "C:\\Users\\Administrator\\Desktop\\git\\windows-process-injection\\module-stomping\\remote-stomp.exe",
"tool_arguments": ["-p", "{pid}", "-d", "wininet.dll", "-f", "IsHostInProxyBypassList"],
"timeout_seconds": 60
},
{
"target_executable": "C:\\Program Files\\Sublime Text\\sublime_text.exe",
"trigger_dll": "comctl32.dll",
"secondary_tool": "C:\\Users\\Administrator\\Desktop\\git\\windows-process-injection\\module-stomping\\remote-stomp.exe",
"tool_arguments": ["-p", "{pid}", "-d", "wininet.dll", "-f", "InternetInitializeAutoProxyDll"],
"timeout_seconds": 60
},
{
"target_executable": "C:\\Program Files\\Sublime Text\\sublime_text.exe",
"trigger_dll": "comctl32.dll",
"secondary_tool": "C:\\Users\\Administrator\\Desktop\\git\\windows-process-injection\\module-stomping\\remote-stomp.exe",
"tool_arguments": ["-p", "{pid}", "-d", "wininet.dll", "-f", "ShowCertificate"],
"timeout_seconds": 60
}
]
@@ -0,0 +1,102 @@
import json
import subprocess
import time
import os
def is_module_loaded(pid, module_name):
"""Checks if a specific DLL is loaded by the target PID via tasklist."""
try:
cmd = ["tasklist", "/FI", f"PID eq {pid}", "/M", module_name]
result = subprocess.run(cmd, capture_output=True, text=True, creationflags=subprocess.CREATE_NO_WINDOW)
return module_name.lower() in result.stdout.lower()
except Exception:
return False
def run_configured_test(config_path):
if not os.path.exists(config_path):
print(f"[-] Configuration file not found: {config_path}")
return
# 1. Parse configuration parameters safely
try:
with open(config_path, "r", encoding="utf-8") as f:
config = json.load(f)
target = config["target_executable"]
trigger_dll = config["trigger_dll"]
tool = config["secondary_tool"]
tool_args = config.get("tool_arguments", [])
timeout_sec = config.get("timeout_seconds", 60)
except Exception as e:
print(f"[-] Failed to parse JSON configuration: {e}")
return
print(f"[*] Loaded profile for: {os.path.basename(target)}")
# 2. Start the primary process
process = subprocess.Popen([target])
pid = process.pid
print(f"[+] Started primary process {pid} normally.")
# 3. Poll until the dependency module settles
print(f"[*] Waiting for {trigger_dll} to stabilize in memory...")
start_time = time.time()
module_found = False
while time.time() - start_time < 10: # 10s initialization boundary
if is_module_loaded(pid, trigger_dll):
module_found = True
print(f"[+] Verified {trigger_dll} mapping established.")
break
time.sleep(0.2)
if process.poll() is not None:
print("[-] Primary process terminated during initialization.")
return
if not module_found:
print(f"[-] Warning: {trigger_dll} not explicitly verified. Proceeding...")
# 4. Resolve arguments and launch secondary tool
cmd_line = [tool] + [arg.replace("{pid}", str(pid)) if isinstance(arg, str) else str(arg) for arg in tool_args]
print(f"[+] Launching companion process: {' '.join(cmd_line)}")
secondary_process = subprocess.Popen(cmd_line)
# 5. Monitor execution life cycle up to the timeout threshold
print(f"[*] Monitoring execution stability window ({timeout_sec}s)...")
try:
exit_code = process.wait(timeout=timeout_sec)
# Interpret termination exit codes
STATUS_ACCESS_VIOLATION = -1073741819 # 0xC0000005
STATUS_INVALID_CRUNTIME = -1073740777 # 0xC0000417
STATUS_INVALID_CRUNTIME_ALT = 3221225622
if exit_code in [STATUS_ACCESS_VIOLATION, 0xC0000005]:
print("[!] Stability Fault: Process crashed due to an Access Violation (0xC0000005).")
elif exit_code in [STATUS_INVALID_CRUNTIME, STATUS_INVALID_CRUNTIME_ALT]:
print("[!] Stability Fault: Process forced closure via Invalid CRT Parameter (0xC0000417).")
elif exit_code != 0:
print(f"[!] Process stopped prematurely with exit code: {exit_code}")
else:
print(f"[+] Process completed run cleanly with exit code: {exit_code}")
except subprocess.TimeoutExpired:
print(f"[+] Stability Window Met: Process handled workload successfully for {timeout_sec}s.")
except KeyboardInterrupt:
print("[-] Execution stopped by user.")
finally:
print("[+] Performing environmental cleanup...")
if process.poll() is None:
process.kill()
process.wait()
if secondary_process.poll() is None:
try:
secondary_process.kill()
secondary_process.wait()
except OSError:
pass
if __name__ == "__main__":
CONFIG_FILE = "stability-harness-config.json"
run_configured_test(CONFIG_FILE)