AWD比赛模式的防御部分

还是挺有学习价值的

今天收集了下网上的思路和脚本,小结下

1.down源码
2.上waf.php
3.上传python监控文件脚本,防止修改;或者上传php监控文件脚本,防止修改
4.上传php日志监控脚本,dump到一个文件进行日志分析
5.Linux下命令

参考:

http://www.leo-blog.cn/2017/12/09/awd%E5%A5%97%E8%B7%AF%E6%80%BB%E7%BB%93/
http://www.cnblogs.com/nul1/p/8972210.html
https://www.jianshu.com/p/0bf0579e3b73 写马姿势 定时写脚本的一些思路
http://blkstone.github.io/2017/11/21/dctf-2017/
https://c0d3p1ut0s.github.io/AWD%E5%9E%8BCTF%E6%AF%94%E8%B5%9B%E5%B0%8F%E6%8A%80%E5%B7%A7%E6%80%BB%E7%BB%93/
https://www.freebuf.com/column/153123.html 攻防源码的下载
https://www.chinacycc.com/thread-2693-1-1.html
https://www.cnblogs.com/liang2580/p/9147806.html CTF 线下AWD 一些py脚本
https://blog.csdn.net/wy_97/article/details/78148705 还未看
https://blog.csdn.net/qq_42114918/article/details/82785960 还未看
https://xz.aliyun.com/t/25 有一个脚本,可以看
https://blog.csdn.net/like98k/article/details/80261603 还未看
https://www.jianshu.com/p/35af80b97ee6 一次别人的比赛
https://www.anquanke.com/post/id/86984 不错的


https://www.anquanke.com/post/id/98653 一次较详细的漏洞列表 可认真思考

https://github.com/ssooking/CTFDefense ctf-awd 防御脚本
AWD线下赛脚本集合 https://github.com/admintony/Prepare-for-AWD
https://www.freebuf.com/articles/web/118149.html 《论如何在CTF比赛中搅“shi”》 不死鸟的编写
https://github.com/Ares-X/AWD-Predator-Framework webshell批量获取脚本
https://github.com/wupco/weblogger 流量监控脚本
https://github.com/WangYihang/Reverse-Shell-Manager
http://blog.51cto.com/simeon/1981572 mysql 数据库利用的总结博文(推荐) 可思考 phpmyadmin内获取webshell的八种方法
v5est0r 写了一个Mysql提权综合利用工具,详细情况请参考其代码共享网站:https://github.com/v5est0r/Python_FuckMySQL其主要功能有:
https://www.anquanke.com/post/id/98653 nice的文章 内有多个exp脚本
http://blog.51cto.com/diudiu/1678358 sqlmap注入命令搭配备忘录
http://blog.51cto.com/simeon/1981572 mysql 提权详细记录
http://www.safedog.cn/website_safedog.html 安全狗linux版:
https://github.com/Ares-X/AWD-Predator-Framework AWD攻防赛webshell批量利用框架
https://github.com/admintony/Prepare-for-AWD AWD线下赛脚本集合
https://github.com/ssooking/CTFDefense CTFDefense
https://github.com/wupco/weblogger 针对ctf线下赛流量抓取(php)、真实环境流量抓取分析的工具
https://www.cnblogs.com/yuhuLin/p/7027342.html Linux中普通用户提权为超级用户
https://github.com/cn-leowong/WebShell-Detector/tree/master 基于深度学习与集成学习的综合策略WebShell检测系统
https://github.com/zer0h/httpscan httscan
https://github.com/WangYihang/Webshell-Sniper
https://www.freebuf.com/sectool/121847.html Linux提权?这四个脚本可以帮助你
https://github.com/InteliSecureLabs/Linux_Exploit_Suggester Linux_Exploit_Suggester


https://blog.csdn.net/dajitui2024/article/details/79396670 CTF比赛工具自收集 可看
1、攻击防护和漏洞检测:https://github.com/jzadeh/Aktaion
2、数据收集,威胁监控:https://github.com/Invoke-IR/ACE
3、AWS基础设施监控:https://github.com/SecurityFTW/cs-suite
4、渗透测试框架,团队协作:https://github.com/dradis/dradis-ce
5、本地扫描,安全度评估:https://github.com/OpenSCAP/openscap
6、日志分析管理:https://github.com/Graylog2/graylog2-server
1、网络注入攻击:https://github.com/xtr4nge/FruityC2

目前流程如下:

一.下载源码:
备份
D盾查看是否有后门
定时本地比较文件是否变化


上传waf.php 各文件写<?php include 'waf.php';?> ( find /home/awd/ -name "*.php" -exec sed -i '1i\<?php include 'waf.php';?>' {} \;)
上传python监控文件脚本,防止修改;或者上传php监控文件脚本,防止修改;
上传php日志监控脚本,dump到一个文件进行日志分析



