首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

防禦本地 fsockopen UDP 洪水攻擊:PHP 配置加固與系統級流量控制實戰

     編輯:PHP 綜合知識

攻擊原理分析

惡意腳本利用 PHP fsockopen() 建立 UDP 連接,向目標 IP 發送大量數據包:

<?php
$fp = fsockopen("udp://$targetIp", $port, $errno, $errstr, 5);
if ($fp) {
    fwrite($fp, $payload); // 發送攻擊負載
    fclose($fp);
}

特點:UDP 無連接、無狀態、源 IP 易偽造、帶寬放大效應明顯(如 NTP/DNS 放大攻擊)。本地用戶通過 Web Shell 或合法上傳腳本發起,消耗服務器出口帶寬,導致合法服務不可用。

PHP 層面防禦:禁用危險函數

php.ini 配置

; 禁用網絡套接字與命令執行相關函數
disable_functions = exec,system,passthru,shell_exec,proc_open,proc_close,proc_get_status,popen, \
    fsockopen,pfsockopen,stream_socket_client,stream_socket_server,stream_socket_accept, \
    stream_socket_sendto,stream_socket_recvfrom,stream_socket_get_name, \
    pcntl_exec,pcntl_fork,pcntl_signal,pcntl_alarm, \
    dl,openlog,syslog,readlink,symlink,link,chroot,chgrp,chown, \
    ini_alter,ini_restore,putenv,getenv, \
    highlight_file,show_source,phpinfo,get_cfg_var, \
    disk_free_space,disk_total_space,diskfreespace

生效方式:修改後重載 PHP-FPM 或重啟 Apache/IIS。驗證:php -r "var_dump(function_exists('fsockopen'));" 應返回 bool(false)。

進階:使用 Suhosin / RASP 運行時攔截

  • Suhosin:suhosin.executor.disable_eval = On、suhosin.executor.func.blacklist 精細控制
  • OpenRASP:掛鉤 fsockopen 等函數,上下文感知攔截(如:允許內部服務調用,禁止外網)
  • 自定義擴展:編寫 Zend 擴展重寫 fsockopen 內部處理器,記錄調用堆棧並阻斷

系統層面防禦:Windows IPsec 策略封鎖 UDP

適用於 Windows Server 2003/2008/2012/2016/2019,通過 netsh ipsec 策略實現內核級 UDP 封鎖。

批處理腳本:banudp.bat

@echo off
REM ==========================================
REM Windows IPsec 策略:封鎖所有入站/出站 UDP
REM 僅保留 DNS (UDP 53) 出站解析
REM 以管理員權限運行
REM ==========================================

REM 1. 創建策略
netsh ipsec static add policy name="Anti-UDP-Flood" description="Block UDP flood attacks from local scripts"

REM 2. 定義篩選器列表
netsh ipsec static add filterlist name="Allow-DNS-Outbound"
netsh ipsec static add filterlist name="Block-All-Other-UDP"

REM 3. 添加允許規則:本機 -> 任意 DNS (UDP 53)
netsh ipsec static add filter filterlist="Allow-DNS-Outbound" srcaddr=me dstaddr=any protocol=udp mirrored=yes dstport=53 description="Allow DNS queries"

REM 4. 添加封鎖規則:任意 -> 本機 所有 UDP (入站)
netsh ipsec static add filter filterlist="Block-All-Other-UDP" srcaddr=any dstaddr=me protocol=udp mirrored=yes description="Block inbound UDP"

REM 5. 添加封鎖規則:本機 -> 任意 所有 UDP (出站),排除 DNS
REM 注意:netsh ipsec 不支持「排除端口」,需通過「允許列表優先」機制
REM 此處封鎖所有出站 UDP,DNS 已在允許列表中,優先級更高
netsh ipsec static add filter filterlist="Block-All-Other-UDP" srcaddr=me dstaddr=any protocol=udp mirrored=yes description="Block outbound UDP except DNS"

REM 6. 定義篩選動作
netsh ipsec static add filteraction name="Permit" action=permit
netsh ipsec static add filteraction name="Block" action=block

REM 7. 創建規則綁定
netsh ipsec static add rule name="Allow-DNS" policy="Anti-UDP-Flood" filterlist="Allow-DNS-Outbound" filteraction="Permit"
netsh ipsec static add rule name="Block-UDP-In" policy="Anti-UDP-Flood" filterlist="Block-All-Other-UDP" filteraction="Block"
netsh ipsec static add rule name="Block-UDP-Out" policy="Anti-UDP-Flood" filterlist="Block-All-Other-UDP" filteraction="Block"

