Documentation
¶
Index ¶
- Constants
- Variables
- type ChannelInfo
- type ChannelSearch
- type ClientInfo
- type Config
- type ConversationItem
- type ConversationMessage
- type ConversationsHistory
- type ConversationsView
- type Emoji
- type EmojiList
- type EmojiPages
- type FileItem
- type FileSearch
- type InfoItem
- type MessageItem
- type MessageSearch
- type Pages
- type ProfileInfo
- type PurposeInfo
- type SearchMessageItem
- type Smack
- func (s *Smack) DownloadAll(fi []FileItem, directory string) error
- func (s *Smack) DownloadFile(i FileItem, location string) (int64, error)
- func (s *Smack) GetChannelList(token, query string, private bool) ([]ConversationItem, error)
- func (s *Smack) GetClientBoot(token string) (ClientInfo, error)
- func (s *Smack) GetConversationHistory(token, convId string, limit int) ([]ConversationMessage, error)
- func (s *Smack) GetConversationInfo(token, convId string) (ConversationsView, error)
- func (s *Smack) GetEmojiInfo(token string) (EmojiList, error)
- func (s *Smack) GetFileList(token, query string) ([]FileItem, error)
- func (s *Smack) GetMessageSearchList(token, query string) ([]SearchMessageItem, error)
- func (s *Smack) SetHeaders(hs map[string]string)
- type TeamItem
- type TopicInfo
Constants ¶
const ( // all, file, post, email, snippet, image, zip, pdf, gdoc, google, gdraw, gpres, and gsheet FileFilterAll = "type:all" FileFilterPDF = "type:pdf" FileFilterFile = "type:file" FileFilterPost = "type:post" FileFilterEmail = "type:email" FileFilterSnippet = "type:snippet" FileFilterImage = "type:image" FileFilterZip = "type:zip" )
These are all the filters that are "supported" by Slack for search filters for files
Variables ¶
var ( APIBoot = "/api/client.boot" APIEmojiAdd = "/api/emoji.add" APIEmojiList = "/api/emoji.adminList" APISearch = "/api/search.modules" APIConversationsView = "/api/conversations.view" APIConversationsHistory = "/api/conversations.history" )
The Slack "private" API endpoints are only ever interacted with from the UIs like the web client or node/electron client. These are the endpoints that were used for the functionality that is needed
Functions ¶
This section is empty.
Types ¶
type ChannelInfo ¶
type ChannelInfo struct { Id string IsChannel bool `json:"is_channel"` IsIm bool `json:"is_im"` Name string User string }
Channel information TODO this can probably be added to the other types
type ChannelSearch ¶
type ChannelSearch struct { Pagination Pages Items []ConversationItem }
Search results for channels, these are paginated and contain multiple items
type ClientInfo ¶
type ClientInfo struct { Ok bool Channels []ConversationItem Info InfoItem `json:"self"` Team TeamItem `json:"team"` }
Client information from the boot API endpoint
type Config ¶
type Config struct { UserAgent string Authority string BCookie string DCookie string XCookie string Token string URL string }
Smack configuration settings
type ConversationItem ¶
type ConversationItem struct { Id string IsMember bool `json:"is_member"` IsPrivate bool `json:"is_private"` IsStarred bool `json:"is_starred"` IsArchived bool `json:"is_archived"` IsGroup bool `json:"is_group"` IsChannel bool `json:"is_channel"` Latest string MemberCount int `json:"member_count"` Members []string History []ConversationsHistory Purpose PurposeInfo Topic TopicInfo Name string }
Group, Channel, and potentially other types of messages are returned through the conversation api and contain information on the channel or group message. This can also potentially contain conversation history.
type ConversationMessage ¶
type ConversationMessage struct { Team string Text string Timestamp string `json:"ts"` Type string User string }
Messages from the conversation endpoint return information on the type of message, the user that posted it, when it was posted, and the content itself
type ConversationsHistory ¶
type ConversationsHistory struct { Ok bool More bool `json:"has_more"` Messages []ConversationMessage }
History information that contains a list of messages from the conversations.view
type ConversationsView ¶
type ConversationsView struct { Ok bool Channel ConversationItem Users []InfoItem History ConversationsHistory Group ConversationItem }
Core structure for the conversations view API enpdoint. The structure of the actual response is surprisingly inconsistent and the specific populated fields change depend on some of the multi-part requests. So error checking and empty value validation should be done by anyone consuming these types, they should never be expected to exist.
type EmojiList ¶
type EmojiList struct { Ok bool Count int `json:"custom_emoji_total_count"` Pagination EmojiPages `json:"paging"` EmojiList []Emoji `json:"emoji"` }
type EmojiPages ¶
type FileItem ¶
type FileItem struct { Name string ID string Permalink string PrivateDownloadURL string `json:"url_private_download"` PrivateURL string `json:"url_private"` PrettyPrint string `json:"pretty_print"` User string Filetype string Mimetype string Size int }
File search result information
type FileSearch ¶
Response from the search API containing the pagination information and results
type InfoItem ¶
type InfoItem struct { Id string IsAdmin bool `json:"is_admin"` IsApp bool `json:"is_app_user"` IsBot bool `json:"is_bot"` IsOwner bool `json:"is_owner"` Username string `json:"name"` Name string `json:"real_name"` Profile ProfileInfo }
Information on the client that is making the request. This can hold valuable information such as if the account is an admin, bot, owner, profile information, etc.
type MessageItem ¶
type MessageItem struct { Extracts string Iid string Text string User string Timestamp string `json:"ts"` Username string }
Information on the message match
type MessageSearch ¶
type MessageSearch struct { Pagination Pages Items []SearchMessageItem }
Results from a search containing matching search matches
type Pages ¶
type Pages struct { Count int `json:"total_count"` PerPage int `json:"per_page"` PageCount int `json:"page_count"` First int Last int }
Pagination information
type ProfileInfo ¶
type ProfileInfo struct { DisplayName string `json:"display_name"` Email string FirstName string `json:"first_name"` LastName string `json:"last_name"` Phone string Skype string Title string }
The profile information contains the personal data of the user.
type PurposeInfo ¶
Channel purpose information
type SearchMessageItem ¶
type SearchMessageItem struct { Messages []MessageItem `json:"messages"` Channel ChannelInfo `json:"channel"` }
The matching messages and channel information
type Smack ¶
type Smack struct { //TODO slack throttling Request *http.Request Headers map[string]string URL string Token string Log log.Logger }
Smack takes Slack client API tokens and cookies and allows for a set of pentest focused functions to be called that can assist with exfiltration of sensitive data or even persistence mechanisms. The goal is to allow for automatic extraction of browser tokens and triggering of Smack for quick sensitive data exposure.
func NewRequest ¶
Create a new HTTP request and prepare headers for use with other utilities
func ReadConfig ¶
Read JSON configuration files. See examples/ directory
func (*Smack) DownloadAll ¶
Download all files from an array of FileItem's and place them into a directory. When downloading all Smack prepends the document ID to the filename before writing to disk to allow for name collisions without overriding.
func (*Smack) DownloadFile ¶
Download a file based on the FileItem information and the location to place the file. If successful the request will return the size of the downloaded file.
func (*Smack) GetChannelList ¶
func (s *Smack) GetChannelList(token, query string, private bool) ([]ConversationItem, error)
Get a list of channels. This can be refined to contain only matching search queries and if channels are marked private. This will make multiple requests due to interactive API pagination, and then return the final list of channels in an slice in whichever order the api returned the data
func (*Smack) GetClientBoot ¶
func (s *Smack) GetClientBoot(token string) (ClientInfo, error)
Retrieve the client information from the "boot" endpoint. This contains information about the hijacked tocken user including all their personal information, Slack settings, and permissions on the Slack server.
func (*Smack) GetConversationHistory ¶
func (s *Smack) GetConversationHistory(token, convId string, limit int) ([]ConversationMessage, error)
Get history of a conversation. If there are scrollbacks more than maximum paginadtion this will recurse until no more messages can be retrieved or the limit is reached.
func (*Smack) GetConversationInfo ¶
func (s *Smack) GetConversationInfo(token, convId string) (ConversationsView, error)
Retrieve information on a conversation, group chat, private message, or channel based on id. These can be retrieved from the Smack channel functions.
func (*Smack) GetFileList ¶
Retrieve a listing of files based on a Slack search query
func (*Smack) GetMessageSearchList ¶
func (s *Smack) GetMessageSearchList(token, query string) ([]SearchMessageItem, error)
Retrieve a list of messages that match a search query.
func (*Smack) SetHeaders ¶
Set the headers for Smack types
type TeamItem ¶
type TeamItem struct { Id string Name string EmailDomain string `json:"email_domain"` Domain string MessageCount int `json:"messages_count"` }
The team information will store data about the slack server and it's team. Slack seems to be moving away from the queries to each of them and to app.slack.com so this might become necessary in order to get the team inforId