새소식

모의해킹/Web

URL Endpoints 파싱

  • -
반응형

 

고객사가 웹 취약점 점검을 매년 받아왔고 조치도 잘 하는 사이트라면 취약점 하나 잡는게 여간 쉬운 일이 아니다.

 

그럴땐 js 나 html 파일에서 화면 상에 노출되지 않는 Endpoint URL 들을  뒤져보면 다른 사람이 아직 발견하지 못한 취약점들이 나오는 경우가 꽤 있기도 하다.

 

이를 위해 버프스위트 익스텐션으로 JS Link Finder 라는게 존재하지만 

특정 URL 을 대상으로만 수동으로 스캔하고 싶어서 Endpoint URL을 파싱해주는 도구를 만들었다.

 

ep.exe
8.76MB

 

위 실행 파일을 다운받아 C:\Windows\System32 등 환경변수로 지정된 경로에 저장하면 된다.

명령어의 옵션은 아래와 같다.

 

 

기본적인 사용방법은 ep 명령어 뒤에 endpoints 를 수집할 URL 경로 또는 파일(js, html 등) 경로를 입력하면 된다.

 

필요에 따라 저장 경로(-o) 나 쿠키 헤더 설정(-c) 이 가능하도록 하였으며, 사용해보면 감이 온다.

아래는 python 원본 코드를 첨부한다.

import requests
import re
from urllib.parse import urljoin
import argparse
import warnings
import os

def extract_endpoints_from_html(html_content, base_url=''):
    potential_endpoints = re.findall(r'(["\'])(https?://[^\s"\']+?)\1|(["\'])(/[^\s"\']+?)\3', html_content)
    
    endpoints = set()
    for match in potential_endpoints:
        if match[1]: 
            endpoints.add(match[1])
        if match[3]:  
            full_url = urljoin(base_url, match[3]) # 절대경로
            #full_url = match[3] # 상대경로
            endpoints.add(full_url)
    
    return list(endpoints)

def extract_endpoints_from_url(base_url, cookies=None):
    try:
        warnings.filterwarnings('ignore', category=requests.packages.urllib3.exceptions.InsecureRequestWarning)
        response = requests.get(base_url, verify=False, cookies=cookies)
        response.raise_for_status()
    except requests.RequestException as e:
        print(f"Error fetching the URL: {e}")
        return []

    return extract_endpoints_from_html(response.text, base_url)

def parse_cookies(cookie_string):
    if not cookie_string:
        return {}
    
    cookies = {}
    try:
        # 쿠키 문자열을 딕셔너리로 변환
        pairs = cookie_string.split(';')
        for pair in pairs:
            key, value = pair.strip().split('=', 1)
            cookies[key.strip()] = value.strip()
    except Exception as e:
        print(f"Error parsing cookies: {e}")
        return {}
    
    return cookies

def extract_endpoints_from_file(file_path, base_url=''):
    if not os.path.isfile(file_path):
        print("File not found.")
        return []
    
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            html_content = file.read()
    except IOError as e:
        print(f"Error reading the file: {e}")
        return []
    
    return extract_endpoints_from_html(html_content, base_url)

def save_endpoints_to_file(endpoints, filename='endpoints.txt'):
    try:
        with open(filename, 'w', encoding='utf-8') as file:
            for endpoint in endpoints:
                file.write(endpoint + '\n')
    except IOError as e:
        print(f"Error writing to file: {e}")

def main():
    parser = argparse.ArgumentParser(description="Extract endpoints from a URL or a file.")
    parser.add_argument('source', help="URL or file path")
    parser.add_argument('-o', '--output', default='endpoints.txt', help="Output file name (default: 'endpoints.txt')")
    parser.add_argument('-b', '--base-url', default='', help="Base URL for resolving relative paths")
    parser.add_argument('-c', '--cookies', help="Cookies in format 'name1=value1; name2=value2'")
    
    args = parser.parse_args()
    source = args.source
    output_file = args.output
    base_url = args.base_url
    cookies = parse_cookies(args.cookies)
    
    if source.startswith('http://') or source.startswith('https://'):
        endpoints = extract_endpoints_from_url(source, cookies)
    else:
        endpoints = extract_endpoints_from_file(source, base_url)
    
    if endpoints:
        save_endpoints_to_file(endpoints, output_file)
        print(f"Extracted {len(endpoints)} endpoints and saved to '{output_file}'.")
        print(f"Made by SECUWORM")
    else:
        print("No endpoints were found.")

if __name__ == "__main__":
    main()
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.