Skip to main content

Red Teaming and Web Bug Bounty Fast Asset Identification Tool

Project description

๐Ÿ„โ€โ™‚๏ธ SubSurfer

Python Version License Version

SubSurfer๋Š” ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์ธ ์„œ๋ธŒ๋„๋ฉ”์ธ ์—ด๊ฑฐ ๋ฐ ์›น ์ž์‚ฐ ์‹๋ณ„ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.


๐ŸŒŸ ํŠน์ง•

  • ๋ ˆ๋“œํŒ€/๋ฒ„๊ทธ๋ฐ”์šดํ‹ฐ ์ง€์›: ๋ ˆ๋“œํŒ€ ์ž‘์ „๊ณผ ์›น ๋ฒ„๊ทธ๋ฐ”์šดํ‹ฐ ํ”„๋กœ์ ํŠธ ๋ชจ๋‘์—์„œ ํ™œ์šฉ ๊ฐ€๋Šฅ
  • ๊ณ ์„ฑ๋Šฅ ์Šค์บ”: ๋น„๋™๊ธฐ ๋ฐ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•œ ๋น ๋ฅธ ์„œ๋ธŒ๋„๋ฉ”์ธ ์ˆ˜์ง‘
  • ํฌํŠธ ์Šค์บ”: ์‚ฌ์šฉ์ž ์ •์˜ ํฌํŠธ ๋ฒ”์œ„๋กœ ์ž์‚ฐ ์Šค์บ” ๋ฒ”์œ„ ํ™•์žฅ
  • ์›น ์„œ๋น„์Šค ์‹๋ณ„: ์›น ์„œ๋ฒ„, ๊ธฐ์ˆ  ์Šคํƒ ๋“ฑ ํ™˜๊ฒฝ ์ •๋ณด ์ˆ˜์ง‘
  • ํŒŒ์ดํ”„๋ผ์ธ ์ง€์›: -pipeweb, -pipesub ์˜ต์…˜์œผ๋กœ ๋‹ค๋ฅธ ๋„๊ตฌ์™€์˜ ์—ฐ๊ณ„ ๊ฐ€๋Šฅ
  • ๋ชจ๋“ˆํ˜• ์„ค๊ณ„: Python ๋ชจ๋“ˆ๋กœ importํ•˜์—ฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ์ง€์†์  ์—…๋ฐ์ดํŠธ: ์ƒˆ๋กœ์šด passive/active ๋ชจ๋“ˆ ์ง€์† ์ถ”๊ฐ€ ์˜ˆ์ •

๐Ÿš€ ์„ค์น˜

bash

git clone https://github.com/arrester/subsurfer.git
cd subsurfer

or

Python

pip install -r requirements.txt

๐Ÿ“– ์‚ฌ์šฉ๋ฒ•

CLI ๋ชจ๋“œ

๊ธฐ๋ณธ ์Šค์บ”
subsurfer -t vulnweb.com

์•กํ‹ฐ๋ธŒ ์Šค์บ” ํ™œ์„ฑํ™”
subsurfer -t vulnweb.com -a

ํฌํŠธ ์Šค์บ” ํฌํ•จ
subsurfer -t vulnweb.com -dp # ๊ธฐ๋ณธ ํฌํŠธ
subsurfer -t vulnweb.com -p 80,443,8080-8090 # ์‚ฌ์šฉ์ž ์ •์˜ ํฌํŠธ

ํŒŒ์ดํ”„๋ผ์ธ ์ถœ๋ ฅ
subsurfer -t vulnweb.com -pipeweb # ์›น ์„œ๋ฒ„ ๊ฒฐ๊ณผ๋งŒ ์ถœ๋ ฅ
subsurfer -t vulnweb.com -pipesub # ์„œ๋ธŒ๋„๋ฉ”์ธ ๊ฒฐ๊ณผ๋งŒ ์ถœ๋ ฅ

