CVE-2026-7161
A insufficient encryption vulnerability exists in the Device Authentication functionality of GV-IP Device Utility (version(s): 9.0.5). A specially crafted network sniffing can lead to credentials leak. An attacker can listen to broadcast messages to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
GV-IP Device Utility (version(s): 9.0.5)
GV-IP Device Utility - https://www.geovision.com.tw/download/product/
9.3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:H
CWE-656 - Reliance on Security Through Obscurity
GV-IP Device Utility is a tool that detects and interacts with existing GeoVision devices present on the same LAN.
When interacting with various Geovision devices on the network, the utility may send privileged commands; in order to do so, the username and password of the device need to be provided. In some instances the command is broadcasted over UDP and the username/password are encrypted using a cryptographic protocol that appears to be derivated from Blowfish. However the symmetric key used for the encryption is also included in the packet, and thus the security of the username/password only relies on the “obscurity” of the encryption scheme. An attacker on the same LAN can listen to the broadcast traffic once an admin user interacts with the device, and decrypt the credentials using their own implementation of the algorithm. With this password the attacker would have full control over the device configuration, allowing them to change its ip address or even reset it to factory default.
For instance, when calling commands such as the Reboot command (id=0xA005), the UDP packet is updated to include the encrypted credentials and key material using the following function:
`
char __stdcall encrypt_username_and_password_to_pkt(int a1, cmd_packet_generic *a2)
{
memset(username_enc, 0, sizeof(username_enc));
memset(password_enc, 0, sizeof(password_enc));
blowfish_init_key(&bf_key, 10);
v11 = 0;
bf_key_ = *(_OWORD *)bf_key;
key = *(_OWORD *)bf_key;
ctx = (blowfish_ctx *)custom_malloc(8);
/* alloc ctx */
init_blowfish(ctx, (char *)&key, 16); // [0]
blowfish_encrypt((char *)ctx, (char *)(a1 + 344), (unsigned int)username_enc, 0x20u); // [1]
blowfish_encrypt((char *)ctx, (char *)(a1 + 376), (unsigned int)password_enc, 0x20u);
/* cleanup ctx */
*(_OWORD *)a2->username = *(_OWORD *)username_enc; //[2]
*(_OWORD *)&a2->username[16] = *(_OWORD *)&username_enc[4];
*(_OWORD *)a2->password = *(_OWORD *)password_enc;
*(_OWORD *)&a2->password[16] = *(_OWORD *)&password_enc[4];
v11 = -1;
v3 = bf_key;
*(_OWORD *)a2->key = bf_key_; //[3]
/* */
return 1;
} `
We can see that at [0] a blowfish key is initialized, then at at [1] the username and password are encrypted, then at [2] the encrypted username and password are added to the data packet and then at [3] the blow fish key is stored as is.
2026-02-24 - Initial Vendor Contact
2026-02-24 - Vendor Disclosure
2026-05-27 - Vendor Patch Release
2026-06-15 - Public Release
Philippe Laulheret of Cisco Talos