Skip to content
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 Duo Security; fix #857 #964

Merged
merged 9 commits into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ steps:
when:
event: [tag]

- name: build report-templates zip package
image: thehiveproject/neurons-build-report-templates
when:
event: [tag]


# Bintray will not be used anymore. We keep it until Feb 21

- name: upload catalogs to bintray
image: thehiveproject/drone-bintray
settings:
Expand Down Expand Up @@ -91,7 +99,32 @@ steps:
when:
event: [tag]

- name: upload catalogs to package server
- name: upload report-templates to bintray
image: thehiveproject/drone-bintray
settings:
user: {from_secret: bintray_user}
key: {from_secret: bintray_key}
subject: thehive-project
package: report-templates
version: latest
override: 1
publish: 1
commands:
- |
export PLUGIN_USER
export PLUGIN_KEY
export PLUGIN_SUBJECT
export PLUGIN_PACKAGE
export PLUGIN_VERSION
export PLUGIN_OVERRIDE
export PLUGIN_PUBLISH
upload \
--file analyzers/report-templates.zip \
--repo binary
when:
event: [tag]

- name: upload catalogs and report-templates package to package server
image: appleboy/drone-scp
settings:
host: {from_secret: package_host}
Expand All @@ -103,6 +136,7 @@ steps:
- analyzers/analyzers-stable.json
- responders/responders.json
- responders/responders-stable.json
- analyzers/report-templates.zip
strip_components: 1
when:
event: [tag]
Expand All @@ -112,6 +146,8 @@ steps:
when:
branch: [develop]


# Bintray will not be used anymore. We keep it until Feb 21
- name: upload devel catalogs to bintray
image: thehiveproject/drone-bintray
settings:
Expand Down
1 change: 1 addition & 0 deletions analyzers/MISPWarningLists/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ ipaddress
tld
sqlalchemy
psycopg2-binary
tqdm
2 changes: 1 addition & 1 deletion analyzers/MISPWarningLists/warninglists_create_db.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# coding: utf-8

import re
Expand Down
1 change: 1 addition & 0 deletions analyzers/Splunk/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
splunk-sdk
cortexutils
3 changes: 2 additions & 1 deletion analyzers/URLhaus/URLhaus_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ def summary(self, raw):
namespace = "URLhaus"

