SkillAgentSearch skills...

port-service-discovery

Nmap scan for MySQL, Redis, FTP, SSH, internal API services.

Install / Use

npx skills add uphiago/recon-skills --skill port-service-discovery

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

89/100

Category

Security

Supported Platforms

Universal

Our assessment of port-service-discovery

port-service-discovery scores 89/100 on our quality scale, 498th of 971 Security skills we index.

Its SKILL.md is 8.7 KB long, well organised into 31 sections with 6 code examples: a thorough specification that gives an agent plenty to work with.

With 1,280 GitHub stars, it is one of the more widely adopted skills in the catalogue.

Substance
29/30
Structure
20/20
Description
12/15
Adoption
13/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 29 days ago, so port-service-discovery is actively maintained.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

port-service-discovery compared with similar skills

All 4 of these similar skills score higher than port-service-discovery; compare them before choosing.

SkillScoreStarsUpdatedFormat
port-service-discovery (this skill)by uphiago891.3k29d agoSKILL.md
claude-memby thedotmack10095.0ktodayCLAUDE.md
Agent-Reachby Panniantong10086.6k15d agoCLAUDE.md
headroomby headroomlabs-ai10074.2ktodayCLAUDE.md
Scraplingby D4Vinci10084.8ktodayMCP Server

Frequently asked questions

How do I install port-service-discovery?
Run npx skills add uphiago/recon-skills --skill port-service-discovery. The install tabs above show the steps for each supported agent.
Which AI agents does port-service-discovery work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is port-service-discovery safe to use?
It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is port-service-discovery still maintained?
The repository was last updated 29 days ago, so port-service-discovery is actively maintained.

name: port-service-discovery description: Nmap scan for MySQL, Redis, FTP, SSH, internal API services. version: 1.1.0 revision_date: 2026-07-25 license: MIT platforms: [linux] compatibility: Requires curl, nmap, masscan tags: [recon, port-scan, mysql, FTP, SSH, internal-api] category: recon related_skills:

  • deep-invade
  • wp-mass-recon
  • cross-attack-chains
  • staging-subdomain-hunt
  • xmlrpc-exploitation

Port & Service Discovery Skill

Use scoped Nmap discovery to identify services adjacent to web applications, including databases, remote administration, mail, caches, and non-standard API ports. An open port is an observation; service identity and unauthorized access require separate validation.

When to Use

  • Running deep-invade Phase 6 on a high-value target.
  • After surface recon shows no exploitable web vulnerabilities — pivot to infrastructure.
  • When the target is a SaaS with backend APIs on non-standard ports.
  • After discovering a staging subdomain — check for database/admin ports.

Prerequisites

  • nmap available in the execution environment.
  • Target domain or IP address.
  • For full port scan: patience (can take 10-60 minutes for all 65535 ports).

How to Run

# Fast top-100 port scan (30 seconds)
nmap -F --open -T4 TARGET -oN nmap_fast.txt

# Top 1000 ports (2-3 minutes)
nmap --top-ports 1000 --open -T4 TARGET -oN nmap_1000.txt

# Service version detection on open ports
nmap -sV -p $(grep 'open' nmap_fast.txt | cut -d/ -f1 | tr '\n' ',') TARGET

# Firewall bypass: fragment packets
nmap -f -F TARGET

Quick Reference

| Port | Service | Finding Severity | |------|---------|-----------------| | 3306 | MySQL | Critical (if open to internet) | | 27017 | MongoDB | Critical (if no auth) | | 6379 | Redis | Critical (if no auth) | | 5432 | PostgreSQL | High | | 1433 | MS SQL Server | High | | 21 | FTP | High (anonymous login?) | | 22 | SSH | Info (check for weak auth) | | 8080/8081/8082/8084 | Internal APIs | High (backend services exposed) | | 9200 | Elasticsearch | High (data exposure) | | 25/587 | SMTP | Medium (open relay?) | | 110/143/993 | POP3/IMAP | Info | | 8443 | HTTPS alt (admin panels) | Medium | | 9090 | Prometheus/Cockpit | Medium | | 3000 | Grafana/Node.js dev | Medium |

Procedure

Step 1 — Fast Top-100 Scan

TARGET="$1"
OUTDIR="$OUTDIR/ports"
mkdir -p "$OUTDIR"

