【教程】AWD中如何通过Python批量快速管理服务器?

AWD中用Python批量管理服务器教程

前言

很多同学都知道,我们常见的CTF赛事除了解题赛之外,还有一种赛制叫AWD赛制。在这种赛制下,我们战队会拿到一个或多个服务器。服务器的连接方式通常是SSH链接,并且可能一个战队可能会同时有多个服务器。

本期文章,我们来详细讲述一下如何使用Python绝地反击、逆风翻盘。

万能的Python

Python作为一个解释型语言,拥有高集成性。虽然高并发、执行效率有些勉强,但是不免是一个好用的语言。

Python几乎可以涵盖在AWD中的多种操作,我们在下面对部分可能用到的和已经用到的功能给大家写一些例子,方便文章后续的综合。

Python的SSH操作

我们想要链接容器,有很多方式,最最最正常的方式,当然是通过SSH操作了。

我们可以通过用户名和密码去连接靶机,然后执行命令,并取得结果。

相信聪明的人已经知道了,我们可以这样操作SSH之后别提有多方便了!

首先,我们需要一个Python库:“paramiko”

pip3 install paramiko

Paramiko

给出示例代码:

import paramiko

def execute_ssh_command(host, username, password, command):
    # 创建SSH客户端对象
    ssh_client = paramiko.SSHClient()

    # 自动添加主机密钥(慎用,可能会有安全风险)
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    try:
        # 连接SSH服务器
        ssh_client.connect(hostname=host, username=username, password=password)

        # 执行命令
        stdin, stdout, stderr = ssh_client.exec_command(command)

        # 获取命令执行结果
        result = stdout.read().decode().strip()

        # 关闭SSH连接
        ssh_client.close()

        return result
    except Exception as e:
        return str(e)

if __name__ == "__main__":
    host = "ip"  # 替换为SSH主机地址
    username = "root"  # 替换为SSH主机用户名
    password = "password"  # 替换为SSH主机用户的密码
    command = "ls /"

    result = execute_ssh_command(host, username, password, command)
    print(result)

我们根据上面的代码,是不是也可以根据一些基础Python知识进行完善,填补更多的内容?

Python SSH 后一些小技巧

上面这个例子,是通过SSH获取容器ID的例子,代码如下:

import paramiko

def get_remote_all_container_ids(host, username, password):
    try:
        # 创建SSH客户端对象
        ssh_client = paramiko.SSHClient()

        # 自动添加主机密钥(慎用,可能会有安全风险)
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        # 连接SSH服务器
        ssh_client.connect(hostname=host, username=username, password=password)

        # 执行docker ps -aq命令并捕获输出
        stdin, stdout, stderr = ssh_client.exec_command('docker ps -aq')

        # 获取命令执行结果,即所有容器的ID
        container_ids = stdout.read().decode().strip().split()

        # 关闭SSH连接
        ssh_client.close()

        return container_ids
    except Exception as e:
        print(f"Error: {str(e)}")
        return []

if __name__ == "__main__":
    host = "192.168.31.161"  # 替换为远程主机的IP地址或主机名
    username = "root"  # 替换为登录用户名
    password = "password"  # 替换为登录密码

    container_ids_list = get_remote_all_container_ids(host, username, password)
    print(container_ids_list)

我们额外注意获取结果那一行的命令:container_ids = stdout.read().decode().strip().split()

这一行的代码是读取执行后输出的结果,解码,然后分割。

事实上我们很多地方都可以根据这样去写,并取回我们想要的东西。

如果我们获取了结果,那么重启docker容器、进入容器执行命令是不是也轻而易举了。

防守篇

在防守篇中,我们着重对SSH后一些操作进行举例。

SSH后快速查看容器和当前目录

适用:AWD中开赛迅速熟悉自身靶机容器。

import paramiko
import sys
import select



class InteractiveShell:
    def __init__(self, ssh_client):
        self.ssh_client = ssh_client
        self.channel = ssh_client.invoke_shell()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.ssh_client.close()

    def execute_command(self, command):
        self.channel.send(command + "\n")
        while not self.channel.recv_ready():
            continue
        output = self.channel.recv(4096).decode()
        return output

    def interactive_shell(self):
        try:
            while True:
                # 监听标准输入和远程终端输出
                inputs, _, _ = select.select([sys.stdin, self.channel], [], [])

                for src in inputs:
                    if src is sys.stdin:
                        # 从标准输入读取输入,并发送到远程终端
                        user_input = sys.stdin.readline()
                        self.channel.sendall(user_input.encode())
                        sys.stdout.flush()  # 用于刷新终端,防止不输出或输出不完整命令提示符
                    else:
                        # 从远程终端读取输出,并显示在本地终端
                        output = self.channel.recv(1024).decode()
                        sys.stdout.write(output)
                        sys.stdout.flush()  # 用于刷新终端,防止不输出
