Research Institute
  • Nuclei Templates 구조 이해하기
    2024년 05월 07일 14시 04분 47초에 업로드 된 글입니다.
    작성자: IIIIIIIIIIIIIIIIIIIIl

    Nuclei 템플릿은 Nuclei 엔진이 사용하는 점검 파일로 HTTP, Headless, Network, DNS, File, JavaScript, Code, Flow, Multi-protocol 등과 같은 다양한 프로토콜을 지원하고 있습니다.

    YAML(YAML Ain't Markup Language)

    Nuclei 템플릿은 요청이 전송되고 처리되는 방식을 정의하는 YAML 기반 템플릿 파일을 기반으로 합니다. 이를 통해 과거에 PoC/Exploit 코드를 작성하는 시간을 줄이고 여러 보안 취약점을 빠르게 점검할 수 있습니다. 그리고 YAML템플릿은 누구나 쉽게 사람이 읽을 수 있는 간단한 형식으로 작성되어 있습니다. YAML 파일은 다소 엄격하며 들여쓰기에 의존하며 지정된 부모 항목의 각 자식 항목은 공백으로 들여쓰기 하여 구분을 진행하고 있습니다. 

    다양한 소프트웨어에서 YAML을 사용하고 있으며 주요 사용하는 애플리케이션은 다음과 같습니다.

    1. Ansible
    2. Kubernetes
    3. OpenStack

    Nuclei Template 구조

    Nuclei 템플릿은 사용자 지정 YAML 기반 DSL을 사용하며, 사용된 특정 프로토콜에 따라 구조가 달라집니다. 일반적으로 템플릿은 다음 요소로 구성됩니다.

    • 템플릿의 ID
    • 템플릿과 관련된 InformationMetadata
    • 지원 Protocol(예: HTTP, Headless, Network, DNS, File, JavaScript, Code, Flow, Multi-protocol 등)
    • HTTP 프로토콜에서 수행된 요청과 같이 선택한 프로토콜과 관련된 세부 정보
    • 결과의 존재를 확인하기 위한 일련의 matchers
    • 결과에서 데이터를 검색하는 데 필요한 extractors

    1) ID

    Nuclei Template 작성 시 가장 먼저 작성되는 값으로 템플릿 출력에 활용됩니다. 그리고 ID에는 공백이 없어야 합니다.

    id: git-config
    

    2) InformationMetadata

    Information 블록은 nameauthorseveritydescriptionreferencetags  등 템플릿에 대한 정보를 작성하는 블록입니다.

    info:
      name: Git Config File Detection Template
      author: Ice3man
      severity: medium
      description: Searches for the pattern /.git/config on passed URLs.
      reference: <https://www.acunetix.com/vulnerabilities/web/git-repository-found/>
      tags: git,config
    

    Metadata 블록은 해당 취약점에 영향받는 서비스를 찾기 위한 shodan 구문이나 여러 검색엔진을 지원하는 uncover를 지원하는 블록입니다.

    info:
      metadata:
        shodan-query: 'vuln:CVE-2021-26855'
    

    3) Protocol (HTTP, Headless, Network, DNS, File, JavaScript, Code, Flow, Multi-protocol)

    • HTTPNuclei에서는 기본적인 요청을 수행하는 URL 형태(method 형태)의 요청과 Raw HTTP 요청 그리고 비 RFC 요청도 지원하고 있습니다.
    • # URL 형태(method 형태) http: - method: GET path: - "{{BaseURL}}/login.php" # Raw HTTP http: - raw: - | POST /path2/ HTTP/1.1 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded a=test&b=pd # 비 RFC 요청 http: - raw: - |+ POST / HTTP/1.1 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded Content-Length: 150 Transfer-Encoding: chunked 0 GET /post?postId=5 HTTP/1.1 User-Agent: a"/><script>alert(1)</script> Content-Type: application/x-www-form-urlencoded Content-Length: 5 x=1 unsafe: true
    • HTTP 프로토콜은 Nuclei에서 가장 많이 사용되고 있는 프로토콜로 주로 웹 애플리케이션 관련 취약점을 다루는데 활용됩니다.

    3) matchers

    Matcher를 사용하면 프로토콜 응답에 대해 다양한 유형의 유연한 탐지가 가능합니다. 

    기본적으로 지원하는 Matcher는 다음과 같습니다.

    Matcher Type Part Matched

    status Integer Comparisons of Part
    size Content Length of Part
    word Part for a protocol
    regex Part for a protocol
    binary Part for a protocol
    dsl Part for a protocol
    xpath Part for a protocol

    응답에 대한 상태 코드를 일치시키려면 다음 Matcher Type를 사용할 수 있습니다.

    해석 : HTTP 요청 이후 응답 상태가 “200”, “302” 경우 정탐

    matchers:
      - type: status
        status:
          - 200
          - 302
    

    dsl matcher를 사용하면 보다 정교한 탐지를 진행할 수 있습니다.

    matchers:
      - type: dsl
        dsl:
          - "len(body)<1024 && status_code==200" # Body length less than 1024 and 200 status code
          - "contains(toupper(body), md5(cookie))" # Check if the MD5 sum of cookies is contained in the uppercase body
    

    Response Part Description Example

    content_length Content-Length Header content_length >= 1024
    status_code Response Status Code status_code==200
    all_headers Unique string containing all headers len(all_headers)
    body Body as string len(body)
    header_name Lowercase header name with converted to -_ len(user_agent)
    raw Headers + Response len(raw)

    조건 구문

    matcher는 여러 단어와 정규식을 지정할 수 있으며 AND 및 OR와 같은 다양한 조건으로 구성할 수 있습니다. 이러한 조건 구문을 사용하면 오탐율을 낮출 수 있습니다.

    1. AND : 조건을 사용하면 matcher의 단어 목록에서 모든 단어를 일치하면 정탐으로 간주합니다.
    2. OR : 조건을 사용하면 matcher 목록에서 단일 단어가 응답에 존재하는 경우 정탐으로 간주합니다.
    matchers:
      - type: word
       words:
         - "[core]"
         - "[config]"
       condition: and
       part: body
    

    참고자료

    댓글