From d0d305b6abb2015e2fc9960992ac6f1396a1b332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=81Z=C3=81R=20Imre=20AI=20Agent?= Date: Thu, 16 Jul 2026 13:57:47 +0200 Subject: [PATCH] docs(readme): clear build guide for the HIDS/verifier side MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Front-and-center, runnable steps to produce the baseline: clone --recurse-submodules, run ./build-baseline.sh, use out/ as the vanilla_ref. Documents prerequisites (no PHP/network; jmap.py is authoring-only), what out/ contains/excludes, the update workflow (submodule update --remote + rebuild), and the current common_cadline_libraries/maintenance divergence. Signed-off-by: LÁZÁR Imre Assisted-by: claude-code@claude-opus-4-8 --- README.md | 111 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 85 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 7146e1a5..70cc153f 100644 --- a/README.md +++ b/README.md @@ -2,42 +2,101 @@ This repo produces the **clean code baseline** of the www.archline.hu docroot (Cadline, Joomla 3.8.11, host `tanis.cadline.hu`) — the post-compromise, malware-free, -faithful reproduction of the live server's source files. The baseline is the **input** -to the operator's HIDS baseline-diff verifier (per-vhost known-good reference); the -verification itself runs there, not here. +faithful reproduction of the live server's source files. -## Model: constituents + a generator script (not a checked-out tree) +The baseline is the **input** to the HIDS baseline-diff verifier: a per-vhost, +known-good reference tree the verifier compares the live docroot against +(`baseline-match / data / malware / residual`). This repo only *produces* that tree; +the verification runs on the HIDS side. -A deployed Joomla docroot differs from any repo/source layout: extensions install their -files across many docroot paths (`administrator/…`, `components/…`, `media/…`, -`plugins/…`) via their manifest. So this repo stores the baseline **constituents** and a -script **assembles** the deployed baseline: +--- -``` -./build-baseline.sh # → out/ = the deployed CODE docroot (the baseline) +## Building the baseline (read this first) + +The repo does **not** contain the deployed docroot — it contains the baseline +*constituents* plus a generator script. Run the script to produce the deployed tree: + +```sh +# 1. Clone WITH submodules (common_cadline_libraries + maintenance are submodules): +git clone --recurse-submodules ssh://git@git.cadline.hu:22222/cadline_web/www_archline_hu.git +cd www_archline_hu +# (if you already cloned without --recurse-submodules:) +git submodule update --init + +# 2. Generate the baseline: +./build-baseline.sh # → ./out/ + +# 3. Use ./out/ as the per-vhost vanilla_ref (the known-good reference tree). ``` -- `core/` — Joomla 3.8.11 official package (deployed form). -- `packages//` — upstream-obtainable extensions; the pristine package is - manifest-mapped to deployed paths by `lib/jmap.py`, then our legit delta - (`cadline.patch`) is applied — so git history shows exactly how we differ from upstream. -- `deployed//` — no-source extensions: vetted live files, placed directly. -- `cadline//` — Cadline own-code (+ submodules for the deployed-layout Cadline repos). -- `overrides/` — Cadline core modifications as patches on vanilla. -- Malware (`malware-iocs.md`) and runtime data are excluded; the result is code only. +`out/` is the deployed **code** docroot (~23.5k files). It is git-ignored and fully +regenerated on every run (the script is idempotent — it `rm -rf out/` first). Point the +verifier's baseline-diff at `out/`, or copy it to wherever the verifier expects the ref. -See [`RUNBOOK.md`](RUNBOOK.md) for the build recipe and module inventory, -[`PROVENANCE.md`](PROVENANCE.md) for per-extension origins, and -[`malware-iocs.md`](malware-iocs.md) for the excluded IOC set. +**Prerequisites:** `bash`, `rsync`, `git` (for submodules), `find`, `sed`. No PHP, no +build toolchain, no network at build time (submodules are already cloned). +`lib/jmap.py` (python3) is a *maintenance* tool used only when authoring a package's +pristine commit — **it is not invoked by `build-baseline.sh`**. + +**What `out/` contains / excludes:** +- **Contains:** Joomla 3.8.11 core + every installed extension (110 components, ~98 + modules, 164 plugins, 8 templates) + the Cadline-own code — all as deployed files. +- **Excludes:** malware/IOCs (see [`malware-iocs.md`](malware-iocs.md)) and runtime + **data** (`cache/`, `tmp/`, `logs/`, `images/`, `public/`, media data). The result is + code only. +- Byte-matches the live docroot for all legit code; it is intentionally **clean** on the + 4 files the attacker infected (3 trojanized core files + `shaper_helix3/index.php`), + so the verifier flags those on the live server. Verified: non-malware code residual = 0. + +--- + +## Repo layout (the constituents) + +| Path | What | How `build-baseline.sh` uses it | +|---|---|---| +| `core/` | Joomla 3.8.11 official package (deployed form) | rsync → `out/`, minus demo assets + data dirs | +| `packages//` | 5 upstream-obtainable extensions, deployed-layout, reconciled to live bytes. Modified ones are two commits (pristine upstream → live delta) so `git log`/`git diff` shows exactly how we differ from upstream. | rsync → `out/` | +| `deployed//` | ~55 no-source extensions: vetted live files (deployed layout). `_shared/` holds cross-extension language/vendor/manifests. | rsync → `out/` | +| `cadline//` | Cadline own-code. `cadline/backend/common_cadline_libraries` and `…/maintenance` are **git submodules** of the developer repos (cadcommonlib / maintenance). | rsync → `out/` (`.git` excluded) | +| `overrides/` | Cadline core modifications (live versions overlaid on the package core) + a few package-missing core files. | rsync → `out/` (last, so it wins) | +| `lib/jmap.py` | Generic Joomla manifest→deployed-path mapper (authoring aid only). | not used at build time | + +Details: [`RUNBOOK.md`](RUNBOOK.md) (recipe + module inventory), +[`PROVENANCE.md`](PROVENANCE.md) (per-extension origins), +[`malware-iocs.md`](malware-iocs.md) (excluded IOC set). + +--- + +## Updating the baseline + +- **Developer-controlled code** (`common_cadline_libraries`, `maintenance`): the + developer pushes to the cadcommonlib / maintenance repos, then: + ```sh + git submodule update --remote # pull the developer's latest + ./build-baseline.sh # regenerate out/ + git add -A && git commit # record the new submodule pointers + ``` +- **Everything else** (Joomla core EOL, 3rd-party extensions): effectively frozen; if a + legit change ever lands, re-sync the affected `deployed//` or `overrides/` from + the live docroot and commit. + +**Known divergence (heads-up for the verifier):** `common_cadline_libraries` and +`maintenance` currently take the *authoritative* submodule HEAD content, which differs +from the current live docroot (mixed CRLF/LF + a content drift on +`crm_hardlock.class.php` / `POfile.php`) because live was not last deployed from those +HEADs. The verifier will flag this until live is re-deployed from the submodules or the +drift is reconciled. Line-ending normalization, if wanted, is a verifier-side choice. + +--- ## Authority -The live docroot (RO mirror) is the source of truth — the goal is its faithful, -malware-free reproduction. The earlier single-commit "monolith" baseline is an -unvalidated helper only (it dropped extension manifests and clean core files and kept -installer junk); it is not a target. +The live docroot (RO mirror) is the source of truth for reproduction; the developer git +repos are authoritative for the code they own. The earlier single-commit "monolith" +baseline is an unvalidated helper only (it dropped extension manifests and clean core +files and kept installer junk) — it is not a target. ## References - The archline.hu 2026 security audit and incident analysis (operator-held). -- The baseline is consumed by the operator's per-vhost HIDS baseline-diff verifier. +- The excluded malware set is documented in [`malware-iocs.md`](malware-iocs.md).