echo "[*] Fast scan (top 100 ports) on $TARGET..."
nmap -F --open -T4 --max-retries 1 --host-timeout 60s "$TARGET" -oN "$OUTDIR/${TARGET}_fast.nmap" 2>/dev/null

echo "[*] Open ports:"
grep 'open' "$OUTDIR/${TARGET}_fast.nmap" || echo "  None found"

Step 2 — Service Version Detection

TARGET="$1"
OUTDIR="$OUTDIR/ports"

# Get comma-separated list of open ports
OPEN_PORTS=$(grep '^[0-9]' "$OUTDIR/${TARGET}_fast.nmap" | awk -F/ '{print $1}' | tr '\n' ',' | sed 's/,$//')

if [[ -n "$OPEN_PORTS" ]]; then
  echo "[*] Service detection on ports: $OPEN_PORTS"
  nmap -sV --version-intensity 5 -p "$OPEN_PORTS" "$TARGET" -oN "$OUTDIR/${TARGET}_services.nmap" 2>/dev/null

  echo "[*] Services:"
  grep 'open' "$OUTDIR/${TARGET}_services.nmap"
else
  echo "[-] No open ports found"
fi

Step 3 — Critical Exposure Check

TARGET="$1"
OUTDIR="$OUTDIR/ports"

echo "[*] Critical exposure assessment:"

# MySQL (3306)
if grep -q '3306.*open' "$OUTDIR/${TARGET}_fast.nmap" 2>/dev/null; then
  echo ""
  echo "[CRITICAL] MySQL 3306 OPEN — attempting banner grab..."
  # Try to get MySQL version
  mysql_info=$(timeout 5 nc -w 3 "$TARGET" 3306 </dev/null 2>/dev/null | head -1)
  [[ -n "$mysql_info" ]] && echo "  Banner: $mysql_info"

  # Test for no-auth MySQL
  echo "  Testing anonymous access..."
  # This typically requires mysql client; note methodology
  echo "  Manual check: mysql -h $TARGET -u root --skip-ssl"
  echo "  Manual check: mysql -h $TARGET -u admin --skip-ssl"
fi

# MongoDB (27017)
if grep -q '27017.*open' "$OUTDIR/${TARGET}_fast.nmap" 2>/dev/null; then
  echo ""
  echo "[CRITICAL] MongoDB 27017 OPEN"
  echo "  Manual check: mongosh mongodb://$TARGET:27017"
fi

# Redis (6379)
if grep -q '6379.*open' "$OUTDIR/${TARGET}_fast.nmap" 2>/dev/null; then
  echo ""
  echo "[HIGH] Redis 6379 OPEN — testing no-auth access..."
  redis_test=$(timeout 5 bash -c "echo -e 'PING\r\nINFO\r\n' | nc -w 3 '$TARGET' 6379 2>/dev/null")
  if echo "$redis_test" | grep -q "PONG"; then
    echo "  [CRITICAL] Redis NO AUTH — full access!"
    echo "  Response: $(echo "$redis_test" | head -5)"
  else
    echo "  Redis requires auth (or connection failed)"
  fi
fi

# Internal API ports (8080-8089)
for port in 8080 8081 8082 8084 8088 8443 3000 5000 9000 9090; do
  if grep -q "${port}.*open" "$OUTDIR/${TARGET}_fast.nmap" 2>/dev/null; then
    echo ""
    echo "[HIGH] Port $port OPEN — probing HTTP..."
    http_code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 5 "http://$TARGET:$port/" 2>/dev/null)

    if [[ "$http_code" != "000" ]]; then
      echo "  HTTP $http_code on port $port"
      title=$(curl -sk --max-time 5 --connect-timeout 5 "http://$TARGET:$port/" 2>/dev/null | grep -Eo '<title>\K[^<]+')
      [[ -n "$title" ]] && echo "  Title: $title"

      # Check for Swagger/API docs
      for api_path in "swagger.json" "api-docs" "swagger-ui.html" "graphql" "actuator/health"; do
        api_code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 5 "http://$TARGET:$port/$api_path")
        [[ "$api_code" == "200" ]] && echo "  [API] http://$TARGET:$port/$api_path (HTTP 200)"
        sleep 0.2
      done
    fi
  fi
done

