SubSurfer is a fast and efficient subdomain enumeration and web property identification tool.

- Red Team/Bug Bounty Support: Useful for both red team operations and web bug bounty projects
- High-Performance Scanning: Fast subdomain enumeration using asynchronous and parallel processing
- Port Scanning: Expand asset scanning range with customizable port selection
- Web Service Identification: Gather environmental details such as web servers and technology stacks
- Pipeline Integration: Supports integration with other tools using
-pipeweband-pipesuboptions - Modular Design: Can be imported and used as a Python module
- Continuous Updates: - Continuous Updates: New passive/active modules will continue to be added
bash
git clone https://github.com/arrester/subsurfer.git
cd subsurferor
Python
pip install subsurferBasic Scan
subsurfer -t vulnweb.com
Enable Active Scanning
subsurfer -t vulnweb.com -a
Include Port Scanning
subsurfer -t vulnweb.com -dp # Default Port
subsurfer -t vulnweb.com -p 80,443,8080-8090 # Custom ports
Pipeline Output
subsurfer -t vulnweb.com -pipeweb # Output only web server
subsurfer -t vulnweb.com -pipesub # Output only subdomain results
Subdomain Scan
from subsurfer.core.controller.controller import SubSurferController
import asyncio
async def main():
controller = SubSurferController(
target="vulnweb.com",
verbose=1,
active=False # Active Scan Option
)
# Collect subdomains
subdomains = await controller.collect_subdomains()
# Print results
print(f"Discovered Subdomains: {len(subdomains)}개")
for subdomain in sorted(subdomains):
print(subdomain)
if __name__ == "__main__":
asyncio.run(main())Port Scan
from subsurfer.core.controller.controller import SubSurferController
import asyncio
async def main():
controller = SubSurferController(
target="vulnweb.com",
verbose=1
)
# Collect subdomains
subdomains = await controller.collect_subdomains()
# Default ports (80, 443)
ports = None
# Set port scan options
# ports = controller.parse_ports() # Default ports
# Or specify custom ports
# ports = controller.parse_ports("80,443,8080-8090")
# Web service scanning
web_services = await controller.scan_web_services(subdomains, ports)
# Print web servers
print("\n웹 서버:")
for server in sorted(web_services['web_servers']):
print(f"https://{server}")
# Print active services
print("\n활성화된 서비스:")
for service in sorted(web_services['enabled_services']):
print(service)
# Print discovered URLs and ports
print("\n발견된 URL:")
for subdomain, urls in web_services['all_urls'].items():
for url, port in urls:
print(f"{url}:{port}")
if __name__ == "__main__":
asyncio.run(main())Result Save
from subsurfer.core.controller.controller import SubSurferController
import asyncio
async def main():
controller = SubSurferController("vulnweb.com")
# Collect subdomains and scan web services
subdomains = await controller.collect_subdomains()
web_services = await controller.scan_web_services(subdomains)
# Save results
results_dict = {
'subdomains': subdomains,
'web_services': web_services.get('web_services', {}),
'web_servers': web_services.get('web_servers', set()),
'enabled_services': web_services.get('enabled_services', set()),
'all_urls': web_services.get('all_urls', {}) # Includes URL and port information
}
# Generate default result file path (stored in the "results" directory)
output_path = controller.get_output_path()
controller.save_results(results_dict, output_path)
if __name__ == "__main__":
asyncio.run(main())pytest tests/handlers/test_passive_handler.py -v
pytest tests/handlers/test_active_handler.py -v
- Add new passive modules
- Add Cloud Detect modules
- Add AI Recon Model
- Recommended: Python 3.13.0 or later
- aiohttp
- rich
- pytest (for testing)
MIT License
Bug Report, Feature Suggestions, Issue Report