subsurfer


Namesubsurfer JSON
Version 0.2.4 PyPI version JSON
download
home_pagehttps://github.com/arrester/subsurfer
SummaryRed Teaming and Web Bug Bounty Fast Asset Identification Tool
upload_time2025-02-01 07:17:20
maintainerNone
docs_urlNone
authorarrester
requires_python>=3.9
licenseNone
keywords security subdomain enumeration bug bounty red team web security
VCS
bugtrack_url
requirements aiohappyeyeballs aiohttp aioresponses aiosignal art asyncio attrs beautifulsoup4 bs4 certifi charset-normalizer dnspython frozenlist httpretty idna iniconfig lxml markdown-it-py mdurl multidict packaging pluggy propcache Pygments pytest pytest-asyncio python-Wappalyzer PyYAML requests rich setuptools soupsieve urllib3 yarl
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # πŸ„β€β™‚οΈ SubSurfer

![Python Version](https://img.shields.io/badge/python-3.13%2B-blue)
![License](https://img.shields.io/badge/license-MIT-green)
![Version](https://img.shields.io/badge/version-0.2-orange)

SubSurfer is a fast and efficient subdomain enumeration and web property identification tool.
![alt text](image.png)

<br>

## 🌟 Features
- **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 `-pipeweb` and `-pipesub` options
- **Modular Design**: Can be imported and used as a Python module
- **Continuous Updates**: - **Continuous Updates**: New passive/active modules will continue to be added

<br>

## πŸš€ Installation
<b>bash</b>
```bash
git clone https://github.com/arrester/subsurfer.git
cd subsurfer
```

or <br>

<b>Python</b>
```bash
pip install subsurfer
```

<br>

## πŸ“– Usage
### CLI Mode
<b>Basic Scan</b><br>
`subsurfer -t vulnweb.com`

<b>Enable Active Scanning</b><br>
`subsurfer -t vulnweb.com -a`

<b>Include Port Scanning</b><br>
`subsurfer -t vulnweb.com -dp` # Default Port <br>
`subsurfer -t vulnweb.com -p 80,443,8080-8090` # Custom ports

<b>Pipeline Output</b><br>
`subsurfer -t vulnweb.com -pipeweb` # Output only web server <br>
`subsurfer -t vulnweb.com -pipesub` # Output only subdomain results

### Using as a Python Module
<b>Subdomain Scan</b><br>
```python
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())
```

<br>

<b>Port Scan</b><br>
```python
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())
```

<br>

<b>Result Save</b><br>
```python
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())
```

<br>

## πŸ§ͺ Testing
### Passive Handler Test
`pytest tests/handlers/test_passive_handler.py -v`

<br>

### Active Handler Test
`pytest tests/handlers/test_active_handler.py -v`

<br>

## πŸ—ΊοΈ To-Do List
### Version 0.3
- Add JSON output option
- Add new passive modules
- Additional etc feature updates

### Version 0.4
- Add new passive modules
- Implement subdomain takeover detection

### Version 0.5
- Add new passive modules
- Add new active modules

## πŸ“‹ Requirements
- Recommended: Python 3.13.0 or later
- aiohttp
- rich
- pytest (for testing)

## πŸ“ License
MIT License

## 🀝 Contributions
Bug Report, Feature Suggestions, Pull Request

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/arrester/subsurfer",
    "name": "subsurfer",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "security, subdomain enumeration, bug bounty, red team, web security",
    "author": "arrester",
    "author_email": "arresterloyal@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/06/7f/b40330a16c77c69c95d53c700f909391b690cfffb83669bd2e95de2e813b/subsurfer-0.2.4.tar.gz",
    "platform": null,
    "description": "# \ud83c\udfc4\u200d\u2642\ufe0f SubSurfer\n\n![Python Version](https://img.shields.io/badge/python-3.13%2B-blue)\n![License](https://img.shields.io/badge/license-MIT-green)\n![Version](https://img.shields.io/badge/version-0.2-orange)\n\nSubSurfer is a fast and efficient subdomain enumeration and web property identification tool.\n![alt text](image.png)\n\n<br>\n\n## \ud83c\udf1f Features\n- **Red Team/Bug Bounty Support**: Useful for both red team operations and web bug bounty projects\n- **High-Performance Scanning**: Fast subdomain enumeration using asynchronous and parallel processing\n- **Port Scanning**: Expand asset scanning range with customizable port selection\n- **Web Service Identification**: Gather environmental details such as web servers and technology stacks\n- **Pipeline Integration**: Supports integration with other tools using `-pipeweb` and `-pipesub` options\n- **Modular Design**: Can be imported and used as a Python module\n- **Continuous Updates**: - **Continuous Updates**: New passive/active modules will continue to be added\n\n<br>\n\n## \ud83d\ude80 Installation\n<b>bash</b>\n```bash\ngit clone https://github.com/arrester/subsurfer.git\ncd subsurfer\n```\n\nor <br>\n\n<b>Python</b>\n```bash\npip install subsurfer\n```\n\n<br>\n\n## \ud83d\udcd6 Usage\n### CLI Mode\n<b>Basic Scan</b><br>\n`subsurfer -t vulnweb.com`\n\n<b>Enable Active Scanning</b><br>\n`subsurfer -t vulnweb.com -a`\n\n<b>Include Port Scanning</b><br>\n`subsurfer -t vulnweb.com -dp` # Default Port <br>\n`subsurfer -t vulnweb.com -p 80,443,8080-8090` # Custom ports\n\n<b>Pipeline Output</b><br>\n`subsurfer -t vulnweb.com -pipeweb` # Output only web server <br>\n`subsurfer -t vulnweb.com -pipesub` # Output only subdomain results\n\n### Using as a Python Module\n<b>Subdomain Scan</b><br>\n```python\nfrom subsurfer.core.controller.controller import SubSurferController\nimport asyncio\n\nasync def main():\n    controller = SubSurferController(\n        target=\"vulnweb.com\",\n        verbose=1,\n        active=False            # Active Scan Option\n    )\n    \n    # Collect subdomains\n    subdomains = await controller.collect_subdomains()\n    \n    # Print results\n    print(f\"Discovered Subdomains: {len(subdomains)}\uac1c\")\n    for subdomain in sorted(subdomains):\n        print(subdomain)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n<br>\n\n<b>Port Scan</b><br>\n```python\nfrom subsurfer.core.controller.controller import SubSurferController\nimport asyncio\n\nasync def main():\n    controller = SubSurferController(\n        target=\"vulnweb.com\",\n        verbose=1\n    )\n    \n    # Collect subdomains\n    subdomains = await controller.collect_subdomains()\n    \n    # Default ports (80, 443)\n    ports = None\n\n    # Set port scan options\n    # ports = controller.parse_ports()  # Default ports\n    # Or specify custom ports\n    # ports = controller.parse_ports(\"80,443,8080-8090\")\n    \n    # Web service scanning\n    web_services = await controller.scan_web_services(subdomains, ports)\n    \n    # Print web servers\n    print(\"\\n\uc6f9 \uc11c\ubc84:\")\n    for server in sorted(web_services['web_servers']):\n        print(f\"https://{server}\")\n    \n    # Print active services\n    print(\"\\n\ud65c\uc131\ud654\ub41c \uc11c\ube44\uc2a4:\")\n    for service in sorted(web_services['enabled_services']):\n        print(service)\n        \n    # Print discovered URLs and ports\n    print(\"\\n\ubc1c\uacac\ub41c URL:\")\n    for subdomain, urls in web_services['all_urls'].items():\n        for url, port in urls:\n            print(f\"{url}:{port}\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n<br>\n\n<b>Result Save</b><br>\n```python\nfrom subsurfer.core.controller.controller import SubSurferController\nimport asyncio\n\nasync def main():\n    controller = SubSurferController(\"vulnweb.com\")\n    \n    # Collect subdomains and scan web services\n    subdomains = await controller.collect_subdomains()\n    web_services = await controller.scan_web_services(subdomains)\n    \n    # Save results\n    results_dict = {\n        'subdomains': subdomains,\n        'web_services': web_services.get('web_services', {}),\n        'web_servers': web_services.get('web_servers', set()),\n        'enabled_services': web_services.get('enabled_services', set()),\n        'all_urls': web_services.get('all_urls', {})  # Includes URL and port information\n    }\n    \n    # Generate default result file path (stored in the \"results\" directory)\n    output_path = controller.get_output_path()\n    controller.save_results(results_dict, output_path)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n<br>\n\n## \ud83e\uddea Testing\n### Passive Handler Test\n`pytest tests/handlers/test_passive_handler.py -v`\n\n<br>\n\n### Active Handler Test\n`pytest tests/handlers/test_active_handler.py -v`\n\n<br>\n\n## \ud83d\uddfa\ufe0f To-Do List\n### Version 0.3\n- Add JSON output option\n- Add new passive modules\n- Additional etc feature updates\n\n### Version 0.4\n- Add new passive modules\n- Implement subdomain takeover detection\n\n### Version 0.5\n- Add new passive modules\n- Add new active modules\n\n## \ud83d\udccb Requirements\n- Recommended: Python 3.13.0 or later\n- aiohttp\n- rich\n- pytest (for testing)\n\n## \ud83d\udcdd License\nMIT License\n\n## \ud83e\udd1d Contributions\nBug Report, Feature Suggestions, Pull Request\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Red Teaming and Web Bug Bounty Fast Asset Identification Tool",
    "version": "0.2.4",
    "project_urls": {
        "Bug Reports": "https://github.com/arrester/subsurfer/issues",
        "Documentation": "https://github.com/arrester/subsurfer#readme",
        "Homepage": "https://github.com/arrester/subsurfer",
        "Source": "https://github.com/arrester/subsurfer"
    },
    "split_keywords": [
        "security",
        " subdomain enumeration",
        " bug bounty",
        " red team",
        " web security"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "614c10a3ff3e565d7e206a42e910d8c9553e90ad32c3881466fd417f9cfd1ee8",
                "md5": "d7dd47713453b377a3834d621177d2e4",
                "sha256": "13dad6decc5c3dfc72da247c70b9ec6d64fd75544cab1c1ee625820b7693c129"
            },
            "downloads": -1,
            "filename": "subsurfer-0.2.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d7dd47713453b377a3834d621177d2e4",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 40208,
            "upload_time": "2025-02-01T07:17:18",
            "upload_time_iso_8601": "2025-02-01T07:17:18.343459Z",
            "url": "https://files.pythonhosted.org/packages/61/4c/10a3ff3e565d7e206a42e910d8c9553e90ad32c3881466fd417f9cfd1ee8/subsurfer-0.2.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "067fb40330a16c77c69c95d53c700f909391b690cfffb83669bd2e95de2e813b",
                "md5": "3c69f7eeeef5d423abb022019e1e0019",
                "sha256": "293e2a99b2d44d93f539423d8e38193771f29c0b555e1818ea61c1352b33f624"
            },
            "downloads": -1,
            "filename": "subsurfer-0.2.4.tar.gz",
            "has_sig": false,
            "md5_digest": "3c69f7eeeef5d423abb022019e1e0019",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 26784,
            "upload_time": "2025-02-01T07:17:20",
            "upload_time_iso_8601": "2025-02-01T07:17:20.442770Z",
            "url": "https://files.pythonhosted.org/packages/06/7f/b40330a16c77c69c95d53c700f909391b690cfffb83669bd2e95de2e813b/subsurfer-0.2.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-02-01 07:17:20",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "arrester",
    "github_project": "subsurfer",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "aiohappyeyeballs",
            "specs": [
                [
                    "==",
                    "2.4.4"
                ]
            ]
        },
        {
            "name": "aiohttp",
            "specs": [
                [
                    "==",
                    "3.11.11"
                ]
            ]
        },
        {
            "name": "aioresponses",
            "specs": [
                [
                    "==",
                    "0.7.7"
                ]
            ]
        },
        {
            "name": "aiosignal",
            "specs": [
                [
                    "==",
                    "1.3.2"
                ]
            ]
        },
        {
            "name": "art",
            "specs": [
                [
                    "==",
                    "6.4"
                ]
            ]
        },
        {
            "name": "asyncio",
            "specs": [
                [
                    "==",
                    "3.4.3"
                ]
            ]
        },
        {
            "name": "attrs",
            "specs": [
                [
                    "==",
                    "24.3.0"
                ]
            ]
        },
        {
            "name": "beautifulsoup4",
            "specs": [
                [
                    "==",
                    "4.12.3"
                ]
            ]
        },
        {
            "name": "bs4",
            "specs": [
                [
                    "==",
                    "0.0.2"
                ]
            ]
        },
        {
            "name": "certifi",
            "specs": [
                [
                    "==",
                    "2024.12.14"
                ]
            ]
        },
        {
            "name": "charset-normalizer",
            "specs": [
                [
                    "==",
                    "3.4.0"
                ]
            ]
        },
        {
            "name": "dnspython",
            "specs": [
                [
                    "==",
                    "2.7.0"
                ]
            ]
        },
        {
            "name": "frozenlist",
            "specs": [
                [
                    "==",
                    "1.5.0"
                ]
            ]
        },
        {
            "name": "httpretty",
            "specs": [
                [
                    "==",
                    "1.1.4"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    "==",
                    "3.10"
                ]
            ]
        },
        {
            "name": "iniconfig",
            "specs": [
                [
                    "==",
                    "2.0.0"
                ]
            ]
        },
        {
            "name": "lxml",
            "specs": [
                [
                    "==",
                    "5.3.0"
                ]
            ]
        },
        {
            "name": "markdown-it-py",
            "specs": [
                [
                    "==",
                    "3.0.0"
                ]
            ]
        },
        {
            "name": "mdurl",
            "specs": [
                [
                    "==",
                    "0.1.2"
                ]
            ]
        },
        {
            "name": "multidict",
            "specs": [
                [
                    "==",
                    "6.1.0"
                ]
            ]
        },
        {
            "name": "packaging",
            "specs": [
                [
                    "==",
                    "24.2"
                ]
            ]
        },
        {
            "name": "pluggy",
            "specs": [
                [
                    "==",
                    "1.5.0"
                ]
            ]
        },
        {
            "name": "propcache",
            "specs": [
                [
                    "==",
                    "0.2.1"
                ]
            ]
        },
        {
            "name": "Pygments",
            "specs": [
                [
                    "==",
                    "2.18.0"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    "==",
                    "8.3.4"
                ]
            ]
        },
        {
            "name": "pytest-asyncio",
            "specs": [
                [
                    "==",
                    "0.25.0"
                ]
            ]
        },
        {
            "name": "python-Wappalyzer",
            "specs": [
                [
                    "==",
                    "0.3.1"
                ]
            ]
        },
        {
            "name": "PyYAML",
            "specs": [
                [
                    "==",
                    "6.0.2"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    "==",
                    "2.32.3"
                ]
            ]
        },
        {
            "name": "rich",
            "specs": [
                [
                    "==",
                    "13.9.4"
                ]
            ]
        },
        {
            "name": "setuptools",
            "specs": [
                [
                    "==",
                    "75.6.0"
                ]
            ]
        },
        {
            "name": "soupsieve",
            "specs": [
                [
                    "==",
                    "2.6"
                ]
            ]
        },
        {
            "name": "urllib3",
            "specs": [
                [
                    "==",
                    "2.2.3"
                ]
            ]
        },
        {
            "name": "yarl",
            "specs": [
                [
                    "==",
                    "1.18.3"
                ]
            ]
        }
    ],
    "lcname": "subsurfer"
}
        
Elapsed time: 0.39763s