diff --git a/Cylance/1.0.0/api.yaml b/Cylance/1.0.0/api.yaml index 48146a49..1b0abc44 100644 --- a/Cylance/1.0.0/api.yaml +++ b/Cylance/1.0.0/api.yaml @@ -1,6 +1,6 @@ app_version: 1.0.0 name: Cylance -description: An app to handle Cylance. Awful authentication. +description: An app to handle Cylance. contact_info: name: "@frikkylikeme" url: https://shuffler.io diff --git a/Docs/aws-iam.md b/Docs/aws-iam.md new file mode 100644 index 00000000..c071763a --- /dev/null +++ b/Docs/aws-iam.md @@ -0,0 +1,38 @@ +## AWS IAM App +Aws IAM (Identity and Access Management) app for managing IAM operations from the shuffle. + +![alt_text](https://github.com/dhaval055/Shuffle-apps/blob/master/Docs/iam.png?raw=true) + +## Actions + +| No. | Action | Description | Parameters | +|-----|--------|-------------|------------| +|1 | Get user | Retrieves information about the specified IAM user, including the user's creation date, path, unique ID, and ARN | access_key, secret_key, region, user_name +|2 | Change password | Change password of the specified user | access_key, secret_key, region, username, password +|3 | List users | Lists the IAM users | access_key, secret_key, region, path_prefix, marker, max_items +|4 | List user tags | Lists the tags that are attached to the specified IAM user | access_key, secret_key, region, user_name, marker, max_items +|5 | List attached user policies | Lists all managed policies that are attached to the specified IAM user | access_key, secret_key, region, user_name, marker, max_items +|6 | Attach user policy | Attach policy to the user | access_key, secret_key, region, username, policy_arn +|7 | Get instance profile | Retrieves information about the specified instance profile, including the instance profile's path, GUID, ARN, and role. | access_key, secret_key, region, instance_profile_name +|8 | List access keys | List all access keys | access_key, secret_key, region, username, marker, max_items +|9 | List ssh public keys | List SSH public keys | access_key, secret_key, region, username, marker, max_items + +__Note__: access_key, secret_key and region are used for authentication. + +## Requirements + +1. AWS account +2. Access key, Secret key and region of the user. + +- __How to find access key & secret key ?__ +1. Open https://console.aws.amazon.com/ +2. From navbar click on user dropwodown → My Security Credentials. +3. Open the Access keys tab, and then choose Create access key. +4. To see the new access key, choose Show. Your credentials resemble the following: + - Access key ID: AKIAIOSFODNN7EXAMPLE + - Secret access key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + + ## Note + Some actions have marker and max_items parameters (Both are used for paginating results). + - marker : Use this parameter only when paginating results and only after you receive a response indicating that the results are truncated. Set it to the value of the marker element in the response that you received to indicate where the next call should start. + - max_items : Use this only when paginating results to indicate the maximum number of items you want in the response. diff --git a/Docs/iam.png b/Docs/iam.png new file mode 100644 index 00000000..3ee433f6 Binary files /dev/null and b/Docs/iam.png differ diff --git a/Microsoft-Teams/1.0.0/api.yaml b/Microsoft-Teams/1.0.0/api.yaml index aa0cb634..39ea7cd8 100644 --- a/Microsoft-Teams/1.0.0/api.yaml +++ b/Microsoft-Teams/1.0.0/api.yaml @@ -104,6 +104,13 @@ actions: example: 'Alert...' schema: type: string + - name: added_information + description: Some extra information to be added to the callback. E.g. an alert + required: true + multiline: true + example: '$new_ticket.ticket_id' + schema: + type: string - name: callback_url description: webhook url of your workflow in shuffle required: true diff --git a/Microsoft-Teams/1.0.0/src/app.py b/Microsoft-Teams/1.0.0/src/app.py index 4e34e9de..1be9556e 100644 --- a/Microsoft-Teams/1.0.0/src/app.py +++ b/Microsoft-Teams/1.0.0/src/app.py @@ -43,15 +43,38 @@ async def send_rich_text(self, webhook_url, title, message, link_button_text, li return f'Message Sent' - async def send_actionable_msg(self, webhook_url, title, message, callback_url): + async def send_actionable_msg(self, webhook_url, title, message, added_information, callback_url): try: myTeamsMessage = teams.connectorcard(webhook_url) # You must create the connectorcard object with the Microsoft Webhook URL myTeamsMessage.title(title) # title for your card myTeamsMessage.text(message) # Add text to the message. myTeamsPotentialAction3 = teams.potentialaction(_name = "Select_Action") - myTeamsPotentialAction3.choices.addChoices("Accept","Accept") #option 1 - myTeamsPotentialAction3.choices.addChoices("Reject","Reject") #option 2 - myTeamsPotentialAction3.addInput("MultichoiceInput","list","Select Action",False) #Dropdown menu + + value = { + "choice": "ACCEPT", + "extra": added_information, + } + + #print(f"VALUE: {value}") + + try: + accept = json.dumps(value) + except: + print("FAILED ENCODING ACCEPT") + accept = "ACCEPT" + + myTeamsPotentialAction3.choices.addChoices("Accept", accept) #option 1 + + value["choice"] = "REJECT" + try: + deny = json.dumps(value) + except: + print("FAILED ENCODING REJECT") + deny = "REJECT" + + myTeamsPotentialAction3.choices.addChoices("Reject", deny) #option 2 + + myTeamsPotentialAction3.addInput("MultichoiceInput","list","Select Action", False) #Dropdown menu myTeamsPotentialAction3.addAction("HttpPost","Submit",callback_url) #post request to Shuffle myTeamsMessage.addPotentialAction(myTeamsPotentialAction3) myTeamsMessage.send()# send the message. @@ -74,5 +97,6 @@ async def get_user_input(self, webhook_url, title, message, callback_url): return f'{e.__class__} occured' return f'Message Sent' + if __name__ == "__main__": asyncio.run(MsTeams.run(), debug=True) diff --git a/aws-iam/1.0.0/Dockerfile b/aws-iam/1.0.0/Dockerfile new file mode 100644 index 00000000..364e1531 --- /dev/null +++ b/aws-iam/1.0.0/Dockerfile @@ -0,0 +1,26 @@ +# Base our app image off of the WALKOFF App SDK image +FROM frikky/shuffle:app_sdk as base + +# We're going to stage away all of the bloat from the build tools so lets create a builder stage +FROM base as builder + +# Install all alpine build tools needed for our pip installs +RUN apk --no-cache add --update alpine-sdk libffi libffi-dev musl-dev openssl-dev + +# Install all of our pip packages in a single directory that we can copy to our base image later +RUN mkdir /install +WORKDIR /install +COPY requirements.txt /requirements.txt +RUN pip install --prefix="/install" -r /requirements.txt + +# Switch back to our base image and copy in all of our built packages and source code +FROM base +COPY --from=builder /install /usr/local +COPY src /app + +# Install any binary dependencies needed in our final image +# RUN apk --no-cache add --update my_binary_dependency + +# Finally, lets run our app! +WORKDIR /app +CMD python app.py --log-level DEBUG diff --git a/aws-iam/1.0.0/api.yaml b/aws-iam/1.0.0/api.yaml new file mode 100644 index 00000000..ec2615f3 --- /dev/null +++ b/aws-iam/1.0.0/api.yaml @@ -0,0 +1,238 @@ +app_version: 1.0.0 +name: AWS IAM +description: An app to interact with Amazon IAM +contact_info: + name: "@dhaval055" + url: https://shuffler.io + email: dhavald@inforpercept.com +tags: + - Access + - Users +categories: + - Access + - Users +authentication: + required: true + parameters: + - name: access_key + description: The access key to use + example: "*****" + required: true + schema: + type: string + - name: secret_key + description: The secret key to use + example: "*****" + required: true + schema: + type: string + - name: region + description: The region to use + example: "ap-south-1" + required: true + schema: + type: string +actions: + - name: change_password + description: Change password of the specified user + parameters: + - name: username + description: Username to change password + required: true + multiline: false + example: 'johnwiliams' + schema: + type: string + - name: password + description: New password for user + required: true + multiline: false + example: '*****' + schema: + type: string + returns: + schema: + type: string + - name: attach_user_policy + description: Attach policy to the user. + parameters: + - name: username + description: Username you want to attach policy to. + required: true + multiline: false + example: 'johnwiliams' + schema: + type: string + - name: policy_arn + description: Amazon Resource Names (ARNs) uniquely identify AWS resources. + required: true + multiline: true + example: 'arn:aws:iam::aws:policy/AdministratorAccess' + schema: + type: string + returns: + schema: + type: string + - name: list_access_keys + description: List all access keys + parameters: + - name: username + description: List all access keys of this username + required: true + multiline: false + example: 'johnwiliams' + schema: + type: string + - name: marker + description: Use this parameter only when paginating results and only after you receive a response indicating that the results are truncated. + required: false + multiline: false + example: '10' + schema: + type: string + - name: max_items + description: Use this only when paginating results to indicate the maximum number of items you want in the response. + required: false + multiline: false + example: '123' + schema: + type: string + returns: + schema: + type: string + - name: list_ssh_public_keys + description: List SSH public keys + parameters: + - name: username + description: List SSH public keys of this username + required: true + multiline: false + example: 'johnwiliams' + schema: + type: string + - name: marker + description: Use this parameter only when paginating results and only after you receive a response indicating that the results are truncated. + required: false + multiline: false + example: '10' + schema: + type: string + - name: max_items + description: Use this only when paginating results to indicate the maximum number of items you want in the response. + required: false + multiline: false + example: '123' + schema: + type: string + returns: + schema: + type: string + - name: get_instance_profile + description: Retrieves information about the specified instance profile, including the instance profile's path, GUID, ARN, and role. + parameters: + - name: instance_profile_name + description: The name of the instance profile to get information about. + required: true + multiline: false + example: 'ExampleInstanceProfile' + schema: + type: string + returns: + schema: + type: string + - name: get_user + description: Retrieves information about the specified IAM user, including the user's creation date, path, unique ID, and ARN. + parameters: + - name: user_name + description: The name of the user to get information about. + required: true + multiline: false + example: 'Bob' + schema: + type: string + returns: + schema: + type: string + - name: list_attached_user_policies + description: Lists all managed policies that are attached to the specified IAM user. + parameters: + - name: user_name + description: The name (friendly name, not ARN) of the user to list attached policies for. + required: true + multiline: false + example: 'johnwiliams' + schema: + type: string + - name: marker + description: Use this parameter only when paginating results and only after you receive a response indicating that the results are truncated. + required: false + multiline: false + example: '10' + schema: + type: string + - name: max_items + description: Use this only when paginating results to indicate the maximum number of items you want in the response. + required: false + multiline: false + example: '123' + schema: + type: string + returns: + schema: + type: string + - name: list_users + description: Lists the IAM users + parameters: + - name: path_prefix + description: The path prefix for filtering the results. + required: true + multiline: false + example: '"/" for all users' + schema: + type: string + - name: marker + description: Use this parameter only when paginating results and only after you receive a response indicating that the results are truncated. + required: false + multiline: false + example: '10' + schema: + type: string + - name: max_items + description: Use this only when paginating results to indicate the maximum number of items you want in the response. + required: false + multiline: false + example: '123' + schema: + type: string + returns: + schema: + type: string + - name: list_user_tags + description: Lists the tags that are attached to the specified IAM user. + parameters: + - name: user_name + description: The path prefix for filtering the results. + required: true + multiline: false + example: 'JohnDoe' + schema: + type: string + - name: marker + description: Use this parameter only when paginating results and only after you receive a response indicating that the results are truncated. + required: false + multiline: false + example: '10' + schema: + type: string + - name: max_items + description: Use this only when paginating results to indicate the maximum number of items you want in the response. + required: false + multiline: false + example: '123' + schema: + type: string + returns: + schema: + type: string + +large_image: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHUAAAB1CAIAAAD/ZjnrAAAEBWlDQ1BpY2MAADjLjVVdaBxVFD67c2cjJM5TbDSFdKg/DSUNk1Y0obS6f93dNm6WSTbaIuhk9u7OmMnOODO7/aFPRVB8MeqbFMS/t4AgKPUP2z60L5UKJdrUICg+tPiDUOiLpuuZOzOZabqx3mXufPOd75577rln7wXouapYlpEUARaari0XMuJzh4+IPSuQhIegFwahV1EdK12pTAI2Twt3tVvfQ8J7X9nV3f6frbdGHRUgcR9is+aoC4iPAfCnVct2AXr6kR8/6loe9mLotzFAxC96uOFj18NzPn6NaWbkLOLTiAVVU2qIlxCPzMX4Rgz7MbDWX6BNauuq6OWiYpt13aCxcO9h/p9twWiF823Dp8+Znz6E72Fc+ys1JefhUcRLqpKfRvwI4mttfbYc4NuWm5ERPwaQ3N6ar6YR70RcrNsHqr6fpK21iiF+54Q28yziLYjPN+fKU8HYq6qTxZzBdsS3NVry8jsEwIm6W5rxx3L7bVOe8ufl6jWay3t5RPz6vHlI9n1ynznt6Xzo84SWLQf8pZeUgxXEg4h/oUZB9ufi/rHcShADGWoa5Ul/LpKjDlsv411tpujPSwwXN9QfSxbr+oFSoP9Es4tygK9ZBqtRjI1P2i256uv5UcXOF3yffIU2q4F/vg2zCQUomDCHvQpNWAMRZChABt8W2Gipgw4GMhStFBmKX6FmFxvnwDzyOrSZzcG+wpT+yMhfg/m4zrQqZIc+ghayGvyOrBbTZfGrhVxjEz9+LDcCPyYZIBLZg89eMkn2kXEyASJ5ijxN9pMcshNk7/rYSmxFXjw31v28jDNSpptF3Tm0u6Bg/zMqTFxT16wsDraGI8sp+wVdvfzGX7Fc6Sw3UbbiGZ26V875X/nr/DL2K/xqpOB/5Ffxt3LHWsy7skzD7GxYc3dVGm0G4xbw0ZnFicUd83Hx5FcPRn6WyZnnr/RdPFlvLg5GrJcF+mr5VhlOjUSs9IP0h7QsvSd9KP3Gvc19yn3Nfc59wV0CkTvLneO+4S5wH3NfxvZq8xpa33sWeRi3Z+mWa6xKISNsFR4WcsI24VFhMvInDAhjQlHYgZat6/sWny+ePR0OYx/mp/tcvi5WAYn7sQL0Tf5VVVTpcJQpHVZvTTi+QROMJENkjJQ2VPe4V/OhIpVP5VJpEFM7UxOpsdRBD4ezpnagbQL7/B3VqW6yUurSY959AlnTOm7rDc0Vd0vSk2IarzYqlprq6IioGIbITI5oU4fabVobBe/e9I/0mzK7DxNbLkec+wzAvj/x7Psu4o60AJYcgIHHI24Yz8oH3gU484TastvBHZFIfAvg1Pfs9r/6Mnh+/dTp3MRzrOctgLU3O52/3+901j5A/6sAZ41/AaCffFV/8BqIAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAGYktHRAD/AP8A/6C9p5MAAAAHdElNRQflAwgJEA0z6yfNAAAP6klEQVR42u2dWXAUR5qA/6yr71tqdUst0ZIQOpCQEIeNB4SFMRb4YGZ3bBxeYjz2xoBf9mntIIIn79rhDTuImPB6IzZifcxgM4a1sWEtG4MYj5FBiEMjoRUgJAE6UQu1unX1Ud1dlbkPJTQsoANMV5c6+nsg6K7qqsxPVZl/ZmVlIkIIpIgbVKITcB9ggvlokBCc6ITcB0yiEzBf/GPD39d/fWXgTNVjGx8p3GzU2hKdonmBlF8+BEMTJ84ePfT9vovtF6wu1lVozneWrV/2fEX+ejWnT3Tq5kDRfiNRvqnt1Fff7T3b3BCJhBGiHXm6jDwtJljFqEsWPVJd8UJh9iqWViU6pTOiUL+CKLRfvfDVkb31p+smAhMURSFAQCAjT5eRpwUAAIIJ1qmMFYsff7z8eXfGUppSYlmnOL+Y4N4bV//n2OdHfzw04htGiEIITW37f34BAAghBIhZn/ZI0eaqsr9zWNwIKavGVpbfYd/gdz98+U3dfw8M9gLA38xK3OV36mtCAMBuyV5b+txjJc9a9I5E5+NvKMXveGD0h1O1X3+/r+tauyiKFHWvy3AGv1MbCUaIyrEvqVr29yuXbNKrzYnOE4AS/IYjoYbzxw8e+bT1YlMsFqUoesZdZ/UrgQlmaHZxZnl1xQvLctep2Nl2loFE+o0J0eaLjV8f+fR0U30oHKRnMStBICNf58jTzplkjEUVpy11r6mu2LYkq5KhuUTlMTF+MRY7rrcdPvanP//03djEKHV7JTYzhIAxncsq1Ks0NAGAORJOMMF6jXlFwRPrl/06x15Eobn+fnFAbr+EkIGh69/UHTjyw9c3vR6E0HzMAoAYI7EIxiLRGJmMXK01Sz0fy1KAYTXY1xQ/vbb0V3ZzzjxP97CQ22/tnw/88Yv/6BvoJkCo+cVSkllBwJJKQoCiQGdm7W6tLUvNzcsyBkAZ1pynV//jL5ZulTO/skaLoijUN9Zd7+lECM1HrigQPiCGg4IQw9MGEQJCYNIf674w3n7a77kajPEiQgAzX5dSED04cq3l6o8Yi3JmWe42D0IIUfMwGyOxKBZjeKa7a8qyLxYcHff2hdMXaWxZGk5NzXItI0TJ3/pQVpuSEMACiUXx7RfsrU0EE0whSvpXKkYlyxMj0YA/6u0Jp7s1tiw1q0pAPTYTCvLLaehISORDAhYAEEzXQxhjAGKzpa1c/khpUXlb+4WmlrN+vw8ASc2QKcu+aGAs6usPu4oNJrtSenwU5Dd9kUZnYif90YmRaHAsxgdEISpSFO12565bU715wy+LFpepVVo+Emrv+t/vfzh8svEv/QN9GBOKRhSFKAbRDIpF8PhwJOX3HlA00hhZjYFJz9EKURwOCGKIfWbNqxvXPpeZkT3drlOrtMtLH11Wsuo3L/TVHj/46Rf/GRMjFDV1tRMyW0WXgEzJfL45ok8yFS4yHGWwsvlLHZuf3Opyuu9uNNMU7XLmblhbYzDq5I1o7w/5/BKC/ePeQGgSze8CIwQIli7I2Xaaf/iOAIWjgfHQiJxP8OQoHwLBiZbLjU2tDc1tZ673dtF0Yup3iqKv3mj590P/tMRVWZSzusi1SqMyxPukcvhtbPnxrd+/HgoFpEzKcMaZEEShd7ijd/hKw6Xa3z39Tnnu+nifUQ6/PB+KRMKJNTuN1G6MCRFBiMpxOhnOgWZvvSYGmZKkrKdVDwVFhRNJ6BdAQXdLkvpVDCm/8SXlN76k/MYXBfXv3AkCqTc8EuXHJkYGb/Z3XLsYFL2L8wuy7YU2g9OgtQBI7WgFVWh3oCC/aCpSJhgDFkksIg6O+f7rT7/3jfgGPL0j/uFgMGDPVWf2GDUqg0Vvd1gXUVilNoNKoIUowSIhBMj99EjIgIL8xiJ4YiQSDgh8QIyExCgvCtHRdvELQgBNPWdGFMUQgGB4IhAe7x/uRAjZCxjrInMkjCNBIRIUwwGBVVNzPbqXDwX5He4JEQLSZQi3mgn3bFVLrqfLBFZFc2raYGFv//lckDnHTzwU5PArXXwiFgkhswwlEQVya//7PsW0U4qe7ccECBBACNEUM8/RAT837zIUVx5vf8vFRq9vaHTcX99Y1z/Y88B5mxp/9kBJJgQ7bbmPLX3WqLXp1MY8R5lJlx7vvMtx/TrTs53V2QAgisLgUH/vwHWKTkBciAl2WvNqVvxWzp48ufOpqMpdBlLti/iS8htfUn7ji9zxLyEYiyJGFNwWwcZnzCi5NRZtqszHWJT/3U9Z/SKEFruLhrw3ItFwJBqNRvloNCKIgiAIgigQjKeaDj8LghBFIZqmaIZmGZplGJWKUXOshmU4t6NE5scbco//jUb5cCTER0LRWDTMh4LhyUgkEgiOj0+O8jx/9MSh9s42auYBlrPHv5jggqzyXyx9TqPSazi9itOqWS3HajhGxTJqluZommUoVs78yl0+cJya49Qmg/XuTQTItd4rlzpaqQetFQjBWbbFVWW/ljlTs6Ck+o0kYXSsJL/JSMpvfEn5jS8pv/FFQf3rPx8EyB+42dZz8p4BHCHYpE/PsRfPc4DsQyGp/FIUfbn3TEd/0z23ilhYUfDE7zb/G5KxfzKp/AIAxhjjew+MFLEgiILM6UmVv/El5Te+pPzGl5Tf+JJs9ds9kWYpSP7+34RAU7RWbTBqrSZdWvGi1TLP/5D8fp9a+ZvVRTUGjVXN6ThGJfMr9EnuFyGUYy92pS1JVAKSvX6bxzw9cSXZ/SaalN/4kvIbX1J+40vyxQ+EECBACMEIEEOz8ozznYlk8IsJJoQgAIqiOVat4fQGrSXNlOW0uh3W3LzM8gSmbcH7ZRnObs62m7MzLDnpJpfNmGnR2w1am1ZlYGhZh5Lck4XtF2NxcWb5K0/9i0mXRss7MGeeLOz6jQCoWI1Ra1OmXFjofiGxjbN5sLD9IgCMhZgox0wkD8bCLn8RQr5Jz5krtTZDZrrJZdSmqTmdohYSUFBSHgxBjHrH+30TN655LmhUeqPWZtFn2IxZJm0ax6gTvpzAgveLAFGIQojCRAyExwLh0UHfNZZR6TVmkzZNr7a40gsTONf9gvc7DQKEKAQEBBwbnbzZM3R5LOCdDI39wxO7l+dXJypVyeAXISQtrRUIjY0HfaMBbyA0FhUiGIsIUaIYS2DaFrpfFImFuz2XRwPeyeAoHwuLogBTbzAjhCg5h5rdk4XtFyE0FvCPBXyEEOmFJJkfX87JwvYLAFILQ2lap1nY7Qvlk+R+E/7KTNL6xQQTgk06m05tTGAylFX+Ss8efuYRCMEqVu205S7Lq1qevyErbXECc6QgvwiBTqtDFMJYfIApMDDBCCGT3rYka/mqwqcWZ1YYtWkJr/cU5BcAvfSrHc4MV139N9d6OvgIP591nwgQgjHHqjNteZUFG8py12Va81hGKesHJH79t7sgvjHvX9sajv9Ue/avP4Uj4dvbCHe8f0yAaFX68ryqisXVBVnLTVqb0maaU6DfKcYn/f/8r79tuXj+9nXh7vCLsbgsb+1rz+5RJ3odvZlQbvzAcSqW5eZYGAuApllGSR2+d6Bcv/NGofefRBL4VTQpv/El5Te+pPzGl5Tf+KJgv0SaUWu28IAQLP8rV/eFcv2yLFdWvMJsMov3siwtF2k12Je4VihqwMMdKLf9BgCRKN/afvbgt3vPNJ8MhgIUohz5+oxcDSZYpzYtz1//eMULi+wlKb8/ixAfPNty4qvvPm1uO2dxUYuK7EsXPfp4+fNLslYopx9nJhaAX4mJwNiJxiNXPc1Vj24qzV2r2A6HO1gwfkEqc7FI08otDe5mIfldiCg3fkgO5L7XwuHwwMCAw+EwGAwA4PF4OI6z2WwA4Pf7Q6FQVlYWQigUCo2MjGRlZYVCoZaWFq/XazabS0pKHA6H9ERDFMWenp5oNIoQys7O1ul0ADA8PBwIBHJychiGAYChoaFQKDT9MRAIeDyezMxMaWd5kPv6bWhoePHFFw8ePCh93L9//yeffCL9f+/evbt27QoEAgBw8uTJ9957b2ho6K233tq3b19HR8dnn322e/duv98v7czz/IEDB1577bU9e/YMDg4CgCAIe/bsefXVV7u7u6V9Pvroo+3bt7e1tU2f66WXXrpw4YKc+ZXbb2Njo9VqbWxsDIfDAJCbm9va2hoOhyORSGdnZ39//9DQEABcunTJYrGcO3dueHj43Xff3b179/vvv79t27bptWd1Ot2OHTvsdvvLL79cUFAAAMPDw11dXRRFNTVNzc8VDocxxnV1dQDg8/lOnTqFEIpEIknrd2Rk5NKlS6+88srIyEhfXx8AlJSUjI+P37x50+fzMQxTUlLS2dmJMe7o6Fi2bNnExARFUWq1GgBMJlNNTY3ZbJ4+mkqlomlapZoKgVtbW81m89atW8+ePSuKIgAAkKqqqvYr7R6Pp7m52WKx5Ofny1yfy+r38uXLhJANGzakpaVJ96nT6dTpdL29vT09PUajsaysrKury+v1DnuHi4uLKysru7u733jjjS8PftnZ2SkIs81e1tDQUF5e/uSTT/b29kolBsbY7XZnu7KPHj168uTJ6upqjuOS2W9TU5Pb7U5PT6+srGxoaBBF0WAwuFyuzs7Oq1evulyu0tLS/v7+rq4umqIdDkdpaek777zDcdwfPvnDjh07Pvzww5kU+3y+jo6O8vJyl8ul0WhaW1sBgBDgOG7jxo379+/3eDwrVqzAOHnn3wkGg+fOnZucnNy1a9eNGzeGhoY8Ho/L5SopKWlra9Pr9evWrcvNzR0fH29qanI4HGazGSG0Zs2a1atX+/3+urq6jz/+uLq6uqio6O6DX7t2rbu7+/PPP6+tre3r6zt//vwzzzwDCDDGK1euTEtLW7Vqlc1mkz/Yl89vV1fXxMTEzp07LRYLz/MffPBB28U2l8tVXl5+6NAhq9Wan5+fkZGhUqnq6+s3btzIMEw4HGZZlmGY9PT0mpqaw4cPS9HF3Zw6daqysnL79u0IocLCwmPHjvn9foQQIUSn07399tsWiyUhLSn5/DY2NmZnZ2/ZsoVlWelj/Yn6zTWb3W43z/M8zzudTpVK5XQ6jx8//vrrrwNAXV3d5cuXa2pqLBbLsWPHTCZTXl6edDRBEJqbm71eb0tLizPTee7cuW3btlVVVQFAUVHRt99+29p6AQhIBYL0q2AwKIrzXb7sYUG/+eabMpyGENLe3l5RUVFcXCx9o9fr/X5/RUWFTqcLBoNlZWUrV66UNmk0mi1btuh0ulgs1tDQcKL+xOnTpycnJ3fu3Ol2u6V9eJ6vra1lWTYYDGbYM0RR3LRpk8lkAgC1Ws3zvMFoNJlMLpdr+k9CCPF6vWVlZXa7XTa/8vU/CIJAUdT02guEEFEUaZpGCImiiBCSNknfSy0uAIjFYpOTkxhjvV4vBWq3H1BKPEVRhJDpnwDArfgMpg87/T1FzT2m7SHyf7ZjExselK36AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIxLTAzLTA4VDA5OjE2OjEzLTA1OjAwnDG3lwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMS0wMy0wOFQwOToxNjoxMy0wNTowMO1sDysAAAAASUVORK5CYII= diff --git a/aws-iam/1.0.0/requirements.txt b/aws-iam/1.0.0/requirements.txt new file mode 100644 index 00000000..06ef1c78 --- /dev/null +++ b/aws-iam/1.0.0/requirements.txt @@ -0,0 +1,2 @@ +boto3==1.16.59 +requests==2.25.1 \ No newline at end of file diff --git a/aws-iam/1.0.0/src/app.py b/aws-iam/1.0.0/src/app.py new file mode 100644 index 00000000..2088df88 --- /dev/null +++ b/aws-iam/1.0.0/src/app.py @@ -0,0 +1,248 @@ +import socket +import asyncio +import time +import random +import json +import boto3 +import botocore +from botocore.config import Config +import datetime + +from walkoff_app_sdk.app_base import AppBase + +def datetime_handler(x): + """ This function is used make datetime object json serilizable, + removing this function can cause error in some actions """ + + if isinstance(x, datetime.datetime): + return x.isoformat() + raise TypeError("Unknown type") + +class AWSIAM(AppBase): + __version__ = "1.0.0" + app_name = "AWS IAM" + + def __init__(self, redis, logger, console_logger=None): + """ + Each app should have this __init__ to set up Redis and logging. + :param redis: + :param logger: + :param console_logger: + """ + super().__init__(redis, logger, console_logger) + + async def auth_iam(self, access_key, secret_key, region): + my_config = Config( + region_name = region, + signature_version = 'v4', + retries = { + 'max_attempts': 10, + 'mode': 'standard' + }, + ) + + self.iam = boto3.resource( + 'iam', + config=my_config, + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + ) + + return self.iam + + async def change_password(self, access_key, secret_key, region, username, password): + self.iam = await self.auth_iam(access_key, secret_key, region) + client = self.iam.meta.client + + try: + return client.update_login_profile(UserName=username, Password=password, PasswordResetRequired=True) + except botocore.exceptions.ClientError as e: + print("Error: %s" % e) + return "%s" % e + + async def attach_user_policy(self, access_key, secret_key, region, username, policy_arn): + self.iam = await self.auth_iam(access_key, secret_key, region) + client = self.iam.meta.client + + try: + response = client.attach_user_policy( + PolicyArn=str(policy_arn), + UserName= str(username), + ) + return json.dumps(response) + except botocore.exceptions.ClientError as e: + print(f"Error: {e}") + return f'{e}' + + async def list_access_keys(self, access_key, secret_key, region, username, marker, max_items): + self.iam = await self.auth_iam(access_key, secret_key, region) + client = self.iam.meta.client + + try: + response = client.list_access_keys( + UserName= str(username) + ) + if marker: + response = client.list_access_keys( + UserName= str(username), + Marker = str(marker) + ) + if max_items: + response = client.list_access_keys( + UserName= str(username), + MaxItems = int(max_items) + ) + if marker and max_items: + response = client.list_access_keys( + UserName= str(username), + MaxItems = int(max_items), + Marker = str(marker) + ) + return json.dumps(response, default=datetime_handler) + except botocore.exceptions.ClientError as e: + return f'{e}' + + async def list_ssh_public_keys(self, access_key, secret_key, region, username, marker, max_items): + self.iam = await self.auth_iam(access_key, secret_key, region) + client = self.iam.meta.client + + try: + response = client.list_ssh_public_keys( + UserName= str(username) + ) + if marker: + response = client.list_ssh_public_keys( + UserName= str(username), + Marker = str(marker) + ) + if max_items: + response = client.list_ssh_public_keys( + UserName= str(username), + MaxItems = int(max_items) + ) + if marker and max_items: + response = client.list_ssh_public_keys( + UserName= str(username), + MaxItems = int(max_items), + Marker = str(marker) + ) + + return json.dumps(response, default=datetime_handler) + except botocore.exceptions.ClientError as e: + return f'{e}' + + async def get_instance_profile(self, access_key, secret_key, region, instance_profile_name): + self.iam = await self.auth_iam(access_key, secret_key, region) + client = self.iam.meta.client + + try: + response = client.get_instance_profile( + InstanceProfileName= str(instance_profile_name) + ) + return json.dumps(response, default=datetime_handler) + except botocore.exceptions.ClientError as e: + print(f"Error: {e}") + return f'{e}' + + async def get_user(self, access_key, secret_key, region, user_name): + self.iam = await self.auth_iam(access_key, secret_key, region) + client = self.iam.meta.client + + try: + response = client.get_user( + UserName= str(user_name) + ) + return json.dumps(response, default= datetime_handler) + except botocore.exceptions.ClientError as e: + print(f"Error: {e}") + return f'{e}' + + async def list_attached_user_policies(self, access_key, secret_key, region, user_name, marker, max_items): + self.iam = await self.auth_iam(access_key, secret_key, region) + client = self.iam.meta.client + + try: + response = client.list_attached_user_policies( + UserName= str(user_name) + ) + if marker: + response = client.list_attached_user_policies( + UserName= str(user_name), + Marker = str(marker) + ) + if max_items: + response = client.list_attached_user_policies( + UserName= str(user_name), + MaxItems = int(max_items) + ) + if marker and max_items: + response = client.list_attached_user_policies( + userName= str(user_name), + MaxItems = int(max_items), + Marker = str(marker) + ) + + return json.dumps(response, default=datetime_handler) + except botocore.exceptions.ClientError as e: + return f'{e}' + + async def list_users(self, access_key, secret_key, region, path_prefix, marker, max_items): + self.iam = await self.auth_iam(access_key, secret_key, region) + client = self.iam.meta.client + + try: + response = client.list_users( + PathPrefix = path_prefix + ) + if marker: + response = client.list_users( + PathPrefix = path_prefix, + Marker = str(marker) + ) + if max_items: + response = client.list_users( + PathPrefix = path_prefix, + MaxItems = int(max_items) + ) + if marker and max_items: + response = client.list_users( + PathPrefix = path_prefix, + MaxItems = int(max_items), + Marker = str(marker) + ) + + return json.dumps(response, default=datetime_handler) + except botocore.exceptions.ClientError as e: + return f'{e}' + + async def list_user_tags(self, access_key, secret_key, region, user_name, marker, max_items): + self.iam = await self.auth_iam(access_key, secret_key, region) + client = self.iam.meta.client + + try: + response = client.list_user_tags( + UserName = str(user_name) + ) + if marker: + response = client.list_user_tags( + UserName = str(user_name), + Marker = str(marker) + ) + if max_items: + response = client.list_user_tags( + UserName = str(user_name), + MaxItems = int(max_items) + ) + if marker and max_items: + response = client.list_user_tags( + UserName = str(user_name), + MaxItems = int(max_items), + Marker = str(marker) + ) + + return json.dumps(response, default=datetime_handler) + except botocore.exceptions.ClientError as e: + return f'{e}' + +if __name__ == "__main__": + asyncio.run(AWSIAM.run(), debug=True) diff --git a/shuffle-tools/1.0.0/api.yaml b/shuffle-tools/1.0.0/api.yaml index 735c832a..6d8c4b28 100644 --- a/shuffle-tools/1.0.0/api.yaml +++ b/shuffle-tools/1.0.0/api.yaml @@ -111,7 +111,7 @@ actions: options: - equals - 'larger than' - - 'less than' + - 'less than' - is empty - contains - starts with @@ -239,6 +239,31 @@ actions: returns: schema: type: string + - name: map_value + description: Takes a mapping dictionary and translates the input data + parameters: + - name: input_data + description: The input data to use + required: true + multiline: true + example: $exec.field1 + schema: + type: string + - name: mapping + description: The mapping dictionary + required: true + multiline: true + example: | + { + "Low": 1, + "Medium": 2, + "High": 3, + } + schema: + type: string + returns: + schema: + type: string - name: parse_list description: Parses a list and returns it as a json object parameters: @@ -285,25 +310,25 @@ actions: multiline: true example: "REPEATING: Hello world" schema: - type: file + type: file returns: schema: - type: string - - name: download_remote_file + type: string + - name: download_remote_file description: Downloads a file from a URL parameters: - - name: url - description: + - name: url + description: required: true - multiline: false + multiline: false example: "https://secure.eicar.org/eicar.com.txt" schema: - type: string + type: string returns: schema: - type: string - - name: get_file_meta - description: Gets the file meta + type: string + - name: get_file_meta + description: Gets the file meta parameters: - name: file_id description: diff --git a/shuffle-tools/1.0.0/src/app.py b/shuffle-tools/1.0.0/src/app.py index efcd0cd1..637d3b64 100644 --- a/shuffle-tools/1.0.0/src/app.py +++ b/shuffle-tools/1.0.0/src/app.py @@ -206,6 +206,17 @@ async def translate_value(self, input_data, translate_from, translate_to): return input_data + async def map_value(self, input_data, mapping): + + mapping = json.loads(mapping) + print(f"Got mapping {json.dumps(mapping, indent=2)}") + + # Get value if input_data in map, otherwise return original input_data + output_data = mapping.get(input_data, input_data) + print(f"Mapping {input_data} to {output_data}") + + return output_data + async def execute_python(self, code, shuffle_input): print("Run with shuffle_data %s" % shuffle_input) print("And python code %s" % code) @@ -261,15 +272,17 @@ async def filter_list(self, input_list, field, check, value, opposite): if not isinstance(input_list, list): return { "success": False, - "reason": "Error: input isnt a list. Remove # to use this app." % type(input_list) + "reason": "Error: input isnt a list. Remove # to use this app." % type(input_list), + "valid": [], + "invalid": [], } input_list = [input_list] new_list = [] failed_list = [] - try: - for item in input_list: + for item in input_list: + try: try: item = json.loads(item) except: @@ -407,7 +420,7 @@ async def filter_list(self, input_list, field, check, value, opposite): else: new_list = file_list #else: - # failed_list = file_list + # failed_list = file_list elif type(tmp) == str: filedata = self.get_file(tmp) @@ -419,8 +432,11 @@ async def filter_list(self, input_list, field, check, value, opposite): else: failed_list.append(item) - except Exception as e: - return "Error: %s" % e + except Exception as e: + #"Error: %s" % e + print("FAILED WITH EXCEPTION: %s" % e) + failed_list.append(item) + #return try: return json.dumps({ @@ -435,7 +451,7 @@ async def filter_list(self, input_list, field, check, value, opposite): "reason": "Failed parsing filter list output" + e, }) - return new_list + return new_list async def multi_list_filter(self, input_list, field, check, value): input_list = input_list.replace("'", '"', -1) @@ -525,7 +541,7 @@ async def delete_file(self, file_id): async def get_file_value(self, filedata): if filedata == None: return "File is empty?" - + print("INSIDE APP DATA: %s" % filedata) return "%s" % filedata["data"].decode() @@ -542,7 +558,7 @@ async def download_remote_file(self, url): else: value = {"success": False, "reason": "No files downloaded"} - return value + return value async def extract_archive(self, file_ids, fileformat="zip", password=None): try: @@ -589,7 +605,7 @@ async def extract_archive(self, file_ids, fileformat="zip", password=None): to_be_uploaded.append( {"filename": source.name, "data": source.read()} ) - return_data["success"] = True + return_data["success"] = True except (zipfile.BadZipFile, Exception): return_data["files"].append( { @@ -617,7 +633,7 @@ async def extract_archive(self, file_ids, fileformat="zip", password=None): to_be_uploaded.append( {"filename": source.name, "data": source.read()} ) - return_data["success"] = True + return_data["success"] = True except Exception: return_data["files"].append( { @@ -646,7 +662,7 @@ async def extract_archive(self, file_ids, fileformat="zip", password=None): "data": source.read(), } ) - return_data["success"] = True + return_data["success"] = True except Exception: return_data["files"].append( { diff --git a/thehive/1.0.0/api.yaml b/thehive/1.0.0/api.yaml index d854bee5..8faedceb 100644 --- a/thehive/1.0.0/api.yaml +++ b/thehive/1.0.0/api.yaml @@ -1,48 +1,48 @@ walkoff_version: 1.0.0 app_version: 1.0.0 name: thehive -description: TheHive implementation for Shuffle +description: TheHive implementation for Shuffle tags: - - Ticketing + - Ticketing - Search categories: - - Ticketing + - Ticketing - Search contact_info: - name: "@frikkylikeme" + name: "@frikkylikeme" url: https://github.com/frikky authentication: required: true parameters: - - name: apikey - description: The Apikey to use + - name: apikey + description: The Apikey to use example: "*****" required: true schema: type: string - - name: url - description: The URL to use + - name: url + description: The URL to use example: "http://localhost:9000" required: true schema: type: string actions: - - name: create_alert - description: Get an item from TheHive + - name: create_alert + description: Create an alert in TheHive parameters: - - name: type + - name: type description: The type to use for the alert example: "incident" required: true schema: type: string - - name: source + - name: source description: The source to use example: "SIEM" required: true schema: type: string - - name: sourceref + - name: sourceref description: The source reference to use example: "incident-1234" required: true @@ -54,26 +54,26 @@ actions: required: false schema: type: string - - name: description + - name: description description: The description to use example: "" required: false multiline: true schema: type: string - - name: tlp + - name: tlp description: The tlp to use example: "2" required: false schema: type: string - - name: severity + - name: severity description: The severity to use example: "2" required: false schema: type: string - - name: tags + - name: tags description: The tags to use example: "ioc,incident,this is a tag,what" required: false @@ -82,37 +82,122 @@ actions: returns: example: '{"data": "this is a test", "this_is_a_number": 1, "this_is_a_list": [{"item": [{"hello": "there", "how_is_this": {"sub_in_sub": [{"another": "list"}]}}]}, {"item": "2"}], "subobject": {"data": "subobject"}}' schema: - type: string + type: string + - name: create_alert_artifact + description: Create an alert artifact (TheHive 4 ONLY) + parameters: + - name: alert_id + description: Alert identifier + example: "~1234" + required: true + schema: + type: string + - name: dataType + description: "Observable's type, must be a valid type, one of the defined data types in TheHive" + example: "ip" + required: true + schema: + type: string + - name: data + description: Observable's data/value + example: "8.8.8.8" + required: true + schema: + type: string + - name: message + description: Observable's description + example: "Extracted IP entity from product X" + required: false + schema: + type: string + - name: tlp + description: "Case's TLP: 0, 1, 2, 3 for WHITE, GREEN, AMBER, RED. Default: 2" + example: "2" + required: false + schema: + type: string + - name: ioc + description: "Observable's ioc flag, True to mark an observable as IOC. Default: False" + example: "False" + required: false + multiline: false + schema: + type: string + - name: sighted + description: "Observable's sighted flag, True to mark the observable as sighted. Default: False" + example: "False" + required: false + multiline: false + schema: + type: string + - name: ignoreSimilarity + description: "Observable's similarity ignore flag. Trueto ignore the observable during similarity computing" + example: "False" + required: false + multiline: false + schema: + type: string + - name: tags + description: List of observable tags + example: "ioc,alienvault,abuse.ch" + required: false + schema: + type: string + returns: + example: | + [ + { + "_id": "~4321", + "id": "~4321", + "createdBy": "user.1@example.com", + "createdAt": 1616443009693, + "_type": "case_artifact", + "dataType": "ip", + "data": "8.8.8.8", + "startDate": 1616443009693, + "tlp": 2, + "tags": [ + "test1" + ], + "ioc": false, + "sighted": false, + "message": "Test IP entity", + "reports": {}, + "stats": {} + } + ] + schema: + type: string - name: create_case description: Get an item from TheHive parameters: - - name: title + - name: title description: The title to use example: "" required: false multiline: true schema: type: string - - name: description + - name: description description: The description to use example: "" required: false multiline: true schema: type: string - - name: tlp + - name: tlp description: The tlp to use example: "2" required: false schema: type: string - - name: severity + - name: severity description: The severity to use example: "2" required: false schema: type: string - - name: tags + - name: tags description: The tags to use example: "ioc,incident,this is a tag,what" required: false @@ -120,7 +205,7 @@ actions: type: string returns: schema: - type: string + type: string - name: create_case_from_alert description: Create a case from alert parameters: @@ -130,7 +215,7 @@ actions: required: true schema: type: string - - name: case_template + - name: case_template description: Case template name to apply when creating the case example: "" required: false @@ -148,7 +233,7 @@ actions: required: true schema: type: string - - name: case_id + - name: case_id description: The case to merge it to example: "" required: true @@ -157,28 +242,28 @@ actions: returns: schema: type: string - - name: add_observable + - name: add_observable description: Add an observable to TheHive parameters: - - name: case_id + - name: case_id description: The case to add it to example: "" required: true schema: - type: string - - name: data + type: string + - name: data description: The item to add itself example: "shuffler.io" required: true schema: type: string - - name: datatype + - name: datatype description: The type of the item to add example: "domain" required: true schema: type: string - - name: tags + - name: tags description: The tags to use example: "shuffle,is,cool" required: false @@ -186,11 +271,11 @@ actions: type: string returns: schema: - type: string - - name: get_item + type: string + - name: get_item description: Get an item from TheHive parameters: - - name: field_type + - name: field_type description: The type to get (alert, case..) example: "alert" options: @@ -199,13 +284,13 @@ actions: - case_observables - case_task - case_tasks - - linked_cases - - task_log + - linked_cases + - task_log - task_logs required: true schema: type: string - - name: cur_id + - name: cur_id description: The ID of the item to retrieve example: "" required: true @@ -213,11 +298,11 @@ actions: type: string returns: schema: - type: string + type: string - name: update_field description: Update an alert field parameters: - - name: field_type + - name: field_type description: The type to modify (alert, case..) options: - alert @@ -225,8 +310,8 @@ actions: - case_observables - case_task - case_tasks - - linked_cases - - task_log + - linked_cases + - task_log - task_logs required: true schema: @@ -236,12 +321,12 @@ actions: required: true schema: type: string - - name: field + - name: field description: The field to modify required: true schema: type: string - - name: data + - name: data description: The data to set the field to. If you want to append to what already exists, start with %s. required: true multiline: true @@ -250,10 +335,10 @@ actions: returns: schema: type: number - - name: search_cases + - name: search_cases description: Get an item from TheHive parameters: - - name: title_query + - name: title_query description: The title to search for example: "injection" required: true @@ -270,34 +355,34 @@ actions: required: true schema: type: string - - name: custom_query + - name: custom_query description: Custom query for search - example: "{\"_field\": \"title\", \"_value\": \"shuffle\"}" + example: "{\"_field\": \"title\", \"_value\": \"shuffle\"}" required: true schema: type: string - name: search_alerts description: Get an item from TheHive parameters: - - name: title_query + - name: title_query description: The title to search for example: "alert" required: true schema: type: string - - name: search_range + - name: search_range description: The amount of alerts to get. Defaults to 0-25 example: "0-50" - required: false + required: false schema: type: string returns: schema: - type: string - - name: close_alert - description: Close an alert in thehive + type: string + - name: close_alert + description: Close an alert in thehive parameters: - - name: alert_id + - name: alert_id description: The ID to close example: "adf5e3d0fd85633be17004735a0a119e" required: true @@ -305,21 +390,21 @@ actions: type: string returns: schema: - type: string - - name: reopen_alert + type: string + - name: reopen_alert description: Reopen an alert in TheHive parameters: - - name: alert_id + - name: alert_id description: The ID to close example: "adf5e3d0fd85633be17004735a0a119e" required: true schema: type: string - - name: run_analyzer + - name: run_analyzer description: Reopen an alert in TheHive parameters: - - name: cortex_id - description: The cortex ID + - name: cortex_id + description: The cortex ID example: "MISP_2_0" required: true schema: @@ -330,19 +415,19 @@ actions: required: true schema: type: string - - name: artifact_id - description: The artifact ID + - name: artifact_id + description: The artifact ID example: "adf5e3d0fd85633be17004735a0a119e" required: true schema: type: string returns: schema: - type: string - - name: create_task_log + type: string + - name: create_task_log description: Creates a task log in TheHive parameters: - - name: task_id + - name: task_id description: The task ID example: "AXX1SWs8Oc6KiwR-tT2f" required: true @@ -354,34 +439,34 @@ actions: required: true schema: type: string - - name: filedata + - name: filedata description: The file ID from Shuffle example: "adf5e3d0fd85633be17004735a0a119e" - required: false + required: false schema: - type: file - - name: create_case_file_observable + type: file + - name: create_case_file_observable description: Creates a task log in TheHive parameters: - - name: case_id + - name: case_id description: The case ID example: "AXX1SWs8Oc6KiwR-tT2f" required: true schema: type: string - - name: tags + - name: tags description: Tags for the case artifact example: "ioc,cool,artifact" required: true schema: type: string - - name: filedata + - name: filedata description: The file ID from Shuffle example: "adf5e3d0fd85633be17004735a0a119e" - required: true + required: true schema: - type: file + type: file returns: schema: - type: string + type: string large_image: data:image/png;base64,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 diff --git a/thehive/1.0.0/src/app.py b/thehive/1.0.0/src/app.py index d2bf8c76..95f087a9 100644 --- a/thehive/1.0.0/src/app.py +++ b/thehive/1.0.0/src/app.py @@ -34,13 +34,13 @@ def __init__(self, redis, logger, console_logger=None): super().__init__(redis, logger, console_logger) # async def run_analyzer(self, apikey, url, title_query): - # self.thehive = TheHiveApi(url, apikey) + # self.thehive = TheHiveApi(url, apikey, cert=False) # response = self.thehive.find_cases(query=String("title:'%s'" % title_query), range='all', sort=[]) # return response.text async def search_cases(self, apikey, url, title_query): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) response = self.thehive.find_cases( query=ContainsString("title", title_query), range="all", sort=[] @@ -48,7 +48,7 @@ async def search_cases(self, apikey, url, title_query): return response.text async def search_query(self, apikey, url, search_for, custom_query): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) try: query = json.loads(custom_query) @@ -63,10 +63,10 @@ async def search_query(self, apikey, url, search_for, custom_query): if response.status_code == 200: return response.text else: - raise IOError(response.text) + raise IOError(response.text) async def add_observable(self, apikey, url, case_id, data, datatype, tags): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) if tags: if ", " in tags: @@ -91,7 +91,7 @@ async def add_observable(self, apikey, url, case_id, data, datatype, tags): return self.thehive.create_case_observable(case_id, item).text async def search_alerts(self, apikey, url, title_query, search_range="0-25"): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) # Could be "all" too if search_range == "": @@ -105,7 +105,7 @@ async def search_alerts(self, apikey, url, title_query, search_range="0-25"): async def create_case( self, apikey, url, title, description="", tlp=1, severity=1, tags="" ): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) if tags: if ", " in tags: tags = tags.split(", ") @@ -164,7 +164,7 @@ async def create_alert( severity=1, tags="", ): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) if tags: if ", " in tags: tags = tags.split(", ") @@ -188,14 +188,14 @@ async def create_alert( tlp = int(tlp) if isinstance(severity, str): if not severity.isdigit(): - return "Severity needs to be a number from 1-3, not %s" % severity + return "Severity needs to be a number from 1-3, not %s" % severity severity = int(severity) if tlp > 3 or tlp < 0: return "TLP needs to be a number from 0-3, not %d" % tlp if severity > 3 or severity < 1: - return "Severity needs to be a number from 1-3, not %d" % severity + return "Severity needs to be a number from 1-3, not %d" % severity alert = thehive4py.models.Alert( title=title, @@ -214,9 +214,61 @@ async def create_alert( except requests.exceptions.ConnectionError as e: return "ConnectionError: %s" % e + async def create_alert_artifact( + self, + apikey, + url, + alert_id, + dataType, + data, + message=None, + tlp="2", + ioc="False", + sighted="False", + ignoreSimilarity="False", + tags=None + ): + self.thehive = TheHiveApi(url, apikey, cert=False, version=4) + + if tlp: + tlp = int(tlp) + else: + tlp = 2 + + ioc = ioc.lower().strip() == "true" + sighted = sighted.lower().strip() == "true" + ignoreSimilarity = ignoreSimilarity.lower().strip() == "true" + + if tags: + tags = [x.strip() for x in tags.split(",")] + else: + tags = [] + + + + alert_artifact = thehive4py.models.AlertArtifact( + dataType=dataType, + data=data, + message=message, + tlp=tlp, + ioc=ioc, + sighted=sighted, + ignoreSimilarity=ignoreSimilarity, + tags=tags + ) + + try: + ret = self.thehive.create_alert_artifact(alert_id, alert_artifact) + except requests.exceptions.ConnectionError as e: + return "ConnectionError: %s" % e + if ret.status_code > 299: + raise ConnectionError(ret.text) + + return ret.text + # Gets an item based on input. E.g. field_type = Alert async def get_item(self, apikey, url, field_type, cur_id): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) newstr = "" ret = "" @@ -247,22 +299,22 @@ async def get_item(self, apikey, url, field_type, cur_id): return ret.text async def close_alert(self, apikey, url, alert_id): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) return self.thehive.mark_alert_as_read(alert_id).text async def reopen_alert(self, apikey, url, alert_id): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) return self.thehive.mark_alert_as_unread(alert_id).text async def create_case_from_alert(self, apikey, url, alert_id, case_template=None): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) response = self.thehive.promote_alert_to_case( alert_id=alert_id, case_template=case_template ) return response.text async def merge_alert_into_case(self, apikey, url, alert_id, case_id): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) req = url + f"/api/alert/{alert_id}/merge/{case_id}" ret = requests.post(req, auth=self.thehive.auth) return ret.text @@ -316,7 +368,7 @@ async def update_field(self, apikey, url, field_type, cur_id, field, data): # https://github.com/TheHive-Project/TheHiveDocs/tree/master/api/connectors/cortex async def run_analyzer(self, apikey, url, cortex_id, analyzer_id, artifact_id): - self.thehive = TheHiveApi(url, apikey) + self.thehive = TheHiveApi(url, apikey, cert=False) return self.thehive.run_analyzer(cortex_id, artifact_id, analyzer_id).text # Creates a task log in TheHive with file