Metadata-Version: 2.1
Name: diffy
Version: 0.1.0
Summary: Forensic differentiator
Home-page: https://github.com/Netflix-Skunkworks/diffy
Author: Netflix
Author-email: security@netflix.com
License: UNKNOWN
Platform: UNKNOWN
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.6
Classifier: Natural Language :: English
Classifier: License :: OSI Approved :: Apache Software License
Requires-Python: >=3.6
Provides-Extra: dev
Provides-Extra: web
Requires-Dist: boto3 (==1.7.9)
Requires-Dist: botocore (==1.10.9)
Requires-Dist: click-log (==0.2.1)
Requires-Dist: click (==6.7)
Requires-Dist: deepdiff (==3.3.0)
Requires-Dist: docutils (==0.14)
Requires-Dist: dogpile.cache (==0.6.4)
Requires-Dist: fuzzywuzzy (==0.16.0)
Requires-Dist: jmespath (==0.9.3)
Requires-Dist: jsondiff (==1.1.1)
Requires-Dist: jsonpickle (==0.9.6)
Requires-Dist: jsonschema (==2.6.0)
Requires-Dist: marshmallow-jsonschema (==0.5.0)
Requires-Dist: marshmallow (==2.15.1)
Requires-Dist: python-dateutil (==2.7.2)
Requires-Dist: python-levenshtein (==0.12.0)
Requires-Dist: pyyaml (==3.12)
Requires-Dist: retrying (==1.3.3)
Requires-Dist: s3transfer (==0.1.13)
Requires-Dist: six (==1.11.0)
Requires-Dist: swag-client (==0.3.8)
Requires-Dist: tabulate (==0.8.2)
Provides-Extra: dev
Requires-Dist: alabaster (==0.7.10); extra == 'dev'
Requires-Dist: aniso8601 (==3.0.0); extra == 'dev'
Requires-Dist: aspy.yaml (==1.1.0); extra == 'dev'
Requires-Dist: attrs (==17.4.0); extra == 'dev'
Requires-Dist: autopep8 (==1.3.5); extra == 'dev'
Requires-Dist: babel (==2.5.3); extra == 'dev'
Requires-Dist: bandit (==1.4.0); extra == 'dev'
Requires-Dist: blinker (==1.4); extra == 'dev'
Requires-Dist: boto3 (==1.7.9); extra == 'dev'
Requires-Dist: botocore (==1.10.9); extra == 'dev'
Requires-Dist: bumpversion (==0.5.3); extra == 'dev'
Requires-Dist: cached-property (==1.4.2); extra == 'dev'
Requires-Dist: certifi (==2018.4.16); extra == 'dev'
Requires-Dist: cfgv (==1.0.0); extra == 'dev'
Requires-Dist: chardet (==3.0.4); extra == 'dev'
Requires-Dist: click-log (==0.2.1); extra == 'dev'
Requires-Dist: click (==6.7); extra == 'dev'
Requires-Dist: codecov (==2.0.15); extra == 'dev'
Requires-Dist: coverage (==4.5.1); extra == 'dev'
Requires-Dist: deepdiff (==3.3.0); extra == 'dev'
Requires-Dist: docutils (==0.14); extra == 'dev'
Requires-Dist: dogpile.cache (==0.6.4); extra == 'dev'
Requires-Dist: first (==2.0.1); extra == 'dev'
Requires-Dist: flake8 (==3.5.0); extra == 'dev'
Requires-Dist: flask-restful (==0.3.6); extra == 'dev'
Requires-Dist: flask (==1.0.1); extra == 'dev'
Requires-Dist: fuzzywuzzy (==0.16.0); extra == 'dev'
Requires-Dist: gitdb2 (==2.0.3); extra == 'dev'
Requires-Dist: gitpython (==2.1.9); extra == 'dev'
Requires-Dist: gunicorn (==19.8.1); extra == 'dev'
Requires-Dist: identify (==1.0.13); extra == 'dev'
Requires-Dist: idna (==2.6); extra == 'dev'
Requires-Dist: imagesize (==1.0.0); extra == 'dev'
Requires-Dist: inflection (==0.3.1); extra == 'dev'
Requires-Dist: itsdangerous (==0.24); extra == 'dev'
Requires-Dist: jinja2 (==2.10); extra == 'dev'
Requires-Dist: jmespath (==0.9.3); extra == 'dev'
Requires-Dist: jsondiff (==1.1.1); extra == 'dev'
Requires-Dist: jsonpickle (==0.9.6); extra == 'dev'
Requires-Dist: jsonschema (==2.6.0); extra == 'dev'
Requires-Dist: markupsafe (==1.0); extra == 'dev'
Requires-Dist: marshmallow-jsonschema (==0.5.0); extra == 'dev'
Requires-Dist: marshmallow (==2.15.1); extra == 'dev'
Requires-Dist: mccabe (==0.6.1); extra == 'dev'
Requires-Dist: more-itertools (==4.1.0); extra == 'dev'
Requires-Dist: mypy (==0.590); extra == 'dev'
Requires-Dist: nodeenv (==1.3.0); extra == 'dev'
Requires-Dist: packaging (==17.1); extra == 'dev'
Requires-Dist: pbr (==4.0.2); extra == 'dev'
Requires-Dist: pip-tools (==2.0.2); extra == 'dev'
Requires-Dist: pluggy (==0.6.0); extra == 'dev'
Requires-Dist: pre-commit-hooks (==1.2.3); extra == 'dev'
Requires-Dist: pre-commit (==1.8.2); extra == 'dev'
Requires-Dist: py (==1.5.3); extra == 'dev'
Requires-Dist: pycodestyle (==2.3.1); extra == 'dev'
Requires-Dist: pyflakes (==1.6.0); extra == 'dev'
Requires-Dist: pygments (==2.2.0); extra == 'dev'
Requires-Dist: pyparsing (==2.2.0); extra == 'dev'
Requires-Dist: pytest-cov (==2.5.1); extra == 'dev'
Requires-Dist: pytest-flask (==0.10.0); extra == 'dev'
Requires-Dist: pytest (==3.5.1); extra == 'dev'
Requires-Dist: python-dateutil (==2.7.2); extra == 'dev'
Requires-Dist: python-levenshtein (==0.12.0); extra == 'dev'
Requires-Dist: pytz (==2018.4); extra == 'dev'
Requires-Dist: pyyaml (==3.12); extra == 'dev'
Requires-Dist: raven[flask] (==6.7.0); extra == 'dev'
Requires-Dist: requests (==2.18.4); extra == 'dev'
Requires-Dist: retrying (==1.3.3); extra == 'dev'
Requires-Dist: s3transfer (==0.1.13); extra == 'dev'
Requires-Dist: six (==1.11.0); extra == 'dev'
Requires-Dist: smmap2 (==2.0.3); extra == 'dev'
Requires-Dist: snowballstemmer (==1.2.1); extra == 'dev'
Requires-Dist: sphinx-autodoc-annotation (==1.0.post1); extra == 'dev'
Requires-Dist: sphinx (==1.7.4); extra == 'dev'
Requires-Dist: sphinxcontrib-websupport (==1.0.1); extra == 'dev'
Requires-Dist: stevedore (==1.28.0); extra == 'dev'
Requires-Dist: swag-client (==0.3.8); extra == 'dev'
Requires-Dist: tabulate (==0.8.2); extra == 'dev'
Requires-Dist: typed-ast (==1.1.0); extra == 'dev'
Requires-Dist: urllib3 (==1.22); extra == 'dev'
Requires-Dist: virtualenv (==15.2.0); extra == 'dev'
Requires-Dist: werkzeug (==0.14.1); extra == 'dev'
Provides-Extra: web
Requires-Dist: aniso8601 (==3.0.0); extra == 'web'
Requires-Dist: blinker (==1.4); extra == 'web'
Requires-Dist: boto3 (==1.7.9); extra == 'web'
Requires-Dist: botocore (==1.10.9); extra == 'web'
Requires-Dist: click-log (==0.2.1); extra == 'web'
Requires-Dist: click (==6.7); extra == 'web'
Requires-Dist: croniter (==0.3.20); extra == 'web'
Requires-Dist: deepdiff (==3.3.0); extra == 'web'
Requires-Dist: docutils (==0.14); extra == 'web'
Requires-Dist: dogpile.cache (==0.6.4); extra == 'web'
Requires-Dist: flask-restful (==0.3.6); extra == 'web'
Requires-Dist: flask-rq2 (==18.0); extra == 'web'
Requires-Dist: flask (==1.0.2); extra == 'web'
Requires-Dist: fuzzywuzzy (==0.16.0); extra == 'web'
Requires-Dist: gunicorn (==19.8.1); extra == 'web'
Requires-Dist: inflection (==0.3.1); extra == 'web'
Requires-Dist: itsdangerous (==0.24); extra == 'web'
Requires-Dist: jinja2 (==2.10); extra == 'web'
Requires-Dist: jmespath (==0.9.3); extra == 'web'
Requires-Dist: jsondiff (==1.1.1); extra == 'web'
Requires-Dist: jsonpickle (==0.9.6); extra == 'web'
Requires-Dist: jsonschema (==2.6.0); extra == 'web'
Requires-Dist: markupsafe (==1.0); extra == 'web'
Requires-Dist: marshmallow-jsonschema (==0.5.0); extra == 'web'
Requires-Dist: marshmallow (==2.15.1); extra == 'web'
Requires-Dist: python-dateutil (==2.7.2); extra == 'web'
Requires-Dist: python-levenshtein (==0.12.0); extra == 'web'
Requires-Dist: pytz (==2018.4); extra == 'web'
Requires-Dist: pyyaml (==3.12); extra == 'web'
Requires-Dist: raven[flask] (==6.7.0); extra == 'web'
Requires-Dist: redis (==2.10.6); extra == 'web'
Requires-Dist: retrying (==1.3.3); extra == 'web'
Requires-Dist: rq-scheduler (==0.8.2); extra == 'web'
Requires-Dist: rq (==0.10.0); extra == 'web'
Requires-Dist: s3transfer (==0.1.13); extra == 'web'
Requires-Dist: six (==1.11.0); extra == 'web'
Requires-Dist: swag-client (==0.3.8); extra == 'web'
Requires-Dist: tabulate (==0.8.2); extra == 'web'
Requires-Dist: werkzeug (==0.14.1); extra == 'web'