REM 8. 激活策略
netsh ipsec static set policy name="Anti-UDP-Flood" assign=y

echo 策略已激活。查看狀態:netsh ipsec static show policy name="Anti-UDP-Flood"
pause

策略驗證與管理

REM 查看策略狀態
netsh ipsec static show policy name="Anti-UDP-Flood"

REM 查看篩選器
netsh ipsec static show filterlist

REM 刪除策略(恢復網絡)
netsh ipsec static delete policy name="Anti-UDP-Flood"

REM 導出策略備份
netsh ipsec static exportpolicy file=ipsec_policy_backup.reg

Linux 系統防禦:iptables/nftables 精細控制

僅允許必要 UDP 流量

# 1. 允許本地回環
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# 2. 允許已建立/相關連接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 3. 允許 DNS 查詢 (UDP 53) - 僅授權 DNS 服務器
iptables -A OUTPUT -p udp -d 8.8.8.8,114.114.114.114 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -s 8.8.8.8,114.114.114.114 --sport 53 -j ACCEPT

# 4. 允許 NTP 時間同步 (UDP 123) - 如有需要
# iptables -A OUTPUT -p udp --dport 123 -j ACCEPT

# 5. 封鎖其他所有 UDP
iptables -A INPUT -p udp -j DROP
iptables -A OUTPUT -p udp -j DROP

# 6. 保存規則
iptables-save > /etc/iptables/rules.v4

nftables 現代語法(推薦)

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        iifname "lo" accept
        ct state established,related accept
        ip saddr { 8.8.8.8, 114.114.114.114 } udp sport 53 accept
        # 其他 UDP 隱式丟棄
    }
    chain output {
        type filter hook output priority 0; policy drop;
        oifname "lo" accept
        ct state established,related accept
        ip daddr { 8.8.8.8, 114.114.114.114 } udp dport 53 accept
        # 其他 UDP 隱式丟棄
    }
}

應用層補充防禦

1. PHP 代碼審計自動化

# 危險函數掃描腳本
grep -rn "fsockopen\|pfsockopen\|stream_socket_client\|stream_socket_server" /var/www/html --include="*.php" | grep -v ".git" | grep -v "vendor"

2. 運行時監控與告警

  • Auditd:審計 socket()、sendto() 系統調用,記錄進程 PID、用戶、目標 IP
  • Falco / Sysdig:內核級行為監控,規則:evt.type=sendto and evt.arg.proto=17 (UDP) 告警
  • Prometheus + Node Exporter:監控 node_network_receive_bytes_total、node_network_transmit_bytes_total 異常激增

3. 容器化環境網絡隔離

  • Docker:--network=none 或自定義橋接網絡 + iptables 限制
  • Kubernetes:NetworkPolicy 僅允許 Pod 訪問 kube-dns (UDP 53) 和必要服務

綜合防禦架構圖

防禦架構:PHP禁用函數 -> 系統防火牆 -> 運行時監控 -> 容器網絡隔離

纵深防禦:代碼層禁用 → 系統層封鎖 → 運行時監控 → 基礎設施層隔離

驗證清單

層級驗證命令預期結果
PHPphp -r "var_dump(@fsockopen('udp://8.8.8.8',53));"bool(false) + 警告
Windowsnetsh ipsec static show policy策略 "Anti-UDP-Flood" 狀態 Assigned: Yes
Linuxiptables -L -n -v | grep udp顯示 DROP 規則計數器增長
網絡從服務器 nc -u -v -w2 8.8.8.8 53DNS 查詢成功
網絡從服務器 nc -u -v -w2 1.1.1.1 12345連接超時/被拒

總結

針對本地 fsockopen UDP 洪水攻擊,單一防禦措施均可被繞過。必須構建纵深防禦體系:

  1. 代碼層:disable_functions 徹底禁用套接字函數,配合 RASP 運行時攔截
  2. 系統層:Windows IPsec / Linux iptables/nftables 內核級封鎖非必要 UDP
  3. 網絡層:邊界防火牆/安全組限制出站 UDP 目的地(僅授權 DNS/NTP)
  4. 監控層:流量基線告警 + 系統調用審計 + 容器網絡策略
  5. 應急層:一鍵封禁腳本、流量清洗服務、攻擊溯源取證流程

定期進行紅隊演練驗證防禦有效性,將攻擊面壓縮至業務絕對必要最小集。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved