编写PHP webshell漏洞的suricata规则-测试(9004205-9004215)

1.测试准备

1.主机A开启服务
python -m http.server 80 --bind 0.0.0.0

2.主机B生成测试流量
cat > gen_webshell.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
DST_IP="10.10.10.1"
DST_PORT="80"
URL="http://${DST_IP}:${DST_PORT}/"
# 每条规则都有 threshold: by_src 60s,只发 1 次最稳
declare -a CASES=(
  # sid 9004205: eval + (decoder chain)(  —— 需要 eval( base64_decode(
  "9004205|eval(base64_decode(|PHP WebShell eval decoder chain"
  # sid 9004206: assert + (decoder chain)(
  "9004206|assert(gzinflate(|PHP WebShell assert decoder chain"
  # sid 9004207: eval( $_POST / $_GET / ... 或 file_get_contents('php://input')
  "9004207|eval(\$_POST|PHP WebShell eval superglobal"
  # sid 9004208: assert( $_POST... 或 file_get_contents('php://input')
  "9004208|assert(file_get_contents('php://input'))|PHP WebShell assert php://input"
  # sid 9004209: preg_replace('/.../e'...) + $_POST/$_GET/...
  "9004209|preg_replace(\"/x/e\", \$_POST[\"a\"], \"b\");|PHP WebShell preg_replace /e legacy"
  # sid 9004210: create_function('', $_POST...)
  "9004210|create_function(\"\", \$_POST[\"a\"]);|PHP WebShell create_function superglobal"
  # sid 9004211: call_user_func('system'...) 等危险函数
  "9004211|call_user_func(\"system\", \"id\");|PHP WebShell call_user_func dangerous"
  # sid 9004212: ${\"ev\".\"al\"}(
  "9004212|\${\"ev\".\"al\"}(\$_POST[\"a\"]);|PHP WebShell variable-function ev.al"
  # sid 9004213: \"ev\".\"al\" 或 \"as\".\"sert\"
  "9004213|\"ev\".\"al\"|PHP WebShell string concat builds eval"
  # sid 9004214: eval%28 ... base64_decode%28
  "9004214|eval%28AAAAbase64_decode%28|PHP WebShell URL-encoded eval%28 base64_decode%28"
  # sid 9004215: assert%28 ... base64_decode%28
  "9004215|assert%28AAAAbase64_decode%28|PHP WebShell URL-encoded assert%28 base64_decode%28"
)
echo "[*] Sending 11 trigger requests to ${URL}"
for c in "${CASES[@]}"; do
  IFS='|' read -r sid payload desc <<<"$c"
  echo "  - SID ${sid}: ${desc}"
  # 把 payload 放在 Header,避免 URI 编码问题;--max-time 防止无响应卡住
  curl -sS --max-time 2 -o /dev/null \
    -H "X-Test-Payload: ${payload}" \
    "${URL}?sid=${sid}" || true
done
echo "[*] Done."
EOF

2.查看suricata告警

1.Linux查看
grep -oP '(?<=\[).*(?=\])' fast.log | sort | uniq -c | sort -nr

2.ES查看
alert.signature_id >= 9004205 and alert.signature_id <= 9004215

 3.准备zeek检测逻辑

1.zeek检测php_webshell
/usr/local/zeek/share/zeek/site目录添加php_webshell.zeek

2.检测逻辑添加到入口
/usr/local/zeek/share/zeek/site/local.zeek 添加@load php_webshell

3.zeek日志转为json
/usr/local/zeek/share/zeek/site/local.zeek 添加@load policy/tuning/json-logs.zeek

4.使zeek忽略校验和
/usr/local/zeek/share/zeek/site/local.zeek 添加 redef ignore_checksums = T;

5.重启zeek
/usr/local/zeek/bin/zeekctl deploy

6.ES端 zeek ingest pipelines确保补齐
filebeat setup --pipelines --modules zeek -c /etc/filebeat/filebeat.yml -M "zeek.notice.enabled=true" -M "zeek.connection.enabled=true" -M "zeek.weird.enabled=true" -E output.logstash.enabled=false -E output.elasticsearch.hosts='["https://10.10.10.1:9200"]' -E output.elasticsearch.username='elastic' -E output.elasticsearch.password='jq5SSXIrIUXW=xDUWQRP' -E output.elasticsearch.ssl.certificate_authorities='["/etc/filebeat/certs/http_ca.crt"]'

7.重启filebeat和logstash
systemctl restart filebeat
journalctl -u filebeat -n --no-page
systemctl restart logstash
journalctl -u logstash -n --no-page

4.查看zeek告警

1.Linux查看
jq . notice.log

2.ELK查看
event.module: "zeek" and event.dataset: "zeek.notice"

 

posted @ 2026-03-03 14:25  岐岐卡卡西  阅读(1)  评论(0)    收藏  举报