diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/RansomwareReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/RansomwareReport.js
index dd0cc2f53..3e7a96311 100644
--- a/monkey/monkey_island/cc/ui/src/components/report-components/RansomwareReport.js
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/RansomwareReport.js
@@ -6,6 +6,7 @@ import FileEncryptionTable from './ransomware/FileEncryptionTable';
import LateralMovement from './ransomware/LateralMovement';
import '../../styles/pages/report/RansomwareReport.scss';
+import BreachSection from './ransomware/BreachSection';
class RansomwareReport extends React.Component {
@@ -16,6 +17,7 @@ class RansomwareReport extends React.Component {
generateReportContent() {
return (
+
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js b/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js
index 7bbef33bc..f06ee4849 100644
--- a/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js
@@ -1,8 +1,34 @@
import React from 'react';
-export let renderArray = function (val) {
- return <>{val.map(x => {x}
)}>;
+export let renderArray = function (val, className='') {
+ return <>{val.map(x => {x}
)}>;
};
export let renderIpAddresses = function (val) {
- return {renderArray(val.ip_addresses)} {(val.domain_name ? ' ('.concat(val.domain_name, ')') : '')}
;
+ return
+ {renderArray(val.ip_addresses, 'ip-address')} {(val.domain_name ? ' ('.concat(val.domain_name, ')') : '')}
+
;
};
+
+export let renderLimitedArray = function (array,
+ limit,
+ className='',
+ separator=',') {
+ let elements = [];
+ if(array.length < limit){
+ limit = array.length;
+ }
+ for(let i = 0; i < limit; i++){
+ let element = '';
+ if(i !== 0) {
+ element = (<>{separator} {array[i]}>);
+ } else {
+ element = (<>{array[i]}>);
+ }
+ elements.push({element}
);
+ }
+ let remainder = array.length - limit;
+ if(remainder > 0){
+ elements.push( and {remainder} more
);
+ }
+ return elements
+}
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/ransomware/BreachSection.tsx b/monkey/monkey_island/cc/ui/src/components/report-components/ransomware/BreachSection.tsx
new file mode 100644
index 000000000..0cf23dfdd
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/report-components/ransomware/BreachSection.tsx
@@ -0,0 +1,49 @@
+import React, {useEffect, useState} from "react";
+import IslandHttpClient from "../../IslandHttpClient";
+import NumberedReportSection from "./NumberedReportSection";
+import LoadingIcon from "../../ui-components/LoadingIcon";
+import {renderLimitedArray} from "../common/RenderArrays";
+
+function BreachSection() {
+ const [machines, setMachines] = useState(null);
+ let description = 'Ransomware attacks start after machines in the internal network get compromised. ' +
+ 'The initial compromise was simulated by running monkeys manually.';
+
+ useEffect(() => {
+ IslandHttpClient.get('/api/exploitations/manual')
+ .then(resp => setMachines(resp.body['manual_exploitations']));
+ }, []);
+
+ if(machines !== null){
+ let body = getBreachSectionBody(machines);
+ return ()
+ } else {
+ return
+ }
+}
+
+function getBreachSectionBody(machines) {
+ let machineList = [];
+ for(let i = 0; i < machines.length; i++){
+ machineList.push({getMachine(machines[i])});
+ }
+ return (
+
+
Ransomware attack started from these machines on the network:
+
+
+ )
+ }
+
+function getMachine(machine) {
+ return (
+ <>
+ {machine['hostname']}
+ ({renderLimitedArray(machine['ip_addresses'], 2, 'ip-address')}) at {machine['start_time']}
+ >
+ )
+}
+
+export default BreachSection;
diff --git a/monkey/monkey_island/cc/ui/src/styles/pages/report/RansomwareReport.scss b/monkey/monkey_island/cc/ui/src/styles/pages/report/RansomwareReport.scss
index 0a3ea2bf9..143e3f835 100644
--- a/monkey/monkey_island/cc/ui/src/styles/pages/report/RansomwareReport.scss
+++ b/monkey/monkey_island/cc/ui/src/styles/pages/report/RansomwareReport.scss
@@ -18,3 +18,7 @@
margin-top: .28em;
margin-right: .5em;
}
+
+.ransomware-breach-section .ip-address {
+ display: inline-block;
+}