Ejemplo n.º 1
0
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)
Ejemplo n.º 2
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()
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
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')
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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.')
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
0
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))
Ejemplo n.º 9
0
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()
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
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)
    )
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
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')
Ejemplo n.º 14
0
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)
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
 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)
Ejemplo n.º 17
0
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))
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
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))
Ejemplo n.º 20
0
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)
Ejemplo n.º 21
0
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()
Ejemplo n.º 22
0
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))
Ejemplo n.º 23
0
def message(msg):
    """Write a MaltegoMessage to stdout and exit successfully"""
    v = MaltegoMessage(message=msg).render()
    return Response(v, status=200, mimetype='text/xml')
Ejemplo n.º 24
0
def croak(error_msg):
    """Throw an exception in the Maltego GUI containing error_msg."""
    return MaltegoMessage(message=MaltegoTransformExceptionMessage(
        exceptions=[MaltegoException(error_msg)])).render()