fix(tools): run tools image as non-root operator (#114)
Stage ProjectDiscovery binaries before installing them into /usr/local/bin, run the tools image as the existing Kali operator identity, preserve runtime access to Foundry tools, and cover the non-root Dockerfile and smoke-test contracts.
This commit is contained in:
1 parent
178a64e9c4
commit
571a7743ae
4 files changed
+77
-6
No files matched your search
@@ -54,6 +54,7 @@
|
|||||||
"test:cybench-ci": "node scripts/test-cybench-ci.mjs",
|
"test:cybench-ci": "node scripts/test-cybench-ci.mjs",
|
||||||
"tools:check": "bash scripts/check-tools-image.sh",
|
"tools:check": "bash scripts/check-tools-image.sh",
|
||||||
"tools:build": "bash tools/build.sh",
|
"tools:build": "bash tools/build.sh",
|
||||||
|
"test:tools-dockerfile": "node scripts/test-tools-dockerfile.mjs",
|
||||||
"install:tools": "bash scripts/install-tools.sh",
|
"install:tools": "bash scripts/install-tools.sh",
|
||||||
"docs:sync": "node scripts/pagenary-docsite.mjs",
|
"docs:sync": "node scripts/pagenary-docsite.mjs",
|
||||||
"docs:build": "npm run docs:sync && pagenary build t3mp3st-docs",
|
"docs:build": "npm run docs:sync && pagenary build t3mp3st-docs",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ if ! command -v docker >/dev/null 2>&1; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Checking tools image: $IMAGE"
|
echo "Checking tools image: $IMAGE"
|
||||||
docker run --rm --platform linux/amd64 "$IMAGE" bash -lc '
|
docker run --rm --platform linux/amd64 "$IMAGE" bash -c '
|
||||||
set -e
|
set -e
|
||||||
fail=0
|
fail=0
|
||||||
for c in radare2 gdb objdump upx; do
|
for c in radare2 gdb objdump upx; do
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* Regression guard for the tools image's non-root runtime contract.
|
||||||
|
*
|
||||||
|
* Python packages install console scripts in /usr/local/bin (including httpx).
|
||||||
|
* Go tools must therefore be built in a staging directory before installation,
|
||||||
|
* otherwise `go install` refuses to overwrite the existing Python script.
|
||||||
|
*/
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
const dockerfile = fs.readFileSync(path.join(here, '..', 'tools', 'Dockerfile'), 'utf8');
|
||||||
|
const smokeScript = fs.readFileSync(path.join(here, 'check-tools-image.sh'), 'utf8');
|
||||||
|
|
||||||
|
let passed = 0;
|
||||||
|
let failed = 0;
|
||||||
|
|
||||||
|
function check(label, condition) {
|
||||||
|
if (condition) {
|
||||||
|
passed += 1;
|
||||||
|
console.log(` ok ${label}`);
|
||||||
|
} else {
|
||||||
|
failed += 1;
|
||||||
|
console.error(` FAIL ${label}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check(
|
||||||
|
'Go binaries are not built directly into /usr/local/bin',
|
||||||
|
!/export\s+GOBIN=\/usr\/local\/bin/.test(dockerfile),
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
'Go binaries use a staging directory',
|
||||||
|
/export\s+GOBIN=\/tmp\/projectdiscovery-bin/.test(dockerfile),
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
'staged Go binaries are installed into /usr/local/bin',
|
||||||
|
/install\s+-m\s+0755\s+"\$GOBIN"\/\*\s+\/usr\/local\/bin\//.test(dockerfile),
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
'Go staging directory is removed',
|
||||||
|
/rm\s+-rf\s+"\$GOBIN"/.test(dockerfile),
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
'operator user reuses the existing Kali operator group',
|
||||||
|
/useradd\s+--gid\s+operator\s+--create-home\s+--shell\s+\/bin\/bash\s+operator/.test(dockerfile),
|
||||||
|
);
|
||||||
|
check('image runtime user is operator', /^USER operator$/m.test(dockerfile));
|
||||||
|
check('image runtime workdir is /work', /^WORKDIR \/work$/m.test(dockerfile));
|
||||||
|
check(
|
||||||
|
'tools smoke avoids a login shell whose logout hook can mask success',
|
||||||
|
/docker run .* "\$IMAGE" bash -c '/.test(smokeScript) &&
|
||||||
|
!/docker run .* "\$IMAGE" bash -lc '/.test(smokeScript),
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`\n${failed === 0 ? 'PASS' : 'FAIL'}: ${passed} passed, ${failed} failed`);
|
||||||
|
process.exit(failed === 0 ? 0 : 1);
|
||||||
+16
-5
@@ -14,8 +14,7 @@
|
|||||||
FROM kalilinux/kali-rolling
|
FROM kalilinux/kali-rolling
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive \
|
ENV DEBIAN_FRONTEND=noninteractive \
|
||||||
PIP_BREAK_SYSTEM_PACKAGES=1 \
|
PIP_BREAK_SYSTEM_PACKAGES=1
|
||||||
PATH="/root/go/bin:/root/.foundry/bin:${PATH}"
|
|
||||||
|
|
||||||
# ── apt: reverse/crypto/pwn + web/recon + osint, plus build deps for the pip layer ──
|
# ── apt: reverse/crypto/pwn + web/recon + osint, plus build deps for the pip layer ──
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
@@ -50,19 +49,25 @@ RUN pip3 install --no-cache-dir pipx \
|
|||||||
&& (pipx install mythril || echo "WARN: mythril pipx install failed")
|
&& (pipx install mythril || echo "WARN: mythril pipx install failed")
|
||||||
|
|
||||||
# ── go: the "+" — ProjectDiscovery suite + dalfox (not in stock Kali apt) ──
|
# ── go: the "+" — ProjectDiscovery suite + dalfox (not in stock Kali apt) ──
|
||||||
RUN go install github.com/projectdiscovery/httpx/cmd/httpx@latest && \
|
# Stage first: the Python dependency layer already creates /usr/local/bin/httpx,
|
||||||
|
# and `go install` refuses to overwrite a non-Go executable at GOBIN. `install`
|
||||||
|
# deliberately replaces that console script with ProjectDiscovery httpx.
|
||||||
|
RUN export GOBIN=/tmp/projectdiscovery-bin && \
|
||||||
|
go install github.com/projectdiscovery/httpx/cmd/httpx@latest && \
|
||||||
go install github.com/projectdiscovery/katana/cmd/katana@latest && \
|
go install github.com/projectdiscovery/katana/cmd/katana@latest && \
|
||||||
go install github.com/projectdiscovery/naabu/v2/cmd/naabu@latest && \
|
go install github.com/projectdiscovery/naabu/v2/cmd/naabu@latest && \
|
||||||
go install github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest && \
|
go install github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest && \
|
||||||
go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest && \
|
go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest && \
|
||||||
go install github.com/hahwul/dalfox/v2@latest && \
|
go install github.com/hahwul/dalfox/v2@latest && \
|
||||||
rm -rf /root/go/pkg /root/.cache/go-build
|
install -m 0755 "$GOBIN"/* /usr/local/bin/ && \
|
||||||
|
rm -rf "$GOBIN" /root/go/pkg /root/.cache/go-build
|
||||||
|
|
||||||
# ── npm + foundry: smart-contract "+" (solhint, forge/cast) ──
|
# ── npm + foundry: smart-contract "+" (solhint, forge/cast) ──
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends nodejs npm && \
|
RUN apt-get update && apt-get install -y --no-install-recommends nodejs npm && \
|
||||||
npm install -g solhint && \
|
npm install -g solhint && \
|
||||||
rm -rf /var/lib/apt/lists/* /root/.npm
|
rm -rf /var/lib/apt/lists/* /root/.npm
|
||||||
RUN curl -L https://foundry.paradigm.xyz | bash && /root/.foundry/bin/foundryup || \
|
RUN curl -L https://foundry.paradigm.xyz | bash && /root/.foundry/bin/foundryup && \
|
||||||
|
cp /root/.foundry/bin/forge /root/.foundry/bin/cast /root/.foundry/bin/anvil /usr/local/bin/ 2>/dev/null || \
|
||||||
echo "foundry install skipped (offline build) — re-run foundryup later"
|
echo "foundry install skipped (offline build) — re-run foundryup later"
|
||||||
|
|
||||||
# nuclei templates (best-effort; the scan still runs without a fresh pull)
|
# nuclei templates (best-effort; the scan still runs without a fresh pull)
|
||||||
@@ -79,5 +84,11 @@ RUN curl -fsSL https://github.com/conda-forge/miniforge/releases/latest/download
|
|||||||
&& /opt/conda/bin/conda clean -afy \
|
&& /opt/conda/bin/conda clean -afy \
|
||||||
|| echo "WARN: sage (conda-forge) install failed/skipped — crypto falls back to z3/sympy/fpylll"
|
|| echo "WARN: sage (conda-forge) install failed/skipped — crypto falls back to z3/sympy/fpylll"
|
||||||
|
|
||||||
|
# Kali already defines the operator group; attach the runtime user to it.
|
||||||
|
RUN useradd --gid operator --create-home --shell /bin/bash operator \
|
||||||
|
&& mkdir -p /work \
|
||||||
|
&& chown operator:operator /work
|
||||||
|
|
||||||
|
USER operator
|
||||||
WORKDIR /work
|
WORKDIR /work
|
||||||
CMD ["bash"]
|
CMD ["bash"]
|
||||||
Reference in new issue
Block a user