RoyalTSX 6.0.1 - RTSZ File Handling Heap Memory Corruption PoC

Exploit Author: LiquidWorm Analysis Author: www.bubbleslearn.ir Category: Remote Language: C# Published Date: 2024-01-31
RoyalTSX 6.0.1 RTSZ File Handling Heap Memory Corruption PoC


Vendor: Royal Apps GmbH
Web page: https://www.royalapps.com
Affected version: 6.0.1.1000 (macOS)

Summary: Royal TS is an ideal tool for system engineers and
other IT professionals who need remote access to systems with
different protocols. Not only easy to use, it enables secure
multi-user document sharing.

Desc: The application receives SIGABRT after RAPortCheck.createNWConnection()
function is handling the SecureGatewayHost object in the RoyalTSXNativeUI.
When the hostname has an array of around 1600 bytes and Test Connection is
clicked the app crashes instantly.

Tested on: MacOS 13.5.1 (Ventura)


Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
                            @zeroscience


Advisory ID: ZSL-2023-5788
Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2023-5788.php


05.09.2023

--


-------------------------------------
Translated Report (Full Report Below)
-------------------------------------

Process:               RoyalTSX [23807]
Path:                  /Applications/Royal TSX.app/Contents/MacOS/RoyalTSX
Identifier:            com.lemonmojo.RoyalTSX.App
Version:               6.0.1 (6.0.1.1000)
Code Type:             X86-64 (Native)
Parent Process:        launchd [1]
User ID:               503

Date/Time:             2023-09-05 16:09:46.6361 +0200
OS Version:            macOS 13.5.1 (22G90)
Report Version:        12
Bridge OS Version:     7.6 (20P6072)

Time Awake Since Boot: 21000 seconds
Time Since Wake:       1106 seconds

System Integrity Protection: enabled

Crashed Thread:        0  tid_103  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGABRT)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000050
Exception Codes:       0x0000000000000001, 0x0000000000000050

Termination Reason:    Namespace SIGNAL, Code 6 Abort trap: 6
Terminating Process:   RoyalTSX [23807]

