-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathAES.h
217 lines (144 loc) · 7.03 KB
/
AES.h
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
/* Header file for AES Decryption (all cryptographic functions are stack spoofed) */
#pragma once
#include <windows.h>
#include <iostream>
#include "functions.h"
#include "retaddrspoof.h"
#define KEYSIZE 32
#define IVSIZE 16
extern PVOID Gdgt;
/* AES Datatype Structure Definition */
typedef struct AES {
PBYTE pPlainText; // Array Will Recieve Decrypted Data
DWORD plainTextSize; // DWORD Variable Will Recieve The Size of Decrypted Data
PBYTE pCipherText; // Array of Encrypted Data
DWORD CipherSize; // The sizeof encrypted data
PBYTE KEY; // 32 Byte AES Key to be used in decryption
PBYTE IV; // 16 Byte AES IV to be used in decryption
}AES, * PAES;
/* ---------------------------------- */
/// <summary>
/// an Internal Function that Performs the AES Decryption using a Provided Pointer to an Initialized AES Structure
/// </summary>
/// <param name="pAES"></param>
/// <returns></returns>
BOOL InternalAESDecrypt(PAES pAES) {
BOOL bSTATE = TRUE;
BCRYPT_ALG_HANDLE hAlgorithm = NULL;
BCRYPT_KEY_HANDLE hKeyHandle = NULL;
ULONG cbResult = NULL;
DWORD dwBlockSize = NULL;
DWORD cbKeyObject = NULL;
PBYTE pbKeyObject = NULL;
PBYTE pbPlainText = NULL;
DWORD cbPlainText = NULL;
NTSTATUS STATUS = NULL;
// Initialize the hAlgorithm Handle as an AES Algorithm
STATUS = reinterpret_cast<NTSTATUS>(RetSpoofCall((void*)e_BCryptOpenAlgorithmProvider, 4, Gdgt, &hAlgorithm, BCRYPT_AES_ALGORITHM, NULL, 0));
if (STATUS != 0) {
std::cout << "[-] BCryptOpenAlgorithmProvider Function Failed To Initialize Algorithm Handle" << std::endl;
std::cout << "[-] Error Code: " << STATUS << std::endl;
bSTATE = FALSE; goto _CLEANUP;
}
// Get The Size of the KeyObject Variable to use Later with BCryptGenerateSymmetricKey Function
STATUS = reinterpret_cast<NTSTATUS>(RetSpoofCall((void*)e_BCryptGetProperty, 6, Gdgt, hAlgorithm, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbKeyObject, sizeof(DWORD), &cbResult, 0));
if (STATUS != 0) {
std::cout << "[-] BCryptGetProperty Function Failed To Get The Size of the KeyObject " << std::endl;
std::cout << "[-] Error Code: " << STATUS << std::endl;
bSTATE = FALSE; goto _CLEANUP;
}
// Get the size of the block used in the encryption. Since this is AES it should be 16 bytes.
STATUS = reinterpret_cast<NTSTATUS>(RetSpoofCall((void*)e_BCryptGetProperty, 6, Gdgt, hAlgorithm, BCRYPT_BLOCK_LENGTH, (PBYTE)&dwBlockSize, sizeof(DWORD), &cbResult, 0));
if (STATUS != 0) {
std::cout << "[-] BCryptGetProperty Function Failed To Get The Size of the Encryption Block" << std::endl;
std::cout << "[-] Error Code: " << STATUS << std::endl;
bSTATE = FALSE; goto _CLEANUP;
}
// Check The Encryption Block Size (Should Always be 16)
if (dwBlockSize != 16) {
std::cout << "[-] Encryption Block Size Is Not 16" << std::endl;
bSTATE = FALSE; goto _CLEANUP;
}
// Allocate Memory on The Heap For The Key ( man do i miss C# )
pbKeyObject = (PBYTE)malloc(cbKeyObject);
RtlSecureZeroMemory(pbKeyObject, cbKeyObject);
if (pbKeyObject == NULL) {
std::cout << "[-] malloc failed to allocate memory for the key" << std::endl;
bSTATE = FALSE; goto _CLEANUP;
}
// Configure The Block Cipher Mode (AES MODE) to CBC This uses a 32 byte key and a 16 byte IV.
STATUS = reinterpret_cast<NTSTATUS>(RetSpoofCall((void*)e_BCryptSetProperty, 5, Gdgt, hAlgorithm, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0));
if (STATUS != 0) {
std::cout << "[-] BCryptSetProperty Failed to Set The Encryption Mode To CBC" << std::endl;
std::cout << "[-] Error Code: " << STATUS << std::endl;
bSTATE = FALSE; goto _CLEANUP;
}
// Generating an AES Key Object from The Provided pAES Structure and Saving the Key Object to pbKeyObject and its size to cbKeyObject and Its Handle to hKeyHandle
STATUS = reinterpret_cast<NTSTATUS>(RetSpoofCall((void*)e_BCryptGenerateSymmetricKey, 7, Gdgt , hAlgorithm, &hKeyHandle, pbKeyObject, cbKeyObject, (PBYTE)pAES->KEY, KEYSIZE, 0));
if (STATUS != 0) {
std::cout << "[-] BCryptGenerateSymmetricKey Failed to Generate a Key Object" << std::endl;
std::cout << "[-] Error Code: " << STATUS << std::endl;
bSTATE = FALSE; goto _CLEANUP;
}
// running BCryptDecrypt For First Time With NULL Parameters to retrieve the Size of the OutPut Buffer And Save
STATUS = reinterpret_cast<NTSTATUS>(RetSpoofCall((void*)e_BCryptDecrypt, 10, Gdgt , hKeyHandle, (PUCHAR)pAES->pCipherText, (ULONG)pAES->CipherSize, NULL, pAES->IV, IVSIZE, NULL, 0, &cbPlainText, BCRYPT_BLOCK_PADDING));
if (STATUS != 0) {
std::cout << "[-] BCryptDecrypt Failed to Retrieve OutPut Buffer Size" << std::endl;
std::cout << "[-] Error Code: " << STATUS << std::endl;
bSTATE = FALSE; goto _CLEANUP;
}
// Allocate Memory On The Heap For OutPut Buffer
pbPlainText = (PBYTE)malloc(cbPlainText);
RtlSecureZeroMemory(pbPlainText, cbPlainText);
if (pbPlainText == NULL) {
std::cout << "[-] malloc failed to allocate memory for the output buffer" << std::endl;
bSTATE = FALSE; goto _CLEANUP;
}
// running BCryptDecrypt again Given The Allocated Buffer so it Puts The Decrypted data To It
STATUS = reinterpret_cast<NTSTATUS>(RetSpoofCall((void*)e_BCryptDecrypt, 10, Gdgt, hKeyHandle, (PUCHAR)pAES->pCipherText, (ULONG)pAES->CipherSize, NULL, pAES->IV, IVSIZE, pbPlainText, cbPlainText, &cbResult, BCRYPT_BLOCK_PADDING));
if (STATUS != 0) {
std::cout << "[-] BCryptDecrypt Failed to Decrypt" << std::endl;
std::cout << "[-] Error Code: " << STATUS << std::endl;
bSTATE = FALSE; goto _CLEANUP;
}
_CLEANUP:
if (hKeyHandle)
RetSpoofCall((void*) e_BCryptDestroyKey, 1, Gdgt , hKeyHandle);
if (hAlgorithm)
RetSpoofCall((void*)e_BCryptCloseAlgorithmProvider, 2, Gdgt, hAlgorithm, 0);
if (pbKeyObject)
free(pbKeyObject);
if (pbPlainText != NULL && bSTATE) {
// if everything went well, we save pbPlainText and cbPlainText to The AES Structure so we can access them later
pAES->pPlainText = pbPlainText;
pAES->plainTextSize = cbPlainText;
}
if (pbPlainText == NULL) {
std::cout << "plain text buffer is NULL" << std::endl;
}
return bSTATE;
}
/// <summary>
/// AES Decrytion Function
/// </summary>
/// <returns>boolean Indicates a Successfull or a Failed Decryption Process</returns>
BOOL AESDecrypt(IN PBYTE EncryptedData, IN DWORD EncryptedDataSize, IN PBYTE KEY, IN PBYTE IV, OUT PVOID* pPlaintTextData, OUT PDWORD pPlaintTextSize) {
if (EncryptedData == NULL || EncryptedDataSize == NULL || KEY == NULL || IV == NULL) {
return FALSE;
}
// Initialize The AES Structure For Decryption
AES Aes;
Aes.KEY = KEY;
Aes.IV = IV;
Aes.pCipherText = EncryptedData;
Aes.CipherSize = EncryptedDataSize;
// Decrypt
if (!InternalAESDecrypt(&Aes)) {
return FALSE;
}
// If Decryption Successfull,
// Set the OUT Parameters of The Function to The Arrays Defined By The Caller to Save The Decrypted Data
*pPlaintTextData = Aes.pPlainText;
*pPlaintTextSize = Aes.plainTextSize;
return TRUE;
}