Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Base64 Format for Log Output #236

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions mimikatz/modules/kuhl_m_standard.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ NTSTATUS kuhl_m_standard_sleep(int argc, wchar_t * argv[])
NTSTATUS kuhl_m_standard_log(int argc, wchar_t * argv[])
{
PCWCHAR filename = (kull_m_string_args_byName(argc, argv, L"stop", NULL, NULL) ? NULL : (argc ? argv[0] : MIMIKATZ_DEFAULT_LOG));
kprintf(L"Using \'%s\' for logfile : %s\n", filename, kull_m_output_file(filename) ? L"OK" : L"KO");
kull_m_string_args_bool_byName(argc, argv, L"base64", &isBase64Output);
kprintf(L"Using \'%s\' for logfile : %s %s\n", filename, kull_m_output_file(filename) ? L"OK" : L"KO", isBase64Output ? L"[UTF16LE+BASE64]" : L"");
return STATUS_SUCCESS;
}

Expand Down Expand Up @@ -267,4 +268,4 @@ NTSTATUS kuhl_m_standard_hostname(int argc, wchar_t * argv[])
}
kprintf(L"\n");
return STATUS_SUCCESS;
}
}
3 changes: 2 additions & 1 deletion mimikatz/modules/kuhl_m_standard.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "../../modules/kull_m_process.h"
#include "../../modules/kull_m_net.h"
#include "../../modules/kull_m_cabinet.h"
#include "../../modules/kull_m_output.h"

const KUHL_M kuhl_m_standard;