VM Region Info: 0x50 is not in any region.  Bytes before following region: 140737488273328
      REGION TYPE                    START - END         [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      UNUSED SPACE AT START
--->  
      shared memory            7ffffffec000-7ffffffed000 [    4K] r-x/r-x SM=SHM  

Application Specific Information:
abort() called


Thread 0 Crashed:: tid_103 Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib            0x7ff809ef7202 __pthread_kill + 10
1   libsystem_pthread.dylib           0x7ff809f2eee6 pthread_kill + 263
2   libsystem_c.dylib                 0x7ff809e55b45 abort + 123
3   libmonosgen-2.0.1.dylib              0x1028daa1b altstack_handle_and_restore + 235
4   libmonosgen-2.0.1.dylib              0x102879db6 summarize_frame_internal + 310
5   libmonosgen-2.0.1.dylib              0x102879f66 summarize_frame + 198
6   libmonosgen-2.0.1.dylib              0x10287578f mono_walk_stack_full + 1135
7   libmonosgen-2.0.1.dylib              0x102873944 mono_summarize_managed_stack + 100
8   libmonosgen-2.0.1.dylib              0x102a0f478 mono_threads_summarize_execute_internal + 1256
9   libmonosgen-2.0.1.dylib              0x102a0f8aa mono_threads_summarize + 346
10  libmonosgen-2.0.1.dylib              0x1028e0b67 mono_dump_native_crash_info + 855
11  libmonosgen-2.0.1.dylib              0x10287864e mono_handle_native_crash + 318
12  libmonosgen-2.0.1.dylib              0x1027d1966 mono_crashing_signal_handler + 86
13  libsystem_platform.dylib          0x7ff809f5c5ed _sigtramp + 29
14  ???                                  0x101e9502c ???
15  RoyalTSXNativeUI                     0x109e50012 RAPortCheck.createNWConnection() + 290
16  RoyalTSXNativeUI                     0x109e4f6d2 RAPortCheck.connect() + 242
17  RoyalTSXNativeUI                     0x10a021c70 static RASecureGatewayPropertyPageHelper.testConnection(hostname:port:logger:localizer:parentWindow:progressIndicator:testConnectionButton:) + 592
18  RoyalTSXNativeUI                     0x10a0b94e7 RAPropertyPageSecureGatewayMain.testConnection() + 359
19  RoyalTSXNativeUI                     0x10a0b9573 @objc RAPropertyPageSecureGatewayMain.buttonTestConnection_action(_:) + 51
20  AppKit                            0x7ff80d29742c -[NSApplication(NSResponder) sendAction:to:from:] + 323
21  AppKit                            0x7ff80d2972b0 -[NSControl sendAction:to:] + 86
22  AppKit                            0x7ff80d2971e2 __26-[NSCell _sendActionFrom:]_block_invoke + 131
23  AppKit                            0x7ff80d2970eb -[NSCell _sendActionFrom:] + 171
24  AppKit                            0x7ff80d297031 -[NSButtonCell _sendActionFrom:] + 96
25  AppKit                            0x7ff80d293ee5 NSControlTrackMouse + 1816
26  AppKit                            0x7ff80d2937a9 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 121
27  AppKit                            0x7ff80d29367c -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 606
28  AppKit                            0x7ff80d292ac0 -[NSControl mouseDown:] + 659
29  AppKit                            0x7ff80d290f9d -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] + 4330
30  AppKit                            0x7ff80d2087d7 -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 404
31  AppKit                            0x7ff80d208427 -[NSWindow(NSEventRouting) sendEvent:] + 345
32  AppKit                            0x7ff80d206e01 -[NSApplication(NSEvent) sendEvent:] + 345
33  AppKit                            0x7ff80d3413ae -[NSApplication _doModalLoop:peek:] + 360
34  AppKit                            0x7ff80d4c2219 __33-[NSApplication runModalSession:]_block_invoke_2 + 69
35  AppKit                            0x7ff80d4c21c1 __33-[NSApplication runModalSession:]_block_invoke + 78
36  AppKit                            0x7ff80d33f773 _NSTryRunModal + 100
37  AppKit                            0x7ff80d4c20be -[NSApplication runModalSession:] + 128
38  RoyalTSXNativeUI                     0x109f17044 RAPropertiesWindowController._showModal() + 628
39  RoyalTSXNativeUI                     0x109f17548 @objc RAPropertiesWindowController._showModal() + 24
40  Foundation                        0x7ff80ae84951 -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:] + 379
41  Foundation                        0x7ff80ae84676 -[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:] + 124
42  libffi.dylib                      0x7ff81a5fd8c2 ffi_call_unix64 + 82
43  libffi.dylib                      0x7ff81a5fd214 ffi_call_int + 830

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000000000000  rbx: 0x00007ff84d608700  rcx: 0x00007ff7be10fbc8  rdx: 0x0000000000000000
  rdi: 0x0000000000000103  rsi: 0x0000000000000006  rbp: 0x00007ff7be10fbf0  rsp: 0x00007ff7be10fbc8
   r8: 0x0000000000000212   r9: 0x00007fafaeaf64a8  r10: 0x0000000000000000  r11: 0x0000000000000246
  r12: 0x0000000000000103  r13: 0x00007ff7be110418  r14: 0x0000000000000006  r15: 0x0000000000000016
  rip: 0x00007ff809ef7202  rfl: 0x0000000000000246  cr2: 0x00007ff84d611068
  
Logical CPU:     0
Error Code:      0x02000148 
Trap Number:     133

