Disclaimer: This article describes a tool intended for ethical, educational, and authorized security work. Only use it against targets you own or have explicit permission to test. Unauthorized scanning is illegal in most jurisdictions.
When you start a security assessment — bug bounty, penetration test, or even just hardening your own infrastructure — the first thing you reach for is reconnaissance. You want answers to questions like:
- What is this server actually running?
- Which ports are exposed to the internet?
- Is that WordPress install behind a CDN? Which framework is it using?
- Are there subdomains I don't know about?
There are many tools that answer each of these questions. But most of them are heavyweight, require lots of setup, or spread the answers across multiple utilities with different output formats.
Jin is a single Go binary that answers all of them — with a friendly interactive shell, clean human-readable output, and JSON mode for scripting. Let me show you what it does and why I think it earns a spot in your toolkit.
What is Jin?
Jin (Just Intelligence Network) is an open-source, passive-first OSINT and reconnaissance CLI toolkit. It's an evolution of a Python project that focused on ethical port scanning, rewritten in Go and redesigned around a clean, testable architecture.
The current version ships three commands, all usable interactively or as one-shot commands:
| Command | What it does |
|---|---|
info |
Full server reconnaissance: headers, TLS, cloud provider, plus an automated security score |
ports |
TCP connect scan for open ports, with service detection |
tech-stack |
Fingerprints the tech stack (CMS, frameworks, CDN, WAF...) with confidence levels and evidence |
tech-stack --subdomains |
Also discovers subdomains from certificate transparency logs and pulls DNS records |
Every command has a --json flag for structured output, so you can pipe results into other tools or CI pipelines.
Why Go?
The original version of Jin was written in Python. The rewrite in Go brings some serious quality-of-life improvements:
- One static binary — no runtime, no virtualenv, no dependency headaches. Copy it to a box and it works.
- Fast startup — a scan kicks off in milliseconds, which matters a lot in an interactive REPL.
- Goroutines for concurrency — subdomain discovery and fingerprinting run in parallel.
- Small container footprint — the Docker image is Alpine-based and statically linked.
- Clean architecture — the codebase uses hexagonal (ports & adapters) design, which makes the tool easy to extend with new scanners without touching the domain logic.
The three commands
Let's walk through each command with real output shapes.
1. info — full server reconnaissance
Point Jin at any URL and it fetches the response, extracts the interesting headers, detects the cloud provider, and — my favorite part — produces a weighted security report with a letter grade:
🌐 URL: https://example.com
🗃️ Base Domain: example.com
☁️ Cloud: Cloudflare
✅ Status: 200
🖥️ Server: cloudflare
📄 Content-Type: text/html; charset=UTF-8
⏱️ Scan Time: 423ms
🔒 TLS Version: TLS 1.3
🔐 Cipher Suite: TLS_AES_128_GCM_SHA256
🛡️ Security Insights: B+ (82/100)
✅ TLS: Serving over TLS 1.3
⚠️ HSTS: Missing Strict-Transport-Security header
✅ Content-Security-Policy: Policy enforced
✅ X-Frame-Options: Clickjacking protection enforced
✅ X-Content-Type-Options: nosniff set
✅ Referrer-Policy: Set to strict-origin-when-cross-origin
ℹ️ Permissions-Policy: Not set
✅ Cookie Flags: No obvious cookie issues
✅ CORS: Restricted to: https://app.example.com
✅ Version Disclosure: No version numbers exposed in Server/X-Powered-By
📋 Headers:
cache-control: max-age=0, private, must-revalidate
content-encoding: br
content-security-policy: default-src 'self'; ...
set-cookie: __cf_bm=<redacted> [Secure, HttpOnly, SameSite=None]
...
The security checks cover the OWASP-relevant quick wins: TLS, HSTS, Content-Security-Policy (including a linter that flags unsafe-inline, unsafe-eval, and overly broad sources), X-Frame-Options, nosniff, Referrer-Policy, Permissions-Policy, cookie flags (Secure / HttpOnly / SameSite), CORS misconfigurations (like * combined with credentials=true), and version disclosure in headers.
Each check has a weight, so the final score is a genuine 0–100 weighted grade (A+ down to F) — not just a checklist. Notice the set-cookie header above: cookie values are redacted in output while security-relevant attributes are preserved, because you don't want to leak a real session token into a report.
You can also run jin https://example.com directly — a bare URL is treated as an info scan.
2. ports — TCP connect scan
Jin scans a curated default list of common services, or your own:
🔍 Open ports:
22/ssh
80/http
443/https
5432/postgresql
jin ports -t example.com -p 80,443,8080,8443
Default ports include FTP, SSH, SMTP, DNS, HTTP(S), mail, MySQL, PostgreSQL, Redis, and MongoDB — and you can pass a comma-separated custom list with -p. Each port is mapped to its service name, and output is clean enough to grep or script against.
3. tech-stack — fingerprinting, subdomains & DNS
This is the most fun one. Jin fingerprints a target across 13 categories — CMS, web server, backend runtime, programming language, web framework, JS framework, JS library, CSS framework, WAF/reverse proxy, analytics, CDN, security, and other:
🧩 Stack: WordPress, Nginx, PHP, jQuery, Cloudflare
⏱️ Scan Time: 1.2s
▸ CMS
WordPress (6.5.2) High (80%)
• Meta tag: generator=WordPress 6.5.2
▸ Web Server
Nginx Very High (97%)
• Header: Server: nginx
▸ Programming Language
PHP High (80%)
• Header: X-Powered-By: PHP/8.2.9
▸ JavaScript Library
jQuery (3.7.1) High (80%)
• Markup: jquery-3.7.1.min.js
▸ WAF / Reverse Proxy
Cloudflare Very High (97%)
• Header: Server: cloudflare
Every detection comes with a confidence level and the evidence that produced it — the actual header value, meta tag, cookie, or script path. No black box.
Run it with --subdomains (or -s) and Jin goes deeper:
jin tech-stack -t example.com --subdomains
- Subdomain discovery queries crt.sh, the public certificate transparency log. This is a purely passive technique — it reads public certificate data and never sends a single packet to the target, so there's no scanning footprint.
- Each discovered subdomain is probed and fingerprinted independently, so you get a map of the whole attack surface:
blog.example.comruns WordPress,api.example.comruns Express,mail.example.comis unreachable. - DNS records (nameservers, MX, TXT) are pulled with the Go standard library, which is great for spotting SPF/DKIM/DMARC posture and hosting infrastructure at a glance:
🗂️ DNS Records:
Nameservers: ns1.cloudflare.com, ns2.cloudflare.com
MX Records: aspmx.l.google.com, ...
TXT Records:
• v=spf1 include:_spf.google.com ~all
• google-site-verification=...
The interactive REPL
Running jin with no arguments drops you into a proper REPL — not a crude loop, but a real readline shell:
jin
jin> https://example.com
jin> ports -t example.com -p 80,443
jin> tech-stack -t example.com --subdomains
jin> exit
Nice touches that make it genuinely usable for research sessions:
- Tab completion for all commands.
-
Command history persisted to
~/.jin_history. - Up/Down arrow to recall previous commands.
-
Ctrl+C aborts the in-flight scan and exits cleanly;
exit/quit/Ctrl+D(EOF) also work. - Even a plain line reader fallback when stdin isn't a TTY.
One-shot usage still works exactly as before, which keeps Docker and scripting happy:
jin ports -t example.com
jin tech-stack -t example.com --subdomains --json | jq '.categories'
JSON output for automation
Every command accepts --json. The output is a stable, well-shaped document designed for parsing — with scanned_at, duration_ms, and machine-friendly fields. For example, the tech-stack JSON groups detections by category and includes per-technology evidence and confidence scores, plus the subdomain and DNS sections when requested.
This makes Jin easy to slot into recon pipelines, dashboards, or internal asset-discovery tooling.
Installation
From source
Requires Go 1.25+:
git clone https://github.com/sapiuwu/jin.git
cd jin
go build -o jin ./cmd/
./jin
With Docker
docker pull wahyouka/jin:v2.3.0
# interactive REPL
docker run -it --entrypoint jin wahyouka/jin:v2.3.0
# one-shot
docker run -it wahyouka/jin:v2.3.0 tech-stack -t example.com --subdomains
The image is a static, Alpine-based build with CA certificates and timezone data baked in.
A peek under the hood
If you're the kind of person who reads the source before trusting a security tool (you should be), Jin won't disappoint. It's organized as a textbook hexagonal architecture:
cmd/ → composition root (main.go)
internal/
domain/ → pure domain models, no dependencies
port/ → driving ports (services) & driven ports (scanners)
application/→ use-case services (scan orchestration, security scoring)
adapter/
in/cli/ → CLI + REPL, argument parsing, rendering
out/scanner/ → HTTP scanner, TCP port scanner, CT-log enumerator, DNS lookup
config/ → centralized timeouts & tuning knobs
container/ → dependency wiring
Each scanner is an out adapter implementing a driven port, and the CLI is the in adapter talking to driving ports. That means:
- Adding a new detection signature is a self-contained change.
- Swapping
crt.shfor another CT log source doesn't touch application code. - The rendering layer is fully decoupled from the scanning layer.
- Everything is testable with fake adapters.
When would you actually use this?
- Bug bounty / pentest recon — map the attack surface before touching a target: what runs, where, on which ports, and which subdomains exist.
-
Own-infrastructure hygiene — run
infoagainst your own sites and fix the "free wins": missing HSTS, missing CSP, cookie flags, CORS misconfigs. - Competitive intel (legally) — a quick fingerprint of public-facing stacks.
- Learning security — watching the evidence lines is a great way to learn how fingerprinting actually works.
- Rapid triage — one binary, one command, one screen, instead of assembling nmap + whatweb + dnsrecon output by hand.
The honest limits
Jin is not a replacement for a full arsenal:
- The port scanner is a TCP connect scan — it's slower and more detectable than SYN scanning, and it won't detect UDP services.
- Fingerprinting is signature-based — heavily obfuscated or custom-built apps may come back with nothing.
- Subdomain discovery relies on certificate transparency only — it won't find subdomains that never got a public certificate.
- The security score is a starting point, not a certification. It can't catch logic bugs, auth flaws, or injection vulnerabilities.
Wrapping up
Jin is a thoughtful, well-engineered little tool that makes the first five minutes of any recon fast and pleasant — a passive OSINT pass, a port overview, and a tech-stack map, all from one binary with output you can actually read.
If that sounds useful to you:
- GitHub: github.com/sapiuwu/jin
- Install it, run
jinwith no arguments, and scan something you own.
And remember — with great recon power comes great responsibility. Only point it at targets you're authorized to investigate. Happy (ethical) hunting.
Top comments (0)