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.5.tar.gz (62.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.5-py3-none-any.whl (101.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: subsurfer-0.1.5.tar.gz
  • Upload date:
  • Size: 62.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.5.tar.gz
Algorithm Hash digest
SHA256 c19e2e9d1d706dc7721df25da174cb16ae304f84df0356e3da969af671ffde31
MD5 c3cafb3f3a6c4a12aa34b2cc4fc2f516
BLAKE2b-256 49c643fc75561a4f2648cf58cc6840580097ac02225a88072fe3292c82c28c2d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: subsurfer-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 101.7 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.5-py3-none-any.whl
Algorithm Hash digest
SHA256 511551a30c800292cec1cec4c98d8e84edcae73dff9f8cde67a1ce9acc2a5e89
MD5 7375b831cbc75e969d732a30febeaec6
BLAKE2b-256 38ab438a71d85e910a91ba27e2fe75fa529a10dd7a4086bb358e19ee264af1bb

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