Expand All @@ -25,4 +26,4 @@ NTSTATUS kuhl_m_standard_version(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_standard_cd(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_standard_localtime(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_standard_hostname(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_standard_test(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_standard_test(int argc, wchar_t * argv[]);
107 changes: 101 additions & 6 deletions modules/kull_m_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,54 @@ void kprintf(PCWCHAR format, ...)
#endif
if(logfile)
{
vfwprintf(logfile, format, args);
fflush(logfile);
if(isBase64Output)
{
// get current size
DWORD current_length = ftell(logfile);
// get new content size
DWORD appended_length = _vscwprintf(format, args);
// set position to 0
fseek(logfile, 0, SEEK_SET);
// alloc current_content buffer
LPWSTR current_content = LocalAlloc(LPTR, current_length + 1);
// read current content
size_t n_read = fread_s(current_content, current_length, sizeof(wchar_t), current_length / sizeof(wchar_t), logfile);
current_content[current_length] = '\x00';
// base64decode
DWORD decoded_length = 0;
CryptStringToBinary(current_content, current_length, CRYPT_STRING_BASE64, NULL, &decoded_length, NULL, NULL);
wchar_t* decoded_content = LocalAlloc(LPTR, decoded_length * sizeof(wchar_t));
CryptStringToBinary(current_content, current_length, CRYPT_STRING_BASE64, (BYTE *) decoded_content, &decoded_length, NULL, NULL);
// concat data
wchar_t* concatenated_content = LocalAlloc(LPTR, decoded_length * sizeof(wchar_t) + appended_length * sizeof(wchar_t) + 1);
memcpy(concatenated_content, decoded_content, decoded_length);
vswprintf(concatenated_content + wcslen(concatenated_content), appended_length + 1, format, args);
// base64encode
DWORD encoded_length = 0;
CryptBinaryToString((const BYTE *) concatenated_content, decoded_length + appended_length * sizeof(wchar_t), CRYPT_STRING_BASE64, NULL, &encoded_length);
LPWSTR encoded_content = LocalAlloc(LPTR, encoded_length * sizeof(wchar_t));
CryptBinaryToString((const BYTE *) concatenated_content, decoded_length + appended_length * sizeof(wchar_t), CRYPT_STRING_BASE64, encoded_content, &encoded_length);
// write to file
fseek(logfile, 0, SEEK_SET);
for(DWORD i = 0; i < encoded_length; i++)
{
if(encoded_content[i] != '\x0d' && encoded_content[i] != '\x0a' && encoded_content[i] != '\x00')
fwrite(encoded_content + i, sizeof(wchar_t), 1, logfile);
}

fflush(logfile);
// free temporary buffers
LocalFree(current_content);
LocalFree(decoded_content);
LocalFree(concatenated_content);
LocalFree(encoded_content);
// TODO: check for errors
}
else
{
vfwprintf(logfile, format, args);
fflush(logfile);
}
}
va_end(args);
}
Expand All @@ -70,8 +116,54 @@ void kprintf_inputline(PCWCHAR format, ...)
va_start(args, format);
if(logfile)
{
vfwprintf(logfile, format, args);
fflush(logfile);
if(isBase64Output)
{
// get current size
DWORD current_length = ftell(logfile);
// get new content size
DWORD appended_length = _vscwprintf(format, args);
// set position to 0
fseek(logfile, 0, SEEK_SET);
// alloc current_content buffer
LPWSTR current_content = LocalAlloc(LPTR, current_length + 1);
// read current content
size_t n_read = fread_s(current_content, current_length, sizeof(wchar_t), current_length / sizeof(wchar_t), logfile);
current_content[current_length] = '\x00';
// base64decode
DWORD decoded_length = 0;
CryptStringToBinary(current_content, current_length, CRYPT_STRING_BASE64, NULL, &decoded_length, NULL, NULL);
wchar_t* decoded_content = LocalAlloc(LPTR, decoded_length * sizeof(wchar_t));
CryptStringToBinary(current_content, current_length, CRYPT_STRING_BASE64, (BYTE *) decoded_content, &decoded_length, NULL, NULL);
// concat data
wchar_t* concatenated_content = LocalAlloc(LPTR, decoded_length * sizeof(wchar_t) + appended_length * sizeof(wchar_t) + 1);
memcpy(concatenated_content, decoded_content, decoded_length);
vswprintf(concatenated_content + wcslen(concatenated_content), appended_length + 1, format, args);
// base64encode
DWORD encoded_length = 0;
CryptBinaryToString((const BYTE *) concatenated_content, decoded_length + appended_length * sizeof(wchar_t), CRYPT_STRING_BASE64, NULL, &encoded_length);
LPWSTR encoded_content = LocalAlloc(LPTR, encoded_length * sizeof(wchar_t));
CryptBinaryToString((const BYTE *) concatenated_content, decoded_length + appended_length * sizeof(wchar_t), CRYPT_STRING_BASE64, encoded_content, &encoded_length);
// write to file
fseek(logfile, 0, SEEK_SET);
for(DWORD i = 0; i < encoded_length; i++)
{
if(encoded_content[i] != '\x0d' && encoded_content[i] != '\x0a' && encoded_content[i] != '\x00')
fwrite(encoded_content + i, sizeof(wchar_t), 1, logfile);
}

fflush(logfile);
// free temporary buffers
LocalFree(current_content);
LocalFree(decoded_content);
LocalFree(concatenated_content);
LocalFree(encoded_content);
// TODO: check for errors
}
else
{
vfwprintf(logfile, format, args);
fflush(logfile);
}
}
va_end(args);
}
Expand All @@ -82,10 +174,13 @@ BOOL kull_m_output_file(PCWCHAR file)
FILE * newlog = NULL;

if(file)
{
#pragma warning(push)
#pragma warning(disable:4996)
newlog = _wfopen(file, L"a"); // XP does not like _wfopen_s
newlog = _wfopen(file, L"w+"); // XP does not like _wfopen_s
fseek(newlog, 0, SEEK_END);
#pragma warning(pop)
}
if(newlog || !file)
{
if(logfile)
Expand Down Expand Up @@ -118,4 +213,4 @@ void kull_m_output_clean()
#endif
SetConsoleOutputCP(previousConsoleOutput);
#endif
}
}
4 changes: 3 additions & 1 deletion modules/kull_m_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
#include "globals.h"
#include <io.h>
#include <fcntl.h>
#include <wincrypt.h>

BOOL isBase64Output;
FILE * logfile;
#if !defined(MIMIKATZ_W2000_SUPPORT)
wchar_t * outputBuffer;
Expand All @@ -20,4 +22,4 @@ void kprintf_inputline(PCWCHAR format, ...);
BOOL kull_m_output_file(PCWCHAR file);

void kull_m_output_init();
void kull_m_output_clean();
void kull_m_output_clean();