def message(m, fd=sys.stdout): """Write a MaltegoMessage to stdout and exit successfully""" if sys.platform == 'win32': decoding = sys.stdout.encoding if sys.version_info[0] > 2 else 'cp1252' print(MaltegoMessage(message=m).render( fragment=True, encoding='utf-8').decode(decoding), file=fd) else: print(MaltegoMessage(message=m).render(fragment=True), file=fd) sys.exit(0)
def croak(cause): """Throw an exception in the Maltego GUI containing cause. :param cause: a string containing the issue description. """ return MaltegoMessage(message=MaltegoTransformExceptionMessage( exceptions=[MaltegoException(cause)])).render()
def remote_canari_transform_runner(host, base_path, transform, entities, parameters, limits, is_ssl=False): c = http_client.HTTPSConnection( host) if is_ssl else http_client.HTTPConnection(host) m = MaltegoTransformRequestMessage() for e in entities: m += e for p in parameters: m += p m += limits msg = MaltegoMessage(message=m).render(encoding='utf-8') path = re.sub(r'/+', '/', '/'.join([base_path, transform])) if is_debug_exec_mode(): sys.stderr.write("Sending following message to {}{}:\n{}\n\n".format( host, path, msg)) c.request('POST', path, msg, headers={'Content-Type': 'application/xml'}) return c.getresponse()
def message(m): """Write a MaltegoMessage to stdout and exit successfully""" v = None if isinstance(m, basestring): # Let's make sure that we're not spewing out local file system information ;) for url in re.findall("<iconurl>\s*(file://[^\s<]+)\s*</iconurl>(?im)", m): path = 'static/%s' % hashlib.md5(url[7:]).hexdigest() new_url = urljoin(request.host_url, path) m.replace(url, new_url, 1) v = m else: sio = StringIO() # Let's make sure that we're not spewing out local file system information ;) for e in m.entities: if e.iconurl is not None: e.iconurl = e.iconurl.strip() if e.iconurl.startswith('file://'): path = 'static/%s' % hashlib.md5(e.iconurl[7:]).hexdigest() new_url = urljoin(request.host_url, path) e.iconurl = new_url Message(MaltegoMessage(m)).write(sio) v = sio.getvalue() # Get rid of those nasty unicode 32 characters return Response(re.sub(r'(&#\d{5};){2}', r'', v), status=200, mimetype='text/html')
def remote_transform(args): entity_type, value = split_validate(args.input, 'entity') fields = {} params = [] for f in args.entity_field: name, value = split_validate(f, 'entity field') fields[name] = Field(name=name, value=value) for p in args.transform_parameter: name, value = split_validate(p, 'transform parameter') params += Field(name=name, value=value) try: r = remote_canari_transform_runner( args.host, args.base_path, args.transform, [_Entity(type=entity_type, value=value, fields=fields)], params, Limits(soft=args.soft_limit, hard=args.hard_limit), args.ssl) if r.status == 200: data = r.read() if args.raw_output: print data else: console_writer(MaltegoMessage.parse(data)) exit(0) print 'ERROR: Received status %d for %s://%s/%s. Are you sure you got the right server?' % ( r.status, 'https' if args.ssl else 'http', args.host, args.transform) except Exception, e: print 'ERROR: %s' % e
def do_transform(transform): try: # Let's get an XML object tree req = MaltegoMessage.parse(request.data).message # If our transform define an input entity type then we should check # whether the request contains the right type if transform.input_type and transform.input_type is not Unknown and \ not isinstance(req.entity, transform.input_type): return Response(application.four_o_four, status=404) # Execute it! msg = transform().do_transform(req, MaltegoTransformResponseMessage(), load_config()) # Let's serialize the return response and clean up whatever mess was left behind if isinstance(msg, MaltegoTransformResponseMessage): return message(msg) else: raise MaltegoException(str(msg)) # Unless we croaked somewhere, then we need to fix things up here... except MaltegoException as me: return croak(str(me)) except Exception: if application.debug: return croak(traceback.format_exc()) else: return croak('Transform execution failed.')
def remote_canari_transform_runner(host, base_path, transform, entities, parameters, limits, is_ssl=False): c = HTTPSConnection(host) if is_ssl else HTTPConnection(host) m = MaltegoTransformRequestMessage() for e in entities: m += e for p in parameters: m += p m += limits message = MaltegoMessage(message=m).render() path = re.sub(r'/+', '/', '/'.join([base_path, transform])) if is_debug_exec_mode(): sys.stderr.write("Sending following message to {}{}:\n{}\n\n".format( host, path, message)) c.request('POST', path, message) return c.getresponse()
def do_transform(transform): try: # Let's get an XML object tree req = MaltegoMessage.parse(request.data).message # If our transform define an input entity type then we should check # whether the request contains the right type if transform.input_type and transform.input_type is not Unknown and \ not isinstance(req.entity, transform.input_type): return Response(application.four_o_four, status=404) # Execute it! msg = transform().do_transform( req, MaltegoTransformResponseMessage(), load_config() ) # Let's serialize the return response and clean up whatever mess was left behind if isinstance(msg, MaltegoTransformResponseMessage): return message(msg) else: raise MaltegoException(str(msg)) # Unless we croaked somewhere, then we need to fix things up here... except MaltegoException, me: return croak(str(me))
def croak(error_msg): """Throw an exception in the Maltego GUI containing error_msg.""" s = StringIO() Message( MaltegoMessage( MaltegoTransformExceptionMessage( exceptions=MaltegoException(error_msg)))).write(file=s) return s.getvalue()
def croak(error_msg, r): """Throw an exception in the Maltego GUI containing error_msg.""" r.send_response(200) r.send_header('Content-Type', 'text/xml') r.send_header('Connection', 'close') r.end_headers() Message( MaltegoMessage( MaltegoTransformExceptionMessage( exceptions=MaltegoException(error_msg)))).write(file=r.wfile)
def croak(error_msg, response): """Throw an exception in the Maltego GUI containing error_msg.""" response.send_response(200) response.send_header('Content-Type', 'text/xml') response.send_header('Connection', 'close') response.end_headers() response.wfile.write( MaltegoMessage( message=MaltegoTransformExceptionMessage(exceptions=[MaltegoException(error_msg)]) ).render(fragment=True) )
def remote_transform(host, transform, input, entity_field, transform_parameter, raw_output, ssl, base_path, soft_limit, hard_limit, verbose): if verbose: set_canari_mode(CanariMode.LocalDebug) entity_type, entity_value = split_validate(input, 'entity') fields = {} params = [] for f in entity_field: name, value = split_validate(f, 'entity field') fields[name] = Field(name=name, value=value) for p in transform_parameter: name, value = split_validate(p, 'transform parameter') params.append(Field(name=name, value=value)) try: r = remote_canari_transform_runner( host, base_path, transform, [_Entity(type=entity_type, value=entity_value, fields=fields)], params, Limits(soft=soft_limit, hard=hard_limit), ssl ) if r.status == 200: data = r.read().decode('utf8') if raw_output: click.echo(data, err=True) exit(0) else: console_writer(MaltegoMessage.parse(data)) exit(0) click.echo('ERROR: Received status %d for %s://%s/%s. Are you sure you got the right server?' % ( r.status, 'https' if ssl else 'http', host, transform ), err=True) if verbose: click.echo(r.read(), err=True) except Exception as e: click.echo('ERROR: %s' % e, err=True) if verbose: traceback.print_exc() exit(-1)
def message(m): """Write a MaltegoMessage to stdout and exit successfully""" v = None if isinstance(m, str): # Let's make sure that we're not spewing out local file system information ;) for url in re.findall("<iconurl>\s*(file://[^\s<]+)\s*</iconurl>(?im)", m): path = 'static/%s' % hashlib.md5(url[7:]).hexdigest() new_url = urljoin(request.host_url, path) m.replace(url, new_url, 1) v = m else: v = MaltegoMessage(message=m).render() return Response(v, status=200, mimetype='text/html')
def message(m, response): """Write a MaltegoMessage to stdout and exit successfully""" response.send_response(200) response.send_header("Content-Type", "text/xml") response.send_header("Connection", "close") response.end_headers() v = None if isinstance(m, basestring): for url in re.findall("<iconurl>\s*(file://[^\s<]+)\s*</iconurl>(?im)", m): path = "/%s" % hashlib.md5(url).hexdigest() new_url = "%s://%s%s" % ("https" if response.server.is_ssl else "http", response.server.hostname, path) if path not in response.server.resources: response.server.resources[path] = url[7:] m.replace(url, new_url, 1) v = m else: mm = MaltegoMessage() mm.message = m v = mm.render(fragment=True) # Get rid of those nasty unicode 32 characters response.wfile.write(v)
def dotransform(self, transform, valid_input_entity_types): try: if "Content-Length" not in self.headers: self.send_error(500, "What?") return request_str = self.rfile.read(int(self.headers["Content-Length"])) msg = MaltegoMessage.parse(request_str).message e = msg.entity entity_type = e.type if valid_input_entity_types and entity_type not in valid_input_entity_types: self.send_error(400, "Unsupported input entity!") return for k, i in msg.parameters.iteritems(): if "." in k: config[k.replace(".", "/", 1)] = i else: config["plume/%s" % k] = i msg = ( transform( msg, request_str if hasattr(transform, "cmd") and callable(transform.cmd) else MaltegoTransformResponseMessage(), ) if get_transform_version(transform) == 2 else transform( msg, request_str if hasattr(transform, "cmd") and callable(transform.cmd) else MaltegoTransformResponseMessage(), config, ) ) if isinstance(msg, MaltegoTransformResponseMessage) or isinstance(msg, basestring): message(msg, self) return else: raise MaltegoException("Could not resolve message type returned by transform.") except MaltegoException, me: croak(str(me), self)
def __call__(self, request, *args): self.args.append(request.entity.value) if isinstance(request.parameters, list) and request.parameters: self.args.extend(request.parameters) if request.entity.fields: self.args.append('#'.join([ '%s=%s' % (k, v.value.replace('#', '\\#').replace('=', '\\=')) for k, v in request.entity.fields.items() ])) if is_local_exec_mode(): p = Popen(self.args, env=self.env) p.communicate() exit(p.returncode) else: p = Popen(self.args, env=self.env, stdout=PIPE) out, _ = p.communicate() return MaltegoMessage.parse(out)
def dotransform(transform, valid_input_entity_types): try: # Get the body of the request request_str = request.data # Let's get an XML object tree maltego_request = MaltegoMessage.parse(request_str).message # Get the entity being passed in. e = maltego_request.entity entity_type = e.type if valid_input_entity_types and entity_type not in valid_input_entity_types: return Response(app.four_o_four, status=404) # Initialize a private copy of the config to pass into the transform config = _config.CanariConfigParser() for p in maltego_request.parameters.values(): if '.' in p.name: config[p.name.replace('.', '/', 1)] = p else: config['plume/%s' % p.name] = p.value # The private config variables CANNOT override the server's settings. This is for security? config._sections.update(_config.config._sections) # Execute it! msg = transform( maltego_request, request_str if hasattr(transform, 'cmd') and callable(transform.cmd) else MaltegoTransformResponseMessage(), config ) # Let's serialize the return response and clean up whatever mess was left behind if ( isinstance(msg, MaltegoTransformResponseMessage) or isinstance(msg, basestring) or isinstance(msg, MaltegoTransformExceptionMessage) ): return message(msg) else: raise MaltegoException('Could not resolve message type returned by transform.') # Unless we croaked somewhere, then we need to fix things up here... except MaltegoException, me: return croak(str(me))
def remote_transform(args): if args.verbose: set_canari_mode(CanariMode.LocalDebug) entity_type, entity_value = split_validate(args.input, 'entity') fields = {} params = [] for f in args.entity_field: name, value = split_validate(f, 'entity field') fields[name] = Field(name=name, value=value) for p in args.transform_parameter: name, value = split_validate(p, 'transform parameter') params.append(Field(name=name, value=value)) try: r = remote_canari_transform_runner( args.host, args.base_path, args.transform, [_Entity(type=entity_type, value=entity_value, fields=fields)], params, Limits(soft=args.soft_limit, hard=args.hard_limit), args.ssl ) if r.status == 200: data = r.read() if args.raw_output: print data exit(0) else: console_writer(MaltegoMessage.parse(data)) exit(0) print 'ERROR: Received status %d for %s://%s/%s. Are you sure you got the right server?' % ( r.status, 'https' if args.ssl else 'http', args.host, args.transform ) except Exception, e: print 'ERROR: %s' % e
def dotransform(transform, valid_input_entity_types): try: # Get the body of the request request_str = request.data # Let's get an XML object tree maltego_request = MaltegoMessage.parse(request_str).message # Get the entity being passed in. e = maltego_request.entity entity_type = e.type if valid_input_entity_types and entity_type not in valid_input_entity_types: return Response(app.four_o_four, status=404) # Initialize a private copy of the config to pass into the transform config = _config.CanariConfigParser() for p in maltego_request.parameters.values(): if '.' in p.name: config[p.name.replace('.', '/', 1)] = p.value else: config['plume/%s' % p.name] = p.value # The private config variables CANNOT override the server's settings. This is for security? config._sections.update(_config.config._sections) # Execute it! msg = transform( maltego_request, request_str if hasattr(transform, 'cmd') and callable(transform.cmd) else MaltegoTransformResponseMessage(), config) # Let's serialize the return response and clean up whatever mess was left behind if isinstance(msg, MaltegoTransformResponseMessage) or isinstance( msg, basestring): return message(msg) else: raise MaltegoException( 'Could not resolve message type returned by transform.') # Unless we croaked somewhere, then we need to fix things up here... except MaltegoException, me: return croak(str(me))
def message(m, response): """Write a MaltegoMessage to stdout and exit successfully""" response.send_response(200) response.send_header('Content-Type', 'text/xml') response.send_header('Connection', 'close') response.end_headers() v = None if isinstance(m, basestring): for url in re.findall("<iconurl>\s*(file://[^\s<]+)\s*</iconurl>(?im)", m): path = '/%s' % hashlib.md5(url).hexdigest() new_url = '%s://%s%s' % ('https' if response.server.is_ssl else 'http', response.server.hostname, path) if path not in response.server.resources: response.server.resources[path] = url[7:] m.replace(url, new_url, 1) v = m else: v = MaltegoMessage(m).render(fragment=True) # Get rid of those nasty unicode 32 characters response.wfile.write(v)
def remote_canari_transform_runner(host, base_path, transform, entities, parameters, limits, is_ssl=False): c = HTTPSConnection(host) if is_ssl else HTTPConnection(host) m = MaltegoTransformRequestMessage() for e in entities: m += e for p in parameters: m += p m += limits c.request('POST', re.sub(r'/+', '/', '/'.join([base_path, transform])), MaltegoMessage(message=m).render()) return c.getresponse()
def message(m, response): """Write a MaltegoMessage to stdout and exit successfully""" response.send_response(200) response.send_header('Content-Type', 'text/xml') response.send_header('Connection', 'close') response.end_headers() v = None if isinstance(m, basestring): for url in findall("<iconurl>\s*(file://[^\s<]+)\s*</iconurl>(?im)", m): path = '/%s' % md5(url).hexdigest() new_url = '%s://%s%s' % ('https' if response.server.is_ssl else 'http', response.server.hostname, path) if path not in response.server.resources: response.server.resources[path] = url[7:] m.replace(url, new_url, 1) v = m else: sio = StringIO() for e in m.entities: if e.iconurl is not None: e.iconurl = e.iconurl.strip() if e.iconurl.startswith('file://'): path = '/%s' % md5(e.iconurl).hexdigest() new_url = '%s://%s%s' % ('https' if response.server.is_ssl else 'http', response.server.hostname, path) if path not in response.server.resources: response.server.resources[path] = e.iconurl[7:] e.iconurl = new_url Message(MaltegoMessage(m)).write(sio) v = sio.getvalue() # Get rid of those nasty unicode 32 characters response.wfile.write(sub(r'(&#\d{5};){2}', r'', v))
def message(msg): """Write a MaltegoMessage to stdout and exit successfully""" v = MaltegoMessage(message=msg).render() return Response(v, status=200, mimetype='text/xml')
def croak(error_msg): """Throw an exception in the Maltego GUI containing error_msg.""" return MaltegoMessage(message=MaltegoTransformExceptionMessage( exceptions=[MaltegoException(error_msg)])).render()