CVE-2022-36436 (published 2022-09-14T11:15Z)

OSU Open Source Lab VNCAuthProxy through 1.1.1 is affected by an vncap/vnc/protocol.py VNCServerAuthenticator authentication-bypass vulnerability that could allow a malicious actor to gain unauthorized access to a VNC session or to disconnect a legitimate user from a VNC session. A remote attacker with network access to the proxy server could leverage this vulnerability to connect to VNC servers protected by the proxy server without providing any authentication credentials. Exploitation of this issue requires that the proxy server is currently accepting connections for the target VNC server.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-287
cwe_name: Improper Authentication
description: When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
extended_description: 
            
			
         
         

Fix information:
repo_url: https://github.com/osuosl/twisted_vncauthproxy
commit_details: repo_url: https://github.com/osuosl/twisted_vncauthproxy
author: Marios Levogiannis
author_date: 2022-07-29 18:40:09+03:00
msg: Fix CVE-2022-36436 - Authentication bypass in RFB security handshake (#1)
repository: repo_url: https://github.com/osuosl/twisted_vncauthproxy
repo_name: osuosl/twisted_vncauthproxy
description: VNCAuthProxy is a proxy server for VNC with man-in-the-middle authentication. This is used as a gateway to VNC servers behind protected networks. It supports WebSockets for use with noVNC.
repo_language: Python
owner: osuosl
file_changes: filename: test_protocol.py
change_type: ModificationType.MODIFY
diff: @@ -13,6 +13,9 @@ class DummyTransport(object):
     def loseConnection(self):
         self.lost = True
 
+    def pauseProducing(self):
+        pass
+
 class TestVNCServerAuthenticator(unittest.TestCase):
 
     def setUp(self):
@@ -29,9 +32,20 @@ class TestVNCServerAuthenticator(unittest.TestCase):
     def test_check_version(self):
         self.t.buf = ""
         self.p.check_version("RFB 003.008\n")
-        self.assertEqual(self.t.buf, "\x02\x01\x02")
+        self.assertEqual(self.t.buf, "\x01\x02")
 
     def test_check_invalid_version(self):
         self.t.buf = ""
         self.p.check_version("RFB 002.000\n")
         self.assertTrue(self.t.lost)
+
+    def test_select_security_type_none(self):
+        self.t.buf = ""
+        self.p.select_security_type("\x01")
+        self.assertTrue(self.t.lost)
+
+    def test_select_security_type_vnc_auth(self):
+        self.t.buf = ""
+        self.p.select_security_type("\x02")
+        self.assertFalse(self.t.lost)
+        self.assertEqual(len(self.t.buf), 16)

programming_language: Python
filename: protocol.py
change_type: ModificationType.MODIFY
diff: @@ -73,8 +73,8 @@ class VNCServerAuthenticator(VNCAuthenticator):
 
         if version == self.VERSION:
             log.msg("Client version %s is valid" % version.strip())
-            # Hardcoded: 2 security types: None and VNC Auth.
-            self.transport.write("\x02\x01\x02")
+            # Hardcoded: 1 security type: VNC Auth.
+            self.transport.write("\x01\x02")
             return self.select_security_type, 1
         else:
             log.err("Can't handle VNC version %r" % version)
@@ -93,9 +93,6 @@ class VNCServerAuthenticator(VNCAuthenticator):
             self.transport.write(self.challenge)
 
             return self.vnc_authentication_result, 16
-        elif security_type == 1:
-            # No authentication. Just move to the SecurityResult.
-            self.authenticated()
         else:
             log.err("Couldn't agree on an authentication scheme!")
             self.transport.loseConnection()

programming_language: Python