awd 主要题型为 WEB 和 PWN,涉及语言多数为 PHP,还有少量 Java、Python。
WEB 主要是一些 CMS 和框架安全漏洞,如注入、上传和反序列化等,更多是依赖已知漏洞
比赛流程#
一般比赛会将加固环节和攻击环节分开,先统一加固后再进行攻击。
比赛开始后显示账号
bugku 平台,如 team1 密码为 fe85d7dec6e3757f391e013efdd67c0c,端口为 2222,一般服务器为 Linux 系统,登录工具可以使用 xSHELL,finalSHELL 等。
Token 主要用于脚本身份凭证用于自动化提交鉴别。虚拟 IP 为靶机访问网址。其他选手地址为 192-168-x-250.pvp1923.bugku.cn,x 可以是 1-255 内任一个数字。
站点源码备份#
源码备份可以用 Winscp或者
FileZilla`,下载可能会比较慢。
速度快的方法就是直接用tar
打包
tar
备份方法如下:
cd /var/www/html
tar -zcvf ~/html.tar.gz *
数据库备份#
有时候数据库里也有 flag,所以要将数据库也备份一下,避免删库跑路
首先是找配置文件,翻一翻账号密码
cd /var/www/html
find .|xargs grep "password"Copy
备份:
$ cd /var/lib/mysql #(进入到MySQL库目录,根据自己的MySQL的安装情况调整目录)
$ mysqldump -u root -p Test > Test.sql # 输入密码即可。
$ mysqldump -u root -p --all-databases > ~/backup.sql # 备份所有数据库
$ mysqldump -u root -p --all-databases -skip-lock-tables > ~/backup.sql # 跳过锁定的数据库表
数据库口令修改#
一般来说,数据库的密码是一定要修改的
$ mysql -u root -p
show databases;
use mysql
set password for root@localhost = password('123');
流量监控#
流量监控脚本。别人打你后,记录访问信息,url, 反过来可以拿它来打别人
<?php
$ip = $_SERVER["REMOTE_ADDR"]; //记录访问者的ip
$filename = $_SERVER['PHP_SELF']; //访问者要访问的文件名
$parameter = $_SERVER["QUERY_STRING"]; //访问者要请求的参数
$method = $_SERVER['REQUEST_METHOD']; //请求方法
$uri = $_SERVER['REQUEST_URI']; //请求URI
$time = date('Y-m-d H:i:s',time()); //访问时间
$post = file_get_contents("php://input",'r'); //接收POST数据
$others = '...其他你想得到的信息...';
$logadd = 'Visit Time:'.$time.' '.'Visit IP:'.$ip."\r\n".'RequestURI:'.$uri.' '.$parameter.'RequestMethod:'.$method."\r\n";
// log记录
$fh = fopen("/tmp/log.txt", "a+");
fwrite($fh, $logadd);
fwrite($fh, print_r($_COOKIE, true)."\r\n");
fwrite($fh, $post."\r\n");
fwrite($fh, $others."\r\n");
fclose($fh);
?>Copy
这种脚本一般放置在 CMS 的入口文件处
文件监控#
# -*- coding: utf-8 -*-#
# awd文件监控脚本
import os
import json
import time
import hashlib
def ListDir(path): # 获取网站所有文件
for file in os.listdir(path):
file_path = os.path.join(path, file)
if os.path.isdir(file_path):
if initialization['ok'] == 'false':
dir_list.append(file_path)
else:
dir_list_tmp.append(file_path)
ListDir(file_path)
else:
if initialization['ok'] == 'false':
file_list.append(file_path)
else:
file_list_tmp.append(file_path)
def GetHash(): # 获取hash,建立索引
for bak in file_list:
with open(bak, 'rb') as f:
md5obj = hashlib.md5()
md5obj.update(f.read())
hash = md5obj.hexdigest()
bak_dict[bak] = hash
if os.path.exists('/tmp/awd_web_hash.txt') == False:
os.system('mkdir /tmp/awd_web_bak/')
os.system('\\cp -a {0}* /tmp/awd_web_bak/'.format(web_dir))
with open('/tmp/awd_web_hash.txt', 'w') as f: # 记录web文件hash
f.write(str(json.dumps(bak_dict)))
for i in file_list: # 记录web文件列表
with open('/tmp/awd_web_list.txt', 'a') as f:
f.write(i + '\n')
for i in dir_list: # 记录web目录列表
with open('/tmp/awd_web_dir.txt', 'a') as f:
f.write(i + '\n')
def FileMonitor(): # 文件监控
# 提取当前web目录状态
initialization['ok'] = 'true'
for file in os.listdir(web_dir):
file_path = os.path.join(web_dir, file)
if os.path.isdir(file_path):
dir_list_tmp.append(file_path)
ListDir(file_path)
else:
file_list_tmp.append(file_path)
for file in file_list_tmp:
with open(file, 'rb') as f:
md5obj = hashlib.md5()
md5obj.update(f.read())
hash = md5obj.hexdigest()
bak_dict_tmp[file] = hash
with open('/tmp/awd_web_hash.txt', 'r') as f: # 读取备份的文件hash
real_bak_dict = json.loads(f.read())
with open('/tmp/awd_web_list.txt', 'r') as f: # 读取备份的文件列表
real_file_list = f.read().split('\n')[0:-1]
with open('/tmp/awd_web_dir.txt', 'r') as f: # 读取备份的目录列表
real_dir_list = f.read().split('\n')[0:-1]
for dir in real_dir_list: # 恢复web目录
try:
os.makedirs(dir)
print("[del-recover]dir:{}".format(dir))
except:
pass
for file in file_list_tmp:
try:
if real_bak_dict[file] != bak_dict_tmp[file]: # 检测被篡改的文件,自动恢复
os.system('\\cp {0} {1}'.format(file.replace(web_dir, '/tmp/awd_web_bak/'), file))
print("[modify-recover]file:{}".format(file))
except: # 检测新增的文件,自动删除
os.system('rm -rf {0}'.format(file))
print("[delete]webshell:{0}".format(file))
for real_file in real_file_list: # 检测被删除的文件,自动恢复
if real_file not in file_list_tmp:
os.system('\\cp {0} {1}'.format(real_file.replace(web_dir, '/tmp/awd_web_bak/'), real_file))
print("[del-recover]file:{0}".format(real_file))
file_list_tmp[:] = []
dir_list_tmp[:] = []
os.system("rm -rf /tmp/awd_web_hash.txt /tmp/awd_web_list.txt /tmp/awd_web_dir.txt /tmp/awd_web_bak/")
web_dir = "/var/www/" # web目录,注意最后要加斜杠
file_list = []
dir_list = []
bak_dict = {}
file_list_tmp = []
dir_list_tmp = []
bak_dict_tmp = {}
initialization = {'ok': 'false'}
ListDir(web_dir)
GetHash()
while True:
print(time.ctime()+" 安全")
FileMonitor()
time.sleep(1) # 监控间隔,按需修改
主机探测#
可以用 nmap 或 httpscan(自己主机端)
本地 python 扫描
import requests
for i in range(1, 255):
try:
url = 'http://192-168-1-{}.pvp2012.bugku.cn/'.format(i)
response = requests.get(url,headers={'Connection':'close'})
print(response)
if response.status_code == 200:
print(url)
else:
pass
except requests.exceptions.RequestException as e:
print(f"{url} is down. Error")
# http://192-168-1-100.pvp2012.bugku.cn/
扫描漏洞#
D 盾扫描下载的 cms 源码漏洞,或者根据 cms 信息网上搜索漏洞
安装 waf#
如果我们想给 web 目录文件添加自定义 waf 脚本,其实可以用一条命令解决,以 php 为例:
find /var/www/html -type f -path "*.php" | xargs sed -i "s/<?php/<?php require_once('\/tmp\/waf.php');/g"
find /var/www/html -type f -path "*.php" | xargs sed -i "s/<?php/<?php require_once('waf.php');/g"
后门查杀#
通过命令查看可疑文件:
find /var/www/html -name *.php -mmin -20 #查看最近20分钟修改文件
find ./ -name '*.php' | xargs wc -l | sort -u #寻找行数最短文件
grep -r --include=*.php '[^a-z]eval($_POST' /var/www/html #查包含关键字的php文件
find /var/www/html -type f -name "*.php" | xargs grep "eval(" |more
fork 炸弹#
:(){ :|:& };:
输入到 bash,递归创建子进程,后果就是耗尽服务器资源,使服务器不能正常的对外提供服务