mirror of https://github.com/hfiref0x/UACME.git
295 lines
6.8 KiB
C
295 lines
6.8 KiB
C
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT AUTHORS, 2016
|
|
*
|
|
* TITLE: MAIN.C
|
|
*
|
|
* VERSION: 2.51
|
|
*
|
|
* DATE: 10 July 2016
|
|
*
|
|
* Naka, support payload compressor.
|
|
*
|
|
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
* PARTICULAR PURPOSE.
|
|
*
|
|
*******************************************************************************/
|
|
#pragma once
|
|
|
|
#if !defined UNICODE
|
|
#error ANSI build is not supported
|
|
#endif
|
|
|
|
#if (_MSC_VER >= 1900)
|
|
#ifdef _DEBUG
|
|
#pragma comment(lib, "vcruntimed.lib")
|
|
#pragma comment(lib, "ucrtd.lib")
|
|
#else
|
|
#pragma comment(lib, "libvcruntime.lib")
|
|
#endif
|
|
#endif
|
|
|
|
//disable nonmeaningful warnings.
|
|
#pragma warning(disable: 4005) // macro redefinition
|
|
#pragma warning(disable: 4055) // %s : from data pointer %s to function pointer %s
|
|
#pragma warning(disable: 4152) // nonstandard extension, function/data pointer conversion in expression
|
|
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
|
|
#pragma warning(disable: 6102) // Using %s from failed function call at line %u
|
|
#pragma warning(disable: 6320) // exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER
|
|
|
|
#include <Windows.h>
|
|
#include <ntstatus.h>
|
|
#include "..\shared\ntos.h"
|
|
#include "..\shared\minirtl.h"
|
|
#include "..\Shared\cmdline.h"
|
|
#include "..\Shared\_filename.h"
|
|
|
|
ULONG g_XorKey = 'naka';
|
|
|
|
/*
|
|
* EncodeBuffer
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Decrypt/Encrypt given buffer.
|
|
*
|
|
*/
|
|
VOID EncodeBuffer(
|
|
PVOID Buffer,
|
|
ULONG BufferSize
|
|
)
|
|
{
|
|
ULONG k, c;
|
|
PUCHAR ptr;
|
|
|
|
if ((Buffer == NULL) || (BufferSize == 0))
|
|
return;
|
|
|
|
k = g_XorKey;
|
|
c = BufferSize;
|
|
ptr = Buffer;
|
|
|
|
do {
|
|
*ptr ^= k;
|
|
k = _rotl(k, 1);
|
|
ptr++;
|
|
--c;
|
|
} while (c != 0);
|
|
}
|
|
|
|
/*
|
|
* supWriteBufferToFile
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Create new file and write buffer to it.
|
|
*
|
|
*/
|
|
BOOL supWriteBufferToFile(
|
|
_In_ LPWSTR lpFileName,
|
|
_In_ PVOID Buffer,
|
|
_In_ DWORD BufferSize
|
|
)
|
|
{
|
|
HANDLE hFile;
|
|
DWORD bytesIO;
|
|
|
|
if (
|
|
(lpFileName == NULL) ||
|
|
(Buffer == NULL) ||
|
|
(BufferSize == 0)
|
|
)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
hFile = CreateFileW(lpFileName,
|
|
GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE) {
|
|
return FALSE;
|
|
}
|
|
|
|
WriteFile(hFile, Buffer, BufferSize, &bytesIO, NULL);
|
|
CloseHandle(hFile);
|
|
|
|
return (bytesIO == BufferSize);
|
|
}
|
|
|
|
/*
|
|
* CompressBufferLZNT1
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Compress given buffer with LZ algorithm.
|
|
*
|
|
* Use VirtualFree to release returned buffer when it no longer needed.
|
|
*
|
|
*/
|
|
PUCHAR CompressBufferLZNT1(
|
|
_In_ PUCHAR SrcBuffer,
|
|
_In_ ULONG SrcSize,
|
|
_Inout_ PULONG FinalCompressedSize
|
|
)
|
|
{
|
|
BOOL cond = FALSE;
|
|
NTSTATUS status;
|
|
ULONG CompressedSize = 0;
|
|
ULONG CompressBufferWorkSpaceSize = 0;
|
|
ULONG CompressFragmentWorkSpaceSize = 0;
|
|
ULONG CompBufferSize = 0;
|
|
PVOID WorkSpace = NULL;
|
|
PUCHAR CompBuffer = NULL;
|
|
|
|
if (FinalCompressedSize == NULL)
|
|
return NULL;
|
|
|
|
do {
|
|
|
|
status = RtlGetCompressionWorkSpaceSize(
|
|
COMPRESSION_FORMAT_LZNT1,
|
|
&CompressBufferWorkSpaceSize,
|
|
&CompressFragmentWorkSpaceSize
|
|
);
|
|
|
|
//accept nothing but STATUS_SUCCESS
|
|
if (status != STATUS_SUCCESS) {
|
|
break;
|
|
}
|
|
|
|
WorkSpace = (PVOID)VirtualAlloc(NULL, CompressBufferWorkSpaceSize,
|
|
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
|
|
if (WorkSpace == NULL) {
|
|
break;
|
|
}
|
|
|
|
//original size + safe buffer + sizeof header
|
|
CompBufferSize = SrcSize + 0x1000 + sizeof(ULONG);
|
|
CompBuffer = (PUCHAR)VirtualAlloc(NULL, CompBufferSize,
|
|
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
|
|
if (CompBuffer == NULL) {
|
|
break;
|
|
}
|
|
|
|
CompressedSize = 0;
|
|
status = RtlCompressBuffer(
|
|
COMPRESSION_FORMAT_LZNT1,
|
|
SrcBuffer,
|
|
SrcSize,
|
|
&CompBuffer[4],
|
|
CompBufferSize,
|
|
4096,
|
|
&CompressedSize,
|
|
WorkSpace
|
|
);
|
|
|
|
if (status != STATUS_SUCCESS) {
|
|
VirtualFree(CompBuffer, 0, MEM_RELEASE);
|
|
break;
|
|
}
|
|
|
|
*(PULONG)&CompBuffer[0] = SrcSize;//save original size
|
|
CompressedSize += sizeof(ULONG); //add header size
|
|
*FinalCompressedSize = CompressedSize;
|
|
|
|
} while (cond);
|
|
|
|
if (WorkSpace != NULL) {
|
|
VirtualFree(WorkSpace, 0, MEM_RELEASE);
|
|
}
|
|
|
|
return CompBuffer;
|
|
}
|
|
|
|
void CompressPayload(
|
|
LPWSTR lpInputFile
|
|
)
|
|
{
|
|
BOOL bCond = FALSE;
|
|
PUCHAR Data = NULL, FileData = NULL;
|
|
ULONG FinalCompressedSize = 0, r = 0;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
LPWSTR NewName = NULL;
|
|
SIZE_T sz = 0;
|
|
LARGE_INTEGER FileSize;
|
|
|
|
do {
|
|
if (lpInputFile == NULL)
|
|
break;
|
|
|
|
sz = _strlen(lpInputFile) * sizeof(WCHAR);
|
|
NewName = LocalAlloc(LPTR, sz);
|
|
if (NewName == NULL)
|
|
break;
|
|
|
|
hFile = CreateFile(lpInputFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
break;
|
|
|
|
FileSize.QuadPart = 0;
|
|
if (!GetFileSizeEx(hFile, &FileSize))
|
|
break;
|
|
|
|
if (FileSize.QuadPart == 0)
|
|
break;
|
|
|
|
FileData = LocalAlloc(LPTR, (SIZE_T)FileSize.LowPart);
|
|
if (FileData == NULL)
|
|
break;
|
|
|
|
if (!ReadFile(hFile, FileData, FileSize.LowPart, (LPDWORD)&r, NULL))
|
|
break;
|
|
|
|
Data = CompressBufferLZNT1((PUCHAR)FileData, r, &FinalCompressedSize);
|
|
if (Data) {
|
|
EncodeBuffer(Data, FinalCompressedSize);
|
|
if (_filename_noext(NewName, lpInputFile)) {
|
|
_strcat(NewName, TEXT(".cd"));
|
|
supWriteBufferToFile(NewName, Data, FinalCompressedSize);
|
|
}
|
|
VirtualFree(Data, 0, MEM_RELEASE);
|
|
}
|
|
|
|
} while (bCond);
|
|
|
|
if (NewName != NULL)
|
|
LocalFree(NewName);
|
|
if (FileData != NULL)
|
|
LocalFree(FileData);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
CloseHandle(hFile);
|
|
|
|
}
|
|
|
|
void main()
|
|
{
|
|
LPWSTR lpInputFile = NULL;
|
|
LPWSTR *szArglist;
|
|
INT nArgs = 0;
|
|
|
|
|
|
szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
|
|
if (szArglist) {
|
|
if (nArgs > 1) {
|
|
lpInputFile = szArglist[1];
|
|
if (nArgs > 2) {
|
|
g_XorKey = strtoul(szArglist[2]);
|
|
}
|
|
if (lpInputFile) {
|
|
CompressPayload(lpInputFile);
|
|
}
|
|
}
|
|
else {
|
|
MessageBox(GetDesktopWindow(), TEXT("Input file not specified"), TEXT("Naka"), MB_ICONINFORMATION);
|
|
}
|
|
|
|
LocalFree(szArglist);
|
|
}
|
|
|
|
ExitProcess(0);
|
|
}
|