linux命令进行敏感词防御:
1.root权限:
(一般不应当有这个权限,真的具备,那么官方的check就会更加严格)权限问题,如果具备root权限,直接创建用户,把web服务目录全部转此用户,再限制权限
useradd ctf123 -p asnjnw87bbsd*!@ 创建用户
chown -R ctf123:apache /var/www/html 改变属组
chattr -R +i /var/www/html或者chmod 755 /var/www/html 不建议限制目录权限
iptables -I INPUT -s 123.4.5.6 -j DROP 封杀某个IP,iptables限制流量


2.正常情况:
iptables
删除漏洞网页,修改漏洞网页
find -name \'*.php\' -mmin -10 查找最近10分钟被修改的文件



日志分析:
很重要的操作

第一步:down源码

备份
D盾查看是否有后门
定时本地比较文件是否变化

第二步:上waf.php

各php文件写<?php include 'waf.php';?>

linux命令写:

find /home/awd/ -name "*.php" -exec sed -i '1i\<?php include 'waf.php';?>' {} \;

python脚本写入到php文件:

# coding=utf-8
import os

def re_file(file):
f = open(file)
urls = []
urls.append("<?php include 'waf.php';?> ")
urls.append("\n")
for i in f.readlines():
urls.append(i)
f.close()
with open(file, "w+", encoding="utf-8") as f:
for i in urls:
f.write(i)
f.close()
def list_file(dir_name):
files=os.listdir(dir_name)
#print(files)
new_file=os.path.abspath(dir_name)
for file in files:
file=new_file+"/"+file
if os.path.isdir(file):
list_file(file)
#print(file)
elif ".php" in file:
print(file)
re_file(file)

dir_name=os.path.dirname("/home/awd/test/")
print(dir_name)
list_file(dir_name)



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|call_user_func|call_user_method";
$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();
?>

第三步:上传python监控文件脚本,防止修改;或者上传php监控文件脚本,防止修改

python监控脚本:

# -*- coding: utf-8 -*-
#use: python file_check.py ./

import os
import hashlib
import shutil
import ntpath
import time

CWD = os.getcwd()
FILE_MD5_DICT = {} # 文件MD5字典
ORIGIN_FILE_LIST = []

# 特殊文件路径字符串
Special_path_str = 'drops_JWI96TY7ZKNMQPDRUOSG0FLH41A3C5EXVB82'
bakstring = 'bak_EAR1IBM0JT9HZ75WU4Y3Q8KLPCX26NDFOGVS'
logstring = 'log_WMY4RVTLAJFB28960SC3KZX7EUP1IHOQN5GD'
webshellstring = 'webshell_WMY4RVTLAJFB28960SC3KZX7EUP1IHOQN5GD'
difffile = 'diff_UMTGPJO17F82K35Z0LEDA6QB9WH4IYRXVSCN'

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
except Exception, e:
print u'[!] getmd5_error : ' + getUnicode(filepath)
print getUnicode(e)
try:
ORIGIN_FILE_LIST.remove(filepath)
FILE_MD5_DICT.pop(filepath, None)
except KeyError, e:
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=[]):
# if len(os.listdir(Special_path['bak'])) == 0:
for filepath in filelist:
if Special_path_str not in filepath:
shutil.copy2(filepath, Special_path['bak'])

if __name__ == '__main__':
print u'---------start------------'
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) # TODO 备份文件可能会产生重名BUG
print u'[*] pre work end!'
while True:
file_list = getfilelist(CWD)
# 移除新上传文件
diff_file_list = list(set(file_list) ^ set(ORIGIN_FILE_LIST))
if len(diff_file_list) != 0:
# import pdb;pdb.set_trace()
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 find : ' + getUnicode(filepath)
shutil.move(filepath, os.path.join(Special_path['webshell'], ntpath.basename(filepath) + '.txt'))
except Exception as e:
print u'[!] move webshell error, "%s" maybe is webshell.'%getUnicode(filepath)
try:
f = open(os.path.join(Special_path['log'], 'log.txt'), 'a')
f.write('newfile: ' + getUnicode(filepath) + ' : ' + str(time.ctime()) + '\n')
f.close()
except Exception as e:
print u'[-] log error : file move error: ' + 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'[*] file had be change : ' + getUnicode(filekey)
shutil.move(filekey, os.path.join(Special_path['difffile'], ntpath.basename(filekey) + '.txt'))
shutil.move(os.path.join(Special_path['bak'], ntpath.basename(filekey)), filekey)
except Exception as e:
print u'[!] move webshell error, "%s" maybe is webshell.'%getUnicode(filekey)
try:
f = open(os.path.join(Special_path['log'], 'log.txt'), 'a')
f.write('diff_file: ' + getUnicode(filekey) + ' : ' + getUnicode(time.ctime()) + '\n')
f.close()
except Exception as e:
print u'[-] log error : done_diff: ' + getUnicode(filekey)
pass
time.sleep(2)
# print '[*] ' + getUnicode(time.ctime())

