ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [웹 정보 수집] 직접 만들어서 써보는 Directory Bruteforcing
    Hacking/개발 및 자동화 2025. 6. 1. 22:15
    728x90
    반응형

    최근 해킹 관련 강의와 영상들을 찾아보다 보니 해킹의 시작은 정보 수집이라는것을 배웠고 웹 정보 수집 기법 중 하나인 Directory Bruteforcing에 대해 공부하고 직접 스크립트를 만들어 실습해 보았습니다.

    Directory Bruteforcing

    웹 서버가 숨기고 있는 디렉터리나 파일들을 사전에 준비된 단어 목록(Dictionary)을 기반으로 요청을 보내며 존재 여부를 파악하는 기법으로 매우 간단한 방식이지만 웹 취약점을 파악하는 데 있어 매우 효과적인 접근입니다.

    이 기법에서 가장 중요한 것은 스크립트를 짜는 실력(1%)이 아닌 효율적이고 효율적인 사전 파일(99%) 입니다.

    사전 파일에 대한 고민

    기본적으로 사전파일을 처음부터 작성하는 것은 비효율적이기 때문에 이미 만들어진 다양한 사전 파일을 Github를 통해 얻을 수 있습니다. ( OpenSource : ex) dirbrute.txt )

    이런 사전 파일들은 기본적으로 여러 사람들의 경험을 토대로 작성되기 때문에 상당히 좋습니다.

    대 Vibe Coding 시대

    최근 들어 코딩을 할줄 몰라도 AI를 사용한 웹사이트 만들기가 흐름이기 때문에 AI의 습관적인 경로도 사전 파일에 추가하면 더 좋아질것으로 생각됩니다.

    직접 만들어 본 Directory Bruteforcing Bash Script

    #!/bin/bash
    
    TARGET_URL=$1
    DICTIONARY=$2
    THREADS=${3:-10}  # 세 번째 인자가 없으면 기본값 10
    
    if [ -z "$TARGET_URL" ] || [ -z "$DICTIONARY" ]; then
        echo "! 사용법 : $0 <TARGET_URL> <DICTIONARY> [MAX_THREADS=10]"
        exit 1
    fi
    
    if [[ ! -f "$DICTIONARY" ]]; then
        echo "❌ 사전 파일이 존재하지 않습니다: $DICTIONARY"
        exit 1
    fi
    
    if [[ ! "$DICTIONARY" =~ \.txt$ ]]; then
        echo "❌ 사전 파일은 .txt 확장자여야 합니다."
        exit 1
    fi
    
    if ! [[ "$THREADS" =~ ^[0-9]+$ ]]; then
        echo "❌ 스레드 수는 숫자여야 합니다."
        exit 1
    fi
    
    MAX_USER_THREADS=$(ulimit -u)
    
    if [ "$THREADS" -gt "$MAX_USER_THREADS" ]; then
        echo "❌ 현재 시스템에서 허용된 최대 스레드 수 ($MAX_USER_THREADS) 를 초과했습니다."
        exit 1
    fi
    
    if [ "$THREADS" -lt 1 ]; then
        echo "❌ 스레드 수는 1 이상이어야 합니다."
        exit 1
    fi
    
    HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$TARGET_URL")
    
    if [[ "$HTTP_CODE" != "200" ]]; then
        echo "❌ 타겟 URL에 접속할 수 없거나, HTTP 상태 코드가 200이 아닙니다. 상태 코드: $HTTP_CODE"
        exit 1
    fi
    
    [[ "$TARGET_URL" =~ /$ ]] || TARGET_URL="${TARGET_URL}/"
    
    echo "$TARGET_URL 에 대한 정보 수집을 시작합니다. (최대 동시 스레드 수: $THREADS)"
    
    ALLOWED_CODES=("200" "401" "403")
    
    JOB_COUNT=0
    FOUND_COUNT=0 
    START_TIME=$(date +%s)
    
    TOTAL_LINES=$(wc -l < "$DICTIONARY")
    
    while IFS= read -r path || [ -n "$path" ]; do
        FULL_URL="${TARGET_URL}${path}"
        
        {
            # STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 -A "Mozilla/5.0" "$FULL_URL")
            # LENGTH=$(curl -s -w "%{size_download}" -o /dev/null --max-time 5 "$FULL_URL")
            # 리팩토링
            CURL_OUTPUT=$(curl -s -w "%{http_code}:%{size_download}" -o /dev/null --max-time 5 -A "Mozilla/5.0" "$FULL_URL")
            STATUS=$(echo "$CURL_OUTPUT" | cut -d':' -f1)
            LENGTH=$(echo "$CURL_OUTPUT" | cut -d':' -f2)
            
            for code in "${ALLOWED_CODES[@]}"; do
                if [[ "$STATUS" == "$code" ]]; then
                    echo "$FULL_URL [$STATUS] Size: $LENGTH"
                    ((FOUND_COUNT++))
                    break
                fi
            done
        } &
    
        ((JOB_COUNT++))
        if (( JOB_COUNT % THREADS == 0 )) || (( JOB_COUNT == TOTAL_LINES )); then
            wait
    
            ELAPSED_TIME=$(( $(date +%s) - START_TIME ))
            if [ "$ELAPSED_TIME" -eq 0 ]; then ELAPSED_TIME=1; fi
    
            PROGRESS_PERCENT=$(awk "BEGIN {printf \"%.2f\", ($JOB_COUNT * 100) / $TOTAL_LINES}")
            PPS=$(( JOB_COUNT / ELAPSED_TIME )) # Path Per Second
            if [ "$PPS" -eq 0 ]; then PPS=1; fi
            EST_REMAINING_SECONDS=$(( (TOTAL_LINES - JOB_COUNT) / PPS ))
    
            printf "\r[🔍 진행률: %.2f%%] 처리된 항목: %s/%s | 발견: %s | 경과 시간: %s초 | 남은 시간 예상: %s초" \
                "$PROGRESS_PERCENT" "$JOB_COUNT" "$TOTAL_LINES" "$FOUND_COUNT" "$ELAPSED_TIME" "$EST_REMAINING_SECONDS"
            
            if (( JOB_COUNT == TOTAL_LINES )); then
                echo ""
            fi
        fi
        
    done < "$DICTIONARY"
    
    wait

     

    728x90
    반응형
Designed by Tistory.