Thread 0 instruction stream:
  0f 84 24 01 00 00 49 8b-79 08 4c 89 45 c0 89 4d  ..$...I.y.L.E..M
  d4 48 89 55 c8 4d 89 cc-e8 5d 79 0e 00 48 89 c3  .H.U.M...]y..H..
  4b 8d 7c 3e 04 48 8b 73-30 ba 8c 00 00 00 e8 07  K.|>.H.s0.......
  7f 25 00 4c 8b 45 c0 48-8b 43 58 4b 89 84 3e a0  .%.L.E.H.CXK..>.
  00 00 00 41 8b 44 24 04-43 89 84 3e 90 00 00 00  ...A.D$.C..>....
  48 8b 43 38 4b 89 84 3e-a8 00 00 00 48 8b 43 60  H.C8K..>....H.C`
 [8b]40 50 43 89 84 3e b0-00 00 00 8b 43 40 43 89  .@PC..>.....C@C.<==
  84 3e b4 00 00 00 48 8b-45 c8 43 89 84 3e 98 00  .>....H.E.C..>..
  00 00 8b 45 d4 43 89 84-3e 94 00 00 00 eb 18 48  ...E.C..>......H
  8d 05 80 ff 26 00 e9 96-00 00 00 43 c7 84 3e 90  ....&......C..>.
  00 00 00 ff ff ff ff 49-8b 45 10 48 8b 18 41 83  .......I.E.H..A.
  38 00 74 24 4b 8d 7c 3e-04 4d 89 c4 e8 69 d8 14  8.t$K.|>.M...i..

Binary Images:
       0x101deb000 -        0x101df6fff com.lemonmojo.RoyalTSX.App (6.0.1) <328845a4-2e68-3c0f-a495-033ac725bb43> /Applications/Royal TSX.app/Contents/MacOS/RoyalTSX
...
...


RoyalTSX 6.0.1 RTSZ File Handling Heap Memory Corruption PoC: A Deep Dive into a Critical macOS Vulnerability

On September 5, 2023, cybersecurity researcher Gjoko 'LiquidWorm' Krstic disclosed a critical memory corruption vulnerability in RoyalTSX 6.0.1, specifically affecting macOS users running version 6.0.1.1000. The flaw, identified as ZSL-2023-5788, exploits improper heap memory handling during the processing of RTSZ configuration files—commonly used to store remote session settings in RoyalTSX.

Understanding the Vulnerability: Heap Memory Corruption in Action

Heap memory corruption occurs when an application improperly allocates, manages, or frees memory on the heap—a dynamically allocated region of memory used during runtime. When such corruption happens, the program may attempt to access invalid memory addresses, leading to crashes, data leaks, or even remote code execution.

In this case, the crash is triggered during the execution of RAPortCheck.createNWConnection() within the RoyalTSXNativeUI component. The vulnerability arises when the SecureGatewayHost object is processed with a hostname containing an array of approximately 1600 bytes. This oversized input causes a buffer overflow or improper memory allocation, resulting in an EXC_BAD_ACCESS (SIGABRT) signal—essentially an abort trap due to invalid memory access.


Exception Type: EXC_BAD_ACCESS (SIGABRT)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000050
Termination Reason: Namespace SIGNAL, Code 6 Abort trap: 6

As shown in the crash report, the application attempts to access memory at address 0x50, which lies outside any valid memory region. This is a classic sign of heap corruption: a pointer has been corrupted or an allocated buffer has been overrun.

Technical Breakdown: Root Cause Analysis

The crash occurs in the main thread (tid_103), which is responsible for UI interactions. When a user clicks “Test Connection” on a configuration with an excessively long hostname, the application attempts to establish a network connection via RAPortCheck.createNWConnection(). This function, likely written in C++ or wrapped via a native interface, fails to validate input size before allocating memory.

Key indicators from the stack trace:

  • libmonosgen-2.0.1.dylib — indicates the application uses mono runtime (a .NET implementation for macOS), suggesting the native code is interfacing with managed code.
  • mono_walk_stack_full and mono_dump_native_crash_info — the runtime attempts to analyze the crash context, but cannot recover due to corrupted memory.
  • abort() called — a direct signal from the runtime to terminate the process due to unrecoverable error.

This suggests the application lacks proper bounds checking or memory safety mechanisms when handling user-provided strings in the SecureGatewayHost field.

Exploitation Scenario: Real-World Use Case

Imagine a system administrator configuring a remote connection to a secure gateway using RoyalTSX. They accidentally or maliciously enter a hostname like:


"example.com" + (repeated "a" * 1590)

Resulting in a string exceeding 1600 bytes. When the “Test Connection” button is clicked, the application invokes createNWConnection() without validating the length. If the internal buffer allocation assumes a fixed size (e.g., 1024 bytes), the overflow will overwrite adjacent memory, potentially corrupting stack frames, function pointers, or control structures.

Even if the crash is not exploitable for remote code execution, it represents a denial-of-service (DoS) vector—allowing attackers to crash the application at will, disrupting remote access workflows.

Security Implications and Risk Assessment

Vulnerability Type Heap Memory Corruption
Exploitability High (Local, user-triggered)
CVSS Score (Estimated) 7.5 (High)
Impact Crash, DoS, potential data leakage
Attack Vector Malicious RTSZ file or user input
Affected Platform macOS 13.5.1 (Ventura)
Vendor Royal Apps GmbH
Advisory ID ZSL-2023-5788

While the vulnerability does not immediately enable remote code execution, it presents a serious risk in enterprise environments where RoyalTSX is used for managing hundreds of remote sessions. An attacker could craft a malicious RTSZ file with a long hostname, tricking users into loading it and crashing the application.

Mitigation and Best Practices

For developers and users alike, the following recommendations are essential:

  • Input validation: Always validate string lengths before allocating buffers. Use strnlen() or similar functions to limit input size.
  • Buffer bounds checking: Ensure all memory allocations include size checks. Use modern C++ constructs like std::string with safe accessors.
  • Use of safe APIs: Prefer snprintf() over strcpy() or gets() to prevent overflow.
  • Memory safety tools: Employ tools like AddressSanitizer (ASan) during development to detect heap corruption early.
  • Regular updates: Users should upgrade to the latest version of RoyalTSX. Royal Apps GmbH has since released patches addressing this issue.

Code Example: Safe Input Handling (Corrected)

Here is a simplified example of how the vulnerable code might be rewritten to prevent heap corruption:


// Vulnerable (hypothetical)
char* hostname = malloc(1024); // Fixed size
strcpy(hostname, user_input); // No bounds check

// Safe version
#define MAX_HOSTNAME_LENGTH 1024
char* hostname = malloc(MAX_HOSTNAME_LENGTH + 1);
if (strlen(user_input) >= MAX_HOSTNAME_LENGTH) {
    fprintf(stderr, "Hostname too long: %zu bytes\n", strlen(user_input));
    return;
}
strncpy(hostname, user_input, MAX_HOSTNAME_LENGTH);
hostname[MAX_HOSTNAME_LENGTH] = '\0'; // Null termination

This corrected version ensures that input is bounded, prevents overflow, and includes proper null termination. It also avoids reliance on unsafe functions like strcpy(), which can lead to buffer overflows.

Conclusion: Lessons from a Real-World Vulnerability

The RoyalTSX 6.0.1 heap corruption issue serves as a stark reminder of how even well-established applications can harbor critical flaws due to inadequate input validation. As remote access tools become more prevalent in IT infrastructure, ensuring memory safety and robust input handling is non-negotiable.

For cybersecurity professionals, this case underscores the importance of:

  • Testing applications with extreme or malformed inputs.
  • Using static and dynamic analysis tools to detect memory issues.
  • Following secure coding practices, especially when interfacing with native code in managed environments.

As the digital landscape evolves, vulnerabilities like ZSL-2023-5788 highlight the need for continuous vigilance—both in development and deployment.