Welcome to my digital homestead - a curated collection of projects, writeups, and experiments in Python, cybersecurity, and creative coding.
Here you'll find CTF writeups covering Azure OAuth privilege escalation, AWS S3 multi-service exploitation, Kubernetes SSRF attack chains, Terraform state poisoning, Go malware reverse engineering, and supply-chain compromises on GitHub Actions runners. You'll also find side projects like the Pokemon Sleep Roster Analyzer, an RDP/VNC network scanner, a LinkedIn feed analyzer powered by Gemini, and word-puzzle solvers for Wordle and Hardle. Plus notes on building this Flask site, migrating to AWS, Bluesky cross-posting, and running a personal AI robot out of my garage.
I'm Mark LaCore - Software Engineer by day, Raspberry Pi tinkerer by night. 25 years of turning caffeine into code, 20+ years of playing guitar, and a growing collection of CTF trophies. Explore the posts below, browse the CTF writeups, or drop me a line.
File: README.md A local network scanner with a casino-themed web UI that discovers RDP and VNC s ## What It Does-- **Discovery** — Scans subnets for RDP (3389–3390) and VNC (5900–5901) in a single nmap pass+- **Discovery** — Scans subnets for RDP (3389–3390), VNC (5900–5901), and RTSP (554, 8554) in a single nmap pass - **Full Enumeration** — OS detection, open ports, NetBIOS names, domain info, SSL certs, MAC addresses - **Auth Checking** — Determines NLA status for RDP and authentication type for VNC (None/password)-- **Screenshots** — Captures login screens from non-NLA RDP hosts (via FreeRDP) and unauthenticated VNC desktops (via vncdotool)+- **Screenshots** — Captures login screens from non-NLA RDP hosts (via [patched scrying](#rdp-screenshots--patched-scrying)), unauthenticated VNC desktops (via vncdotool), web admin panels (via Playwright), and IP-camera frames (via ffmpeg over RTSP, with multi-channel NVR enumeration) - **Enrichment** — ASN, GeoIP, reverse DNS, and IP type classification for every host-- **Bluesky Announcements** — Posts discoveries with screenshots to Bluesky via AT Protocol (opt-in)+- **Bluesky Announcements** — Posts discoveries with screenshots to Bluesky via AT Protocol (opt-in); camera posts carry up to 4 channel frames in a single post - **Live Logging** — Real-time scan output streamed to the browser via SSE - **External Feeds** — Import scan targets from an external host feed or VNC Resolver's random endpoint A local network scanner with a casino-themed web UI that discovers RDP and VNC s │ ┌────────────┼────────────┐ │ │ │- SQLite DB nmap binary vncdotool- (WAL mode) / FreeRDP+ SQLite DB nmap binary scrying / vncdotool+ (WAL mode) / ffmpeg / Playwright ``` **Backend** — Python/FastAPI with raw SQLite (no ORM). Scans run in daemon threads because python-nmap is synchronous. Each nmap call creates its own `PortScanner()` instance for thread safety. A local network scanner with a casino-themed web UI that discovers RDP and VNC s - **Python 3.11+** - **Node.js 18+** - **nmap** — `brew install nmap` / `apt install nmap`-- **FreeRDP** (optional, for RDP screenshots) — `brew install freerdp3`+- **scrying** (for RDP screenshots) — see [RDP Screenshots — patched scrying](#rdp-screenshots--patched-scrying) below. Recommended: install the `scrying-basic-rdp` fork so legacy/no-NLA servers aren't skipped.+- **ffmpeg** (for IP-camera RTSP frame grabs) — `brew install ffmpeg` / `apt install ffmpeg` - **vncdotool** (installed automatically via pip)+### RDP Screenshots — patched scrying++Upstream [`nccgroup/scrying`](https://github.com/nccgroup/scrying) (and its underlying `rdp-rs` library) only offers `ProtocolSSL` (+ optionally NLA) during RDP negotiation. Servers that only accept legacy `ProtocolRDP` (basic security, no TLS) reject scrying with `ProtocolNegFailure` — even though nmap's `rdp-enum-encryption` reports them as "no NLA". This rules out a meaningful fraction of internet-exposed RDP servers.++Recommended install — the patched fork [`nerdymark/scrying-basic-rdp`](https://github.com/nerdymark/scrying-basic-rdp) adds offer-and-handle support for basic RDP security in `rdp-rs`, plus an automatic retry-on-NegFailure path in scrying:++```bash+# Requires Rust toolchain (brew install rust)+cargo install --git https://github.com/nerdymark/scrying-basic-rdp.git --locked+```++The binary lands at `~/.cargo/bin/scrying`. Make sure that directory is on `PATH` when you launch the backend (e.g. `PATH="$HOME/.cargo/bin:$PATH" uvicorn backend.main:app --reload`). Upstream scrying still works for the SSL/NLA-off case if you don't want to build the fork.++Either way, scrying decodes RDP bitmap updates straight to PNG — no XQuartz, no Screen Recording permission, no FreeRDP install needed.+ ## Quick Start ```bash Each scan executes these phases sequentially per subnet: | Phase | What | Scope | |-------|------|-------|-| 1 | **Discovery** — `nmap -Pn --open -p 3389-3390,5900-5901` | All IPs in subnet |-| 2 | **Full scan** — `nmap -A -Pn` (OS, ports, scripts) | Each RDP host, then VNC-only hosts |+| 1 | **Discovery** — `nmap -Pn --open -p 3389-3390,5900-5901,554,8554` | All IPs in subnet |+| 2 | **Full scan** — `nmap -A -Pn` (OS, ports, scripts) | Each RDP host, then VNC- and RTSP-only hosts | | 2.25 | **SSL cert** — `nmap --script ssl-cert` | Each RDP host | | 2.5 | **NLA check** — `nmap --script rdp-enum-encryption` | Each RDP host |-| 3 | **RDP screenshot** — FreeRDP + screencapture | Non-NLA RDP hosts |+| 3 | **RDP screenshot** — patched [scrying](#rdp-screenshots--patched-scrying) | RDP hosts where NLA isn't required | | 4 | **VNC auth** — `nmap --script vnc-info,vnc-title` | Each VNC port per host | | 4.1 | **VNC screenshot** — `vncdo capture` | No-auth VNC ports |+| 4.5 | **Web screenshot** — Playwright (Chromium) | Detected web ports |+| 4.6 | **Camera detect + RTSP probe + frame grab** — ffmpeg/ffprobe across known vendor URL templates, enumerates channels 1–16 on multi-channel NVRs | Hikvision, Dahua, Axis, etc. | | 5 | **Enrichment** — ip-api.com + reverse DNS | All discovered hosts | The `-Pn` flag is used everywhere because many hosts block ICMP probes. rdp-lottery/ - **`-Pn` is slow** — A /24 probes all 256 IPs without ping, which is slower than default nmap but necessary because many hosts block ICMP - **SSE proxy ordering** — The Vite config has a specific entry for `/api/logs/stream` before the general `/api` proxy to prevent buffering issues - **nmap must be installed** — `python-nmap` is just a wrapper; the `nmap` binary must be on PATH-- **macOS screenshots** — FreeRDP screenshot capture requires Screen Recording permission for Terminal/Python in System Settings > Privacy & Security+- **scrying on PATH** — the backend shells out to `~/.cargo/bin/scrying`; if the backend is launched from a context that doesn't include that path, RDP screenshots silently won't be captured. Easiest fix is `PATH="$HOME/.cargo/bin:$PATH" uvicorn …` in your launch script - **VNC displays** — VNC servers can run on non-default ports (5901 for display :1); both 5900 and 5901 are scanned - **RDP on alternate ports** — ms-wbt-server sometimes runs on 3390; both 3389 and 3390 are scanned+- **All-black VNC frames** — discarded automatically; common on headless X11 servers with no active desktop, no amount of mouse/keyboard input over RFB will conjure pixels ## License
A local network scanner with a casino-themed web UI — discovers RDP and VNC servers, checks auth, and captures screenshots of unauthenticated desktops.
Multi-service AWS exploitation chain: account ID enumeration via s3recon, SNS StringLike policy bypass, and os.path.join path traversal to read the flag from a private S3 bucket.
Built a Hardle solver companion tool for the Bulls and Cows style word puzzle. Enter guesses, set correct and misplaced counts, and narrow down candidates from 12,000+ words.
Two classic browser games — Flappy Nerd (cyberpunk arcade) and Gorillas (QBasic artillery classic) — now have their own dedicated pages with fullscreen mode, controls reference, and background info.