Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hacking Mattermost: An Assessment of an Open So...

Hacking Mattermost: An Assessment of an Open Source Messaging Platform for Hipsters (Security Fest 2016)

As presented at Security Fest, Gothenburg, Sweden, June 2nd, 2016.

Andreas Lindh

June 13, 2016
Tweet

Other Decks in Technology

Transcript

  1. Hacking Mattermost An Assessment of an Open Source Messaging Platform

    for Hipsters Andreas Lindh, @addelindh, [email protected] Security Fest 2016
  2. $ whoami  Security consultant at Recurity Labs  Located

    in Gothenburg  Web, mobile, embedded  Previously I Secure/Coresec, Volvo  @addelindh on Twitter
  3. Outline  Background / about Mattermost  Platform  Features

    & functionality  Desktop client  Conclusions
  4. Background  The “Hacking Open Source Software for Fun and

    Non-Profit” project*  Somewhat foolishly, I took a request  You won’t believe what happened next... *http://haxx.ml/post/137946990286/hacking-open-source-software-for-fun-and
  5. About Mattermost  “Self-hosted Slack-alternative”  Company funded by Y

    Combinator  Open source – MIT License  Team and Enterprise editions  Built on modern technologies – Golang, React.js, Node.js  New release monthly (16th)
  6. Why audit it?  What part of “Messaging Platform” don’t

    you understand? :)  Exposed by design  Rapidly growing user base  Interesting use cases (SaaS?)  Open Source  Provide info for those considering using it
  7. Platform  Web GUI is static HTML + React.js 

    Backend/API written in Golang – One Linux ELF binary + static resources  All business logic in the API  MySQL or PostgreSQL database  Mobile and desktop apps – Android, iOS, Windows, OS X, Linux
  8. Brief Golang primer  Open source language by Google 

    Compiled but “memory safe” – No manual memory management, etc.  Runtime built-in  Designed with security in mind – Context-based output encoding – Secure standard libraries – No “easy” path to dynamic execution
  9. API  Basic RESTful JSON web service  /api/v1/ +

    logical area + endpoint  Access model well implemented  No injection vulnerabilities (?)  Some team-related information leaks  Fairly clean with some legacy/redundant functionality
  10. Access control  Multiple Sign-In methods – Local DB (email/username

    + password) – GitLab OAuth Single Sign-On – LDAP (enterprise edition) – Multi-factor (enterprise edition, v3.0)  Hardcoded minimum password length
  11. Access control  Session cookies protected by HttpOnly  Effectively

    undone by Access History view – Session ID can be used as cookie!
  12. Invites  Any team member can invite new ones 

    Somewhat configurable – Restrict to specific domains – Require email verification – Limit to SSO service (OAuth/LDAP)  Two methods – Direct Invite (email from system) – Team Invite Link (more interesting)
  13. Team Invite Link  Access to id means unauthorized sign-up

     The value of id is static – can be leaked?
  14. Sign-in flow  POST to /api/v1/users/login – Payload: {"name":"suchteam","email":"[email protected]","passw ord":"passw0rd"}

     POST to /api/v1/teams/find_teams – Payload: {"email":"[email protected]"} – Returns team data, including Invite ID – Can be called unauthenticated  Only pre-req: team member’s email/username
  15. User roles  Member – Default role, basic privileges 

    Team Admin – Manage team settings and members  System Admin – Manage system settings through System Console  Admins are Members too – No access to other users’ private channels, DMs, etc. – Except in this one particular case…
  16. Forgotten functionality  Source code contains export.go file  No

    export functionality in sight  Hmmm…  Looks promising...
  17. Forgotten functionality  GET /api/v1/teams/export_team – Triggers export – Returns

    {"link":"/api/v1/files/get_export"}  GET /api/v1/files/get_export – Returns ZIP file with exported data for ALL teams – Chat messages, team invite IDs, etc.  Can be triggered by any Team Admin – Local and cross-team information leak
  18. Crypto  No native transport encryption – nginx reverse proxy

    officially recommended  Passwords stored as bcrypt hashes  Chat messages stored in clear text  Shared files stored as-is on file system  Crypto used in “interesting” ways…
  19. Pass the salt please  Several static salts used for

    “signing” – Invite salt – Public link salt – Password reset salt  Accessible in the System Console – For System Admins only
  20. Pass the salt please  Password reset URL example: –

    http://192.168.1.54:8065/suchteam/reset_password? d={"time":"1462383751298","user_id":"55u99xsze7fc9y gs7d9zgqwhjh"}&h=$2a$10$L9yhcWMoS4qY.wSxJx/i JO77xZcGiFP.XDkwZEyJrH7M7eUkqx.am  The value of d is known/predictable  bcrypt hash (h) is generated by: – bcrypt(value_of_d + “:” + password_reset_salt)  Hmmm… But why?
  21. Pass the salt please  Password reset hashes are not

    stored – Any bcrypt hash will be accepted as long as it matches d + password reset salt – Cost factor can be reduced to 4!  The “time” value of d can be set arbitrarily  Knowing the password reset salt => reset any user’s password
  22. Messaging  Channels – Open (any member can join) –

    Private (invite only)  Direct Messages – Two or more members  Threaded messaging  Slash commands  Rich formatting (some minor bugs here)
  23. File sharing  Upload attachment to post  No file

    type restrictions – Preview functionality for common file types  Stored as-is under folder path based on: – Channel ID – Uploading user’s ID – Random string  Access to files is well protected
  24. File sharing  Example URL to uploaded file: – http://192.168.2.9:8065/api/v1/files/get/e1objp7t3ift8dq1

    s37zh35fmc/r5kcfatee7d6zfnjjiss9xwn1c/geb8dieqhib43 g3u9bedqiqn1o/hello.html? session_token_index=0&download=1  Downloads the file as an attachment – Content-Disposition: attachment;filename="hello.html”  What happens if the value of download is 0? – Or just remove the query string – HTML executes!
  25. Desktop client  Windows, OS X, Linux  Runs on

    Node.js – Engine for running JavaScript on the server – Not the same restrictions as in a browser  Mostly just emulates a browser – Uses cookies – Local config, HTML, and JS files  Not much to see here… Or?
  26. Desktop client  Desktop client URL handling (index.jsx)  Opens

    internal URL in client, external in browser  Get client to execute untrusted HTML => RCE! – But how..?
  27. Conclusions  Version 3.0 released May 16th – Proper use

    of crypto – New, cleaner API version – Better team separation – No sensitive data in System Console  Root cause analysis over single fixes  Potential improvements – Optional database encryption – Team separation on database level