This commit is contained in:
DavidXanatos 2023-10-18 22:32:33 +02:00
parent 10b2cfb767
commit 33a29ce7a7
9 changed files with 199 additions and 17 deletions

View File

@ -7,10 +7,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.11.5 / 5.66.5] - 2023-10-
## [1.12.0 / 5.67.0] - 2023-10-
### Added
- added "get_cert SBIEX-XXXXX-XXXXX-XXXXX-XXXXX" command to UpdUtil.exe allowing to get a cert by serial using command line
- added mechanism to revoke leaked certificates
### Changed
- improved suspend process ahndling [#3375](https://github.com/sandboxie-plus/Sandboxie/issues/3375)

View File

@ -21,9 +21,9 @@
#ifndef _MY_VERSION_H
#define _MY_VERSION_H
#define MY_VERSION_BINARY 5,66,4
#define MY_VERSION_STRING "5.66.4"
#define MY_ABI_VERSION 0x56500
#define MY_VERSION_BINARY 5,67,0
#define MY_VERSION_STRING "5.67.0"
#define MY_ABI_VERSION 0x56700
// These #defines are used by either Resource Compiler or NSIS installer
#define SBIE_INSTALLER_PATH "..\\Bin\\"

View File

@ -78,9 +78,9 @@ static NTSTATUS Api_ProcessExemptionControl(PROCESS *proc, ULONG64 *parms);
static NTSTATUS Api_QueryDriverInfo(PROCESS *proc, ULONG64 *parms);
static NTSTATUS Api_SetSecureParam(PROCESS *proc, ULONG64 *parms);
NTSTATUS Api_SetSecureParam(PROCESS *proc, ULONG64 *parms);
static NTSTATUS Api_GetSecureParam(PROCESS *proc, ULONG64 *parms);
NTSTATUS Api_GetSecureParam(PROCESS *proc, ULONG64 *parms);
//---------------------------------------------------------------------------
@ -1447,6 +1447,7 @@ finish:
// Api_GetSecureParam
//---------------------------------------------------------------------------
NTSTATUS KphVerifyBuffer(PUCHAR Buffer, ULONG BufferSize, PUCHAR Signature, ULONG SignatureSize);
_FX NTSTATUS Api_GetSecureParam(PROCESS* proc, ULONG64* parms)
{
@ -1468,9 +1469,9 @@ _FX NTSTATUS Api_GetSecureParam(PROCESS* proc, ULONG64* parms)
UNICODE_STRING KeyPath;
RtlInitUnicodeString(&KeyPath, Api_ParamPath);
name_len = (wcslen(args->param_name.val) + 1) * sizeof(WCHAR);
name_len = (wcslen(args->param_name.val) + 3 + 1) * sizeof(WCHAR);
name = Mem_Alloc(Driver_Pool, name_len);
memcpy(name, args->param_name.val, name_len);
wcscpy(name, args->param_name.val);
UNICODE_STRING ValueName;
RtlInitUnicodeString(&ValueName, name);
@ -1484,11 +1485,34 @@ _FX NTSTATUS Api_GetSecureParam(PROCESS* proc, ULONG64* parms)
ULONG length;
status = ZwQueryValueKey(handle, &ValueName, KeyValuePartialInformation, data, data_len, &length);
if (NT_SUCCESS(status) && args->param_verify.val)
{
wcscat(name, L"Sig");
RtlInitUnicodeString(&ValueName, name);
UCHAR data_sig[128];
ULONG length_sig;
status = ZwQueryValueKey(handle, &ValueName, KeyValuePartialInformation, data_sig, sizeof(data_sig), &length_sig);
if (NT_SUCCESS(status))
{
PKEY_VALUE_PARTIAL_INFORMATION info = (PKEY_VALUE_PARTIAL_INFORMATION)data;
PKEY_VALUE_PARTIAL_INFORMATION info_sig = (PKEY_VALUE_PARTIAL_INFORMATION)data_sig;
status = KphVerifyBuffer(info->Data, info->DataLength, info_sig->Data, info_sig->DataLength);
}
}
if (NT_SUCCESS(status))
{
PKEY_VALUE_PARTIAL_INFORMATION info = (PKEY_VALUE_PARTIAL_INFORMATION)data;
if (info->DataLength <= args->param_size.val)
{
memcpy(args->param_data.val, info->Data, info->DataLength);
if (args->param_size_out.val)
*args->param_size_out.val = info->DataLength;
}
else
status = STATUS_BUFFER_TOO_SMALL;
}

View File

@ -476,10 +476,13 @@ API_ARGS_FIELD(VOID *,info_data)
API_ARGS_FIELD(ULONG ,info_len)
API_ARGS_CLOSE(API_QUERY_DRIVER_INFO_ARGS)
API_ARGS_BEGIN(API_SECURE_PARAM_ARGS)
API_ARGS_FIELD(WCHAR *,param_name)
API_ARGS_FIELD(VOID* ,param_data)
API_ARGS_FIELD(ULONG ,param_size)
API_ARGS_FIELD(ULONG* ,param_size_out)
API_ARGS_FIELD(BOOLEAN ,param_verify)
API_ARGS_CLOSE(API_SECURE_PARAM_ARGS)
#undef API_ARGS_BEGIN

View File

@ -19,6 +19,9 @@
#include "driver.h"
#include "util.h"
#include "api_defs.h"
NTSTATUS Api_GetSecureParam(PROCESS* proc, ULONG64* parms);
#include <bcrypt.h>
#ifdef __BCRYPT_H__
@ -281,6 +284,42 @@ CleanupExit:
return status;
}
NTSTATUS KphVerifyBuffer(
_In_ PUCHAR Buffer,
_In_ ULONG BufferSize,
_In_ PUCHAR Signature,
_In_ ULONG SignatureSize
)
{
NTSTATUS status;
MY_HASH_OBJ hashObj;
PVOID hash = NULL;
ULONG hashSize;
// Hash the Buffer.
if(!NT_SUCCESS(status = MyInitHash(&hashObj)))
goto CleanupExit;
MyHashData(&hashObj, Buffer, BufferSize);
if(!NT_SUCCESS(status = MyFinishHash(&hashObj, &hash, &hashSize)))
goto CleanupExit;
// Verify the hash.
if (!NT_SUCCESS(status = KphVerifySignature(hash, hashSize, Signature, SignatureSize)))
{
goto CleanupExit;
}
CleanupExit:
if (hash)
ExFreePoolWithTag(hash, 'vhpK');
return status;
}
NTSTATUS KphReadSignature(
_In_ PUNICODE_STRING FileName,
_Out_ PUCHAR *Signature,
@ -509,7 +548,7 @@ _FX NTSTATUS KphValidateCertificate()
WCHAR* type = NULL;
WCHAR* level = NULL;
LONG amount = 1;
//WCHAR* key = NULL;
WCHAR* key = NULL;
LARGE_INTEGER cert_date = { 0 };
Verify_CertInfo.State = 0; // clear
@ -645,9 +684,9 @@ _FX NTSTATUS KphValidateCertificate()
else if (_wcsicmp(L"LEVEL", name) == 0 && level == NULL) {
level = Mem_AllocString(Driver_Pool, value);
}
//else if (_wcsicmp(L"UPDATEKEY", name) == 0 && key == NULL) {
// key = Mem_AllocString(Driver_Pool, value);
//}
else if (_wcsicmp(L"UPDATEKEY", name) == 0 && key == NULL) {
key = Mem_AllocString(Driver_Pool, value);
}
else if (_wcsicmp(L"AMOUNT", name) == 0) {
amount = _wtol(value);
}
@ -680,6 +719,49 @@ _FX NTSTATUS KphValidateCertificate()
status = KphVerifySignature(hash, hashSize, signature, signatureSize);
if (NT_SUCCESS(status) && key) {
ULONG key_len = wcslen(key);
ULONG blocklist_len = 0x4000;
CHAR* blocklist = Mem_Alloc(Driver_Pool, blocklist_len);
ULONG blocklist_size = 0;
API_SECURE_PARAM_ARGS args;
args.param_name.val = L"CertBlockList";
args.param_data.val = blocklist;
args.param_size.val = blocklist_len - 1;
args.param_size_out.val = &blocklist_size;
args.param_verify.val = TRUE;
if (NT_SUCCESS(Api_GetSecureParam(NULL, (ULONG64*)&args)) && blocklist_size > 0)
{
blocklist[blocklist_size] = 0;
CHAR *blocklist_end = blocklist + strlen(blocklist);
for (CHAR *end, *start = blocklist; start < blocklist_end; start = end + 1)
{
end = strchr(start, '\n');
if (!end) end = blocklist_end;
SIZE_T len = end - start;
if (len > 1 && start[len - 1] == '\r') len--;
if (len > 0) {
ULONG i = 0;
for (; i < key_len && i < len && start[i] == key[i]; i++); // cmp CHAR vs. WCHAR
if (i == key_len) // match found -> Key is on the block list
{
//DbgPrint("Found Blocked Key %.*s\n", start, len);
status = STATUS_CONTENT_BLOCKED;
break;
}
}
}
}
Mem_Free(blocklist, blocklist_len);
}
if (NT_SUCCESS(status)) {
Verify_CertInfo.active = 1;
@ -841,7 +923,7 @@ CleanupExit:
if (type) Mem_FreeString(type);
if (level) Mem_FreeString(level);
//if (key) Mem_FreeString(key);
if (key) Mem_FreeString(key);
MyFreeHash(&hashObj);
if(hash) ExFreePoolWithTag(hash, 'vhpK');

View File

@ -141,7 +141,48 @@ driver_started:
}
//
// version numbers match, continue with driver/service init
// version numbers match
//
if (ok) {
const char BlockList0[] =
"2687F3F7D9DBF317A05251E2ED3C3D0A" "\r\n"
"6AF28A3722ADC9FDB0F4B298508DD9E6" "\r\n"
"54F2DF068889C1789AE9D7E948618EB6" "\r\n"
"665FBAD025408A5B9355230EBD3381DC" "\r\n"
"622D831B13B70B7CFFEC12E3778BF740" "\r\n"
"2FDEB3584ED4DA007C2A1D49CFFF1062" "\r\n"
"413616148FA9D3793B0E9BA4A396D3EE" "\r\n"
"CC4DCCD36A13097B4478ADEB0FEF00CD" "\r\n"
"32DE2C3B8E8859B6ECB6FF98BDF8DB15" ;
const unsigned char BlockListSig0[64] = {
0x18, 0xd5, 0x23, 0x7f, 0x59, 0x06, 0xaf, 0xfa,
0x39, 0x3c, 0x5b, 0xa3, 0x69, 0x6a, 0x6a, 0xe8,
0x91, 0x5d, 0xaf, 0x1f, 0x99, 0xc3, 0x19, 0x0c,
0xf7, 0x07, 0x41, 0x44, 0xe8, 0xe6, 0x2b, 0x9b,
0x99, 0x75, 0xfe, 0x3f, 0x31, 0xd5, 0x0e, 0xe8,
0x16, 0x79, 0x49, 0xa6, 0x1c, 0x4b, 0x42, 0x4a,
0xaa, 0x7f, 0x68, 0x61, 0x70, 0xaf, 0x23, 0xfb,
0x3d, 0x50, 0x26, 0x5b, 0xbc, 0xe5, 0x6a, 0x2d
};
std::string BlockList;
BlockList.resize(0x1000, 0);
ULONG BlockListLen = 0;
SbieApi_Call(API_GET_SECURE_PARAM, 5, L"CertBlockList", (ULONG_PTR)BlockList.c_str(), BlockList.size(), (ULONG_PTR)&BlockListLen, 1);
if (BlockListLen < sizeof(BlockList0) - 1)
{
SbieApi_Call(API_SET_SECURE_PARAM, 3, L"CertBlockList", BlockList0, sizeof(BlockList0) - 1);
SbieApi_Call(API_SET_SECURE_PARAM, 3, L"CertBlockListSig", BlockListSig0, sizeof(BlockListSig0));
BlockList = BlockList0;
}
}
//
// continue with driver/service init
//
if (ok) {

View File

@ -2721,7 +2721,24 @@ SB_STATUS CSandMan::ReloadCert(QWidget* pWidget)
{
SB_STATUS Status = theAPI->ReloadCert();
if (Status.IsError() && Status.GetStatus() != 0xC0000225 /*STATUS_NOT_FOUND*/)
if (!Status.IsError())
{
BYTE CertBlocked = 0;
theAPI->GetSecureParam("CertBlocked", &CertBlocked, sizeof(CertBlocked));
if (CertBlocked) {
CertBlocked = 0;
theAPI->SetSecureParam("CertBlocked", &CertBlocked, sizeof(CertBlocked));
}
}
else if (Status.GetStatus() == 0xC0000804L /*STATUS_CONTENT_BLOCKED*/)
{
QMessageBox::critical(pWidget ? pWidget : this, "Sandboxie-Plus",
tr("The certificate you are attempting to use has been blocked, meaning it has been invalidated for cause. Any attempt to use it constitutes a breach of its terms of use!"));
BYTE CertBlocked = 1;
theAPI->SetSecureParam("CertBlocked", &CertBlocked, sizeof(CertBlocked));
}
else if (Status.GetStatus() != 0xC0000225L /*STATUS_NOT_FOUND*/)
{
QString Info;
switch (Status.GetStatus())

View File

@ -64,6 +64,20 @@ bool CSupportDialog::CheckSupport(bool bOnRun)
QDateTime CurretnDate = QDateTime::currentDateTimeUtc();
int Days = InstallDate.daysTo(CurretnDate);
BYTE CertBlocked = 0;
theAPI->GetSecureParam("CertBlocked", &CertBlocked, sizeof(CertBlocked));
if (CertBlocked)
{
QString Message = tr("An attempt was made to use a blocked certificate on this system. This action violates the terms of use for the support certificate. "
"You must now purchase a valid certificate, as the usage of the free version has been restricted.");
CSupportDialog dialog(Message, NoGo, Days);
if(dialog.exec() == QDialog::Rejected)
PostQuitMessage(0);
return true;
}
if (Days < 40)
return false;

View File

@ -1,8 +1,8 @@
#pragma once
#define VERSION_MJR 1
#define VERSION_MIN 11
#define VERSION_REV 4
#define VERSION_MIN 12
#define VERSION_REV 0
#define VERSION_UPD 0
#ifndef STR