php脚本监控文件变化并复制到指定文件夹.php

<?php
/**
* Created by PhpStorm.
* User: iyahe@qq.com (天明)
* Date: 2017/4/26
* Time: 10:33
* https://www.php.cn/php-weizijiaocheng-386566.html
*/

define('sleep',1000); //延迟时间(毫秒)
define('fileLen',2); //文件名称长度
define('baginPath','/dist/ideal/src'); //开始目录
define('endPath','/ideal/dist/'); //复制到的目录

date_default_timezone_set('PRC');
echo "PHP开始监控文件变化 by 天明°...".PHP_EOL;
$fileArr = array();
do {
$path = __DIR__.baginPath;
$dir = __DIR__.endPath;
$file = scandir($path);
foreach($file as $k=>$v){
if(strlen($v) > fileLen){
$filePathTemp = $path.'/'.$v;
$md5File = md5_file($filePathTemp);
if(@$fileArr[$v] != $md5File){
//microtime(sleep);//延迟
copy($filePathTemp,$dir.$v);
if(isset($fileArr[$v])){
echo date('Y-m-d H:i:s',time()).' >> '.$dir.$v.' ---> '.$filePathTemp.PHP_EOL;
}
$fileArr[$v] = $md5File;
unlink(@$fileArr[$v]); //删除文件
}
}
}
} while (true);
?>

第四步:上传php日志监控脚本,dump到一个文件进行日志分析

<?php

error_reporting(0);
define('LOG_FILEDIR','./logs');
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"];
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']);
$input = array("Get"=>$get, "Post"=>$post, "Cookie"=>$cookie, "File"=>$files, "Header"=>$header);

logging($input);

}

function logging($var){
$filename = $_SERVER['REMOTE_ADDR'];
$LOG_FILENAME = LOG_FILEDIR."/".$filename;
$time = date("Y-m-d G:i:s");
file_put_contents($LOG_FILENAME, "\r\n".$time."\r\n".print_r($var, true), FILE_APPEND);
file_put_contents($LOG_FILENAME,"\r\n".'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'], FILE_APPEND);
file_put_contents($LOG_FILENAME,"\r\n***************************************************************",FILE_APPEND);
}

waf();
?>

第五步:Linux下命令



###ssh操作
ssh <-p 端口> 用户名@IP  //登录
scp 文件路径 用户名@IP:存放路径  //向ssh服务器上传输文件

###备份web目录
tar -zcvf web.tar.gz /var/www/html/

###查看已建立的网络连接以及对应进程
netstat -antulp | grep EST

###用户管理
w   //查看当前用户
pkill -kill -t <用户tty>   //踢掉当前登录用户

###进程管理
查看进程信息
ps aux | grep pid或者进程名  

查看指定端口被哪个进程占用
lsof -i:端口号
或者 netstat -tunlp|grep 端口号

结束进程命令
kill PID
killall <进程名>
kill -9 <PID>

###iptables命令
iptables:#可参考https://www.anquanke.com/post/id/86984
封杀某个IP或者ip段,如:123.4.5.6
iptables -I INPUT -s 123.4.5.6 -j DROP
iptables -I INPUT -s 123.4.5.1/24 -j DROP

禁止从某个主机ssh远程访问登陆到本机,如123.4.5.6
iptable -t filter -A INPUT -s 123.4.5.6 -p tcp --dport 22 -j DROP

##Mysql数据库操作

备份mysql数据库
mysqldump -u 用户名 -p 密码 数据库名 > back.sql  //备份指定数据库
mysqldump --all-databases > bak.sql    //备份所有数据库

还原mysql数据库
mysql -u 用户名 -p 密码 数据库名 < bak.sql

###安全检查

find -name \'*.php\' -mmin -10 查找最近10分钟被修改的文件
find / *.php -perm 4777    //查找777的权限的php文件
awk -F: '{if($3==0)print $1}' /etc/passwd  //查看root权限的账号
crontab -l  //查看计划任务

检测所有的tcp连接数量及状态
netstat -ant|awk '{print $5 "\t" $6}' |grep "[1-9][0-9]*\."|sed -e 's/::ffff://' -e 's/:[0-9]*//'|sort|uniq -c|sort -rn
  
查看页面访问排名前十的IP
cat /var/log/apache2/access.log | cut -f1 -d " " | sort | uniq -c | sort -k 1 -r | head -10
  
查看页面访问排名前十的URL
cat /var/log/apache2/access.log | cut -f4 -d " " | sort | uniq -c | sort -k 1 -r | head -10  

 

再推荐一篇安全应急排查手册:[https://yq.aliyun.com/articles/177337](https://yq.aliyun.com/articles/177337)

2019.7.17

标签: