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.6.tar.gz (35.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.6-py3-none-any.whl (37.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: subsurfer-0.1.6.tar.gz
  • Upload date:
  • Size: 35.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.6.tar.gz
Algorithm Hash digest
SHA256 6d38688443c78cb4e10f2bff7b8afb73a8943442c118b0df7162aa68772e5b39
MD5 8f57aa324f79d154b63bec6d250e2162
BLAKE2b-256 8d3f93127d9c4bdee339b5cd993cad02639672fcc8d89f9f7dc0904482c15ee0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: subsurfer-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 37.9 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.6-py3-none-any.whl
Algorithm Hash digest
SHA256 902ec076f249f6e34e167eecbea9225a0615e9f6c9a84588956594d881759d92
MD5 7479dcac7d529c2f6e525e80d2b921b0
BLAKE2b-256 f03b1b12155269ca6b0fd1a544a81325d391125c6dc3018be8959f40d3bb937a

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