Python ๋ชจ๋“ˆ๋กœ ์‚ฌ์šฉ

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
    )
    
    # ์„œ๋ธŒ๋„๋ฉ”์ธ ์ˆ˜์ง‘
    subdomains = await controller.collect_subdomains()
    
    # ๊ฒฐ๊ณผ ์ถœ๋ ฅ
    print(f"๋ฐœ๊ฒฌ๋œ ์„œ๋ธŒ๋„๋ฉ”์ธ: {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
    )
    
    # ์„œ๋ธŒ๋„๋ฉ”์ธ ์ˆ˜์ง‘
    subdomains = await controller.collect_subdomains()
    
    # ๊ธฐ๋ณธ 80, 443 ์Šค์บ” ์„ค์ •
    ports = None

    # ํฌํŠธ ์Šค์บ” ์„ค์ •
    # ports = controller.parse_ports()  # ๊ธฐ๋ณธ ํฌํŠธ
    # ๋˜๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ํฌํŠธ
    # ports = controller.parse_ports("80,443,8080-8090")
    
    # ์›น ์„œ๋น„์Šค ์Šค์บ”
    web_services = await controller.scan_web_services(subdomains, ports)
    
    # ์›น ์„œ๋ฒ„ ์ถœ๋ ฅ
    print("\n์›น ์„œ๋ฒ„:")
    for server in sorted(web_services['web_servers']):
        print(f"https://{server}")
    
    # ํ™œ์„ฑํ™”๋œ ์„œ๋น„์Šค ์ถœ๋ ฅ    
    print("\nํ™œ์„ฑํ™”๋œ ์„œ๋น„์Šค:")
    for service in sorted(web_services['enabled_services']):
        print(service)
        
    # URL๊ณผ ํฌํŠธ ์ •๋ณด ์ถœ๋ ฅ
    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")
    
    # ์„œ๋ธŒ๋„๋ฉ”์ธ ์ˆ˜์ง‘ ๋ฐ ์›น ์„œ๋น„์Šค ์Šค์บ”
    subdomains = await controller.collect_subdomains()
    web_services = await controller.scan_web_services(subdomains)
    
    # ๊ฒฐ๊ณผ ์ €์žฅ
    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', {})  # URL๊ณผ ํฌํŠธ ์ •๋ณด ํฌํ•จ
    }
    
    # ๊ธฐ๋ณธ ๊ฒฐ๊ณผ ํŒŒ์ผ ๊ฒฝ๋กœ ์ƒ์„ฑ (results ๋””๋ ‰ํ† ๋ฆฌ์— ์ €์žฅ)
    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


๐Ÿ—บ๏ธ ToDo

0.2 ๋ฒ„์ „

  • ์ƒˆ๋กœ์šด ํŒจ์‹œ๋ธŒ ๋ชจ๋“ˆ ์ถ”๊ฐ€

0.3 ๋ฒ„์ „

  • JSON ๊ฒฐ๊ณผ ์ถœ๋ ฅ ์˜ต์…˜ ์ถ”๊ฐ€
  • ์ƒˆ๋กœ์šด ํŒจ์‹œ๋ธŒ ๋ชจ๋“ˆ ์ถ”๊ฐ€
  • ๊ธฐํƒ€ ๊ธฐ๋Šฅ ์—…๋ฐ์ดํŠธ

0.4 ๋ฒ„์ „

  • ์ƒˆ๋กœ์šด ํŒจ์‹œ๋ธŒ ๋ชจ๋“ˆ ์ถ”๊ฐ€
  • ์„œ๋ธŒ๋„๋ฉ”์ธ ํƒˆ์ทจ ๊ฒ€์‚ฌ ๊ธฐ๋Šฅ

0.5 ๋ฒ„์ „

  • ์ƒˆ๋กœ์šด ํŒจ์‹œ๋ธŒ ๋ชจ๋“ˆ ์ถ”๊ฐ€
  • ์ƒˆ๋กœ์šด ์•กํ‹ฐ๋ธŒ ๋ชจ๋“ˆ ์ถ”๊ฐ€

๐Ÿ“‹ ์š”๊ตฌ์‚ฌํ•ญ

  • Python 3.13.0 ์ด์ƒ ๊ถŒ์žฅ
  • aiohttp
  • rich
  • pytest (ํ…Œ์ŠคํŠธ์šฉ)

๐Ÿ“ ๋ผ์ด์„ ์Šค

MIT License

๐Ÿค ๊ธฐ์—ฌ

Bug Report, Feature Suggestions, Pull Request

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

subsurfer-0.1.2.tar.gz (76.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

subsurfer-0.1.2-py3-none-any.whl (119.5 kB view details)

Uploaded Python 3

File details

Details for the file subsurfer-0.1.2.tar.gz.

File metadata

  • Download URL: subsurfer-0.1.2.tar.gz
  • Upload date:
  • Size: 76.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.13.0

File hashes

Hashes for subsurfer-0.1.2.tar.gz
Algorithm Hash digest
SHA256 e34783f8584ee4816c53e6bcf5d663e573c9c622549f4e54d150a11f1f57f2d1
MD5 380796cdc0c5260fd92bb57037924678
BLAKE2b-256 3a94325c7bd8c47f5592742727181477759bb3c55a1976772ac5192afb4d62c8

See more details on using hashes here.

File details

Details for the file subsurfer-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: subsurfer-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 119.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.13.0

File hashes

Hashes for subsurfer-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b71f5afd54b2e0ab8cd75e0c06ead2fb6817f139b139d8c3c4a40cfb624bd9c9
MD5 b56720e1d0a1ea65cd51d257c9911d28
BLAKE2b-256 c3c3f30a4bfe6031cc1a8663c51abe45417ec3ecfc38a34846be4be9771bd489

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page