if raw['query_status'] == 'no_results' \
or raw['query_status'] == 'ok' and raw['md5_hash'] == None and raw['sha256_hash'] == None:
or (raw['query_status'] == 'ok' and not raw.get('md5_hash', None) \
and not raw.get('sha256_hash', None)):
taxonomies.append(self.build_taxonomy(
'info',
namespace,
Expand Down
Binary file added responders/Duo_Security/AddObservableType.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions responders/Duo_Security/DuoLockUserAccount.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "DuoLockUserAccount",
"version": "1.0",
"author": "Sven Kutzer / Gyorgy Acs, @oscd_initiative",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "AGPL-V3",
"description": "Lock User Account in Duo Security via AdminAPI (The user will not be able to log in)",
"dataTypeList": ["thehive:case_artifact"],
"command": "Duo_Security/duoLockUserAccount.py",
"baseConfig": "Duo_Security_main",
"configurationItems": [
{
"name": "API_hostname",
"description": "Duo Admin API hostname, api-XXXXXXXX.duosecurity.com",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Integration_Key",
"description": "Integration Key",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Secret_Key",
"description": "Secret Key",
"type": "string",
"multi": false,
"required": true
}
]
}
34 changes: 34 additions & 0 deletions responders/Duo_Security/DuoUnlockUserAccount.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "DuoUnlockUserAccount",
"version": "1.0",
"author": "Sven Kutzer / Gyorgy Acs, @oscd_initiative",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "AGPL-V3",
"description": "Unlock User Account in Duo Security via AdminAPI (The user must complete secondary authentication)",
"dataTypeList": ["thehive:case_artifact"],
"command": "Duo_Security/duoUnlockUserAccount.py",
"baseConfig": "Duo_Security_main",
"configurationItems": [
{
"name": "API_hostname",
"description": "Duo Admin API hostname, api-XXXXXXXX.duosecurity.com",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Integration_Key",
"description": "Integration Key",
"type": "string",
"multi": false,
"required": true
},
{
"name": "Secret_Key",
"description": "Secret Key",
"type": "string",
"multi": false,
"required": true
}
]
}
31 changes: 31 additions & 0 deletions responders/Duo_Security/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# CortexResponder_DuoUserAccount
Rep. for Cortex Responder (TheHive project - https://github.com/TheHive-Project/CortexDocs)
to Lock/Unlock User Accounts in the Duo Admin Portal (Cisco Security)


There are two Responder available in order to change the status of a User in Duo Security via the AdminAPI (https://duo.com/docs/adminapi)

**DuoLockUserAccount** -> changes the "status" to “disabled” - The user will not be able to log in.

**DuoUnlockUserAccount** -> changes the "status" to “active” - The user must complete secondary authentication.

The Responder is looking for a "**username**" as input and queries the Duo Admin API, to receive the associated UserID.
The UserID is used to change the "status" of the particular user.

## How to install:
* copy the folders "DuoLockUserAccount" & "DuoUnlockUserAccount" into your Cortex responders path
* install necessary python modules from the requirements.txt (**pip install -r requirements.txt**)
* restart Cortex to initialize the new Responder "**systemctl restart cortex**"
* add the ResponderConfig
* ![ResponderConfig](ResponderConfig.jpg)
* enable the Responder Actions
* ![Responders](Responders.jpg)

## Add Observable type in TheHive**
* per default TheHive has no "username" Observable type, so we have to add this in the Admin settings
* ![AddObservableType](AddObservableType.jpg)

## Run the Responder action in TheHive

If you have add an observable, you can now take action and lock/unlock the User in Duo Security
* ![Demo_Lock-Unlock_DuoUser](Demo_Lock-Unlock_DuoUser.gif)
Binary file added responders/Duo_Security/ResponderConfig.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added responders/Duo_Security/Responders.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions responders/Duo_Security/duoLockUserAccount.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
# encoding: utf-8

from cortexutils.responder import Responder
import requests
import duo_client
from datetime import datetime

class DuoLockUserAccount(Responder):
def __init__(self):
Responder.__init__(self)
self.API_hostname = self.get_param('config.API_hostname', None, "API hostname is missing")
self.iKey = self.get_param('config.Integration_Key', None, "Integration Key is missing")
self.sKey = self.get_param('config.Secret_Key', None, "Secret Key is missing")

def run(self):
Responder.run(self)

if self.get_param('data.dataType') == 'username':

str_username = self.get_param('data.data', None, 'No artifacts available')

admin_api = duo_client.Admin(self.iKey, self.sKey, self.API_hostname)

response = admin_api.get_users_by_name(username=str_username)

# print(response)

user_id=response[0]["user_id"]

# print("user_id:",user_id)

r = admin_api.update_user(user_id=user_id,status='disabled')

# print("response:",r)

if r.get('status') == 'disabled':
self.report({'message': 'User is locked in Duo Security.'})
else:
self.error('Failed to lock User Account in Duo.')
else:
self.error('Incorrect dataType. "username" expected.')

def operations(self, raw):
return [self.build_operation('AddTagToArtifact', tag='Duo User: locked')]

if __name__ == '__main__':
DuoLockUserAccount().run()
48 changes: 48 additions & 0 deletions responders/Duo_Security/duoUnlockUserAccount.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
# encoding: utf-8

from cortexutils.responder import Responder
import requests
import duo_client
from datetime import datetime

class DuoUnlockUserAccount(Responder):
def __init__(self):
Responder.__init__(self)
self.API_hostname = self.get_param('config.API_hostname', None, "API hostname is missing")
self.iKey = self.get_param('config.Integration_Key', None, "Integration Key is missing")
self.sKey = self.get_param('config.Secret_Key', None, "Secret Key is missing")

def run(self):
Responder.run(self)

if self.get_param('data.dataType') == 'username':

str_username = self.get_param('data.data', None, 'No artifacts available')

admin_api = duo_client.Admin(self.iKey, self.sKey, self.API_hostname)

response = admin_api.get_users_by_name(username=str_username)

# print(response)

user_id=response[0]["user_id"]

# print("user_id:",user_id)

r = admin_api.update_user(user_id=user_id,status='active')

# print("response:",r)

if r.get('status') == 'active':
self.report({'message': 'User is unlocked in Duo Security. The user must complete secondary authentication.'})
else:
self.error('Failed to unlock User Account in Duo.')
else:
self.error('Incorrect dataType. "username" expected.')

def operations(self, raw):
return [self.build_operation('AddTagToArtifact', tag='Duo User: reactivated')]

if __name__ == '__main__':
DuoUnlockUserAccount().run()
4 changes: 4 additions & 0 deletions responders/Duo_Security/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cortexutils
requests
datetime
duo_client