Ejemplo n.º 1
0
/*
* SfExtractDropper
*
* Purpose:
*
* Extract Sirefef/ZeroAccess from image resource.
*
* CNG variant
*
*/
UINT SfExtractDropper(
	LPWSTR lpCommandLine
	)
{
	BOOL                  cond = FALSE, bSuccess = FALSE;
	ULONG                 c, uKey = 0, imagesz;
	WCHAR                 szInputFile[MAX_PATH + 1];
	WCHAR                 szOutputFile[MAX_PATH + 1];
	WCHAR                 szKey[MAX_PATH];
	PVOID                 ImageBase = NULL, EncryptedData = NULL, DecryptedData = NULL;
	IStream              *pImageStream = NULL;
	ULONG_PTR             gdiplusToken = 0;
	GdiplusStartupInput   input;
	GdiplusStartupOutput  output;
	PVOID                 BitmapPtr = NULL;
	GdiPlusBitmapData     BitmapData;
	GdiPlusRect           rect;
	SIZE_T                sz;
	PULONG                ptr, i_ptr;
	
	//input file
	c = 0;
	RtlSecureZeroMemory(szInputFile, sizeof(szInputFile));
	GetCommandLineParam(lpCommandLine, 1, (LPWSTR)&szInputFile, MAX_PATH, &c);
	if (c == 0) {
		SfcuiPrintText(g_ConOut,
			T_SFEXTRACTUSAGE,
			g_ConsoleOutput, FALSE);
		return (UINT)-1;
	}

	//output file
	c = 0;
	RtlSecureZeroMemory(&szOutputFile, sizeof(szOutputFile));
	GetCommandLineParam(lpCommandLine, 2, (LPWSTR)&szOutputFile, MAX_PATH, &c);
	if (c == 0) {
		_strcpy(szOutputFile, TEXT("extracted.bin"));
	}

	//key
	c = 0;
	RtlSecureZeroMemory(&szKey, sizeof(szKey));
	GetCommandLineParam(lpCommandLine, 3, (LPWSTR)&szKey, MAX_PATH, &c);
	if ((c == 0) || (c > 10)) {
		SfcuiPrintText(g_ConOut,
			T_SFEXTRACTUSAGE,
			g_ConsoleOutput, FALSE);
		return (UINT)-1;
	}

	c = 0;
	if (locase_w(szKey[1]) == 'x') {
		c = 2;
	} 
	uKey = hextoul(&szKey[c]);

	do {

		ImageBase = SfuCreateFileMappingNoExec(szInputFile);
		if (ImageBase == NULL)
			break;

		c = 0;
		EncryptedData = SfLdrQueryResourceData(1, ImageBase, &c);
		if ((EncryptedData == NULL) || (c == 0))
			break;

		pImageStream = SHCreateMemStream((BYTE *)EncryptedData, (UINT)c);
		if (pImageStream == NULL)
			break;

		RtlSecureZeroMemory(&input, sizeof(input));
		RtlSecureZeroMemory(&output, sizeof(output));
		input.GdiplusVersion = 1;

		if (GdiplusStartup(&gdiplusToken, &input, &output) != GdiplusOk)
			break;

		BitmapPtr = NULL;
		if (GdipCreateBitmapFromStream(pImageStream, &BitmapPtr) != GdiplusOk)
			break;

		RtlSecureZeroMemory(&rect, sizeof(rect));
		
		if (
			(GdipGetImageWidth(BitmapPtr, (UINT *)&rect.Width) == GdiplusOk) &&
			(GdipGetImageHeight(BitmapPtr, (UINT *)&rect.Height) == GdiplusOk)
			)
		{
			RtlSecureZeroMemory(&BitmapData, sizeof(BitmapData));
			if (GdipBitmapLockBits(BitmapPtr, &rect, ImageLockModeRead, PixelFormat32bppARGB, &BitmapData) == GdiplusOk) {

				c = (rect.Width * rect.Height);
				
				imagesz = sizeof(ULONG) * c;
				sz = imagesz;
				DecryptedData = NULL;
				NtAllocateVirtualMemory(NtCurrentProcess(), &DecryptedData, 0, &sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
				if (DecryptedData) {
					
					i_ptr = (PULONG)BitmapData.Scan0;
					ptr = DecryptedData;				
					while (c > 0) {
						*ptr = *i_ptr ^ uKey;
						ptr++;
						i_ptr++;
						c--;
					}

					bSuccess = (SfuWriteBufferToFile(szOutputFile, DecryptedData, imagesz, FALSE, FALSE) == imagesz);

					sz = 0;
					NtFreeVirtualMemory(NtCurrentProcess(), &DecryptedData, &sz, MEM_RELEASE);
				}
				GdipBitmapUnlockBits(BitmapPtr, &BitmapData);
			}
		}

	} while (cond);

	if (bSuccess == FALSE) {
		SfcuiPrintText(g_ConOut,
			T_SFEXTRACTFAIL,
			g_ConsoleOutput, FALSE);
	}
	else
	{
		SfcuiPrintText(g_ConOut,
			szOutputFile,
			g_ConsoleOutput, TRUE);
		SfcuiPrintText(g_ConOut,
			T_SFEXTRACTED,
			g_ConsoleOutput, TRUE);
	}

	if (BitmapPtr != NULL) {
		GdipDisposeImage(&BitmapPtr);
	}

	if (gdiplusToken != 0) {
		GdiplusShutdown(gdiplusToken);
	}

	if (pImageStream != NULL) {
		pImageStream->lpVtbl->Release(pImageStream);
	}

	if (ImageBase != NULL) {
		NtUnmapViewOfSection(NtCurrentProcess(), ImageBase);
	}
	return 0;
}
Ejemplo n.º 2
0
UINT SfDecryptPayload(
	LPWSTR lpParameter
	)
{
	BOOL                cond = FALSE, bSuccess = FALSE;
	PBYTE               cng_object, hashdata, decrypted, enc_data, extracted;
	ULONG               obj_sz, rlen, hdatasz, enc_data_size;
	BCRYPT_ALG_HANDLE   h_alg = NULL;
	BCRYPT_HASH_HANDLE  h_hash = NULL;
	BCRYPT_KEY_HANDLE   h_rc4key = NULL;
	NTSTATUS            status;
	HANDLE              pheap = NULL;
	PIMAGE_FILE_HEADER  fheader;
	PVOID               pdll = NULL;
	WCHAR               InputFile[MAX_PATH + 1], OutputFile[MAX_PATH + 1];

	rlen = 0;
	RtlSecureZeroMemory(InputFile, sizeof(InputFile));
	GetCommandLineParam(lpParameter, 1, InputFile, MAX_PATH, &rlen);
	if (rlen == 0) {
		SfcuiPrintText(g_ConOut,
			T_SFDECRYPTUSAGE,
			g_ConsoleOutput, FALSE);
		return (UINT)-1;
	}

	do {

		rlen = 0;
		GetCommandLineParam(lpParameter, 2, OutputFile, MAX_PATH, &rlen);
		
		if (rlen == 0)
			_strcpy(OutputFile, TEXT("out.bin"));
		
		pdll = SfuCreateFileMappingNoExec(InputFile);
		if (pdll == NULL)
			break;

		enc_data_size = 0;
		enc_data = SfuQueryResourceData(2, pdll, &enc_data_size);
		if (enc_data == NULL)
			break;

		fheader = &(RtlImageNtHeader(pdll)->FileHeader);

		status = BCryptOpenAlgorithmProvider(&h_alg, BCRYPT_MD5_ALGORITHM, NULL, 0);
		if (!NT_SUCCESS(status))
			break;
		obj_sz = 0;
		rlen = 0;
		status = BCryptGetProperty(h_alg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&obj_sz, sizeof(obj_sz), &rlen, 0);
		if (!NT_SUCCESS(status))
			break;

		hdatasz = 0;
		rlen = 0;
		status = BCryptGetProperty(h_alg, BCRYPT_HASH_LENGTH, (PUCHAR)&hdatasz, sizeof(hdatasz), &rlen, 0);
		if (!NT_SUCCESS(status))
			break;

		pheap = HeapCreate(0, 0, 0);
		if (pheap == NULL)
			break;

		cng_object = HeapAlloc(pheap, HEAP_ZERO_MEMORY, obj_sz);
		if (cng_object == NULL)
			break;

		hashdata = HeapAlloc(pheap, HEAP_ZERO_MEMORY, hdatasz);
		if (hashdata == NULL)
			break;

		status = BCryptCreateHash(h_alg, &h_hash, cng_object, obj_sz, NULL, 0, 0);
		if (!NT_SUCCESS(status))
			break;

		status = BCryptHashData(h_hash, (PUCHAR)fheader, sizeof(IMAGE_FILE_HEADER), 0);
		if (!NT_SUCCESS(status))
			break;

		status = BCryptFinishHash(h_hash, hashdata, hdatasz, 0);
		if (!NT_SUCCESS(status))
			break;

		BCryptDestroyHash(h_hash);
		BCryptCloseAlgorithmProvider(h_alg, 0);
		HeapFree(pheap, 0, cng_object);
		h_alg = NULL;
		h_hash = NULL;

		status = BCryptOpenAlgorithmProvider(&h_alg, BCRYPT_RC4_ALGORITHM, NULL, 0);
		if (!NT_SUCCESS(status))
			break;

		obj_sz = 0;
		rlen = 0;
		status = BCryptGetProperty(h_alg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&obj_sz, sizeof(obj_sz), &rlen, 0);
		if (!NT_SUCCESS(status))
			break;

		cng_object = HeapAlloc(pheap, HEAP_ZERO_MEMORY, obj_sz);
		if (cng_object == NULL)
			break;

		status = BCryptGenerateSymmetricKey(h_alg, &h_rc4key, cng_object, obj_sz, hashdata, hdatasz, 0);
		if (!NT_SUCCESS(status))
			break;

		decrypted = HeapAlloc(pheap, HEAP_ZERO_MEMORY, enc_data_size);
		if (decrypted == NULL)
			break;

		rlen = 0;
		status = BCryptEncrypt(h_rc4key, enc_data, enc_data_size, NULL, NULL, 0, decrypted, enc_data_size, &rlen, 0);
		if (!NT_SUCCESS(status))
			break;

		bSuccess = FALSE;
		enc_data_size = rlen;
		rlen = 0;
		extracted = SfcabExtractMemory(decrypted, enc_data_size, &rlen);
		if (extracted) {

			if (SfuWriteBufferToFile(OutputFile, extracted, rlen, FALSE, FALSE) == rlen) {
				bSuccess = TRUE;
			}
			LocalFree(extracted);
		}
		else {
			//failed to extract, drop cab as is
			if (SfuWriteBufferToFile(OutputFile, decrypted, enc_data_size, FALSE, FALSE) == enc_data_size) {
				bSuccess = TRUE;
			}
		}

		if (bSuccess) {

			SfcuiPrintText(g_ConOut,
				T_SFDECRYPTED,
				g_ConsoleOutput, FALSE);

			SfcuiPrintText(g_ConOut,
				OutputFile,
				g_ConsoleOutput, FALSE);
		}

	} while (cond);

	if (bSuccess == FALSE) {

		SfcuiPrintText(g_ConOut,
			T_SFDECRYPTFAIL,
			g_ConsoleOutput, FALSE);
		
	}

	if (h_rc4key != NULL)
		BCryptDestroyKey(h_rc4key);

	if (h_hash != NULL)
		BCryptDestroyHash(h_hash);

	if (h_alg != NULL)
		BCryptCloseAlgorithmProvider(h_alg, 0);

	if (pheap != NULL)
		HeapDestroy(pheap);

	if (pdll != 0)
		NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)pdll);

	return 0;
}