{"adoption": {"forks": 235, "observed_at": "2026-08-28T04:06:07.078530+00:00", "stars": 2031}, "canonical_url": "https://ross.abutalabs.com/products/penelope", "card": {"archived": false, "artifact_type": "cli-tool", "description": "Penelope Shell Handler", "domain": ["security", "penetration-testing", "developer-tools"], "enriched": true, "function": ["cli", "security", "networking", "developer-tools"], "health_score": 98, "homepage": null, "language": "Python", "license": "GPL-3.0", "license_family": "copyleft", "maturity": "active", "member_repos": ["brightio/penelope"], "name": "brightio/penelope", "platform": ["python", "cli"], "pushed_at": "2026-08-23T18:11:54+00:00", "repo": "brightio/penelope", "stars": 2031, "tags": ["reverse-shell", "shell-handler", "ctf-tools", "pty", "penetration-testing", "hackthebox", "oscp", "netcat-alternative", "command-line", "linux", "macos"], "topics": ["pty", "tty", "ctf-tools", "rce", "ctf", "reverse-shell", "shell-handler", "hackthebox", "oscp", "oscp-tools", "tryhackme"], "urls": [], "use_cases": ["catch reverse shells during CTF challenges", "replace netcat listener with a better shell handler", "auto-upgrade shells to a fully interactive PTY", "manage multiple reverse shell sessions across hosts", "upload and download files to compromised targets", "log shell activity during penetration tests", "generate reverse shell payloads", "maintain persistent shells that respawn on death"], "what_it_is": "Penelope is a modern reverse shell handler for penetration testers and CTF players, serving as a more capable alternative to basic netcat listeners. Built entirely with Python's standard library, it adds automatic PTY upgrades, multi-session management, activity logging, file transfers, and helper modules.", "when_to_avoid": ["you need a Windows-native handler with full feature parity (Windows support is experimental)", "you're looking for a full exploitation framework like Metasploit", "you only need a simple one-shot listener for a quick test", "you need a GUI-based shell management tool"], "when_to_choose": ["you need a feature-rich netcat replacement for catching reverse shells", "you want automatic PTY/readline upgrades without manual stty tricks", "you're doing CTFs (HackTheBox, TryHackMe, OSCP) or pentest engagements", "you need session management, logging, and file transfer in one tool", "you want a zero-dependency Python script that runs anywhere"]}, "data_as_of": "2026-08-30T08:39:29.467469+00:00", "members": [{"path": "/products/penelope", "repo": "brightio/penelope", "role": "main", "score": 92}], "provenance": {"archived": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "artifact_type": {"confidence": null, "enriched_at": "2026-08-30T02:59:32.243516+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "c4ffe5dd071f8040dc6e7d87495d7c0ed851c10d2d0f85c9ff5091f71e1b54cb", "fetched_at": "2026-08-28T04:06:07.078530+00:00", "kind": "readme", "missing": false, "url": "https://github.com/brightio/penelope"}], "taxonomy_version": 1}, "description": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "domain": {"confidence": null, "enriched_at": "2026-08-30T02:59:32.243516+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "c4ffe5dd071f8040dc6e7d87495d7c0ed851c10d2d0f85c9ff5091f71e1b54cb", "fetched_at": "2026-08-28T04:06:07.078530+00:00", "kind": "readme", "missing": false, "url": "https://github.com/brightio/penelope"}], "taxonomy_version": 1}, "enriched": {"inputs": [], "kind": "computed", "method": "enrichment_status"}, "function": {"confidence": null, "enriched_at": "2026-08-30T02:59:32.243516+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "c4ffe5dd071f8040dc6e7d87495d7c0ed851c10d2d0f85c9ff5091f71e1b54cb", "fetched_at": "2026-08-28T04:06:07.078530+00:00", "kind": "readme", "missing": false, "url": "https://github.com/brightio/penelope"}], "taxonomy_version": 1}, "health_score": {"inputs": ["days_since_push", "days_since_release", "archived"], "kind": "computed", "method": "health_v1"}, "homepage": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "language": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "license": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "license_family": {"inputs": ["license"], "kind": "computed", "method": "license_family"}, "maturity": {"confidence": null, "enriched_at": "2026-08-30T02:59:32.243516+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "c4ffe5dd071f8040dc6e7d87495d7c0ed851c10d2d0f85c9ff5091f71e1b54cb", "fetched_at": "2026-08-28T04:06:07.078530+00:00", "kind": "readme", "missing": false, "url": "https://github.com/brightio/penelope"}], "taxonomy_version": 1}, "member_repos": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "name": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "platform": {"confidence": null, "enriched_at": "2026-08-30T02:59:32.243516+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "c4ffe5dd071f8040dc6e7d87495d7c0ed851c10d2d0f85c9ff5091f71e1b54cb", "fetched_at": "2026-08-28T04:06:07.078530+00:00", "kind": "readme", "missing": false, "url": "https://github.com/brightio/penelope"}], "taxonomy_version": 1}, "pushed_at": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "repo": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "stars": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "tags": {"confidence": null, "enriched_at": "2026-08-30T02:59:32.243516+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "c4ffe5dd071f8040dc6e7d87495d7c0ed851c10d2d0f85c9ff5091f71e1b54cb", "fetched_at": "2026-08-28T04:06:07.078530+00:00", "kind": "readme", "missing": false, "url": "https://github.com/brightio/penelope"}], "taxonomy_version": 1}, "topics": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "urls": {"kind": "observed", "observed_at": "2026-08-28T04:06:07.078530+00:00", "source": "github"}, "use_cases": {"confidence": null, "enriched_at": "2026-08-30T02:59:32.243516+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "c4ffe5dd071f8040dc6e7d87495d7c0ed851c10d2d0f85c9ff5091f71e1b54cb", "fetched_at": "2026-08-28T04:06:07.078530+00:00", "kind": "readme", "missing": false, "url": "https://github.com/brightio/penelope"}], "taxonomy_version": 1}, "what_it_is": {"confidence": null, "enriched_at": "2026-08-30T02:59:32.243516+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "c4ffe5dd071f8040dc6e7d87495d7c0ed851c10d2d0f85c9ff5091f71e1b54cb", "fetched_at": "2026-08-28T04:06:07.078530+00:00", "kind": "readme", "missing": false, "url": "https://github.com/brightio/penelope"}], "taxonomy_version": 1}, "when_to_avoid": {"confidence": null, "enriched_at": "2026-08-30T02:59:32.243516+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "c4ffe5dd071f8040dc6e7d87495d7c0ed851c10d2d0f85c9ff5091f71e1b54cb", "fetched_at": "2026-08-28T04:06:07.078530+00:00", "kind": "readme", "missing": false, "url": "https://github.com/brightio/penelope"}], "taxonomy_version": 1}, "when_to_choose": {"confidence": null, "enriched_at": "2026-08-30T02:59:32.243516+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "c4ffe5dd071f8040dc6e7d87495d7c0ed851c10d2d0f85c9ff5091f71e1b54cb", "fetched_at": "2026-08-28T04:06:07.078530+00:00", "kind": "readme", "missing": false, "url": "https://github.com/brightio/penelope"}], "taxonomy_version": 1}}, "score": {"components": {"activity": 99, "longevity": 100, "rhythm": 77}, "computed_at": "2026-09-03T02:20:16.233290+00:00", "flags": [], "formula": "round(0.45*activity + 0.35*rhythm + 0.20*longevity); archived -> min(score, 10)", "inputs": {"age_days": 1915, "days_push": 10, "days_rel": 77, "gap_med": 38.5, "n_releases_24m": 7}, "score": 92, "version": 2}, "staleness": {"enrichment_outdated": false, "low_confidence": false, "scrape_days": 9, "stale_scrape": false}}