Giter Site home page Giter Site logo

papermtn / slack-watchman Goto Github PK

View Code? Open in Web Editor NEW
290.0 10.0 38.0 1.87 MB

Slack enumeration and exposed secrets detection tool

License: GNU General Public License v3.0

Python 99.38% Dockerfile 0.62%
blueteam blue-team cybersecurity infosec slack tools redteam red-team purpleteam purple-team

slack-watchman's Introduction

Slack Watchman

Python 2.7 and 3 compatible PyPI version License: MIT

Monitoring and enumerating Slack for exposed secrets

About Slack Watchman

Slack Watchman is an application that uses the Slack API to find potentially sensitive data exposed in a Slack workspace, and to enumerate other useful information for red, blue and purple teams.

More information about Slack Watchman can be found on my blog.

Features

Slack Watchman looks for:

  • API Keys, Tokens & Service Accounts
    • AWS, Azure, GCP, Google API, Slack (keys & webhooks), Twitter, Facebook, GitHub and more
    • Generic Private keys
    • Access Tokens, Bearer Tokens, Client Secrets, Private Tokens
  • Files
    • Certificate files
    • Potentially interesting/malicious/sensitive files (.docm, .xlsm, .zip etc.)
    • Executable files
    • Keychain files
    • Config files for popular services (Terraform, Jenkins, OpenVPN and more)
  • Personal Data
    • Leaked passwords
    • Passport numbers, Dates of birth, Social security numbers, National insurance numbers and more
  • Financial data
    • Paypal Braintree tokens, Bank card details, IBAN numbers, CUSIP numbers and more

It also enumerates the following:

  • User data
    • All users & all admins
  • Channel data
    • All channels, including externally shared channels

Time based searching

You can run Slack Watchman to look for results going back as far as:

  • 24 hours
  • 7 days
  • 30 days
  • All time

This means after one deep scan, you can schedule Slack Watchman to run regularly and only return results from your chosen timeframe.

Signatures

Slack Watchman uses custom YAML signatures to detect matches in Slack. These signatures are pulled from the central Watchman Signatures repository. Slack Watchman automatically updates its signature base at runtime to ensure its using the latest signatures to detect secrets.

Logging

Slack Watchman gives the following logging options:

  • Terminal-friendly Stdout
  • JSON to Stdout

Slack Watchman defaults to terminal-friendly stdout logging if no option is given. This is designed to be easier for humans to read.

JSON logging is also available, which is perfect for ingesting into a SIEM or other log analysis platforms.

JSON formatted logging can be easily redirected to a file as below:

slack-watchman --timeframe a --all --output json >> slack_watchman_log.json 

Authentication Requirements

Slack API token

To run Slack Watchman, you will need a Slack API OAuth access token. You can do this by creating a simple Slack App.

The app needs to have the following User Token Scopes added:

channels:read
files:read
groups:read
im:read
links:read
mpim:read
remote_files:read
search:read
team:read
users:read
users:read.email

Note: User tokens act on behalf of the user who authorises them, so I would suggest you create this app and authorise it using a service account, otherwise the app will have access to your private channels and chats.

Cookie Authentication

Alternatively, Slack Watchman can also authenticate to Slack using a user d cookie, which is stored in the browser of each user logged into a workspace.

To use cookie authentication, you will need to provide the d cookie, and the URL of the target workspace. Then you will need to use the --cookie flag when running Slack Watchman

More information on cookie authentication can be found on my blog

Providing tokens

Slack Watchman will first try to get the Slack token (plus the cookie token and URL if selected) from the environment variables

  • SLACK_WATCHMAN_TOKEN
  • SLACK_WATCHMAN_COOKIE
  • SLACK_WATCHMAN_URL

If this fails it will try to load the token(s) from .conf file (see below).

.conf file

Configuration options can be passed in a file named watchman.conf which must be stored in your home directory. The file should follow the YAML format, and should look like below:

slack_watchman:
  token: xoxp-xxxxxxxx
  cookie: xoxd-%2xxxxx
  url: https://xxxxx.slack.com

Slack Watchman will look for this file at runtime, and use the configuration options from here. If you are not using cookie auth, leave cookie and url blank.

If you are having issues with your .conf file, run it through a YAML linter.

An example file is in docs/example.conf

Note: Cookie and URL values are optional, and not required if not using cookie authentication.

Installation

You can install the latest stable version via pip:

python3 -m pip install slack-watchman

Or build from source yourself:

Download the release source files, then from the top level repository run:

