The following script will protect a KeyScaler instance against CVE-2021-44228.
The upcoming release of KeyScaler v6.7.4 will address this vulnerability directly, however any KeyScaler v6.7.3 or earlier should use the following process to mitigate this vulnerability.
• The script must be run on ALL KeyScaler nodes
• You must stop services before running it
Executing the script:
- Stop dfactor services
service dfactor stop - Copy the contents of this script into a new file in the /var/www/tomcat/webapps directory
- Make the script executable
chmod +x fix-log4j.sh - Execute
./fix-log4j.sh - Start services again
service dfactor start
The Script
# copy the contents of this script into /var/www/tomcat/webapps directory
# make it executable: chmod +x fix-log4j.sh
# run the script: ./fix-log4j.sh
arr=(./*.war)
# create a backup dir for existing war files
mkdir backup
GPROC="[o]rg.apache.catalina.startup.Bootstrap start"
procCount() {
procCount="$(ps ax | grep "$(echo $GPROC)" | awk '{printf $1 " "}' | wc | awk '{print $2}')"
echo $procCount
}
procRunning() {
if [ $(procCount) -gt 0 ]
then
return 0
else
return 1
fi
}
if procRunning
then
echo "dfactor service is currently running - please stop dfactor service before running this script."
exit 99
fi
for i in "${arr[@]}"
do
SERVICENAME="${i%.*}"
echo -e "\n######### ${SERVICENAME} #########"
echo "Copying existing ${SERVICENAME} to ./backup directory"
cp ${i} backup/
echo "Removing existing unpacked files (if they exist)..."
rm -rf ${SERVICENAME}
echo "Unpacking ${i} file..."
unzip -q -d ${SERVICENAME} ${i}
if [ $? -eq 0 ]
then
echo "War file unpacked!"
rm ${i}
else
echo "Failed to unpack ${i} - cannot continue"
exit 1
fi
# check if log4j-core is present in this service
if [ -f ${SERVICENAME}/WEB-INF/lib/log4j-core-*.jar ]
then
# get an MD5 hash of the current version of log4j - so we can be sure it changed
echo "Getting MD5 of log4j-core..."
md5sum ${SERVICENAME}/WEB-INF/lib/log4j-core*.jar
# remove the JndiLookup.class from log4j-core
echo "Removing JndiLookup.class from log4j-core..."
zip -q -d ${SERVICENAME}/WEB-INF/lib/log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
if [ $? -eq 0 ]
then
echo "Successfully removed class from log4j-core!"
# print the new MD5 of log4j-core, post-modification
echo "Getting new MD5 of log4j-core... (should be different from previous value)"
md5sum ${SERVICENAME}/WEB-INF/lib/log4j-core*.jar
# repack the directory as a new .war file
echo "Repacking ${i}..."
cd ${SERVICENAME}/; zip -qr ../${i} ./*; cd ..
if [ $? -eq 0 ]
then
echo "Successfully repackaged ${i}!"
else
echo "Failed to repackage ${i}..."
exit 1
fi
else
# this can happen if running against a version that has already been fixed
echo "Failed to remove JndiLookup.class from log4j-core. Has this version already been fixed?"
echo "Restoring backup of ${i} and moving on."
mv ./backup/${i} .
fi
else
echo "log4j-core not found in ${i} - restoring backup and moving on."
# not much to do - revert to backup and move on
mv ./backup/${i} .
fi
rm -rf ${SERVICENAME}
done
echo "Finished!"
With JAR Utility
If you do not have unzip/zip on the host machine - you can do it using the native JAR utility using the following script:
NB: You must define the location of your jar executable on line 11.
# copy the contents of this script into /var/www/tomcat/webapps directory
# make it executable: chmod +x fix-log4j.sh
# run the script: ./fix-log4j.sh
arr=(./*.war)
# create a backup dir for existing war files
mkdir backup
# location of the 'jar' executable
JAR_BIN="/usr/java/jdk1.8.0_311-amd64/bin/jar"
GPROC="[o]rg.apache.catalina.startup.Bootstrap start"
procCount() {
procCount="$(ps ax | grep "$(echo $GPROC)" | awk '{printf $1 " "}' | wc | awk '{print $2}')"
echo $procCount
}
procRunning() {
if [ $(procCount) -gt 0 ]
then
return 0
else
return 1
fi
}
if procRunning
then
echo "dfactor service is currently running - please stop dfactor service before running this script."
exit 99
fi
for i in "${arr[@]}"
do
SERVICENAME="${i%.*}"
echo -e "\n######### ${SERVICENAME} #########"
echo "Copying existing ${SERVICENAME} to ./backup directory"
cp ${i} backup/
echo "Removing existing unpacked files (if they exist)..."
rm -rf ${SERVICENAME}
echo "Unpacking ${i} file..."
mkdir ${SERVICENAME}; cd ${SERVICENAME}; ${JAR_BIN} -xvf ../${i} > /dev/null 2>&1; cd ..
if [ $? -eq 0 ]
then
echo "War file unpacked!"
rm ${i}
else
echo "Failed to unpack ${i} - cannot continue"
exit 1
fi
# check if log4j-core is present in this service
if [ -f ${SERVICENAME}/WEB-INF/lib/log4j-core-*.jar ]
then
# get an MD5 hash of the current version of log4j - so we can be sure it changed
echo "Getting MD5 of log4j-core..."
md5sum ${SERVICENAME}/WEB-INF/lib/log4j-core*.jar
cd ./${SERVICENAME}/WEB-INF/lib
log4j=(./log4j-core-*.jar)
for lib in "${log4j[@]}"
do
echo "Extracting ${lib}..."
LIBNAME="${lib%.*}"
mkdir ${LIBNAME}; cd ${LIBNAME}; ${JAR_BIN} -xvf ../${lib} > /dev/null 2>&1; cd ..
echo "Removing JndiLookup.class from log4j-core..."
rm -f ${LIBNAME}/org/apache/logging/log4j/core/lookup/JndiLookup.class
echo "Successfully removed class from log4j-core!"
echo "Compressing log4j-core and removing temp directory.."
cd ${LIBNAME}; ${JAR_BIN} -cvf ../${lib} * > /dev/null 2>&1; cd ../; rm -rf ./${LIBNAME}
echo "Getting new MD5 of log4j-core... (should be different from previous value)"
md5sum log4j-core*.jar
echo "Recompressing ${i}..."
cd ../../; ${JAR_BIN} -cvf ../${SERVICENAME}.war * > /dev/null 2>&1; cd ../
done
else
echo "log4j-core not found in ${i} - restoring backup and moving on."
# not much to do - revert to backup and move on
mv ./backup/${i} .
fi
rm -rf ${SERVICENAME}
done
echo "Finished!"