# FTP (21) — check for anonymous login
if grep -q '21.*open' "$OUTDIR/${TARGET}_fast.nmap" 2>/dev/null; then
  echo ""
  echo "[HIGH] FTP 21 OPEN — testing anonymous login..."
  anon_test=$(timeout 10 bash -c "echo -e 'anonymous\nanonymous\n' | nc -w 3 '$TARGET' 21 2>/dev/null")
  if echo "$anon_test" | grep -qi "230"; then
    echo "  [CRITICAL] Anonymous FTP login successful!"
  elif echo "$anon_test" | grep -qi "530\|331"; then
    echo "  Anonymous FTP: requires auth"
  fi
fi

# SSH (22) — check for weak ciphers
if grep -q '22.*open' "$OUTDIR/${TARGET}_fast.nmap" 2>/dev/null; then
  echo ""
  echo "[INFO] SSH 22 OPEN"
  ssh_banner=$(timeout 5 nc -w 3 "$TARGET" 22 </dev/null 2>/dev/null | head -1)
  [[ -n "$ssh_banner" ]] && echo "  Banner: $ssh_banner"
fi

Step 4 — Extended Port Range (when fast scan finds nothing)

TARGET="$1"
OUTDIR="$OUTDIR/ports"

# If no ports found in top-100, expand to top-1000
if ! grep -q 'open' "$OUTDIR/${TARGET}_fast.nmap" 2>/dev/null; then
  echo "[*] No ports in top-100, scanning top-1000..."
  nmap --top-ports 1000 --open -T4 --max-retries 1 --host-timeout 120s "$TARGET" -oN "$OUTDIR/${TARGET}_1000.nmap" 2>/dev/null

  OPEN=$(grep 'open' "$OUTDIR/${TARGET}_1000.nmap")
  if [[ -z "$OPEN" ]]; then
    # Try SYN scan with fragmentation for firewall evasion
    echo "[*] Still nothing — trying fragmented SYN scan..."
    nmap -f -sS -F --open -T4 "$TARGET" -oN "$OUTDIR/${TARGET}_frag.nmap" 2>/dev/null
  fi
fi

Step 5 — Firewall/WAF Fingerprinting

TARGET="$1"

echo "[*] WAF/CDN detection:"

# Check for Cloudflare
cf_header=$(curl -skI --max-time 5 --connect-timeout 5 "https://$TARGET/" 2>/dev/null | grep -i "cf-ray\|cloudflare")
[[ -n "$cf_header" ]] && echo "  Cloudflare detected"

# Check for AWS CloudFront
cf_header=$(curl -skI --max-time 5 --connect-timeout 5 "https://$TARGET/" 2>/dev/null | grep -i "x-amz-cf\|cloudfront")
[[ -n "$cf_header" ]] && echo "  AWS CloudFront detected"

# Check origin IP (bypass CDN)
echo "[*] Historical DNS records for origin IP discovery:"
# SecurityTrails, DNSDumpster, etc. — use HTTP fetch for these
echo "  Manual: securitytrails.com/domain/$TARGET/dns/a"
echo "  Manual: dnsdumpster.com"

# Try direct IP connection (if known)
# curl -sk --resolve "$TARGET:443:ORIGIN_IP" "https://$TARGET/"

Pitfalls

  • nmap SYN scan requires raw-socket privileges. Use -sT (TCP connect) when the execution environment does not grant them.
  • Rate limiting on port scans. Some providers (AWS, Cloudflare) rate-limit or block port scans. Use -T2 (polite timing) and --max-retries 1 on sensitive targets.
  • MySQL/MongoDB banner grab may not work. Some DBs require TLS negotiation (MySQL 8.0+ defaults to caching_sha2_password). Banner may be empty.
  • Internal API ports may time out. Some services only respond to specific Host headers or valid HTTP requests. Use curl with various Host headers.

Verification

  • Every open port MUST be confirmed with service version detection (nmap -sV).
  • MySQL access MUST be tested with actual connection attempt (not just port open).
  • Redis no-auth MUST return PONG to PING command.
  • FTP anonymous MUST return code 230 (login successful).
  • All findings MUST be documented with exact port, service, version, and access level.

Related Skills

View on GitHub
GitHub Stars1.3k
CategorySecurity
Updated29d ago
Forks215

Languages

Python

Trust signals

100/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

No cautions