python3 -m pip build
python3 -m pip install --force-reinstall dist/*.whl

Docker Image

Slack Watchman is also available from the Docker hub as a Docker image:

docker pull papermountain/slack-watchman:latest

You can then run Slack Watchman in a container, making sure you pass the required environment variables:

// help
docker run --rm papermountain/slack-watchman -h

// scan all
docker run --rm -e SLACK_WATCHMAN_TOKEN=xoxp... papermountain/slack-watchman --timeframe a --all --output json
docker run --rm --env-file .env papermountain/slack-watchman --timeframe a --all --output stdout

Usage

Slack Watchman will be installed as a global command, use as follows:

usage: slack-watchman [-h] --timeframe {d,w,m,a} [--output {json,stdout}] [--version] [--all] [--users] [--channels] [--pii] [--secrets]
                      [--debug] [--verbose] [--cookie]

Monitoring and enumerating Slack for exposed secrets

options:
  -h, --help            show this help message and exit
  --output {json,stdout}, -o {json,stdout}
                        Where to send results
  --version, -v         show program's version number and exit
  --all, -a             Find secrets and PII
  --users, -u           Enumerate users and output them to .csv
  --channels, -c        Enumerate channels and output them to .csv
  --pii, -p             Find personal data: DOB, passport details, drivers licence, ITIN, SSN etc.
  --secrets, -s         Find exposed secrets: credentials, tokens etc.
  --debug, -d           Turn on debug level logging
  --verbose, -V         Turn on more verbose output for JSON logging. This includes more fields, but is larger
  --cookie              Use cookie auth using Slack d cookie. REQUIRES either SLACK_WATCHMAN_COOKIE and SLACK_WATCHMAN_URL environment
                        variables set, or both values set in watchman.conf

required arguments:
  --timeframe {d,w,m,a}, -t {d,w,m,a}
                        How far back to search: d = 24 hours w = 7 days, m = 30 days, a = all time

You can run Slack Watchman to look for everything, and output to default stdout:

slack-watchman --timeframe a --all

Other Watchman apps

You may be interested in the other apps in the Watchman family:

License

The source code for this project is released under the GNU General Public Licence. This project is not associated with Slack Technologies or Salesforce.

slack-watchman's People

Contributors

j-boivie avatar papermtn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

slack-watchman's Issues

File based rules - "posted_by" left blank

When posting files I noticed that posted_by is left blank:

{"localtime": "2020-09-19 23:40:05,824", "level": "NOTIFY", "source": "Slack Watchman", "workspace": "DevCorner", "scope": "files", "detection.type": "Executable Files", "severity": "30", "detection": {"created": 1600372359, "file_id": "F01B9QV2EKT", "file_type": "binary", "mimetype": "application/octet-stream", "name": "balenaEtcher-1.5.102.dmg", "permalink": "https://slackoverloadgroup.slack.com/files/U019SN08GQP/F01B9QV2EKT/balenaetcher-1.5.102.dmg", "posted_by": "", "preview": null, "timestamp": "2020-09-16 19:27:39"}}

I am not sure if that is intentional since all file based rules seem to behave the same way. The username should be catched as with other detection rules.

Broken JSON

When logging to STDOUT I noticed the JSON formatting is broken, at least according to logstash.

Example...

{"localtime": "2020-09-17 14:05:39,943", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".dmg""}
{"localtime": "2020-09-17 14:05:40,315", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".iso""}
{"localtime": "2020-09-17 14:05:40,963", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".pkg""}
{"localtime": "2020-09-17 14:05:41,478", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".pptx""}
{"localtime": "2020-09-17 14:05:41,918", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".pptm""}
{"localtime": "2020-09-17 14:05:43,636", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".ppt""}
{"localtime": "2020-09-17 14:05:44,004", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".conf""}
{"localtime": "2020-09-17 14:05:44,445", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".ini""}
{"localtime": "2020-09-17 14:05:44,856", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".openvpn""}
{"localtime": "2020-09-17 14:05:45,268", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".cscfg""}
{"localtime": "2020-09-17 14:05:45,780", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".rdp""}
{"localtime": "2020-09-17 14:05:46,363", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".jks""}
{"localtime": "2020-09-17 14:05:46,804", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".psafe3""}
{"localtime": "2020-09-17 14:05:47,520", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".agilekeychain""}
{"localtime": "2020-09-17 14:05:48,135", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".keychain""}
{"localtime": "2020-09-17 14:05:48,541", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".kwallet""}
{"localtime": "2020-09-17 14:05:48,912", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: ".tblk""}
{"localtime": "2020-09-17 14:59:34,192", "level": "INFO", "source": "Slack Watchman", "message": "2 messages found matching: "password:"*"}
{"localtime": "2020-09-17 14:59:34,953", "level": "INFO", "source": "Slack Watchman", "message": "2 messages found matching: "password is"*"}

Should be escaped like this and logstash can work with it...

{"localtime": "2020-09-17 14:05:39,943", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".dmg\""}
{"localtime": "2020-09-17 14:05:40,315", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".iso\""}
{"localtime": "2020-09-17 14:05:40,963", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".pkg\""}
{"localtime": "2020-09-17 14:05:41,478", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".pptx\""}
{"localtime": "2020-09-17 14:05:41,918", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".pptm\""}
{"localtime": "2020-09-17 14:05:43,636", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".ppt\""}
{"localtime": "2020-09-17 14:05:44,004", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".conf\""}
{"localtime": "2020-09-17 14:05:44,445", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".ini\""}
{"localtime": "2020-09-17 14:05:44,856", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".openvpn\""}
{"localtime": "2020-09-17 14:05:45,268", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".cscfg\""}
{"localtime": "2020-09-17 14:05:45,780", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".rdp\""}
{"localtime": "2020-09-17 14:05:46,363", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".jks\""}
{"localtime": "2020-09-17 14:05:46,804", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".psafe3\""}
{"localtime": "2020-09-17 14:05:47,520", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".agilekeychain\""}
{"localtime": "2020-09-17 14:05:48,135", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".keychain\""}
{"localtime": "2020-09-17 14:05:48,541", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".kwallet\""}
{"localtime": "2020-09-17 14:05:48,912", "level": "INFO", "source": "Slack Watchman", "message": "0 files found matching: \".tblk\""}
{"localtime": "2020-09-17 14:59:34,192", "level": "INFO", "source": "Slack Watchman", "message": "2 messages found matching: \"password:\"*"}
{"localtime": "2020-09-17 14:59:34,953", "level": "INFO", "source": "Slack Watchman", "message": "2 messages found matching: \"password is\"*"}

According to the code it looks like the double quotes are inherited from the rules, so I do not know if there is a quick fix to this. It's probably minor, however nice if someone wants to get some stats out of it ๐Ÿ˜„

JSON is broken

When exporting results to JSON, any message that itself has quote marks in results in broken JSON. For example:

{"timestamp": "2023-06-14 15:02:29,374", "level": "WORKSPACE", "message": "{"name": "Slack Team", "domain": "slack-team", "url": "https://slack-team.slack.com/", "email_domain": "", "is_verified": true, "discoverable": "open"}"}

What I'm hopeful for: that messages that are printed out to JSON escape quote marks before they're logged.

Error on incorrect scope

When the Slack app associated with the token does not have a required scope attached to it Slack Watchman fails.

Support getting Slack token from args/env var

It would be really nice if it was possible to get the slack token through another method than a file, such as a CLI arg or environment variable, f.ex. for running this unsupervised in a container or similar.

No output .CSV file

Hey There,

The following does not output to a .csv file to see results, only the number found.
--pii
--tokens
--financial

Can you assist please??

Thanks!

Custom Rules

Hi,
Can you provide an example of how to call an example rule.

I created a rule, changed the category.
then ran slack-watchman --custom <catname> --timeframe a
recieved: slack-watchman: error: unrecognized arguments:

Thanks

Enhancement - App Permissions

Hi,
Is is possible to get a report on the apps installed (any details that go with that) and their permissions?
Reason being some apps may have overly permissive permissions and it would be good to know which ones.

Other things I can think:
User details - some PII in user details such as phone numbers/skype etc.

Anyway, loving this app. Its currently helping me loads with a task Ive been given.

Getting error 'encoding' is an invalid keyword argument for this function

I have installed slack-watchman. As soon as i run slack-watchman --timeframe a --all watchman starts but gives error.

Version: 2.3.1

Searching workspace: ****
Workspace URL: https://*****.com/

Getting everything...
+++++++++++++++++++++
Getting users
+++++++++++++++++++++
Getting channels
+++++++++++++++++++++
Getting admin users
+++++++++++++++++++++
'encoding' is an invalid keyword argument for this function

Please let me now how can we fix this.

Python version used - Python 2.7.16

Can't see message information

Describe the bug

Hi, I can't see any info (user, content) of the messages that are suspected. I haven't found any docs or additional options on it.

To Reproduce

docker run --rm --platform linux/x86_64 papermountain/slack-watchman --timeframe d --all --output json --cookie --debug --verbose

Expected behaviour

Information pointing to the message and its author included in the logs, as shown in a screenshot on the website.

image

Actual behaviour

No info about the message found in the logs.

{"timestamp": "2023-07-21 09:53:42,218", "level": "INFO", "message": "Searching for PII and Secrets"}
{"timestamp": "2023-07-21 09:53:42,219", "level": "INFO", "message": "Searching for posts containing Passwords"}
{"timestamp": "2023-07-21 09:53:43,338", "level": "INFO", "message": "1 potential matches found"}
{"timestamp": "2023-07-21 09:53:43,341", "level": "INFO", "message": "No matches found after filtering"}
{"timestamp": "2023-07-21 09:53:43,371", "level": "INFO", "message": "Searching for posts containing Twitter API Tokens"}

Desktop (please complete the following information):

  • OS: macOS

'NoneType' object has no attribute 'get'

Version 3.0.7

Running sudo slack-watchman --pii --timeframe a

Importing rules...
40 rules loaded
Searching PII/Personal Data
Searching for posts containing Drivers Licence Numbers (UK)
'NoneType' object has no attribute 'get'

Running sudo slack-watchman --financial --timeframe a

Importing rules...
40 rules loaded
Searching financial data
Searching for posts containing IBAN Numbers
'NoneType' object has no attribute 'get

Running sudo slack-watchman --tokens --timeframe a

Importing rules...
40 rules loaded
Searching tokens
Searching for posts containing Client Secrets
'NoneType' object has no attribute 'get'

Any Ideas on how to fix?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.