CTF竞赛中的奇葩注册方式

2024-03-05 06:38
文章标签 方式 注册 ctf 竞赛 奇葩

本文主要是介绍CTF竞赛中的奇葩注册方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近看了来看ctftime中的比赛,看到ictf比赛,就索性点进去看看,发现,我XXXX,竟然用Python写了写了一个注册client端,需要用程序注册,现将源码更新如下,以后我们国内比赛说不定也可以参考一下:

    ## The iCTF game client.## Written by subwire and the iCTF team, 2015## Because websites are so 1995.#from builtins import inputimport jsonimport requestsimport base64import randomDEFAULT_GAME_INTERFACE = "https://api.ictf2017.net/"class iCTF(object):"""The iCTF client!If you're just getting started, you probably want to register a team.You can access the interactive registration wizard like this:>>> from ictf import iCTF()>>> i = iCTF()>>> i.register_wizard()Afterward, your password will be emailed to the email address you specified.With that, you can now login:>>> t = i.login('team@acme.edu', 'asdfSLKDFSJL')Check out the other methods in this class for all kinds of useful functions.Have fun!- The iCTF Team"""def __init__(self, game_interface=DEFAULT_GAME_INTERFACE):self.game_url = game_interfaceself._token = Nonedef _post_json(self,endpoint,j):# EG says: Why can't Ubuntu stock a recent version of Requests??? Ugh.headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}resp = requests.post(self.game_url + endpoint, data=json.dumps(j), headers=headers)try:js = json.loads(resp.content.decode('utf-8'))return js, resp.status_codeexcept:return "", resp.status_codedef _get_json(self, endpoint):resp = requests.get(self.game_url + endpoint)try:js = json.loads(resp.content.decode('utf-8'))return js, resp.status_codeexcept:return "", resp.status_code# Flag parameters, borrowed from the gamebotFLAG_ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"FLAG_LENGTH = 13FLAG_PREFIX = "FLG"FLAG_SUFFIX = ""@staticmethoddef generate_flag():"""Generates flags, in the same manner as the game bot.This is useful for creating realistic-looking benign traffic for services.:return: Flag following the predefined flag format."""flag = "".join(random.choice(iCTF.FLAG_ALPHABET)for _ in range(iCTF.FLAG_LENGTH))return "{0}{1}{2}".format(iCTF.FLAG_PREFIX, flag, iCTF.FLAG_SUFFIX)def get_metadata_labels(self):resp, code = self._get_json("api/metadata")if code == 200:return respif isinstance(resp,dict) and 'message' in resp:raise RuntimeError(resp['message'])else:raise RuntimeError("An unknown error occurred contacting the iCTF server!")def register_team(self, name, email, country, logo=None, url="", metadata={}):"""Register a team:param name: The team name:param email: The team's primary POC email:param country: The team's 2-letter ISO country code:param url: The team's URL (optional):param logo: File path to the team's PNG logo, 256x256 (optional):param metadata: Dictionary of metadata responses.  See "get_metadata_labels":return: A CAPTCHA! (Yes! Really!)"""args = {'name':name,'team_email': email,'country': country,'url': url,'metadata': metadata}if logo:try:with open(logo,'rb') as f:logo_data = base64.b64encode(f.read())args['logo'] = logo_dataexcept:raise RuntimeError("Could not open logo file!")resp, code = self._post_json('api/team', args)if code == 200:return resp['captcha']if isinstance(resp,dict) and 'message' in resp:raise RuntimeError(resp['message'])else:raise RuntimeError("An unknown error occurred contacting the iCTF server!")def verify(self, response):"""Verify a captcha response, and sign up your team!This will send an email to your POCs with your team password!:param response: The CAPTCHA response:return: None"""args = {'response': response.strip()}ret, code = self._post_json('api/team/verify', args)return retdef register_wizard(self):"""The interactive iCTF setup wizard! OMFG!!Walks you through signup, including entering metadata,CAPTCHA, etc:return: none"""labels_ret = self.get_metadata_labels()if not labels_ret:print("Error connecting to iCTF server")returnlabels = labels_ret['labels']print("Hi! Welcome to iCTF! ")args = {}args['name'] = input("Please enter your team name: ")args['team_email'] = input("Please enter your team's primary POC email.  ""We will send the game password here: ")args['url'] = input("[optional] Please enter a URL for your team (e.g., team's web page): ")while True:try:logo_fp = input("[optional] Please enter the local file path to your team's logo (a 256x256 PNG): ")if not logo_fp.strip():print("OK fine, going without a logo.")breakwith open(logo_fp,'rb') as f:args['logo'] = base64.b64encode(f.read()).decode('utf-8')breakexcept:print("Couldn't open logo! Try again.")args['country'] = input("Please enter your two-letter ISO country code. (eg. US, DE, JP, etc): ").upper()print("Great.  Now take our short registration survey.")metadata = {}for q in labels:metadata[q['id']] = input(q['description'] + " ")args['metadata'] = metadataresp, code = self._post_json("api/team", args)if code != 200:print(resp['message'])returnprint("Cool! Now prove you're human.")print(resp['captcha'])print("Yeah.  That's seriously a CAPTCHA.")while True:captcha_resp = input("Enter the 8 uppercase letters you see:")answer = self.verify(captcha_resp)if 'message' in answer and answer['message'].startswith('Account creation failed'):raise RuntimeError(answer['message'])elif 'message' in answer and answer['message'].startswith('Incorrect'):print(answer['message'])else:print(answer['message'])breakprint("Oops! Try again.")print("Great! You're done.  Go check your email for your password!  Then try iCTF.login()")def login(self, username, password):"""Log into iCTF:param username: The team's username (email address):param password: The team's password, sent via email:return: An auth token (Which is also saved to the iCTF object)"""args = {'email': username, 'password': password}resp, code = self._post_json('api/login', args)if code != 200:if isinstance(resp,dict) and 'message' in resp:raise RuntimeError(resp['message'])else:raise RuntimeError("An unknown error occurred contacting the iCTF server!")self._token = resp['token']return Team(self._token, username, game_url=self.game_url)def reset_password(self, team_email):args = {}args['team_email'] = team_emailret, code =  self._post_json("api/reset", args)return retclass Team(object):"""This object represents a logged-in iCTF team.This object can be used to perform actions on behalf of the team, such as submitting game artifacts"""def __init__(self, token, email, game_url=DEFAULT_GAME_INTERFACE):self._token = tokenself._email = emailself.game_url = game_urldef __str__(self):return "<Team %s>" % self._emaildef _post_json(self,endpoint,j):# EG says: Why can't Ubuntu stock a recent version of Requests??? Ugh.headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}resp = requests.post(self.game_url + endpoint, auth=(self._token, ""), data=json.dumps(j), headers=headers)try:js = json.loads(resp.content)return js, resp.status_codeexcept:return "", resp.status_codedef _get_json(self,endpoint):assert (self._token is not None)resp = requests.get(self.game_url + endpoint, auth=(self._token, ""))try:js = resp.json()except:return "", resp.status_codereturn resp.json(), resp.status_codedef _get_large_file_authenticated(self, endpoint, save_to):r = requests.get(self.game_url + endpoint, auth=(self._token, ""), stream=True)if r.status_code != 200:raise RuntimeError("Error downloading file!")with open(save_to, 'wb') as f:for chunk in r.iter_content(chunk_size=1024):if chunk: # filter out keep-alive new chunksf.write(chunk)def get_vpn_config(self, fname):"""Download and save your team's VPN configuration.The resulting file will be an OpenVPN configuration file, complete with certificate.Just run it with 'openvpn [configfile]', and you're in!(HINT: you might need to be root):param fname: File name to save the Tar-Gzipped service bundle to:return: None"""resp,code = self._get_json("api/vpnconfig")if code != 200:if isinstance(resp,dict) and 'message' in resp:raise RuntimeError(resp['message'])else:raise RuntimeError("An unknown error occurred getting the OpenVPN config!")with open(fname,'wb') as f:f.write(base64.b64decode(resp['vpnconfig']))def submit_service(self, name, service_bundle_fp):"""Submit a service:param name: The service's name:param service_bundle_fp: Path to the Service Bundle.  See the documentation for details:return:""""""args = {}args['name'] = namewith open(service_bundle_fp, 'rb') as f:args['payload'] = base64.b64encode(f.read())resp, code = self._post_json("api/service", args)if code != 200:raise RuntimeError(repr(resp))return resp['upload_id']"""raise RuntimeError("Not needed this year.  Submitting services so 2015 :) ")def submit_dashboard(self, name, dashboard_bundle_fp):"""Submit a dashboard for the dashboard contest!:param name: The dashboard's name:param dashboard_bundle_fp: Path to the Dashboard Bundle.  See the documentation for details:return:""""""args = {}args['name'] = namewith open(dashboard_bundle_fp, 'rb') as f:args['archive'] = base64.b64encode(f.read())resp, code = self._post_json("api/dashboard", args)if code != 200:raise RuntimeError(repr(resp))print("Done.")"""raise RuntimeError("Not needed this year.  The dashboard is like Highlander, there can be only one!")def get_service_status(self):"""Get the service status and possible error message for the submitted service:return:""""""resp, code = self._get_json("api/service")if code == 200:return resp['uploads']else:if isinstance(resp,dict) and 'message' in resp:raise RuntimeError(resp['message'])else:raise RuntimeError("An unknown error occurred getting the service status!!")"""raise RuntimeError("Not needed this year.  Submitting services so 2015 :) ")def get_vm_bundle(self, save_to):"""Download the team's VM bundle, and save it to the given file.:param save_to: Path to save the bundle to:return: None"""raise RuntimeError("Not needed this year.  Seee get_ssh_key() for details!") #self._get_large_file_authenticated("api/vmbundle",save_to)def get_test_vm_bundle(self, save_to):"""Download the team's VM bundle, and save it to the given file.:param save_to: Path to save the bundle to:return: None"""raise RuntimeError("Not needed this year.  Seee get_ssh_key() for details!") #self._get_large_file_authenticated("api/testvmbundle",save_to)def get_ssh_keys(self):"""Gets the location of your team's VM, as well as the keys to the ctf and root users.:return: Returns a dict, with the following:* 'ctf_key': The SSH private key needed to login to the 'ctf' user* 'root_key': The SSH private key needed to login to the 'root' ser* 'ip': The IP of your team's VM* 'port': the port of your team VM's SSH server"""resp, code = self._get_json("api/ssh")if code == 200:return respelse:if isinstance(resp,dict):raise RuntimeError(resp['message'])else:raise RuntimeError("An unknown error occurred getting the SSH keys")def send_support_request(self, subject,msg):"""Send an (authenticated) support request to the iCTF admins.This is the only official way to get support from the iCTF admins, as we must be ableto authenticate people asking for help!:param subject: the subject of the message:param msg: A description of the problem"""resp, code = self._post_json("api/ticket", {'subject': subject, 'message': msg})if code != 200:raise RuntimeError("Uh oh, we couldn't send the support ticket.  Is your network connection OK?  If so, Bother us on IRC or send a message to ctf-admin@lists.cs.ucsb.edu!")return respdef get_support_tickets(self):"""Get the list of support tickets for your team:return: a list of tickets"""resp, code = self._get_json("api/ticket")if code != 200:raise RuntimeError("Couldn't get your tickets.  Is your network connection OK?  If so, Bother us on IRC or send a message to ctf-admin@lists.cs.ucsb.edu!")return respdef get_team_list(self):"""Return the list of teams!"""resp, code = self._get_json("api/teams")if code == 200:return resp['teams']else:if isinstance(resp,dict):raise RuntimeError(resp['message'])else:raise RuntimeError("An unknown error occurred getting the team list")def get_tick_info(self):"""Return information about the current game "tick".The iCTF game is divided into rounds, called "ticks".  Scoring is computed at the end of each tick.New flags are set only at the next tick.If you're writing scripts or frontends, you should use this to figure out when torun them.The format looks like:{u'approximate_seconds_left': <int seconds>,u'created_on': Timestamp, like u'2015-12-02 12:28:03',u'tick_id': <int tick ID>}"""resp, code = self._get_json("api/status/tick")if code == 200:return respelse:if isinstance(resp,dict):raise RuntimeError(resp['message'])else:raise RuntimeError("An unknown error occurred getting the tick info.")def submit_flag(self, flags):"""Submit a list of one or more flags:param flags: A list of flags:return: List containing a response for each flag, either:"correct" | "ownflag" (do you think this is defcon?)| "incorrect"| "alreadysubmitted"| "notactive",| "toomanyincorrect","""if not isinstance(flags,list):raise TypeError("Flags should be in a list!")resp, code = self._post_json("api/flag", {'flags': flags})if code == 200:return respelse:if isinstance(resp,dict):raise RuntimeError(resp['message'])else:raise RuntimeError("An unknown error occurred submitting flags.")def get_targets(self, service):"""Get a list of teams, their hostnames, and the currently valid flag_ids.Your exploit should then try to exploit each team, and steal the flag with the given ID.You can/should use this to write scripts to run your exploits!:param service: The name or ID of a service (see get_service_list() for IDs and names):return: A list of targets:[{'team_name' : "Team name",'hostname' : "hostname",'port' : <int port number>,'flag_id' : "Flag ID to steal"},...]"""service_id = Noneif isinstance(service,str):services = self.get_service_list()svc = filter(lambda x: x['service_name'] == service, services)if not svc:raise RuntimeError("Unknown service " + service)service_id = int(svc[0]['service_id'])else:service_id = serviceresp, code = self._get_json("api/targets/" + str(service_id))if code == 200:return respelse:if isinstance(resp,dict):raise RuntimeError(resp['message'])else:raise RuntimeError("Something went wrong getting targets.")def get_service_list(self):"""Returns the list of services, and some useful information about them.The output will look like:[{'service_id' : <int service id>,'team_id' : <team_id which created that service>'service_name' : "string service_name",'description' : "Description of the service",'flag_id_description' : "Description of the 'flag_id' in this service, indicating which flag you should steal",'port' : <int port number>}]"""resp, code = self._get_json("api/services")if code == 200:return resp['services']else:if isinstance(resp,dict):raise RuntimeError(resp['message'])else:raise RuntimeError(repr(resp))def get_game_status(self):"""Return a dictionary containing game status information.This will include:- The scores of all teams- Game timing information- Information about services, including their status, number of exploitations, etcThis API is suitable for use in the creation of frontends.The return value is a large dictionary, containing the following:- 'teams' : Basic team info, name, country, latitude, longitude, etc- 'service_states': For each team and service, provides its "state" (up/down/etc)- 'exploited_services': For each service that has been exploited, list who exploited it- 'first_bloods': For each service, which team scored on it first (they get extra points!)- 'scores': The scoring data for each team.- 'tick': Info about the game's current "tick" -- see get_tick_info()It will look something like:{'teams' :{<team_id> :{'country' : "ISO 2 letter country code",'logo' : <base64 logo>,'name' : "1338-offbyone"'url' : "http://teamurl.here"}                   }}'exploited_services' :{<service_id> :{'service_name' : "string_service_name",'teams' :[{'team_id' : <team_id>,'team_name' : "string team name"},...],'total_stolen_flags' : <integer>}}'service_states' :{<team_id> :{<service_id> :{'service_name' : "string_service_name"'service_state' : "untested" | "up" | "down"}}},'first_bloods' :{<service_id> :{'created_on' : Timestamp eg. '2015-12-02 10:57:49','team_id' : <ID of exploiting team>}},'scores' :{<team_id> :{'attack_points' : <float number of points scored through exploitation>,'service_points' : <float number of points for having a "cool" service, see rules for details>,'sla' : <float SLA score>'total_points' : <float normalized final score>}},'tick' :{'approximate_seconds_left': <int seconds>,'created_on': Timestamp, like '2015-12-02 12:28:03','tick_id': <int tick ID>}}"""resp, code = self._get_json("api/status")if code == 200:return respelse:if isinstance(resp,dict) and 'message' in resp:raise RuntimeError(resp['message'])else:raise RuntimeError("An unknown error occurred contacting the game status! Perhaps try again?")def submit_service_vote(self, service_1, service_2, service_3):"""Submit your team's vote for the "Best service" prize!:param service_1::param service_2::param service_3: Names of services, as listed in get_game_status() (in order, 1 = best):return: None""""""resp, code = self._post_json("api/vote", {'service_1':service_1,'service_2':service_2,'service_3':service_3})if code == 200:returnelse:if not resp:raise RuntimeError("An unknown error occurred submitting your vote")raise RuntimeError(resp['message'])"""raise RuntimeError("Nope, not necessary this year.")def get_team_status(self):"""Get your team's current status, including whether yourteam has been verified, metadata submitted, service submitted, etc:return: String"""resp, code = self._get_json("api/team")if code == 200:return resp

这篇关于CTF竞赛中的奇葩注册方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/775608

相关文章

Python实现终端清屏的几种方式详解

《Python实现终端清屏的几种方式详解》在使用Python进行终端交互式编程时,我们经常需要清空当前终端屏幕的内容,本文为大家整理了几种常见的实现方法,有需要的小伙伴可以参考下... 目录方法一:使用 `os` 模块调用系统命令方法二:使用 `subprocess` 模块执行命令方法三:打印多个换行符模拟

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,

SpringBoot整合Dubbo+ZK注册失败的坑及解决

《SpringBoot整合Dubbo+ZK注册失败的坑及解决》使用Dubbo框架时,需在公共pom添加依赖,启动类加@EnableDubbo,实现类用@DubboService替代@Service,配... 目录1.先看下公共的pom(maven创建的pom工程)2.启动类上加@EnableDubbo3.实

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

Jenkins分布式集群配置方式

《Jenkins分布式集群配置方式》:本文主要介绍Jenkins分布式集群配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装jenkins2.配置集群总结Jenkins是一个开源项目,它提供了一个容易使用的持续集成系统,并且提供了大量的plugin满

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys