def check(host): cm = CheckMachine(host) index_resp = cm.get_index() check_html_page(index_resp) register_resp = cm.get_register_page() checklib.assert_in('registerForm', register_resp, 'No registration form') check_html_page(register_resp) login, password = cm.register_service() last_user_resp = cm.get_last_users() checklib.assert_in(login, last_user_resp, 'Failed to find last user') login_resp = cm.get_login_page() check_html_page(login_resp) checklib.assert_in('loginForm', login_resp, 'No login form') sess = cm.login_in_service(login, password) resp = cm.get_add_page(sess) check_html_page(resp) checklib.assert_in('addForm', resp, 'No add form') icecream_name = checklib.rnd_string(20) resp = cm.add_icecream(sess, icecream_name) checklib.assert_in('Icecream added', resp, 'Failed to add icecream') my_icecreams = cm.get_my_icecreams(sess) checklib.assert_in(icecream_name, my_icecreams, 'Failed to get user icecreams') checklib.cquit(checklib.Status.OK)
def put(host, flag_id, flag, vuln): cm = CheckMachine(host) register_resp = cm.get_register_page() checklib.assert_in('registerForm', register_resp, 'No registration form') check_html_page(register_resp) password = None if vuln == '2': password = flag login, password = cm.register_service(password=password) login_resp = cm.get_login_page() check_html_page(login_resp) checklib.assert_in('loginForm', login_resp, 'No login form') sess = cm.login_in_service(login, password) resp = cm.get_add_page(sess) check_html_page(resp) checklib.assert_in('addForm', resp, 'No add form') icecream_name = checklib.rnd_string(20) if vuln == '1': icecream_name = flag resp = cm.add_icecream(sess, icecream_name) checklib.assert_in('Icecream added', resp, 'Failed to add icecream') checklib.cquit(checklib.Status.OK, f'{login}:{password}:{icecream_name}')
def extract_secret(url, sugar, marshmallows): shares = [(1, sugar)] for marshmallow in marshmallows: sugar_, is_private, filling = get_marshmallow(url, marshmallow) shares.append((len(shares) + 1, sugar_)) try: number = recover_secret(shares, PRIME) except Exception: cquit(Status.MUMBLE, 'Incorrect sugar values') return number.to_bytes(64, 'little').replace(b'\x00', b'')
def get(host, flag_id, flag, vuln): cm = CheckMachine(host) login, password, icecream_name = flag_id.split(':') login_resp = cm.get_login_page() check_html_page(login_resp) checklib.assert_in('loginForm', login_resp, 'No login form') sess = cm.login_in_service(login, password) my_icecreams = cm.get_my_icecreams(sess) checklib.assert_in(icecream_name, my_icecreams, 'Failed to get user icecreams', status=checklib.Status.CORRUPT) checklib.cquit(checklib.Status.OK)
def put(host, flag_id, flag, vuln): if vuln == VULN_SIMPLE: flag_password = None program, length = generate_simple(flag) elif vuln == VULN_ENCRYPTED: flag_password = rnd_string(16) program, length = generate_encrypted(flag, flag_password) else: cquit(Status.ERROR, 'System error', f'Vuln number {vuln} is unknown') io = SocketIO(host, PORT, TIMEOUT) try: # banner if b''.join(io.recvlines(7)) != BANNER: cquit(Status.MUMBLE, 'Logo was changed') # main menu (Create VM) io.recvlines(4) io.sendline(b'1') # send length io.recvline() io.sendline(str(length).encode()) # send program io.recvline() io.send(program) # run menu (No) io.recvlines(4) io.sendline(b'2') # save menu (Yes) io.recvlines(3) io.sendline(b'1') if b'saved' not in io.recvline(): cquit(Status.MUMBLE, 'VM can not be saved') # get vm info vm_name = io.recvline()[10:].decode() vm_password = io.recvline()[14:].decode() # bye io.recvline() except Exception as e: cquit(Status.MUMBLE, 'Error while putting flag', f'Error while putting flag: {str(e)}, vuln: {vuln}') finally: io.close() flag_info = FlagInfo(vm_name, vm_password, flag_password) cquit(Status.OK, flag_info.dump())
def add_pack(url, name, flavour): data = {'name': name, 'flavour': flavour} try: response = requests.post(url + '/addPack', json=data).json() except Exception: cquit(Status.MUMBLE, 'Invalid JSON response') if not response.get('success', False): cquit(Status.MUMBLE, 'Can not add a new pack') if 'guid' not in response: cquit(Status.MUMBLE, 'Can not get guid of new pack') if 'sugar' not in response: cquit(Status.MUMBLE, 'Can not get sugar of new pack') guid, sugar = response['guid'], response['sugar'] try: sugar = int(sugar) except Exception: cquit(Status.MUMBLE, 'Sugar must be int') return guid, sugar
def check(host): url = 'http://%s:%d' % (host, PORT) def check_marshmallow(is_private): sugar, filling = random_int(), random_str() guid = add_marshmallow(url, sugar, filling, is_private) if guid not in list_all_marshmallows(url): cquit(Status.MUMBLE, 'Can not find marshmallow in list') sugar_, is_private_, filling_ = get_marshmallow(url, guid) if sugar != sugar_: cquit(Status.MUMBLE, 'Sugars are not the same') if is_private != is_private_: cquit(Status.MUMBLE, 'Private status is not the same') success, filling_ = prove_marshmallow(url, guid, filling) if not success or filling != filling_: cquit(Status.MUMBLE, 'Fillings are not the same') def check_pack(): name, flavour = random_str(), random_str() guid, sugar = add_pack(url, name, flavour) if guid not in list_all_packs(url): cquit(Status.MUMBLE, 'Can not find pack in list') name_, flavour_, marshmallows = get_pack(url, guid) if name != name_: cquit(Status.MUMBLE, 'Names are not the same') flavour_ = extract_secret(url, sugar, marshmallows) if flavour.encode() not in flavour_ or flavour_ not in flavour.encode( ): cquit(Status.MUMBLE, 'Flavours are not the same') check_marshmallow(True) check_marshmallow(False) check_pack() cquit(Status.OK)
def get_pack(url, guid): html = requests.get(url + '/packs/' + guid).text if 'Pack not found' in html: cquit(Status.MUMBLE, 'Can not find a pack') values = re.findall('value="(.*?)"', html) if len(values) < 3: cquit(Status.MUMBLE, 'Pack fields do not exist') guid_val, name_val, flavour_val = values[:3] if guid != guid_val: cquit(Status.MUMBLE, 'Guids should be the same') marshmallows = re.findall('href="/marshmallows/(.*?)"', html) if len(marshmallows) == 0: cquit(Status.MUMBLE, 'Can not find marshmallows in the pack') return name_val, flavour_val, marshmallows
def get(host, flag_id, flag, vuln): url = 'http://%s:%d' % (host, PORT) if vuln == VULN_SSS: flag_id = json.loads(flag_id) guid, sugar = flag_id['guid'], flag_id['sugar'] name, flavour, marshmallows = get_pack(url, guid) actual_flag = extract_secret(url, sugar, marshmallows) if flag.encode() in actual_flag or actual_flag in flag.encode(): cquit(Status.OK) else: cquit(Status.CORRUPT, 'Can not get flag from packs') if vuln == VULN_PROVE: flag_id = json.loads(flag_id) guid = flag_id['guid'] success, filling = prove_marshmallow(url, guid, flag) if filling in flag or flag in filling: cquit(Status.OK) else: cquit(Status.CORRUPT, 'Can not get flag from marshmallows') cquit(Status.ERROR, 'Unknown vuln')
def check_marshmallow(is_private): sugar, filling = random_int(), random_str() guid = add_marshmallow(url, sugar, filling, is_private) if guid not in list_all_marshmallows(url): cquit(Status.MUMBLE, 'Can not find marshmallow in list') sugar_, is_private_, filling_ = get_marshmallow(url, guid) if sugar != sugar_: cquit(Status.MUMBLE, 'Sugars are not the same') if is_private != is_private_: cquit(Status.MUMBLE, 'Private status is not the same') success, filling_ = prove_marshmallow(url, guid, filling) if not success or filling != filling_: cquit(Status.MUMBLE, 'Fillings are not the same')
def add_marshmallow(url, sugar, filling, is_private): data = {'sugar': sugar, 'filling': filling, 'isPrivate': is_private} try: response = requests.post(url + '/addMarshmallow', json=data).json() except Exception: cquit(Status.MUMBLE, 'Invalid JSON response') if not response.get('success', False): cquit(Status.MUMBLE, 'Can not add a new marshmallow') if 'guid' not in response: cquit(Status.MUMBLE, 'Can not get guid of new marshmallow') guid = response['guid'] return guid
def prove_marshmallow(url, guid, filling): data = {'filling': filling} try: response = requests.post(url + '/marshmallows/' + guid, json=data).json() except Exception: cquit(Status.MUMBLE, 'Invalid JSON response') if not response.get('success', False): cquit(Status.MUMBLE, 'Can not prove a marshmallow') if 'filling' not in response: cquit(Status.MUMBLE, 'Can not find filling in prove response') return response['success'], response['filling']
def get_marshmallow(url, guid): html = requests.get(url + '/marshmallows/' + guid).text if 'Marshmallow not found' in html: cquit(Status.MUMBLE, 'Can not find a marshmallow') values = re.findall('value="(.*?)"', html) if len(values) < 2: cquit(Status.MUMBLE, 'Marshmallow fields do not exist') guid_val, sugar_val = values[:2] if guid != guid_val: cquit(Status.MUMBLE, 'Guids should be the same') try: sugar = int(sugar_val) except Exception: cquit(Status.MUMBLE, 'Sugar must be int') is_private = 'Marshmallow is private' in html if not is_private: filling_val = values[2] else: filling_val = None return sugar, is_private, filling_val
def put(host, flag_id, flag, vuln): url = 'http://%s:%d' % (host, PORT) if vuln == VULN_SSS: guid, sugar = add_pack(url, random_str(), flag) flag_id = {'guid': guid, 'sugar': sugar} cquit(Status.OK, json.dumps(flag_id)) if vuln == VULN_PROVE: guid = add_marshmallow(url, random_int(), flag, True) flag_id = {'guid': guid} cquit(Status.OK, json.dumps(flag_id)) cquit(Status.ERROR, 'Unknown vuln')
def check_pack(): name, flavour = random_str(), random_str() guid, sugar = add_pack(url, name, flavour) if guid not in list_all_packs(url): cquit(Status.MUMBLE, 'Can not find pack in list') name_, flavour_, marshmallows = get_pack(url, guid) if name != name_: cquit(Status.MUMBLE, 'Names are not the same') flavour_ = extract_secret(url, sugar, marshmallows) if flavour.encode() not in flavour_ or flavour_ not in flavour.encode( ): cquit(Status.MUMBLE, 'Flavours are not the same')
action, *args = sys.argv[1:] try: if action == 'check': host, = args check(host) elif action == 'put': host, flag_id, flag, vuln = args put(host, flag_id, flag, vuln) elif action == 'get': host, flag_id, flag, vuln = args get(host, flag_id, flag, vuln) else: cquit(Status.ERROR, 'System error', f'Unknown action: {action}') cquit(Status.ERROR, 'System error', f'Action {action} ended without cquit') except socket.error as e: cquit(Status.DOWN, 'Connection error', f'Connection error: {str(e)}') except socket.timeout as e: cquit(Status.DOWN, 'Connection timeout', f'Connection timeout: {str(e)}') except Exception as e: cquit(Status.ERROR, 'System error', f'Unhandled exception: {str(e)}')
check_marshmallow(False) check_pack() cquit(Status.OK) if __name__ == '__main__': action, *args = sys.argv[1:] try: if action == "check": host, = args check(host) elif action == "put": host, flag_id, flag, vuln = args put(host, flag_id, flag, vuln) elif action == "get": host, flag_id, flag, vuln = args get(host, flag_id, flag, vuln) else: cquit(Status.ERROR, 'System error', 'Unknown action: ' + action) cquit(Status.ERROR, 'System error', f'Action {action} did not cquit') except requests.exceptions.ConnectionError: cquit(Status.DOWN, 'Connection error') except SystemError as e: raise except Exception as e: cquit(Status.ERROR, 'System error', str(e))
def list_all_marshmallows(url): try: html = requests.get(url + '/marshmallows').text except Exception: cquit(Status.MUMBLE, 'Can not get marshmallows list') return re.findall('"/marshmallows/(.*?)"', html)
checklib.assert_in('Icecream added', resp, 'Failed to add icecream') my_icecreams = cm.get_my_icecreams(sess) checklib.assert_in(icecream_name, my_icecreams, 'Failed to get user icecreams') checklib.cquit(checklib.Status.OK) if __name__ == '__main__': action, *args = sys.argv[1:] try: if action == "check": host, = args check(host) elif action == "put": host, flag_id, flag, vuln = args put(host, flag_id, flag, vuln) elif action == "get": host, flag_id, flag, vuln = args get(host, flag_id, flag, vuln) else: checklib.cquit(checklib.Status.ERROR, 'System error', 'Unknown action: ' + action) except requests.exceptions.ConnectionError: checklib.cquit(checklib.Status.DOWN, 'Connection error') except SystemError as e: raise except Exception as e: checklib.cquit(checklib.Status.ERROR, 'System error', str(e))
def get(host, flag_id, flag, vuln): if vuln not in [VULN_SIMPLE, VULN_ENCRYPTED]: cquit(Status.ERROR, 'System error', f'Vuln number {vuln} is unknown') flag_info = FlagInfo.load(flag_id) io = SocketIO(host, PORT, TIMEOUT) try: # banner if b''.join(io.recvlines(7)) != BANNER: cquit(Status.MUMBLE, 'Logo was changed') # main menu (List VMs) io.recvlines(4) io.sendline(b'3') # reading names vm_names = [] while True: vm_name = io.recvline() if b'Create VM' in vm_name: break vm_names.append(vm_name.decode()) # checking vm existing if flag_info.vm_name not in vm_names: cquit(Status.CORRUPT, 'VM not found', f'VM not found, vuln: {vuln}') # main menu (Load VM) io.recvlines(3) io.sendline(b'2') # send vm info io.recvline() io.sendline(flag_info.vm_name.encode()) if b'Invalid character' in io.recvline(): cquit(Status.MUMBLE, 'Name does not require restrictions') io.sendline(flag_info.vm_password.encode()) answer = io.recvline() if b'Invalid character' in answer: cquit(Status.MUMBLE, 'Password does not require restrictions') if b'Invalid password' in answer: cquit(Status.MUMBLE, 'Invalid password') if b'Program loaded' not in answer: cquit(Status.CORRUPT, 'VM can not be loaded') # run vm (Yes) io.recvlines(3) io.sendline(b'1') # get flag message = io.recvline() if b'VM exited' in message: cquit(Status.MUMBLE, 'VM does not work as expected', f'VM does not work as expected: {message}') if (b'protected' in message) != (vuln == VULN_ENCRYPTED): cquit(Status.CORRUPT, 'Password requirements does not match', f'Password requirements does not match, vuln: {vuln}') if b'protected' in message: io.sendline(flag_info.flag_password.encode()) result = io.recvline() if b'No!' in result: cquit(Status.MUMBLE, 'Invalid password', f'Invalid password, expected: {flag_id.flag_password}') if flag.strip() not in result.strip().decode(): cquit( Status.CORRUPT, 'Invalid flag', f'Invalid flag, expected: {flag}, actual: {result}, vuln: {vuln}' ) #read vm code code = io.recvline()[4:] if b'code 0' not in code: cquit(Status.MUMBLE, 'VM does not work as expected', f'VM does not work as expected: {code}') # bye io.recvline() except Exception as e: cquit(Status.MUMBLE, 'Error while getting flag', f'Error while getting flag: {str(e)}, vuln: {vuln}') finally: io.close() cquit(Status.OK)
def list_all_packs(url): try: html = requests.get(url + '/packs').text except Exception: cquit(Status.MUMBLE, 'Can not get packs list') return re.findall('"/packs/(.*?)"', html)
def check(host): program, length, output, code = generate_checking() io = SocketIO(host, PORT, TIMEOUT) try: # banner if b''.join(io.recvlines(7)) != BANNER: cquit(Status.MUMBLE, 'Logo was changed') # main menu (Create VM) io.recvlines(4) io.sendline(b'1') # send length io.recvline() io.sendline(str(length).encode()) # send program io.recvline() io.send(program) # run menu (Yes) io.recvlines(4) io.sendline(b'1') # checking output result = io.recvline() + b'\n' + io.recv(16) if output not in result: cquit(Status.MUMBLE, 'Invalid checking value') result = io.recvline() if b'code ' + code not in result: cquit(Status.MUMBLE, 'Invalid checking code') # save vm (Yes) io.recvlines(3) io.sendline(b'1') if b'saved' not in io.recvline(): cquit(Status.MUMBLE, 'VM can not be saved') # get vm info vm_name = io.recvline()[10:].decode() vm_password = io.recvline()[14:].decode() # bye io.recvline() except Exception as e: cquit(Status.MUMBLE, 'Error while checking flag', f'Error while checking flag: {str(e)}') finally: io.close() flag_info = FlagInfo(vm_name, vm_password) io = SocketIO(host, PORT, TIMEOUT) try: # banner if b''.join(io.recvlines(7)) != BANNER: cquit(Status.MUMBLE, 'Logo was changed') # main menu (List VMs) io.recvlines(4) io.sendline(b'3') # reading names vm_names = [] while True: vm_name = io.recvline() if b'Create VM' in vm_name: break vm_names.append(vm_name.decode()) # checking vm existing if flag_info.vm_name not in vm_names: cquit(Status.MUMBLE, 'VM not found', f'VM not found, vuln: {vuln}') # main menu (Load VM) io.recvlines(3) io.sendline(b'2') # send vm info io.recvline() io.sendline(flag_info.vm_name.encode()) if b'Invalid character' in io.recvline(): cquit(Status.MUMBLE, 'Name does not require restrictions') io.sendline(flag_info.vm_password.encode()) answer = io.recvline() if b'Invalid character' in answer: cquit(Status.MUMBLE, 'Password does not require restrictions') if b'Invalid password' in answer: cquit(Status.MUMBLE, 'Invalid password') if b'Program loaded' not in answer: cquit(Status.CORRUPT, 'VM can not be loaded') # run vm (Yes) io.recvlines(3) io.sendline(b'1') # checking output result = io.recvline() + b'\n' + io.recv(16) if output not in result: cquit(Status.MUMBLE, 'Invalid checking value') result = io.recvline() if b'code ' + code not in result: cquit(Status.MUMBLE, 'Invalid checking code') # save vm (No) io.recvlines(3) io.sendline(b'2') # bye io.recvline() except Exception as e: cquit(Status.MUMBLE, 'Error while checking flag', f'Error while checking flag: {str(e)}') finally: io.close() cquit(Status.OK)
self.mch.login(s, login, password) #check upload by http link (+ get this file ; + it appears in uploads) #self.mch.check_upload_by_link(s, "http://example.com") self.mch.check_upload_by_link_random(s, login) self.cquit(Status.OK) def put(self, flag_id, flag, vuln): login = secrets.token_hex(10) password = secrets.token_hex(10) s = self.get_initialized_session() self.mch.register(s, login, password) self.mch.login(s, login, password) link = self.mch.upload_text(s, flag) self.cquit(Status.OK, f'{login}', f'{login}:{password}:{link}') def get(self, flag_id, flag, vuln): s = self.get_initialized_session() u, p, link = flag_id.split(':') self.mch.login(s, u, p, Status.CORRUPT) self.mch.check_file_content_by_link(s, link, flag, Status.CORRUPT) self.cquit(Status.OK) if __name__ == '__main__': c = Checker(sys.argv[2]) try: c.action(sys.argv[1], *sys.argv[3:]) except c.get_check_finished_exception(): cquit(Status(c.status), c.public, c.private)