The Registration Data Access Protocol (RDAP) is the definitive source for delivering generic top-level domain name (gTLD) registration information in place of sunsetted WHOIS services. The rdap command is a full-featured, command-line interface (CLI) client for RDAP. It supports RDAP bootstrapping, caching, different output formats, and many more features.
rdap
Basic Queries
Email Recon (T1589.002)
curl emailrep.io/john.smith@gmail.com
Hunter.io
Search for email addresses associated with a specific domain or company. You can also search for specific individuals by providing their name and the company domain:
nrich IP Enumeration (T1595.002)
A command-line tool to quickly analyze all IPs in a file and see which ones have open ports/ vulnerabilities. Can also be fed data from stdin to be used in a data pipeline.
Install
Confirmation
Usage
Extracting PDF Text with Python Image OCR (T1213)
Threat Intelligence Streams with Python and Reddit (T1589)
Enumerate new Reddit comments for threat intelligence. This script can be modified with regular expressions to hone in on exploit development, modern threats, and any newsworthy cyber events.
Note : Use shodan_eye.py to search for FTP servers that have the anon login enabled.
Search Keyword : 230 anonymous
Python Keylogger (T1056.001)
Mailtrap.io implementation:
Python Reverse Shell (T1059.006)
Python Basic File Upload (T1105)
Generating HoneyDocs with Python (T1203)
Python's Faker module can be utilized to create honeydocs of PII with malicious macros, wordlists, emails for login brute-forcing, and much more.
Shodan CLI (T1595)
The shodan command-line interface (CLI) is packaged with the official Python library for Shodan, which means if you're running the latest version of the library you already have access to the CLI. To install the new tool simply execute:
Once the tool is installed you have to initialize the environment with your API key using shodan init:
count
Returns the number of results for a search query:
host
See information about the host such as where it's located, what ports are open and which organization owns the IP:
myip
Returns your Internet-facing IP address:
search
This command lets you search Shodan and view the results in a terminal-friendly way. By default it will display the IP, port, hostnames and data. You can use the --fields parameter to print whichever banner fields you're interested in:
Azure Subdomain Enumeration (T1595.003)
A simple Go program for enumerating Azure targets:
Output:
GitHub Email Addresses (T1589.002)
A script for enumerating GitHub to find a user's email:
Script to enumerate all users in a GitHub organization and find their public emails
Code Enumeration with Grep App (T1213)
Rapidly scan millions of code repositories with Grep App:
Certificate Transparency Logs Enumeration with Go (T1596.002)
Certificate Transparency (CT) logs are publicly accessible repositories that record all SSL/TLS certificates issued by Certificate Authorities. These logs make it possible to monitor certificate issuance, detect misissued certificates, and discover subdomains and services associated with a target domain.
A popular way to search these logs is via crt.sh, which provides a web interface and API for querying certificate records. For programmatic access in Go applications, the go-crtsh library offers a convenient wrapper around the crt.sh API:
{
"ip": "8.8.8.8",
"country_code": "US",
"country_name": "United States of America",
"region_name": "California",
"city_name": "Mountain View",
"latitude": 37.38605,
"longitude": -122.08385,
"zip_code": "94035",
"time_zone": "-07:00",
"asn": "15169",
"as": "Google LLC",
"is_proxy": false,
"message": "Limit to 500 queries per day. Sign up for a Free plan at https://www.ip2location.io to get 30K queries per month."
}
$ nrich --help
nrich 0.1.0
Add network information to IPs
USAGE:
nrich [OPTIONS] <filename>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-o, --output <output> Output format (shell or json) [default: shell]
ARGS:
<filename> File containing an IP per line. Non-IPs are ignored
#!/usr/bin/env python3
from PIL import Image
import pyTesseract
import numpy as np
# Simple PDF Image OCR Extractor
file = '/home/rosesecurity/Desktop/Target_OrgChart.pdf'
pdf_img = np.array(Image.open(file))
text = pyTesseract.image_to_string(pdf_img)
#!/usr/bin/env python3
import praw
reddit = praw.Reddit(client_id ='xxxxxxxxxxxxxxx',
client_secret ='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
user_agent ='Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
username ='username',
password ='pass')
for comment in reddit.subreddit('hacking+infosec+redteamsec+cybersecurity+netsec+hackernews+malware+blueteamsec').stream.comments():
print(comment.body)
# Listen to files
python3 -m pip install --user uploadserver
python3 -m uploadserver
# With basic auth:
# python3 -m uploadserver --basic-auth hello:world
# Send a file
curl -X POST http://HOST/upload -H -F 'files=@file.txt'
# With basic auth:
# curl -X POST http://HOST/upload -H -F 'files=@file.txt' -u hello:world
import pandas as pd
from faker import Faker
# Create a Faker object
fake = Faker()
# Options to data:
fake.name()
fake.text()
fake.address()
fake.email()
fake.date()
fake.country()
fake.phone_number()
fake.random_number(digits=5)
# Example DataFrame
faker_df = pd.DataFrame({'date':[fake.date() for i in range(10)],
'name':[fake.name() for i in range(10)],
'email':[fake.email() for i in range(10)],
'text':[fake.text() for i in range(10)]})
faker_df
easy_install shodan
shodan init YOUR_API_KEY
shodan count microsoft iis 6.0
5310594
shodan host 189.201.128.250
shodan myip
199.30.49.210
shodan search --fields ip_str,port,org,hostnames microsoft iis 6.0
package main
import (
"flag"
"fmt"
"net"
"os"
"github.com/miekg/dns"
)
type Config struct {
Domain string
Permutations bool
EnumA bool
EnumCNAME bool
EnumMX bool
EnumNS bool
EnumSOA bool
EnumTXT bool
}
func main() {
cfg := parseFlags()
if cfg.Domain == "" {
flag.Usage()
os.Exit(1)
}
subdomains := []string{
".onmicrosoft.com", ".scm.azurewebsites.net", ".azurewebsites.net", ".p.azurewebsites.net", ".cloudapp.net",
".file.core.windows.net", ".blob.core.windows.net", ".queue.core.windows.net", ".table.core.windows.net",
".mail.protection.outlook.com", ".sharepoint.com", ".redis.cache.windows.net", ".documents.azure.com",
".database.windows.net", ".vault.azure.net", ".azureedge.net", ".search.windows.net", ".azure-api.net", ".azurecr.io",
}
targets := generateTargetDomains(cfg, subdomains)
for _, t := range targets {
if cfg.EnumA && hasARecord(t) {
fmt.Printf("[+] Discovered: %s\n", t)
performLookups(cfg, t)
}
}
}
func parseFlags() Config {
var c Config
flag.StringVar(&c.Domain, "domain", "", "Target domain without TLD (e.g., victim)")
flag.BoolVar(&c.Permutations, "perm", false, "Generate keyword permutations around the domain")
flag.BoolVar(&c.EnumA, "a", true, "Enumerate A records")
flag.BoolVar(&c.EnumCNAME, "cname", true, "Enumerate CNAME records")
flag.BoolVar(&c.EnumMX, "mx", true, "Enumerate MX records")
flag.BoolVar(&c.EnumNS, "ns", true, "Enumerate NS records")
flag.BoolVar(&c.EnumSOA, "soa", true, "Enumerate SOA records")
flag.BoolVar(&c.EnumTXT, "txt", true, "Enumerate TXT records")
flag.Parse()
return c
}
func generateTargetDomains(cfg Config, subs []string) []string {
bases := []string{cfg.Domain}
if cfg.Permutations {
keywords := []string{
"root", "web", "api", "azure", "azure-logs", "data", "database", "data-private", "data-public", "dev",
"development", "demo", "files", "filestorage", "internal", "keys", "logs", "private", "prod", "production",
"public", "service", "services", "splunk", "sql", "staging", "storage", "storageaccount", "test", "useast",
"useast2", "centralus", "northcentralus", "westcentralus", "westus", "westus2",
}
for _, k := range keywords {
bases = append(bases, fmt.Sprintf("%s-%s", cfg.Domain, k))
bases = append(bases, fmt.Sprintf("%s-%s", k, cfg.Domain))
}
}
var targets []string
for _, b := range bases {
for _, s := range subs {
targets = append(targets, b+s)
}
}
return targets
}
func hasARecord(d string) bool {
_, err := net.LookupIP(d)
return err == nil
}
func performLookups(cfg Config, d string) {
if cfg.EnumA {
if ips, _ := net.LookupIP(d); len(ips) > 0 {
fmt.Printf(" A %v\n", ips)
}
}
if cfg.EnumCNAME {
if c, err := net.LookupCNAME(d); err == nil {
fmt.Printf(" CNAME %s\n", c)
}
}
if cfg.EnumNS {
if nss, err := net.LookupNS(d); err == nil {
var hosts []string
for _, ns := range nss {
hosts = append(hosts, ns.Host)
}
fmt.Printf(" NS %v\n", hosts)
}
}
if cfg.EnumMX {
if mxs, err := net.LookupMX(d); err == nil {
var entries []string
for _, mx := range mxs {
entries = append(entries, fmt.Sprintf("%s (%d)", mx.Host, mx.Pref))
}
fmt.Printf(" MX %v\n", entries)
}
}
if cfg.EnumTXT {
if txts, err := net.LookupTXT(d); err == nil {
fmt.Printf(" TXT %v\n", txts)
}
}
if cfg.EnumSOA {
if soa, err := querySOA(d); err == nil {
fmt.Printf(" SOA %s\n", soa)
}
}
}
func querySOA(name string) (string, error) {
m := new(dns.Msg)
m.SetQuestion(dns.Fqdn(name), dns.TypeSOA)
in, err := dns.Exchange(m, "8.8.8.8:53")
if err != nil {
return "", err
}
for _, ans := range in.Answer {
if soa, ok := ans.(*dns.SOA); ok {
return soa.String(), nil
}
}
return "", fmt.Errorf("SOA record not found")
}
#!/usr/bin/env bash
# A script for enumerating GitHub to find a user's email
USERNAME="$1"
if [ -z "$USERNAME" ]; then
echo "Usage: $0 <github_username>"
exit 1
fi
echo "Searching emails for GitHub user: $USERNAME"
echo -e "\nChecking public profile..."
PROFILE_EMAIL=$(curl -s "https://api.github.com/users/$USERNAME" | jq -r '.email')
if [ "$PROFILE_EMAIL" != "null" ] && [ -n "$PROFILE_EMAIL" ]; then
echo "Public profile email: $PROFILE_EMAIL"
else
echo "No public email found on profile."
fi
echo -e "\nChecking recent commit activity..."
EMAILS=$(curl -s "https://api.github.com/users/$USERNAME/events/public" |
jq -r '.[].payload.commits[]? | select(.author.email | contains("noreply") | not) | .author.email' |
sort -u)
if [ -n "$EMAILS" ]; then
echo "Emails found in recent commits:"
echo "$EMAILS"
else
echo "No commit emails found."
fi
#!/usr/bin/env bash
# Script to enumerate all users in a GitHub org and find their public emails using gh CLI
ORG="$1"
PER_PAGE=100
if [ -z "$ORG" ]; then
echo "Usage: $0 <github_organization>"
exit 1
fi
echo "Enumerating users and searching for public emails in GitHub organization: $ORG"
page=1
while :; do
USERS=$(gh api "/orgs/$ORG/members?per_page=$PER_PAGE&page=$page" | jq -r '.[].login')
[ -z "$USERS" ] && break
for USERNAME in $USERS; do
PROFILE_EMAIL=$(gh api "/users/$USERNAME" | jq -r '.email // empty')
if [ -n "$PROFILE_EMAIL" ]; then
echo "$USERNAME: $PROFILE_EMAIL"
else
echo "$USERNAME: No public email"
fi
done
((page++))
done