T07 · Tool Hijacking and Spoofing
- Location
scripts/office/soffice.py:28- Finding
Predictable LD_PRELOAD Library Allows Local Native-Code Hijacking
- Content
View full analysis
dict: env = os.environ.copy() env["SAL_USE_VCLPLUGIN"] = "svp" if _needs_shim(): shim = _ensure_shim() env["LD_PRELOAD"] = str(shim) return env _SHIM_SO = Path(tempfile.gettempdir()) / "lo_socket_shim.so" def _needs_shim() -> bool: try: s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.close() return False except OSError: return True def _ensure_shim() -> Path: if _SHIM_SO.exists(): return _SHIM_SO src = Path(tempfile.gettempdir()) / "lo_socket_shim.c" src.write_text(_SHIM_SOURCE) subprocess.run( ["gcc", "-shared", "-fPIC", "-o", str(_SHIM_SO), str(src), "-ldl"], check=True, capture_output=True, ) src.unlink() return _SHIM_SO ``` ### Technical Analysis The LibreOffice compatibility shim is stored under the fixed path `/tmp/lo_socket_shim.so`. When that path already exists, `_ensure_shim()` accepts the file without validating: - Its owner or permissions - Whether it is a regular file or symbolic link - Whether it was generated from the trusted embedded source - Its cryptographic digest - Whether another process replaced it between validation and use When Unix-domain socket creation is unavailable, the existing file is assigned to `LD_PRELOAD`. The dynamic loader then loads that shared library into the LibreOffice process before normal libraries. An attacker-controlled library can therefore execute arbitrary native code through a constructor or overridden functions. The source path `/tmp/lo_socket_shim.c` is also predictable and written without exclusive creation, creating additional symlink and race-condition exposure. ### Attack Path 1. A local attacker with write access ...[truncated 1201 chars]- Remediation
View remediation
