-
Notifications
You must be signed in to change notification settings - Fork 385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[OSCD Initiative] Develop Responder for Gmail #859
Comments
I would implement this responder. @yugoslavskiy do you have some hints if the API is the same for G Suite and private GMail? |
OK. If I understood correctly everything is based on the OAuth 2.0 Authentication / Authorization. So the API is the same for GSuite/Google Workplace and a private Gmail Account. According to
Apps can be given a service account which authenticates via OAuth 2.0. This service account is able to connect to G Suite / Google Workspace data without individual user consent. Otherwise users must authorize the app access to their data. OAuth 2.0 authorizes actions via scopes. The valid Gmail scopes can be under https://developers.google.com/identity/protocols/oauth2/scopes#gmail. For the feature we might need the following scopes:
The API endpoint It shall be mentioned, that Gmail also has usage limites for the Gmail API: https://developers.google.com/gmail/api/reference/quota
The responders per-method cost is as follows:
By the nature of this responder I do not think any rate limit issues will arise. |
Just found out, that interaction with the Gmail API in this case needs a service account. A normal OAuth 2.0 Flow is not going to work. Here is a link to the documentation how to create a service account : https://support.google.com/a/answer/7378726?hl=en |
I'm currently stuck on this issue googleapis/google-api-nodejs-client#2322. Since I do not have a G Suite account I cannot delegate the service account. Working as a real user might be quite inconvenient. Maybe the respondere could return a OAuth 2.0 URL for the analyst but I'm not sure if this is helping a lot. |
Hello @strassi ! Thank you for your contribution! |
Hello @strassi ! Sorry for the long answers. Lot's of Sigma rules were contributed since Monday. |
I basically need OAuth2 to work. I created this gist https://gist.github.com/strassi/326edd3193e0cf3ea8db3198b09131cc with the authentication method in the responder. If you could get it to work, this would already help a lot. |
@yugoslavskiy if we talk about deleting an email, can I assume an analyst does have the message id of the email in question? Otherwise I need to search the email based on some specified parameters. This could be from, subject, body strings etc. |
Hello @strassi! I am sorry for the delays, too many tasks.... |
Here are the updates:
no results. still have the same:
I think it could be related to the authorization timeout: So let's see how it will go tomorrow. |
@strassi I can also help with this one and give it a go to your code snipped.
I think it makes sense to assume the analyst will have the message id though. |
@alejandroortuno Yeah I also think an analyst does have a message id, but it has the disadvantage of not being able to delete phishing messages via a bulk operation. Proposal
Filtering messages
Deleting Message
A disadvantage of working with a single message_id is, that you can't perform a bulk delete operation for many We could also operate like this:
This responder might be used on phishing cases, so I imagined it might me useful if operations could always be carried out in bulk. @alejandroortuno @yugoslavskiy any thoughts or additional ideas on this? |
Hello guys! Today I've tried to authorize on Gmail API for 6 hours and didn't succeed. It seems that there is something that I am missing. Need some help with it. Does anyone else have access to Gsuite? |
Code snipped seems fine. @yugoslavskiy did you perform the steps for the https://github.com/googleapis/google-api-python-client/blob/master/docs/oauth-server.md#delegating-domain-wide-authority-to-the-service-account as the app will be accessing the user inboxes so this is a required steps. This requires a GSuite enterprise account which I am not in possession for personal purposes. An idea is we can get in contact with GSuite to get into their enterprise solutions with some of their non-profit programs https://edu.google.com/products/gsuite-for-education/enterprise/ to get us unlocked. @strassi your proposal looks good! |
Hello @alejandroortuno! Yep, I performed them. |
I now pushed a first implementation into my forked repository. Service files need to be updated and the authentication is still missing. Maybe I can get a trail of Gsuite and get a service account working. Sry for breaking the sprint timeframe, but I had multiple things get in my way these two weeks. |
Hello @strassi! No worries, you didn't break anything. We will finalize existing PRs and everything which is WIP. Technically the sprint ended yesterday, but that's totally fine (: Last year we've been finalizing results for 4 months (: So it's fine, we have plenty of time to find somebody with Gsuit account and properly test the responder. Thank you very much for your contribution, @strassi! And sorry that I didn't participate much. Lots of work at the moment... |
I've used this in the past to get the audit logs, I imagine it should be similar at least from an auth perspective:
The key difference here is that you aren't including an account to impersonate. A way to think about it is that the service account is only performing authentication, while the impersonation account has the authorization IIRC. edit - oh didn't see your |
Yes, this code looks pretty much like my implementations. To manipulate the mailbox of a user one must use the service account credentials and a domain wide delegation. credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, subject='[email protected]', scopes=SCOPES)
# get delegation for each gmail account
credentials.with_subject("[email protected]")
gmail_service = build("gmail", "v1", credentials=credentials)
result = gmail_service.users().messages().trash(userId=observable, id=message_id).execute() I would love to test this and get a working Gsuite environment to test this responder. Since I'm not a professional developer I need my short and fast trail and error feedback loops 😄 |
I created a Gsuite trail account. I followed the guideline and it did not work. you basically need to
The authentication works now. Maybe it didn't work for @yugoslavskiy because of an error in my snippet: credentials = service_account.Credentials.from_service_account_file(
service_account_file,
scopes=scopes,
subject=subject
)
if (credentials.valid) and (credentials.has_scopes(scopes)):
return credentials
else:
return None The credentials are not valid until they are refreshed. The refresh gets you an oauth token which sets the print(credentials.valid) # is false
my_emails = gmail_service.users().messages().list(userId=subject).execute()
print(credentials.valid) # is true |
Thank you, @tuckner, @strassi! You guys ROCK! Finally, from google.oauth2 import service_account
from googleapiclient.discovery import build
SUBJECT = "[email protected]"
SCOPES = [ "https://mail.google.com/", "https://www.googleapis.com/auth/gmail.settings.basic"]
SERVICE_ACCOUNT_FILE = "/path/to/credentials.json"
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, subject=SUBJECT, scopes=SCOPES)
gmail_service = build("gmail", "v1", credentials=credentials)
my_emails = gmail_service.users().messages().list(userId=SUBJECT).execute()
print(credentials.valid) And this way I moved the messages from query = "from:[email protected]"
response = gmail_service.users().messages().list(userId=SUBJECT,q=query).execute()
for message in response['messages']:
gmail_service.users().messages().trash(userId=SUBJECT, id=message['id']).execute() And permanently deleted them using the following: for message in response['messages']:
gmail_service.users().messages().delete(userId=SUBJECT, id=message['id']).execute() I believe that deleting is our case, but we could develop the responder with both options. Now we need to figure out how to remove specific email from all users' mailboxes. |
I pushed some new code with updated authentication into my fork At the moment I'm fixing bugs on thehive observable updates (like tagging gmail adresses with their filter ids). The ground work on the blocking, unblocking and deleting of messages is done. Support for custom gmail domains has also been implemented. |
Alright I think it is working (at least in my tests xD). I implemented the responder with bulk operations in mind. The responder behaves as follows:
My fork should be ready to run. Maybe some of you guys can run some test cases and report bugs here if you find one. |
Feature description
Responder for Gmail that would be able to execute the following Response Actions:
Describe the solution you'd like
It could be done via Gmail API using the following methods:
The text was updated successfully, but these errors were encountered: