
Crawlector는 악성 객체를 검사하기 위해 웹사이트를 스캔하도록 설계된 위협 헌팅 프레임워크입니다.
Crawlector (이름 Crawlector는 Crawler & Detector의 조합입니다)는 웹사이트에서 악성 객체를 스캔하기 위해 설계된 위협 헌팅 프레임워크입니다.
참고-1: 이 프레임워크는 2022년 10월 22일 이탈리아 베르가모에서 열린 No Hat 컨퍼런스에서 처음 발표되었습니다 (슬라이드, YouTube 녹화). 또한, 2022년 12월 2일 싱가포르에서 열린 AVAR 컨퍼런스에서 두 번째로 발표되었습니다.
참고-2: 발표에서 언급된 동반 도구 EKFiddle2Yara (EKFiddle 규칙을 가져와 Yara 규칙으로 변환하는 도구)도 두 컨퍼런스에서 함께 공개되었습니다.
참고-3: 버전 2.0 (Photoid Build:180923)은 2023년 9월 18일에 출시된 중요한 릴리스입니다.
참고-4: 버전 2.1 (Universe-647 Build:031023)은 2023년 10월 3일에 출시되었습니다. 주요 추가 사항은 Slack 알림 기능입니다.
참고-5: 버전 2.2 (Hallstatt Build:051123)은 2023년 11월 5일에 출시되었습니다. 주요 추가 사항은 Slack 원격 제어 기능입니다.
참고-6: 버전 2.3 (Munich Build:241123)은 2023년 11월 24일에 출시되었습니다. 주요 추가 사항은 DNS 네임서버 기능입니다.
참고-6: 버전 2.3.1 {Nero Build:131225}은 2025년 12월 13일에 출시되었습니다. 유지보수 릴리스입니다.
이는 스캔 중인 모든 페이지에 대해 악성 URL을 확인하는 기능입니다. 프레임워크는 URLHaus 서버 (설정: url_list_web)에서 악성 URL 목록을 쿼리하거나 디스크의 파일 (설정: url_list_file)에서 쿼리할 수 있으며, 후자가 지정되면 전자보다 우선합니다.
작동 방식: 모든 페이지의 콘텐츠를 url_list_web 또는 url_list_file의 모든 URL 항목에 대해 검색하여 모든 발생을 확인합니다. 또한, 일치하는 경우 check_url_api 설정 옵션이 true로 설정되어 있으면 Crawlector는 url_api 설정 옵션에 설정된 API URL로 POST 요청을 보내며, 일치하는 URL에 대한 추가 정보가 포함된 JSON 객체를 반환합니다. 이러한 정보에는 urlh_status (예: online, offline, unknown), urlh_threat (예: malware_download), urlh_tags (예: elf, Mozi), urlh_reference (예: https://urlhaus.abuse.ch/url/1116455/)가 포함됩니다. 이 정보는 check_url_api가 true로 설정된 경우에만 로그 파일 cl_mlog_<current_date><current_time><(pm|am)>.csv (아래 참조)에 포함됩니다. 그렇지 않으면 로그 파일에는 urlh_url (일치하는 악성 URL 목록) 및 urlh_hit (일치하는 각 악성 URL의 발생 횟수) 열이 포함되며, 이는 check_url이 true로 설정된 경우에만 해당됩니다.
URLHaus 기능은 설정 옵션 check_url을 false로 설정하여 완전히 비활성화할 수 있습니다.
이 기능은 확인해야 하는 방대한 악성 URL (~ 현재 약 1억 3천만 개 항목)과 URLHaus 서버에서 추가 정보를 가져오는 시간(옵션 check_url_api가 true로 설정된 경우)으로 인해 스캔 속도가 느려질 수 있습니다.
세션을 실행하기 전에 반드시 설정 파일 cl_config.ini에 익숙해져야 합니다. 모든 섹션과 매개변수는 설정 파일 자체에 문서화되어 있습니다.
Yara 오프라인 스캔 기능은 독립 실행형 옵션입니다. 즉, 활성화되면 Crawlector는 다른 활성화된 기능과 관계없이 이 기능만 실행합니다. 도메인/사이트 디지털 인증서 크롤링 기능도 마찬가지입니다. 어느 쪽이든 설정 파일에서 사용하지 않는 모든 기능을 비활성화하는 것이 좋습니다.
log_to_file 또는 log_to_cons)에 따라 Yara 규칙이 모듈 속성(예: PE, ELF, Hash 등)만 참조하는 경우, Crawlector는 일치 시 규칙 이름만 표시하고 오프셋 및 길이 데이터는 제외합니다.참고: 경로를 사용하는 모든 옵션에는 항상 절대 경로를 제공하십시오.
웹사이트를 방문/스캔하려면 URL 목록이 텍스트 파일에 저장되어야 하며, 디렉토리 "cl_sites"에 있어야 합니다.
Crawlector는 세 가지 유형의 URL을 허용합니다:
[a-zA-Z0-9_-]{1,128} = <url><id>[depth:<0|1>-><\d+>,total:<\d+>,sleep:<\d+>] = <url>
예를 들어,
mfmokbel[depth:1->3,total:10,sleep:0] = https://www.mfmokbel.com
이는 다음과 동일합니다:
mfmokbel[d:1->3,t:10,s:0] = https://www.mfmokbel.com
여기서, <id> := [a-zA-Z0-9_-]{1,128}
depth, total 및 sleep can also be replaced with their shortened versions d, t and s, respectively.
40 (10 + (10*3))개의 URL을 얻게 됩니다.참고 1: 유형 3 URL은 설정 파일의 spider 섹션에서 설정 매개변수 live_crawler를 false로 설정하여 유형 1 URL로 전환할 수 있습니다.
참고 2: 빈 줄과 ";" , "#" 또는 "//"로 시작하는 줄은 무시됩니다.
스파이더 기능은 Crawlector에 대상 페이지에서 추가 링크를 찾는 기능을 제공합니다. 스파이더는 다음 기능을 지원합니다:
유형 3이어야 합니다.exclude_url 설정 옵션을 통해 스파이더링에서 일치하는 URL을 제외하기 위해 와일드카드 패턴 목록(파이프로 구분)을 지정할 수 있습니다. 예를 들어, *.zip|*.exe|*.rar|*.zip|*.7z|*.pdf|.*bat|*.dbinclude_url 설정 옵션을 통해 패턴과 일치하는 URL만 스파이더링하도록 와일드카드 패턴 목록(파이프로 구분)을 지정할 수 있습니다. 예를 들어, */checkout/*|*/products/*exclude_https 설정 옵션을 통해 HTTPS URL을 제외할 수 있습니다.add_ext_links 설정 옵션을 통해 기본 페이지만의 아웃바운드/외부 링크를 고려할 수 있습니다. 이 기능은 exclude_url 및 include_url 설정 옵션을 따릅니다.ext_links_only 설정 옵션을 통해 기본 페이지만의 아웃바운드/외부 링크를 고려하고 다른 모든 URL은 제외할 수 있습니다. 이 기능은 exclude_url 및 include_url 설정 옵션을 따릅니다.릴리스 2.0에서 ID는 ID 자체에 다음 유형 중 하나를 추가하여 명시적으로 유형이 할당됩니다:
각 ID가 유형을 함께 전달하면 결과를 탐색하고 필터링하기가 더 쉽습니다. 또한, 이는 내부적으로 다양한 목적으로 사용됩니다.
site_ranking 섹션은 CSV 파일을 읽는 방식을 변경하는 몇 가지 옵션을 제공합니다.site 섹션은 동일한 도메인에 대해 사용 가능한 모든 최상위 도메인(TLD) 및/또는 서브도메인을 찾아 주어진 사이트를 확장하는 기능을 제공합니다. 발견된 새 TLD/서브도메인은 다른 도메인과 마찬가지로 확인됩니다.rapid_api_key 키에 입력합니다.find_tlds가 활성화된 경우, Omnisint Labs API의 tld 결과 외에도 프레임워크는 tlds_file 또는 tlds_url의 모든 tld 항목을 검토하여 다른 활성/등록된 도메인을 찾으려고 시도합니다.tlds_url이 설정된 경우, 각 줄에 하나씩 tld를 호스팅하는 URL을 가리켜야 합니다 (';', '#' 또는 '//' 문자로 시작하는 줄은 무시됩니다).tlds_file은 tld 목록이 포함된 파일 이름을 보유합니다 (tlds_url과 동일, '.'을 제외한 tld만, 예: "com", "org").tlds_file이 설정되면 tlds_url보다 우선합니다.tld_dl_time_out은 확인 중인 도메인이 해석되는지 여부를 확인할 때 dnslookup 함수의 최대 시간 제한을 설정합니다.이전 릴리스의 URL 리디렉션 기능은 손상되었습니다. 이 릴리스는 리디렉션 기능의 완전한 재작성을 제공하며, 작동 제어를 위한 높은 수준의 매개변수화를 제공합니다. 릴리스 버전 2.0에서 리디렉션은 설정 파일에 [redirect] 라는 전용 섹션이 있습니다. 리디렉션 기능 전체는 [default] 섹션의 follow_redir 옵션을 통해 켜고 끌 수 있습니다.
리디렉션 함수는 HTTP 응답 상태 코드 301, 302, 303, 307 및 308을 확인합니다. 일치하는 경우 Crawlector는 Location 헤더를 구문 분석하여 리디렉션 대상 URL을 확인하며, 절대 및 상대 리디렉션 URL을 모두 처리합니다. Crawlector의 리디렉션 기능은 성능과 민첩성을 위해 설계되었습니다. [redirect] 섹션은 다음 옵션 목록을 제공합니다:
depth 옵션은 값 last 또는 all 중 하나를 사용합니다. visit 옵션이 활성화되었는지 여부에 따라 발견된 리디렉션 URL 중 방문할 대상을 제어합니다. all 은 발견된 모든 리디렉션 URL을 방문하는 것입니다. last 는 마지막 리디렉션 URL만 방문하는 것입니다. 해당 URL의 방문은 동일/현재 세션에서 이루어집니다. depth 값에 관계없이 Crawlector는 발견된 모든 리디렉션 URL 목록을 절대 형식으로 총 개수와 함께 기록합니다. 이는 cl_mlog CSV 파일의 열 redirect_urls 및 redirect_total 아래에 기록됩니다.
max_redirect 옵션은 발견할 URL 리디렉션의 총 개수에 상한을 설정합니다.
skip_similar 옵션은 다음 예를 통해 가장 잘 설명됩니다:
Crawlector에 크롤링할 원래 URL이 "https://www.mfa.gov.law"이고 발견된 redirect_urls 중 하나가 "https://mfa.gov.law/"라고 가정합니다. 보시다시피 유일한 차이점은 URL 끝의 슬래시입니다. 이 두 URL은 동일하며 서버는 동일한 페이지로 응답합니다. visit 옵션이 true로 설정되면 Crawlector는 두 URL을 모두 크롤링하여 리소스를 낭비하고 동일한 작업을 두 번 수행합니다. 이는 1~2개의 URL에는 문제가 되지 않을 수 있지만, 크롤링하려는 URL이 1000개 이상이고 visit 옵션이 활성화된 경우 절반 이상이 그러한 발견된 URL을 가질 가능성이 매우 높아져 이는 중요한 문제가 됩니다. 따라서 skip_similar 옵션을 true로 설정하면 유사한 URL 방문을 건너뛰어 이 문제를 해결하는 데 도움이 됩니다. skip_similar 옵션은 forward_slash 시나리오 외에도 다음 두 가지 시나리오를 처리합니다: 리디렉션 URL이 접두사 "https://" 및 "www." 중 하나 또는 둘 모두만 다른 경우.
릴리스 2.0의 주요 추가 사항 중 하나는 페이지에서 다양한 유형의 객체를 추출하여 디스크에 저장하고 Yara 및 URLHaus로 스캔한 후 결과를 CSV 파일에 저장하는 기능입니다. 이 기능을 활성화하려면 [page] 섹션의 extract_obj 옵션을 true로 설정하십시오.The implementation of the deep object extraction feature works by creating an MHT web archive file from the webpage, including external scripts, images and CSS files. All embedded files will be extracted into the path specified by the option obj_dir (path: obj_dir/objects/), where each file will be scanned. The implementation is not to be confused with headless browser functionality. DOE is different and doesn't involve loading the page to retrieve all dynamically queried URLs. Therefore, it has its limitations.
All of the extracted objects will have some of their metadata written into the CSV file. Things to keep in mind when reading the CSV file: the ID of the domain with the extracted object has a unique format, as follows, <domain_id>_<type>_p_obj_<counter> (for example, _mfa_gov_cef40bc5-ba6a-41_t1_p_obj_0_). And, the url will have the following format, <url>__<object_filename> (for example, https://www.mfa.gov.law\_\_bilmur.min.js).
If the option delete_obj is set to true, then all extracted objects that aren't being detected by Yara are deleted from disk. If the option log_all_objs is set to true, then log all extracted objects metadata to the same cl_mlog CSV file. If the option check_urlhaus under the [page] section is set to true, then every extracted object will be URLHaus-scanned. Note that this option's options are inherited from the section [urlhaus].
Note: if the domain being crawled redirects to another domain, then the last redirect to URL has to be passed to DOE to work. Moreover, the domain has to start with "HTTP(S)://" for DOE to work.
Sometimes, you might want to run Crawlector sessions that might take days to complete, for example, by crawling the top 1-million Alexa websites, and for such a scenario, you need a way to monitor the framework's operation and progress remotely. Therefore, in release 2.1, I've added the Slack alert notification feature to provide a mechanism to monitor the execution of Crawlector in real-time, by sending Yara's alerts, std::exit() events, and process warnings and errors, to a Slack channel of your choosing. In addition to that, Crawlector installs a console handler in an attempt to monitor certain event types, including ctrl_c, ctrl_close, ctrl_break, ctrl_logoff and ctrl_shutdown. It is important to keep in mind that Crawlector doesn't change/alter the default handler's behaviour; it merely reports to the Slack channel the receipt of any of the listed events. This could be extended in the future to account for other types of events.
This feature uses Slack REST API, and for authentication with the server, it uses OAuth 2.0. You'll need a Slack API token to use it, and a channel configured with the right permissions. This feature only posts messages to the Slack channel and doesn't receive or process any incoming messages.
The [slack_alert] section provides the following list of options:
To disable or enable this feature, simply set the option alert to true or false. Moreover, you need to specify the api_token, with a channel name.
Note-1: In the initialization phase of Crawlector, it tests whether the provided authentication token is valid or not, or if the channel is set, and in case of failure, this feature is disabled automatically.
All alerts reported to the Slack channel are reported under the user's name Crawlector v<version_number>, for example, Crawlector v2.1. The user has the icon of a spider web. Additionally, all alerts are threaded, meaning all subsequent alerts after the first starting message, are posted as replies. This was a design decision and helps in case you're running multiple sessions at the same time, all reporting to the same channel. Some alerts use the markdown markup language for formatting.
When the process has finished successfully and is about to exit, it posts the following message:
Crawlector has finished and is shutting down successfully
Note-2: Slack rate limit on the post message API is one message per second, with leeway for some bursts. Crawlector does not queue messages to account for more posts per second. This might change in the future if required; however, the option sleep allows for the process to sleep for a specified amount of time after every successfully posted message.
With release 2.2 (code-named Hallstatt), I'm introducing the capability to remotely control Crawlector via a selected set of specially designed control commands. The reason for introducing this functionality is to monitor and control certain behaviours of sessions that are supposed to run for hours or days. For example, you might want to turn on/off the Slack alert functionality, terminate Crawlector, and upload a configuration file, among others.
This feature uses Slack REST API, and for authentication with the server, it uses OAuth 2.0. You'll need a Slack API token to use it, and a channel configured with the right permissions. The API token is the same as that used in the [slack_alert] section, option api_token.
The [slack_alert] section provides the following additional list of options for the remote control functionality:
To disable or enable this feature, simply set the option control to true or false. The ctrl_channel name has to be the channel ID name and not the channel name. You can get it by right-clicking on the channel name -> View channel details -> Scroll down to the bottom of the window, and you'll see the Channel ID: <channel_id> field.
The option ctrl_sleep determines the frequency of calling out to the control channel specified in the ctrl_channel option for retrieving control commands. You could also update this option via the control command cl_update_delay <time_in_ms>.
The list of supported control commands is the following:
Note-1: In the initialization phase of Crawlector, it tests whether the provided authentication token is valid or not, or if the channel is set, and in case of failure, this feature is disabled automatically.
If this functionality is enabled, and once it passes API token validation, Crawlector sends the message "Crawlector is ready for receiving control commands. Type the command cl_help for a list of supported control commands." to the designated ctrl_channel.
All responses to a given control command are threaded. Moreover, control commands are read on a session-by-session basis, from the time a session is started.
Note-2: Slack rate limit on the retrieval (conversation history) message API is one request per second, with leeway for some bursts. So, if the ctrl_sleep option is set to a value less than a second or greater than a second, Crawlector does queue messages to account for more control commands per second, and execute them in the order received.
With release 2.3 (code-named Munich), the capability to specify a list of DNS nameservers for all DNS queries and DNS-to-IP resolutions attempted by Crawlector is introduced with a high level of control. This is important in case you're crawling blocked or malicious websites. This feature applies to every function in Crawlector where a DNS query or DNS-to-IP request is made. More importantly, it provides the capability to perform DNS over TLS for every nameserver that supports it.
The [dns_ns] section provides the following list of options for administering this functionality:
The option name_servers takes a parametrized list of DNS name servers to use, comma-separated. The value of this option has the format: <IPv4_address>(<tls_option>) where <tls_option> takes either of the values "d_tls" or "e_tls". The options "d_tls" or "e_tls" indicate whether the nameserver in question supports DNS over TLS or not, respectively. This option will be enforced depending on the value set for the option dns_tls. For example, the entry 8.8.8.8(e_tls) indicates to use the Google DNS server 8.8.8.8 with TLS support, whereas the entry 12.13.14.15(d_tls) indicates to use the DNS server 12.13.14.15 with no TLS support.
The option dns_tls specifies the required level of TLS enforcement. This option takes either of the values, "yes" "no" or "force".
The option keep_default is for whether to add the default nameserver(s) to the list of nameservers. A default nameserver is assumed not to support TLS.
The option conn_time_out specifies the time in milliseconds to wait for an answer to a DNS query.
The option enable turns this functionality on or off.
cl_sites are allowed.Open for pull requests and issues. Comments and suggestions are greatly appreciated.
Mohamad Mokbel (@MFMokbel)
| id_postfix (유형) | 설명 |
|---|
| _t1_p | ID가 없는 일반 유형 1 |
| _sd | 서브도메인에 대한 하위 유형 |
| _tld | TLD에 대한 하위 유형 |
| _t2_p | ID가 있는 일반 유형 2 |
| _t3_s | 스파이더링된 도메인 유형 3 |
| _t3_sc | 하위 노드가 있는 스파이더링된 도메인 유형 3 |
| _t3_ss | 유형 3 (_t3_s) URL이 유형 1 URL로 전환된 경우 유형 3 |
| _t3_s_e | 스파이더링된 도메인 유형 3의 외부 링크 |
| _obj_ | 심층 스캔 및 객체 추출용 |
| _t4_ru | 리디렉션 URL용 (모든 유형) |
tld_use_connect는 옵션 tlds_connect_ports에 정의된 포트 목록을 통해 해당 도메인에 연결하는 기능을 활성화합니다.tlds_connect_ports는 쉼표로 구분된 포트 목록 또는 25-40,90-100,80,443,8443과 같은 범위 목록(범위 시작과 끝 포함)을 허용합니다.
tld_con_time_out은 연결 함수의 최대 시간 제한을 설정합니다.tld_con_use_ssl은 도메인에 연결할 때 SSL 사용을 활성화/비활성화합니다.save_to_file_subd가 true로 설정되면 발견된 서브도메인이 "\expanded\exp_subdomain_<pm|am>.txt"에 저장됩니다.save_to_file_tld가 true로 설정되면 발견된 도메인이 "\expanded\exp_tld_<pm|am>.txt"에 저장됩니다.exit_here가 true로 설정되면 Crawlector는 이 [site] 함수를 실행한 후 다른 활성화된 옵션에 관계없이 종료됩니다. 즉, 발견된 사이트는 크롤링/스파이더링되지 않습니다.| Control Command | Description |
|---|
| cl_get_date | Retrieves the date and time Crawlector was started and the current date and time. |
| cl_ping | Sends back the message "Pong...". This is to check that the C&C channel is working. |
| cl_get_config | Uploads the currently used configuration (e.g., cl_config.ini) file as a text file. |
| cl_update_delay <integer_in_milliseconds> | Updates the check-in time between every pull request for control commands. - Changes the value (ctrl_sleep) for the current session only. |
| cl_turn_off_slack_alert | Turns off Slack alert feature for the currently active session. |
| cl_turn_on_slack_alert | Turns on Slack alert feature for the currently active session |
| cl_help | Lists this help message. |
| cl_exit | Terminates Crawlector, forcefully. |