红蓝对抗-AWD全流程攻略06(起手防御)

01 防守流程

1.重中之重:备份网站源码和数据库。这个作用有二,一是以防自己魔改网站源码或数据库后无法恢复,二是裁判一般会定时 Check 服务是否正常,如果不正常会进行扣分,因此备份也可以防对手入侵主机删源码后快速恢复服务。
2.系统安全性检查。就是不该开的端口 3306 有没有开启、有没有限制 SSH 登陆、SSH密码修改、MySQL 是否为默认密码等等,这里可以用脚本刷一遍,

3.部署 WAF。用自己提前准备好的 WAF,使用脚本进行快速部署,但是要注意验证会不会部署完后服务不可用。

4.修改权限。比如说 MySQL 用户读表权限,上传目录是否可执行的权限等等,监控可读写权限的目录是否新增。

5.部署文件监控脚本。删除文件并及时提醒。这里说下,如果被种了不死马的话通常有以下几种克制方法。(1)强行 kill 掉进程后重启服务(2)建立一个和不死马相同名字的文件或者目录(3)写脚本不断删除文件(4)不断写入一个和不死马同名的文件。

6.部署流量监控脚本或开启服务器日志记录。目的主要是为了进行流量回放,看其它大佬如何用我们没发现的漏洞来打我们的机子,抓取到之后把看不懂的流量直接回放到别的机子去,这里还得提到,我们自己在攻击的时候,也要试着混淆一下自己的攻击流量,不能轻易被别人利用。

 02 备份

Web网站源码备份
(1)直接利用Moba/Xshell把源码拖下来

(2)利用linux自带命令的进行备份
Mysql数据库备份
(1)查看网站源码下是否有备份好的数据库

(2)利用mysql命令进行备份

 

 mysql -u root -p root 登录

create databases test; 创建数据库

source /var/www/html/test01.sql 导入备份数据库

 03 修改密码

Web网站后台登录密码修改

(1)直接在数据库中查询,然后进行修改

Mysql数据库密码修改

(1)利用mysql命令进行密码修改

修改数据库配置文件

修改ssh登录密码

(1)直接使用linux自带命令

04 部署WAF 

根据网站使用语言类型准备WAF

(1)挂waf的php语句

include once( 'waf');

require once( 'waf');

05 文件监控

根据特点网站进行文件监控

编写python脚本实现文件监控

# -*- 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)

 06 杀死不死马

1.ps auxwwlgrep shell.php 找到pid后杀掉进程就可以你删掉脚本是起不了作用的,因为php执行的时候已经把脚本读进去解释成opcode运行了
2.重启php等web服务
3.用一个ignore_user_abort(true)脚本,一直竞争写入(断断续续)。usleep要低于对方不死马设置的值。

4.创建一个和不死马生成的马一样名字的文件夹。

<?php
while (1) {
$pid=1234;
@unlink('.index.php');
exec('kill -9 $pid');
}
?>

07 修复万能密码

$user =$_POST['user'];修改成
$user = mysql_real_escape_string($ POST['user']);

08  预留后门处理

删除或注释

修改如下内容:

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
一个awd攻防比赛的裁判平台。 版本:beta v2.0 开发语言:python3 + django 平台分为两个部分 裁判机 靶机 通过特定接口,来实现靶机flag与服务器的通信 搭建流程 裁判机 安装所需环境 裁判机:python3+django 局搜索woshiguanliyuan,并修改为随机字符串,此处为管理平台地址 /untitled/urls.py path('woshiguanliyuan/',views.admin,name='admin'), path('woshiguanliyuan/table/',views.admin_table,name='admin_table'), /app/views.py if 'woshiguanliyuan' not in request.META['HTTP_REFERER']: 第31和47换为你的目录 列:("/var/www/awd_platform/app/qwe.txt","a") 修改app/management/commands/init.py,添加用户 #['用户名','用户靶机token','用户靶机token'] user=[ ['123456','FF9C92C7SDFABB71566F73422C','FF9C92C7SDFABB71566F73422C'], ['aaabbb','311F8A54SV9K6B5FF4EAB20536','311F8A54SV9K6B5FF4EAB20536'] ] 修改/app/views.py第行d89f33b18ba2a74cd38499e587cb9dcd为靶机中设置的admin_token值的md5 if('d89f33b18ba2a74cd38499e587cb9dcd'==hl.hexdigest()): 运行 python3 manage.py init python3 manage.py manage.py runserver --insecure 靶机 安装所需环境 靶机:python+requests 修改send_flag.py参数,并将其放入靶机,设权限700。 靶机 sudo python send_flag.py。 靶机生成flag脚本,send_flag.py import requests import time import random import string import hashlib token='woshiwuxudong' # 红队 baji='311F8A54SV9K6B5FF4EAB20536' def getFlag(): #return ''.join(random.sample(string.ascii_letters + string.digits, 48)) m = hashlib.md5(''.join(random.sample(string.ascii_letters + string.digits, 48)).encode(encoding="utf-8")).hexdigest() return m while(1): f=open('/flag','w') flag=getFlag() f.write(flag) data={ 'flag':flag, 'token':token, 'baji':baji, } r=requests.post('http://127.0.0.1/caipanflag/',data=data) print(r.text) f.close() time.sleep(300) 重要须知 更新作者基础上: 1.增加flag验证一次性失效性,使得每个用户都并且仅可以提交一次flag 2.增加排名情况 3.flag改为MD5 4.增加丢失flag一轮扣100分

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值