## Summary
CVE-2026-32833 is an OS command injection in the Cudy LT300 3.0 firmware LuCI web administration interface. The vulnerable firmware 2.4.5 exposes the product HTTP endpoint `POST /cgi-bin/luci/admin/system/systime`; authenticated attacker-controlled form data for the system time setting reaches the original firmware `usr/lib/lua/luci/model/cbi/system/systime.lua` handler. In the vulnerable image, the `cbid.system.ntp.current` value is interpolated into a shell command of the form `date -s '%s'` without shell metacharacter sanitization, allowing a payload containing a quote and command separator to execute arbitrary commands.

## Impact
- Package/component affected: Cudy LT300 3.0 firmware LuCI/uhttpd administrative web interface, specifically `model/cbi/system/systime.lua` behind `/cgi-bin/luci/admin/system/systime`.
- Affected versions: firmware before 2.5.12; reproduced against `LT300V3-R100-2.4.5-20250519-131314`.
- Fixed/control version: `LT300V3-R100-2.5.12-20260518-234632`.
- Risk level and consequences: high. An attacker with access to the administrative interface/session can execute shell commands in the router firmware context by submitting crafted time-setting form data. On a physical router this can lead to device compromise, persistence, traffic interception, or pivoting from the router.

## Impact Parity
- Disclosed/claimed maximum impact: code execution / OS command injection via a router administrative interface API endpoint.
- Reproduced impact from this run: code execution. The reproduction created attacker-chosen proof files with controlled contents by sending HTTP POST requests to the original firmware `/cgi-bin/luci/admin/system/systime` endpoint through the firmware `uhttpd` server and original `/www/cgi-bin/luci` LuCI dispatcher/CBI path.
- Parity: `full`.
- Not demonstrated: no post-exploitation persistence or interactive shell was attempted; the proof stops after deterministic command execution side effects.

## Root Cause
The root cause is unsafe construction of a shell command from HTTP form input in the LuCI system time handler. In the vulnerable 2.4.5 firmware, the system time page includes bytecode string markers showing the affected flow: `timeclock`, `date -s '%s'`, and `fork_exec`. When the CBI form is submitted with the manual time-setting option, the user-supplied `cbid.system.ntp.current`/time value is used in a `date -s '<user value>'` command. Because the value is surrounded by single quotes but not sanitized before shell execution, an attacker can close the quote and append a shell command, e.g. `2025-01-01 12:00:00'; echo MARKER > /tmp/proof; #`.

The fixed 2.5.12 firmware preserves the same endpoint and command structure but adds a `gsub` sanitization marker in the same `systime.lua` handler before `fork_exec`. The fixed negative-control runs reached the same product endpoint and form handler but did not create the attacker-controlled proof files.

No public fix commit was provided in the ticket. The reproduction compares vendor firmware images directly: vulnerable `LT300V3-R100-2.4.5-20250519-131314` versus fixed `LT300V3-R100-2.5.12-20260518-234632`.

## Reproduction Steps
1. Use `bundle/repro/reproduction_steps.sh`.
2. The script:
   - Downloads or reuses the vendor LT300 V3 2.4.5 and 2.5.12 firmware zip files.
   - Extracts their SquashFS root filesystems.
   - Runs the firmware `usr/sbin/uhttpd` under `qemu-mipsel` and `proot`.
   - Uses the original firmware `/www/cgi-bin/luci`, `luci.dispatcher`, `luci.cbi`, and `usr/lib/lua/luci/model/cbi/system/systime.lua` path for the endpoint.
   - Adds only emulation shims for router-only services/hardware state (`ubus` session, `bdinfo`, and route-forbidden state) so the firmware web interface can run outside physical hardware; it does not replace the vulnerable endpoint handler.
   - Sends two vulnerable HTTP POST attempts to `/cgi-bin/luci/admin/system/systime` with payloads in `cbid.system.ntp.current`.
   - Sends two equivalent fixed-version negative-control attempts through the same endpoint.
3. Expected evidence:
   - Vulnerable attempts create proof files containing `VULN_ATTEMPT_1_COMMAND_EXECUTED` and `VULN_ATTEMPT_2_COMMAND_EXECUTED`.
   - Fixed attempts do not create proof files.
   - GET requests for both versions render the original `System Time` CBI form and include `cbid.system.ntp.current`, proving endpoint reachability.

## Evidence
Primary runtime evidence:
- `bundle/logs/reproduction_steps.log` records successful runs.
- `bundle/repro/runtime_manifest.json` records the runtime endpoint path, `service_started=true`, `healthcheck_passed=true`, and `target_path_reached=true`.
- `bundle/logs/artifacts/product/proof_summary.txt` contains:
  - `vuln attempt 1 proof: VULN_ATTEMPT_1_COMMAND_EXECUTED`
  - `vuln attempt 2 proof: VULN_ATTEMPT_2_COMMAND_EXECUTED`
  - `fixed attempt 1 no proof file (negative control passed)`
  - `fixed attempt 2 no proof file (negative control passed)`
- `bundle/logs/artifacts/http/vuln_attempt1_request.txt` and `bundle/logs/artifacts/http/vuln_attempt2_request.txt` contain the malicious POST fields sent to `/cgi-bin/luci/admin/system/systime`.
- `bundle/logs/artifacts/http/vuln_attempt1_response_headers.txt` shows `HTTP/1.1 200 OK` and `X-CBI-State: 1` for a submitted form.
- `bundle/logs/artifacts/http/fixed_attempt1_response_headers.txt` shows the fixed endpoint was reached but did not accept the injected payload as a successful proof-producing command.
- `bundle/logs/code_comparison.txt` and `bundle/logs/artifacts/product/code_identity.txt` capture firmware code identity and string-level handler differences. The vulnerable handler shows `timeclock`, `date -s '%s'`, and `fork_exec`; the fixed handler additionally shows `gsub`.

Environment details:
- Firmware rootfs execution used `qemu-mipsel` and `proot` in user-mode emulation.
- The production-facing server was the firmware `uhttpd` binary serving the original firmware web root.
- The entrypoint was the HTTP endpoint `/cgi-bin/luci/admin/system/systime`.

## Recommendations / Next Steps
- Upgrade Cudy LT300 3.0 devices to firmware 2.5.12 or newer.
- Do not build shell commands by concatenating or formatting raw HTTP form values. Use argument-vector APIs where possible, or strictly validate time values against a narrow date/time grammar before invoking any command.
- If shell invocation is unavoidable, reject metacharacters such as quotes, semicolons, backticks, pipes, ampersands, redirection operators, `$()`, and newlines, and add regression tests for command-injection payloads.
- Add endpoint-level tests for `/cgi-bin/luci/admin/system/systime` verifying that invalid time values fail closed and cannot create shell side effects.

## Additional Notes
- Idempotency confirmation: `bundle/repro/reproduction_steps.sh` was run successfully multiple times consecutively after fixing non-root SquashFS extraction handling. Each run recreated fresh proof artifacts and revalidated both vulnerable and fixed firmware behavior.
- The run uses emulation shims for hardware/session dependencies that are normally present on a physical router. The vulnerability proof itself is not a reimplemented handler: the HTTP request traverses firmware `uhttpd`, original `/www/cgi-bin/luci`, LuCI dispatcher/CBI, and the original firmware `systime.lua` bytecode handler.
- The fixed-version negative control uses the actual fixed firmware handler rather than a hand-written surrogate.
