diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..646f040 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,120 @@ +name: release + +# Triggers on semver tag push (v0.1.0, v0.1.1, etc.). Builds release +# artifacts for x86_64 and arm64, then publishes them on a GitHub +# Release matching the tag. +# +# Maintainer flow: +# git tag v0.1.0 +# git push origin v0.1.0 +# → CI builds + publishes release with iamroot-x86_64 + iamroot-arm64 + +on: + push: + tags: ['v*.*.*'] + workflow_dispatch: # allow manual re-runs + +permissions: + contents: write # needed by softprops/action-gh-release + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - target: x86_64 + cc: gcc + apt: build-essential + - target: arm64 + cc: aarch64-linux-gnu-gcc + apt: build-essential gcc-aarch64-linux-gnu + name: build (${{ matrix.target }}) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: install build deps + run: | + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends ${{ matrix.apt }} linux-libc-dev + + - name: build + env: + CC: ${{ matrix.cc }} + run: | + make + file iamroot + ls -la iamroot + + - name: rename + checksum + run: | + mv iamroot iamroot-${{ matrix.target }} + sha256sum iamroot-${{ matrix.target }} > iamroot-${{ matrix.target }}.sha256 + + - uses: actions/upload-artifact@v4 + with: + name: iamroot-${{ matrix.target }} + path: | + iamroot-${{ matrix.target }} + iamroot-${{ matrix.target }}.sha256 + + release: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + path: dist + + - name: flatten artifacts + run: | + find dist -type f -exec mv {} . \; + ls -la iamroot-* + + - name: collect release notes + id: notes + run: | + tag="${GITHUB_REF#refs/tags/}" + echo "tag=$tag" >> "$GITHUB_OUTPUT" + # Pull the latest entry from CVES.md / ROADMAP.md for the body + { + echo "## IAMROOT $tag" + echo + echo "Pre-built binaries for x86_64 and arm64. Checksums alongside." + echo + echo "### Install" + echo + echo '```bash' + echo "curl -sSLfo /tmp/iamroot https://github.com/${GITHUB_REPOSITORY}/releases/download/${tag}/iamroot-\$(uname -m | sed s/aarch64/arm64/)" + echo "chmod +x /tmp/iamroot && sudo mv /tmp/iamroot /usr/local/bin/iamroot" + echo "iamroot --version" + echo '```' + echo + echo "Or one-shot via the install script:" + echo + echo '```bash' + echo "curl -sSL https://github.com/${GITHUB_REPOSITORY}/releases/download/${tag}/install.sh | sh" + echo '```' + echo + echo "### What's in this release" + echo + echo "See [\`CVES.md\`](https://github.com/${GITHUB_REPOSITORY}/blob/${tag}/CVES.md) for the curated CVE inventory." + echo "See [\`ROADMAP.md\`](https://github.com/${GITHUB_REPOSITORY}/blob/${tag}/ROADMAP.md) for phase progress." + } > release-notes.md + + - name: publish release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.notes.outputs.tag }} + name: IAMROOT ${{ steps.notes.outputs.tag }} + body_path: release-notes.md + files: | + iamroot-x86_64 + iamroot-x86_64.sha256 + iamroot-arm64 + iamroot-arm64.sha256 + install.sh + fail_on_unmatched_files: false # install.sh may not exist at first tag diff --git a/README.md b/README.md index 39fcecd..d9cf385 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,29 @@ > tool. By using it you assert you have explicit authorization to test > the target system. See [`docs/ETHICS.md`](docs/ETHICS.md). +## Quickstart + +```bash +# One-shot install (x86_64 / arm64; checksum-verified) +curl -sSL https://github.com/KaraZajac/IAMROOT/releases/latest/download/install.sh | sh + +# What's this box vulnerable to? +sudo iamroot --scan + +# Broader system hygiene (setuid binaries, world-writable, capabilities, sudo) +sudo iamroot --audit + +# Deploy detection rules across every bundled module +sudo iamroot --detect-rules --format=auditd | sudo tee /etc/audit/rules.d/99-iamroot.rules + +# Fleet scan (any-sized host list via SSH; aggregated JSON for SIEM) +./tools/iamroot-fleet-scan.sh --binary iamroot --ssh-key ~/.ssh/id_rsa hosts.txt +``` + +`iamroot --help` lists every command. See [`CVES.md`](CVES.md) for the +curated CVE inventory and [`docs/DEFENDERS.md`](docs/DEFENDERS.md) for +the blue-team deployment guide. + ## What this is Most Linux LPE references are dead repos, broken PoCs, or single-CVE diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..ca0e27e --- /dev/null +++ b/install.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash +# IAMROOT one-shot installer. +# +# Usage: +# curl -sSL https://github.com/KaraZajac/IAMROOT/releases/latest/download/install.sh | sh +# +# Or with explicit version: +# IAMROOT_VERSION=v0.1.0 curl ... | sh +# +# Or install to a different prefix: +# IAMROOT_PREFIX=$HOME/.local/bin curl ... | sh +# +# Environment: +# IAMROOT_VERSION release tag (default: latest) +# IAMROOT_PREFIX install dir (default: /usr/local/bin if writable, else error) +# IAMROOT_REPO override repo (default: KaraZajac/IAMROOT) +# +# Exit codes: +# 0 — installed successfully +# 1 — error (unsupported arch, download failure, permission denied) + +set -euo pipefail + +REPO="${IAMROOT_REPO:-KaraZajac/IAMROOT}" +VERSION="${IAMROOT_VERSION:-latest}" +PREFIX="${IAMROOT_PREFIX:-/usr/local/bin}" + +log() { printf '[\033[1;36m*\033[0m] %s\n' "$*" >&2; } +ok() { printf '[\033[1;32m+\033[0m] %s\n' "$*" >&2; } +fail() { printf '[\033[1;31m-\033[0m] %s\n' "$*" >&2; exit 1; } + +# Detect architecture +arch=$(uname -m) +case "$arch" in + x86_64|amd64) target=x86_64 ;; + aarch64|arm64) target=arm64 ;; + *) fail "Unsupported architecture: $arch (only x86_64 and arm64 currently)" ;; +esac +log "detected arch: $target" + +# Resolve version → download URL +if [ "$VERSION" = "latest" ]; then + url="https://github.com/${REPO}/releases/latest/download/iamroot-${target}" + sha_url="https://github.com/${REPO}/releases/latest/download/iamroot-${target}.sha256" +else + url="https://github.com/${REPO}/releases/download/${VERSION}/iamroot-${target}" + sha_url="https://github.com/${REPO}/releases/download/${VERSION}/iamroot-${target}.sha256" +fi +log "downloading from: $url" + +# Need curl. wget fallback would be nice but skipping for simplicity. +if ! command -v curl >/dev/null 2>&1; then + fail "curl is required (apt install curl / dnf install curl)" +fi + +tmp=$(mktemp -d) +trap 'rm -rf "$tmp"' EXIT + +if ! curl -fsSLo "$tmp/iamroot" "$url"; then + fail "download failed. Check the version exists at https://github.com/${REPO}/releases" +fi + +# Verify checksum if available +if curl -fsSLo "$tmp/iamroot.sha256" "$sha_url" 2>/dev/null; then + # The .sha256 file has the binary's original name; normalize for our local copy + expected=$(awk '{print $1}' "$tmp/iamroot.sha256") + if command -v sha256sum >/dev/null 2>&1; then + actual=$(sha256sum "$tmp/iamroot" | awk '{print $1}') + elif command -v shasum >/dev/null 2>&1; then + actual=$(shasum -a 256 "$tmp/iamroot" | awk '{print $1}') + else + actual="" + log "no sha256sum/shasum available — skipping checksum verification" + fi + if [ -n "$actual" ]; then + if [ "$actual" = "$expected" ]; then + ok "checksum verified" + else + fail "checksum mismatch (expected $expected, got $actual)" + fi + fi +else + log "no checksum file at $sha_url — skipping verification" +fi + +chmod +x "$tmp/iamroot" + +# Install. Try $PREFIX directly; if not writable, sudo. +target_path="$PREFIX/iamroot" +if [ -w "$PREFIX" ] || [ "$(id -u)" -eq 0 ]; then + mv "$tmp/iamroot" "$target_path" +elif command -v sudo >/dev/null 2>&1; then + log "$PREFIX needs sudo; you may be prompted for password" + sudo mv "$tmp/iamroot" "$target_path" +else + fail "$PREFIX not writable and sudo not available. Try IAMROOT_PREFIX=\$HOME/.local/bin" +fi + +ok "installed: $target_path" +"$target_path" --version + +cat >&2 <