<think>好的,我需要帮助用户寻找一个用于CTF AWD比赛中批量提交Flag的Python脚本示例。首先,我得理解AWD比赛的特点。在这种比赛中,团队需要同时攻击其他队伍的服务并防守自己的服务,通常需要自动化脚本来快速提交Flag以获取分数。 用户明确提到需要批量提交Flag的Python脚本,所以我应该提供一个基本的脚本框架,涵盖关键功能,比如读取Flag、发送HTTP请求到评分平台、处理可能的错误等。同时,考虑到AWD环境中的网络不稳定和服务器压力,脚本需要具备重试机制和并发处理能力。 接下来,我需要参考提供的引用内容。引用[1]提到了别名和伪装命令程序,这可能与防守策略相关,但用户的问题集中在提交Flag的脚本,所以这部分可能暂时用不上。引用[2]是关于Shell脚本编程的例子,虽然不直接相关,但可以借鉴循环和条件判断的结构。引用[3]展示了iptables规则,可能用于网络安全防护,但同样不直接涉及提交脚本。 然后,我需要确保脚本符合Python的最佳实践,比如使用requests库发送POST请求,处理异常,以及合理的超时设置。同时,考虑到比赛中的Flag可能存储在不同的文件或目录中,脚本需要能够遍历指定目录或读取特定文件中的Flag。 另外,用户可能需要脚本支持多线程或异步请求,以加快提交速度。不过,作为示例,可能先提供一个简单版本,再建议扩展的方向。同时,需要提醒用户注意比赛规则,确保脚本的使用符合规定,避免违规行为。 最后,要检查脚本中的潜在问题,比如是否处理了服务器返回的不同状态码,是否有重试机制,以及如何避免重复提交相同的Flag。可能还需要添加日志功能,方便调试和记录提交结果。 总结下来,脚本应包含以下部分: 1. 读取Flag的输入(文件或直接输入)。 2. 构造HTTP请求,包括必要的请求头和数据。 3. 实现重试机制,应对网络波动。 4. 处理响应,输出成功或失败信息。 5. 可能的并发处理以提高效率。</think>### CTF AWD批量提交Flag脚本实现 在CTF AWD比赛中,批量提交Flag脚本需要实现以下核心功能: 1. 自动获取本地生成的Flag文件 2. 向计分平台发送合法格式的POST请求 3. 处理网络异常和平台响应 4. 支持多线程并发提交 ```python import requests import threading import os import time # 基础配置(根据比赛实际情况修改) SUBMIT_URL = "http://192.168.1.100:8080/submit" # 提交地址 TEAM_TOKEN = "your_team_token" # 队伍凭证 RETRY_TIMES = 3 # 失败重试次数 FLAG_DIR = "./flags/" # Flag存储目录 def submit_flag(flag): headers = { "User-Agent": "Mozilla/5.0 (AWD Script)", "Content-Type": "application/x-www-form-urlencoded" } data = { "token": TEAM_TOKEN, "flag": flag.strip() } for _ in range(RETRY_TIMES): try: resp = requests.post(SUBMIT_URL, data=data, headers=headers, timeout=5) if "success" in resp.text: print(f"[+] 提交成功: {flag}") return True else: print(f"[-] 提交失败: {flag} -> {resp.text}") except Exception as e: print(f"[!] 网络错误: {str(e)}") time.sleep(1) return False def batch_submit(): while True: try: for filename in os.listdir(FLAG_DIR): filepath = os.path.join(FLAG_DIR, filename) with open(filepath, 'r') as f: flags = f.readlines() for flag in flags: t = threading.Thread(target=submit_flag, args=(flag,)) t.start() except Exception as e: print(f"文件读取错误: {str(e)}") time.sleep(60) # 每分钟扫描一次新Flag if __name__ == "__main__": batch_submit() ``` 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值