From b651efa4261d3b1654995293e11e4a0973b1790b Mon Sep 17 00:00:00 2001 From: xmjp Date: Wed, 17 Jul 2024 11:11:11 -0500 Subject: [PATCH 01/11] added slack sdk to requirements.txt --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 8adfc4c..3223a2b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ scapy @ https://github.com/secdev/scapy/archive/refs/heads/master.zip requests==2.32.2 discord-webhook -urllib3>=2.2.2 # not directly required, pinned by Snyk to avoid a vulnerability \ No newline at end of file +urllib3>=2.2.2 # not directly required, pinned by Snyk to avoid a vulnerability +slack_sdk \ No newline at end of file From db52a19f40b134c710c73d49e0617af26bedd5a5 Mon Sep 17 00:00:00 2001 From: xmjp Date: Wed, 17 Jul 2024 11:11:43 -0500 Subject: [PATCH 02/11] drafted slack webhook --- utils/slack.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 utils/slack.py diff --git a/utils/slack.py b/utils/slack.py new file mode 100644 index 0000000..c6d5bc5 --- /dev/null +++ b/utils/slack.py @@ -0,0 +1,17 @@ +from slack_sdk import WebClient +from slack_sdk.errors import SlackApiError +import time + +def send_slack_message(webhook_url, title, details): + client = WebClient(token=webhook_url) + response = client.chat_postMessage( + text=f"{title}\n{details}" + ) + if response['ok']: + print("Message sent successfully") + if e.response.status_code == 429: + # Slack rate limits to one message per channel per second, with short bursts of >1 allowed + retry_after = int(e.response.headers['Retry-After']) + print(f"Rate limited. Retrying in {retry_after} seconds") + time.sleep(retry_after) + send_slack_message(webhook_url, title, details) \ No newline at end of file From d56262bf3564ae78f39912adf9bc7c21321ea498 Mon Sep 17 00:00:00 2001 From: xmjp Date: Wed, 17 Jul 2024 11:15:20 -0500 Subject: [PATCH 03/11] added response status code --- utils/slack.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/slack.py b/utils/slack.py index c6d5bc5..e3b1f37 100644 --- a/utils/slack.py +++ b/utils/slack.py @@ -14,4 +14,6 @@ def send_slack_message(webhook_url, title, details): retry_after = int(e.response.headers['Retry-After']) print(f"Rate limited. Retrying in {retry_after} seconds") time.sleep(retry_after) - send_slack_message(webhook_url, title, details) \ No newline at end of file + send_slack_message(webhook_url, title, details) + else : + print(f"Failed to send message: {e.response.status_code}") \ No newline at end of file From f8b0c4986767f55aac766bcd384984e55f41cb47 Mon Sep 17 00:00:00 2001 From: xmjp Date: Wed, 17 Jul 2024 11:42:53 -0500 Subject: [PATCH 04/11] added send_slack_message function --- respotter.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/respotter.py b/respotter.py index 7f5443b..6199775 100644 --- a/respotter.py +++ b/respotter.py @@ -15,6 +15,7 @@ from time import sleep from utils.teams import send_teams_message from utils.discord import send_discord_message +from utils.slack import send_slack_message import logging import logging.config import logging.handlers @@ -112,6 +113,9 @@ def webhook_responder_alert(self, responder_ip): if "discord" in self.webhooks: send_discord_message(self.webhooks["discord"], title=title, details=details) self.log.info(f"[+] Alert sent to Discord for {responder_ip}") + if "slack" in self.webhooks: + send_slack_message(self.webhooks["slack"], title=title, details=details) + self.log.info(f"[+] Alert sent to Slack for {responder_ip}") self.responder_alerts[responder_ip] = datetime.now() with self.state_lock: with open("state/state.json", "r+") as state_file: From 98250cb719d952765e39cc35b77874ea493403c3 Mon Sep 17 00:00:00 2001 From: xmjp Date: Wed, 17 Jul 2024 11:44:26 -0500 Subject: [PATCH 05/11] added send_slack_message to sniffer alert --- respotter.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/respotter.py b/respotter.py index 6199775..b5f30f5 100644 --- a/respotter.py +++ b/respotter.py @@ -140,6 +140,9 @@ def webhook_sniffer_alert(self, protocol, requester_ip, requested_hostname): if "discord" in self.webhooks: send_discord_message(self.webhooks["discord"], title=title, details=details) self.log.info(f"[+] Alert sent to Discord for {requester_ip}") + if "slack" in self.webhooks: + send_slack_message(self.webhooks["slack"], title=title, details=details) + self.log.info(f"[+] Alert sent to Slack for {requester_ip}") if requester_ip in self.vulnerable_alerts: self.vulnerable_alerts[requester_ip][protocol] = datetime.now() else: From 0969d57f2b69e43362c835b22db281e0abf3723a Mon Sep 17 00:00:00 2001 From: xmjp Date: Wed, 17 Jul 2024 11:51:13 -0500 Subject: [PATCH 06/11] changed to webhook client --- utils/slack.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/slack.py b/utils/slack.py index e3b1f37..2df6101 100644 --- a/utils/slack.py +++ b/utils/slack.py @@ -1,9 +1,9 @@ -from slack_sdk import WebClient +from slack_sdk import WebhookClient from slack_sdk.errors import SlackApiError import time def send_slack_message(webhook_url, title, details): - client = WebClient(token=webhook_url) + client = WebClient(webhook_url) response = client.chat_postMessage( text=f"{title}\n{details}" ) From 432d838456962712bbba1bcd61ab82b57fcdeda6 Mon Sep 17 00:00:00 2001 From: xmjp Date: Wed, 17 Jul 2024 11:52:15 -0500 Subject: [PATCH 07/11] changed to client.send --- utils/slack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/slack.py b/utils/slack.py index 2df6101..56d677a 100644 --- a/utils/slack.py +++ b/utils/slack.py @@ -4,7 +4,7 @@ def send_slack_message(webhook_url, title, details): client = WebClient(webhook_url) - response = client.chat_postMessage( + response = client.send( text=f"{title}\n{details}" ) if response['ok']: From 7066d7ff007897ada900ff8e1027702cdd9cfae5 Mon Sep 17 00:00:00 2001 From: xmjp Date: Wed, 17 Jul 2024 11:53:41 -0500 Subject: [PATCH 08/11] fixed webhook client error --- utils/slack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/slack.py b/utils/slack.py index 56d677a..5e8b308 100644 --- a/utils/slack.py +++ b/utils/slack.py @@ -3,7 +3,7 @@ import time def send_slack_message(webhook_url, title, details): - client = WebClient(webhook_url) + client = WebhookClient(webhook_url) response = client.send( text=f"{title}\n{details}" ) From 166508565fb6228a10ddbf14a2f9a995b11a75b9 Mon Sep 17 00:00:00 2001 From: xmjp Date: Wed, 17 Jul 2024 11:57:03 -0500 Subject: [PATCH 09/11] changed response status codes --- utils/slack.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/slack.py b/utils/slack.py index 5e8b308..3fa96fe 100644 --- a/utils/slack.py +++ b/utils/slack.py @@ -7,9 +7,9 @@ def send_slack_message(webhook_url, title, details): response = client.send( text=f"{title}\n{details}" ) - if response['ok']: + if response.status_code == 200: print("Message sent successfully") - if e.response.status_code == 429: + if response.status_code == 429: # Slack rate limits to one message per channel per second, with short bursts of >1 allowed retry_after = int(e.response.headers['Retry-After']) print(f"Rate limited. Retrying in {retry_after} seconds") From 7aaeb3bc557ca206acf17bafa111a7911138cc01 Mon Sep 17 00:00:00 2001 From: xmjp Date: Wed, 17 Jul 2024 12:01:18 -0500 Subject: [PATCH 10/11] fixed error handling --- utils/slack.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/utils/slack.py b/utils/slack.py index 3fa96fe..19cf495 100644 --- a/utils/slack.py +++ b/utils/slack.py @@ -4,16 +4,20 @@ def send_slack_message(webhook_url, title, details): client = WebhookClient(webhook_url) - response = client.send( - text=f"{title}\n{details}" - ) - if response.status_code == 200: - print("Message sent successfully") - if response.status_code == 429: - # Slack rate limits to one message per channel per second, with short bursts of >1 allowed - retry_after = int(e.response.headers['Retry-After']) - print(f"Rate limited. Retrying in {retry_after} seconds") - time.sleep(retry_after) - send_slack_message(webhook_url, title, details) - else : - print(f"Failed to send message: {e.response.status_code}") \ No newline at end of file + try: + response = client.send( + text=f"{title}\n{details}" + ) + if response.status_code == 200: + print("Message sent successfully") + except SlackApiError as e: + if e.response.status_code == 429: + # Slack rate limits to one message per channel per second, with short bursts of >1 allowed + retry_after = int(e.response.headers['Retry-After']) + print(f"Rate limited. Retrying in {retry_after} seconds") + time.sleep(retry_after) + response = client.send( + text=f"{title}\n{details}" + ) + else : + print(f"Failed to send message: {e.response.status_code}") \ No newline at end of file From ff576f4ab095e3dc63dace3c694f1ad1ea0e6a4e Mon Sep 17 00:00:00 2001 From: "C.J. May" Date: Wed, 17 Jul 2024 17:25:45 +0000 Subject: [PATCH 11/11] use block formatting --- utils/slack.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/utils/slack.py b/utils/slack.py index 19cf495..baefd29 100644 --- a/utils/slack.py +++ b/utils/slack.py @@ -6,7 +6,21 @@ def send_slack_message(webhook_url, title, details): client = WebhookClient(webhook_url) try: response = client.send( - text=f"{title}\n{details}" + text=f"{title}\n{details}", + blocks=[ + { + "type": "image", + "image_url": "https://raw.githubusercontent.com/lawndoc/Respotter/main/assets/respotter_logo.png", + "alt_text": "Respotter" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": f"_*{title}*_\n\n{details}", + } + } + ] ) if response.status_code == 200: print("Message sent successfully")