Diffy
=====

.. image:: docs/images/diffy_small.png
    :align: right

.. image:: https://img.shields.io/travis/liiight/diffy/master.svg?style=flat-square
    :target: https://travis-ci.org/Netflix-Skunkworks/diffy
    :alt: Travis CI

.. image:: https://img.shields.io/codecov/c/github/Netflix-Skunkworks/diffy/master.svg?style=flat-square
    :target: https://codecov.io/gh/Netflix-Skunkworks/diffy
    :alt: Codecov

.. image:: https://img.shields.io/gitter/room/nwjs/nw.js.svg?style=flat-square
    :target: https://gitter.im/diffy/diffy

.. image:: https://img.shields.io/pypi/v/diffy.svg?style=flat-square
    :target: https://pypi.python.org/pypi/diffy
    :alt: PyPi version

.. image:: https://img.shields.io/pypi/pyversions/diffy.svg?style=flat-square
    :target: https://pypi.org/project/diffy
    :alt: Supported Python versions

.. image:: https://img.shields.io/pypi/l/diffy.svg?style=flat-square
    :target: https://choosealicense.com/licenses
    :alt: License

.. image:: https://img.shields.io/pypi/status/diffy.svg?style=flat-square
    :target: https://pypi.python.org/pypi/diffy
    :alt: Status

