def handle_open_lock(casting_spell, effect, caster, target): if not caster or caster.get_type_id() != ObjectTypeIds.ID_PLAYER: return if target.get_type_id() == ObjectTypeIds.ID_GAMEOBJECT: target.use(caster, target) elif target.get_type_id() == ObjectTypeIds.ID_ITEM: target.set_unlocked() else: Logger.debug(f'Unimplemented open lock spell effect.') return lock_type = effect.misc_value lock_id = target.lock bonus_points = effect.get_effect_simple_points() # Lock opening is already validated at this point, but use can_open_lock to fetch lock info. lock_result = LockManager.can_open_lock( caster, lock_type, lock_id, cast_item=casting_spell.source_item, bonus_points=bonus_points) caster.skill_manager.handle_gather_skill_gain( lock_result.skill_type, lock_result.skill_value, lock_result.required_skill_value)
def process_incoming(self): while self.keep_alive: reader = self.incoming_pending.get(block=True, timeout=None) if reader: # Can be None if we shutdown the thread. if reader.opcode: handler, found = Definitions.get_handler_from_packet( self, reader.opcode) if handler: res = handler(self, self.request, reader) if res == 0: Logger.debug( f'[{self.client_address[0]}] Handling {OpCode(reader.opcode).name}' ) elif res == 1: Logger.debug( f'[{self.client_address[0]}] Ignoring {OpCode(reader.opcode).name}' ) elif res < 0: self.disconnect() break elif not found: Logger.warning( f'[{self.client_address[0]}] Received unknown data: {reader.data}' ) else: self.disconnect()
def load(self): filename = f'{self.cell_map:03}{self.cell_x:02}{self.cell_y:02}.map' maps_path = PathManager.get_map_file_path(filename) Logger.debug(f'[Maps] Loading map file: {filename}') if not path.exists(maps_path): Logger.warning(f'Unable to locate map file: {filename}') else: with open(maps_path, "rb") as map_tiles: version = PacketReader.read_string(map_tiles.read(10), 0) if version != MapTile.EXPECTED_VERSION: Logger.error(f'Unexpected map version. Expected "{MapTile.EXPECTED_VERSION}", received "{version}".') return # TODO: AreaFlags # for x in range(0, RESOLUTION_FLAGS + 1): # for y in range(0, RESOLUTION_FLAGS + 1): # self.explore_flag[x][y] = unpack('<H', map_tiles.read(2))[0] # # TODO: AreaTerrain # for x in range(0, RESOLUTION_TERRAIN + 1): # for y in range(0, RESOLUTION_TERRAIN + 1): # self.area_terrain[x][y] = map_tiles.read(1)[0] # # TODO: Liquids # for x in range(0, RESOLUTION_WATER + 1): # for y in range(0, RESOLUTION_WATER + 1): # self.water_level[x][y] = unpack('<f', map_tiles.read(4))[0] # Height Map for x in range(0, RESOLUTION_ZMAP + 1): for y in range(0, RESOLUTION_ZMAP + 1): self.z_coords[x][y] = unpack('<f', map_tiles.read(4))[0]
def load(self): # Set as initialized to avoid another load() call from another thread. self.initialized = True filename = f'{self.cell_map:03}{self.cell_x:02}{self.cell_y:02}.map' maps_path = PathManager.get_map_file_path(filename) Logger.debug( f'[Maps] Loading map file: {filename}, Map:{self.cell_map} Tile:{self.cell_x},{self.cell_y}' ) if not path.exists(maps_path): Logger.warning( f'Unable to locate map file: {filename}, Map:{self.cell_map} Tile:{self.cell_x},{self.cell_y}' ) return else: with open(maps_path, "rb") as map_tiles: version = PacketReader.read_string(map_tiles.read(10), 0) if version != MapTile.EXPECTED_VERSION: Logger.error( f'Unexpected map version. Expected "{MapTile.EXPECTED_VERSION}", found "{version}".' ) return # Height Map for x in range(RESOLUTION_ZMAP): for y in range(RESOLUTION_ZMAP): self.z_height_map[x][y] = unpack( '<f', map_tiles.read(4))[0] # ZoneID, AreaNumber, AreaFlags, AreaLevel, AreaExploreFlag(Bit), AreaFactionMask for x in range(RESOLUTION_AREA_INFO): for y in range(RESOLUTION_AREA_INFO): zone_id = unpack('<i', map_tiles.read(4))[0] if zone_id == -1: # No area information. continue area_number = unpack('<I', map_tiles.read(4))[0] area_flags = unpack('<B', map_tiles.read(1))[0] area_level = unpack('<B', map_tiles.read(1))[0] area_explore_bit = unpack('<H', map_tiles.read(2))[0] area_faction_mask = unpack('<B', map_tiles.read(1))[0] # noinspection PyTypeChecker self.area_information[x][y] = AreaInformation( zone_id, area_number, area_flags, area_level, area_explore_bit, area_faction_mask) # Liquids for x in range(RESOLUTION_LIQUIDS): for y in range(RESOLUTION_LIQUIDS): liquid_type = unpack('<b', map_tiles.read(1))[0] if liquid_type == -1: # No liquid information / not rendered. continue height = unpack('<f', map_tiles.read(4))[0] # noinspection PyTypeChecker self.liquid_information[x][y] = LiquidInformation( liquid_type, height) # This is a valid tile, set as loaded. self.is_valid = True
def redirect_to_world(sck): world_bytes = PacketWriter.string_to_bytes( ('%s:%s' % (config.Server.Connection.WorldServer.host, config.Server.Connection.WorldServer.port))) packet = pack('<%us' % len(world_bytes), world_bytes) Logger.debug('[%s] Redirecting to world server...' % sck.getpeername()[0]) sck.sendall(packet)
def apply_effect(casting_spell, effect, caster, target): if effect.effect_type not in SPELL_EFFECTS: Logger.debug( f'Unimplemented spell effect called ({SpellEffects(effect.effect_type).name}: ' f'{effect.effect_type}) from spell {casting_spell.spell_entry.ID}.' ) return SPELL_EFFECTS[effect.effect_type](casting_spell, effect, caster, target)
def handle_aura_effect_change(aura, remove=False): if aura.spell_effect.effect_type != SpellEffects.SPELL_EFFECT_APPLY_AURA: return if aura.spell_effect.aura_type not in AURA_EFFECTS: Logger.debug( f'Unimplemented aura effect called: {aura.spell_effect.aura_type}' ) return AURA_EFFECTS[aura.spell_effect.aura_type](aura, remove)
def redirect_to_world(sck): forward_address = os.getenv('FORWARD_ADDRESS_OVERRIDE', config.Server.Connection.WorldServer.host) world_bytes = PacketWriter.string_to_bytes( f'{forward_address}:{config.Server.Connection.WorldServer.port}') packet = pack(f'<{len(world_bytes)}s', world_bytes) Logger.debug( f'[{sck.getpeername()[0]}] Redirecting to world server...') sck.sendall(packet)
def handle_aura_effect_change(aura, effect_target, remove=False, is_proc=False): aura_type = aura.spell_effect.aura_type if aura_type not in AURA_EFFECTS: Logger.debug(f'Unimplemented aura effect called ({AuraTypes(aura.spell_effect.aura_type).name}: ' f'{aura.spell_effect.aura_type}) from spell {aura.source_spell.spell_entry.ID}.') return if not is_proc and aura_type in PROC_AURA_EFFECTS: return # Only call proc effects when a proc happens. AURA_EFFECTS[aura.spell_effect.aura_type](aura, effect_target, remove)
def serve_realm(sck): name_bytes = PacketWriter.string_to_bytes( config.Server.Connection.RealmServer.realm_name) address_bytes = PacketWriter.string_to_bytes( ('%s:%s' % (config.Server.Connection.RealmProxy.host, config.Server.Connection.RealmProxy.port))) packet = pack('<B%us%usI' % (len(name_bytes), len(address_bytes)), 1, name_bytes, address_bytes, 0) Logger.debug('[%s] Sending realmlist...' % sck.getpeername()[0]) sck.sendall(packet)
def receive(self, sck): try: data = sck.recv(1024) reader = PacketReader(data) if reader.opcode: handler = Definitions.get_handler_from_packet(reader.opcode) if handler: Logger.debug('Handling %s' % OpCode(reader.opcode)) if handler(self, sck, reader) != 0: return -1 except OSError: Logger.warning('Tried to interact with a closed socket.') return -1
def handle_aura_effect_change(aura, effect_target, remove=False, is_proc=False): aura_type = aura.spell_effect.aura_type if aura_type not in AURA_EFFECTS: Logger.debug( f'Unimplemented aura effect called: {aura.spell_effect.aura_type}' ) return if not is_proc and aura_type in PROC_AURA_EFFECTS: return # Only call proc effects when a proc happens. AURA_EFFECTS[aura.spell_effect.aura_type](aura, effect_target, remove)
def serve_realm(sck): name_bytes = PacketWriter.string_to_bytes(config.Server.Connection.RealmServer.realm_name) forward_address = os.getenv('FORWARD_ADDRESS_OVERRIDE', config.Server.Connection.RealmProxy.host) address_bytes = PacketWriter.string_to_bytes(f'{forward_address}:{config.Server.Connection.RealmProxy.port}') # TODO: Should probably move realms to database at some point, instead of config.yml packet = pack( f'<B{len(name_bytes)}s{len(address_bytes)}sI', 1, # Number of realms name_bytes, address_bytes, RealmDatabaseManager.character_get_online_count() ) Logger.debug(f'[{sck.getpeername()[0]}] Sending realmlist...') sck.sendall(packet)
def receive(self, sck): try: data = sck.recv(2048) if len(data) > 0: reader = PacketReader(data) if reader.opcode: handler, res = Definitions.get_handler_from_packet(self, reader.opcode) if handler: Logger.debug('[%s] Handling %s' % (self.client_address[0], OpCode(reader.opcode))) if handler(self, sck, reader) != 0: return -1 elif res == -1: Logger.warning('[%s] Received unknown data: %s' % (self.client_address[0], data)) else: return -1 except OSError: self.disconnect() return -1
def serve_realm(sck): name_bytes = PacketWriter.string_to_bytes( config.Server.Connection.RealmServer.realm_name) address_bytes = PacketWriter.string_to_bytes( ('%s:%s' % (config.Server.Connection.RealmProxy.host, config.Server.Connection.RealmProxy.port))) # TODO: Should probably move realms to database at some point, instead of config.yml packet = pack( '<B%us%usI' % (len(name_bytes), len(address_bytes)), 1, # Number of realms name_bytes, address_bytes, 0 # Number of players online? Can't be characters per account because we don't have account info yet. ) Logger.debug('[%s] Sending realmlist...' % sck.getpeername()[0]) sck.sendall(packet)
def serve_realm(sck): name_bytes = PacketWriter.string_to_bytes(config.Server.Connection.RealmServer.realm_name) address_bytes = PacketWriter.string_to_bytes(('%s:%s' % (config.Server.Connection.RealmProxy.host, config.Server.Connection.RealmProxy.port))) # TODO: Should probably move realms to database at some point, instead of config.yml packet = pack( '<B%us%usI' % (len(name_bytes), len(address_bytes)), 1, # Number of realms name_bytes, address_bytes, # I assume this number is meant to show current online players since there is # no way of knowing the account yet when realmlist is requested in 0.5.3. WorldSessionStateHandler.get_process_shared_session_number() ) Logger.debug('[%s] Sending realmlist...' % sck.getpeername()[0]) sck.sendall(packet)
def serve_realm(sck): name_bytes = PacketWriter.string_to_bytes( config.Server.Connection.RealmServer.realm_name) forward_address = os.getenv('FORWARD_ADDRESS_OVERRIDE', config.Server.Connection.RealmProxy.host) address_bytes = PacketWriter.string_to_bytes( f'{forward_address}:{config.Server.Connection.RealmProxy.port}') # TODO: Should probably move realms to database at some point, instead of config.yml packet = pack( f'<B{len(name_bytes)}s{len(address_bytes)}sI', 1, # Number of realms name_bytes, address_bytes, # I assume this number is meant to show current online players since there is # no way of knowing the account yet when realmlist is requested in 0.5.3. WorldSessionStateHandler.get_process_shared_session_number()) Logger.debug(f'[{sck.getpeername()[0]}] Sending realmlist...') sck.sendall(packet)
def _debug_field_acquisition(self, requester, index, was_protected): update_field_info = ENCAPSULATION_INFORMATION[self.fields_type][index] result = {'[PROTECTED]' if was_protected else '[ACCESSED]'} Logger.debug(f"{requester.player.name} - [{update_field_info}] - {result}, Value [{self.update_values[index]}]")
class Pipeline(object): def __init__(self, hostname="scanme.nmap.org", config=None): self.config = Config.from_file(config) if config else Config() self.target = Target(hostname) self.tools = [] self.outdir = self.make_outdir() self.assetdir = self.get_assetdir() self.logger = Logger(self.config, f"{self.outdir}/logs") self.available = self.check_dependencies() self.load_tools() self.logger.info(f"Pipeline initialized for target: {hostname}") # load from config def load_tools(self): missing = [] for k, v in self.config.tools(): tool, *options = v.split(";") options = ";".join(options) Tool = [ T for T in TOOLS if T.__name__ == tool and T in self.available ] if len(Tool) == 0: missing.append(tool) else: self.add_tool(Tool.pop()(options), from_config=True) if len(missing) > 0: os.system("clear") [ self.logger.error( f"Skipping tool {tool} in configuration (Missing)") for tool in missing ] acknowledge() def add_tool(self, tool, from_config=False): self.logger.info(f"Adding {tool}") for t in self.tools: if tool == t: # same tool with same options... self.logger.info(f"Duplicate") return tool.set_logger(self.logger) tool.set_target(self.target) tool.set_outdir(f"{self.outdir}/commands") tool.set_reportdir(f"{self.outdir}/reports") tool.set_assetdir(self.assetdir) self.tools.append(tool) if from_config == False: if not hasattr(self, "tool_iota"): # self.tool_iota = len(self.config.tools()) tool_indexes = [ int(k.split("_")[-1]) for k, v in self.config.tools() ] self.tool_iota = len(tool_indexes) and max(tool_indexes) self.tool_iota += 1 setattr(self.config, f"TOOL_{self.tool_iota}", f"{repr(tool)}") self.logger.info(f"Success") return -1 # "só" ficar uniforme com o comportamento do remove_tool def remove_tool(self, tool): self.logger.info(f"Removing {tool}") for t in self.tools: if tool == t: # same tool with same options... self.tools.remove(t) configentry = [v for k, v in self.config.tools() ].index(repr(tool)) delattr(self.config, f"{self.config.tools()[configentry][0]}") self.logger.info(f"Success") return -1 # só para sair do menu... (forçar a atualizar) self.logger.info(f"Not found") # def update_target(self, hostname): # self.target.set_target(hostname) # need to update for each tool? maybe refactor? def run(self): if len(self.tools) == 0: self.logger.error("Must add tools...") return missing = missing_tool_dependencies(self.tools) if missing: self.logger.error(missing) self.logger.error( "Did not execute. Please fullfil requirements...") return sorted_tools = sortby_dependencies(self.tools) if not sorted_tools: return self.logger.debug( f"Tool order: {','.join([t.__class__.__name__ for t in sorted_tools])}" ) outputs = {} reports = {} report_obj = None for tool in sorted_tools: out, err = tool.run(outputs) for p in tool.PROVIDES: outputs[p] = out if err and not tool.IGNORE_STDERR: self.logger.error(f"{err.decode('ascii')}\nExiting...") return else: self.logger.info("Output saved") report_obj = tool.report(reports) for p in tool.PROVIDES: reports[p] = report_obj self.create_report(reports, sorted_tools) def create_report(self, reports, sorted_tools): outfile = f"{self.outdir}/reports/Report.md" title = f"PENSEC - Report of {self.target.hostname}" reportfile = MdUtils(file_name=outfile, title=title) # "Execute Summary" reportfile.new_header(level=3, title="Common Statistics") for tool in sorted_tools: tool.write_report_summary(reportfile, reports) # "Technical Details" for tool in sorted_tools: tool.write_report(reportfile, reports) reportfile.create_md_file() self.logger.info("Report saved in " + outfile) def check_dependencies(self): self.logger.info("Checking dependencies...") dependencies = TOOLS available = check_dependencies(dependencies, self.logger) if len(dependencies) != len(available): acknowledge() return available def make_outdir(self): hostname = self.target.hostname timestamp = re.sub(r'[/:]', '-', datetime.now().strftime('%x_%X')) outdir = f"{self.config.OUTPUT_DIRECTORY}/{hostname}/{timestamp}" os.makedirs(outdir) subdirs = ["logs", "commands", "reports"] for sd in subdirs: os.mkdir(f"{outdir}/{sd}") return outdir def get_assetdir(self): path = Path().absolute() return str(path) + "/assets/" def viewconfig(self): self.logger.info(f"Showing current config:") self.logger.debug("\n" + str(self.config)) print("\n") acknowledge() def saveconfig(self): outfile = input("Config name\n>> ") with open(f"config/{outfile}", "w+") as f: f.write(str(self.config)) self.logger.info(f"Config saved to {outfile}") # called on exit from main menu def cleanup(self): self.logger.end() from utils.Menu import Menu return Menu.EXIT
def apply_effect(casting_spell, effect, target): if effect.effect_type not in SPELL_EFFECTS: Logger.debug(f'Unimplemented effect called: {effect.effect_type}') return SPELL_EFFECTS[effect.effect_type](casting_spell, effect, casting_spell.spell_caster, target)