.. image:: https://img.shields.io/readthedocs/diffy.svg?style=flat-square
    :target: https://readthedocs.org/projects/diffy/badge/?version=latest
    :alt: RTD


Diffy is a digital forensics and incident response (DFIR) tool developed by
Netflix's Security Intelligence and Response Team (SIRT). 

Diffy allows a forensic investigator to quickly scope a compromise across cloud
instances during an incident, and triage those instances for followup actions.
Diffy is currently focused on Linux instances running within Amazon Web
Services (AWS), but owing to our plugin structure, could support multiple
platforms and cloud providers.

It's called "Diffy" because it helps a human investigator to identify the
*differences* between instances, and because `Alex`_ pointed out that "The
Difforensicator" was unnecessarily tricky.

See `Releases`_ for recent changes. See `our Read the Docs site`_ for
well-formatted documentation.

.. _Alex: https://www.linkedin.com/in/maestretti/
.. _Releases: https://github.com/Netflix-Skunkworks/diffy/releases
.. _our Read the Docs site: http://diffy.readthedocs.io/

Supported Technologies
----------------------

- AWS (AWS Systems Manager / SSM)
- Local
- osquery

Each technology has its own plugins for targeting, collection and persistence.


Features
--------

- Efficiently highlights outliers in security-relevant instance behavior. For
  example, you can use Diffy to tell you which of your instances are listening
  on an unexpected port, are running an unusual process, include a strange
  crontab entry, or have inserted a surprising kernel module.
- Uses one, or both, of two methods to highlight differences: 

    - Collection of a "functional" baseline from a "clean" running instance,
      against which your instance group is compared, and
    - Collection of a "clustered" baseline, in which all instances are surveyed,
      and outliers are made obvious.

- Uses a modular plugin-based architecture. We currently include plugins for
  collection using osquery via AWS Systems Manager (formerly known as Simple
  Systems Manager or SSM).


Installation
------------

Via pip::

    pip install diffy


Roadmap
-------

We are actively adding more plugins & tests, and improving the documentation.


Why python 3 only?
~~~~~~~~~~~~~~~~~~

Please see `Guido's guidance
<https://mail.python.org/pipermail/python-dev/2018-March/152348.html>`_
regarding the Python 2.7 end of life date.


