Skip to content

Commit

Permalink
Merge pull request #219 from aegoroff:develop
Browse files Browse the repository at this point in the history
fix: correct ntlm hash restoring under linux
  • Loading branch information
aegoroff authored Dec 1, 2024
2 parents 4b367f8 + 968fbbc commit 51d1ba2
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 7 deletions.
7 changes: 7 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,12 @@
"name": "l2h",
"program": "${workspaceFolder}/build/l2h",
"args": ["-q", "from md5 x in '202cb962ac59075b964b07152d234b70' select x.string;"]
},
{
"type": "lldb",
"request": "launch",
"name": "_tst",
"program": "${workspaceFolder}/build/_tst",
"args": []
}]
}
14 changes: 13 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
"output.h": "c",
"hashes.h": "c",
"encoding.h": "c",
"builtin.h": "c"
"builtin.h": "c",
"uchar.h": "c",
"sstream": "c",
"random": "c",
"queue": "c",
"stack": "c",
"locale": "c",
"*.tcc": "cpp",
"codecvt": "cpp",
"cwchar": "cpp",
"__locale": "cpp",
"iosfwd": "cpp",
"string": "cpp"
}
}
50 changes: 50 additions & 0 deletions src/_tst/BruteForceTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,13 @@ TEST_P(BruteForceTest, BruteForce_CrackHash_RestoredStringAsSpecified) {
constexpr uint32_t num_of_threads = 1;

if(hdef->use_wide_string_) {
#ifdef _MSC_VER
const auto s = enc_from_ansi_to_unicode(t, pool_);
hdef->pfn_digest_(digest, s, wcslen(s) * sizeof(wchar_t));
#else
const auto s = enc_from_ansi_to_wide_chars(t, pool_);
hdef->pfn_digest_(digest, s, 3 * sizeof(char16_t));
#endif
} else {
hdef->pfn_digest_(digest, t, strlen(t));
}
Expand All @@ -75,8 +80,13 @@ TEST_P(BruteForceTest, BruteForce_CrackHashWithBase64TransformStep_RestoredStrin
constexpr uint32_t num_of_threads = 1;

if(hdef->use_wide_string_) {
#ifdef _MSC_VER
const auto s = enc_from_ansi_to_unicode(t, pool_);
hdef->pfn_digest_(digest, s, wcslen(s) * sizeof(wchar_t));
#else
const auto s = enc_from_ansi_to_wide_chars(t, pool_);
hdef->pfn_digest_(digest, s, 3 * sizeof(char16_t));
#endif
} else {
hdef->pfn_digest_(digest, t, strlen(t));
}
Expand All @@ -102,8 +112,13 @@ TEST_P(BruteForceTest, BruteForce_CrackHashDigitsDictAsTemplate_RestoredStringAs
constexpr uint32_t num_of_threads = 1;

if(hdef->use_wide_string_) {
#ifdef _MSC_VER
const auto s = enc_from_ansi_to_unicode(t, pool_);
hdef->pfn_digest_(digest, s, wcslen(s) * sizeof(wchar_t));
#else
const auto s = enc_from_ansi_to_wide_chars(t, pool_);
hdef->pfn_digest_(digest, s, 3 * sizeof(char16_t));
#endif
} else {
hdef->pfn_digest_(digest, t, strlen(t));
}
Expand All @@ -125,8 +140,13 @@ TEST_P(BruteForceTest, BruteForce_CrackHashDigitsDictAsTemplateAndCustomChars_Re
constexpr uint32_t num_of_threads = 1;

if(hdef->use_wide_string_) {
#ifdef _MSC_VER
const auto s = enc_from_ansi_to_unicode(t, pool_);
hdef->pfn_digest_(digest, s, wcslen(s) * sizeof(wchar_t));
#else
const auto s = enc_from_ansi_to_wide_chars(t, pool_);
hdef->pfn_digest_(digest, s, 3 * sizeof(char16_t));
#endif
} else {
hdef->pfn_digest_(digest, t, strlen(t));
}
Expand All @@ -148,8 +168,13 @@ TEST_P(BruteForceTest, BruteForce_CrackHashDigitsAndLowCaseDictAsTemplate_Restor
constexpr uint32_t num_of_threads = 1;

if(hdef->use_wide_string_) {
#ifdef _MSC_VER
const auto s = enc_from_ansi_to_unicode(t, pool_);
hdef->pfn_digest_(digest, s, wcslen(s) * sizeof(wchar_t));
#else
const auto s = enc_from_ansi_to_wide_chars(t, pool_);
hdef->pfn_digest_(digest, s, 3 * sizeof(char16_t));
#endif
} else {
hdef->pfn_digest_(digest, t, strlen(t));
}
Expand All @@ -171,8 +196,13 @@ TEST_P(BruteForceTest, BruteForce_CrackHashAllDictClassesAsTemplate_RestoredStri
constexpr uint32_t num_of_threads = 1;

if(hdef->use_wide_string_) {
#ifdef _MSC_VER
const auto s = enc_from_ansi_to_unicode(t, pool_);
hdef->pfn_digest_(digest, s, wcslen(s) * sizeof(wchar_t));
#else
const auto s = enc_from_ansi_to_wide_chars(t, pool_);
hdef->pfn_digest_(digest, s, 3 * sizeof(char16_t));
#endif
} else {
hdef->pfn_digest_(digest, t, strlen(t));
}
Expand All @@ -194,8 +224,13 @@ TEST_P(BruteForceTest, BruteForce_CrackHashAsciiDictAsTemplate_RestoredStringAsS
constexpr uint32_t num_of_threads = 1;

if(hdef->use_wide_string_) {
#ifdef _MSC_VER
const auto s = enc_from_ansi_to_unicode(t, pool_);
hdef->pfn_digest_(digest, s, wcslen(s) * sizeof(wchar_t));
#else
const auto s = enc_from_ansi_to_wide_chars(t, pool_);
hdef->pfn_digest_(digest, s, 3 * sizeof(char16_t));
#endif
} else {
hdef->pfn_digest_(digest, t, strlen(t));
}
Expand All @@ -217,8 +252,13 @@ TEST_P(BruteForceTest, BruteForce_CrackHashManyThreads_RestoredStringAsSpecified
constexpr uint32_t num_of_threads = 2;

if(hdef->use_wide_string_) {
#ifdef _MSC_VER
const auto s = enc_from_ansi_to_unicode(t, pool_);
hdef->pfn_digest_(digest, s, wcslen(s) * sizeof(wchar_t));
#else
const auto s = enc_from_ansi_to_wide_chars(t, pool_);
hdef->pfn_digest_(digest, s, 3 * sizeof(char16_t));
#endif
} else {
hdef->pfn_digest_(digest, t, strlen(t));
}
Expand All @@ -240,8 +280,13 @@ TEST_P(BruteForceTest, BruteForce_CrackHashTooSmallMaxLength_RestoredStringNull)
constexpr uint32_t num_of_threads = 1;

if(hdef->use_wide_string_) {
#ifdef _MSC_VER
const auto s = enc_from_ansi_to_unicode(t, pool_);
hdef->pfn_digest_(digest, s, wcslen(s) * sizeof(wchar_t));
#else
const auto s = enc_from_ansi_to_wide_chars(t, pool_);
hdef->pfn_digest_(digest, s, 3 * sizeof(char16_t));
#endif
} else {
hdef->pfn_digest_(digest, t, strlen(t));
}
Expand All @@ -263,8 +308,13 @@ TEST_P(BruteForceTest, BruteForce_CrackHashDictionaryWithoutNecessaryChars_Resto
constexpr uint32_t num_of_threads = 1;

if(hdef->use_wide_string_) {
#ifdef _MSC_VER
const auto s = enc_from_ansi_to_unicode(t, pool_);
hdef->pfn_digest_(digest, s, wcslen(s) * sizeof(wchar_t));
#else
const auto s = enc_from_ansi_to_wide_chars(t, pool_);
hdef->pfn_digest_(digest, s, 3 * sizeof(char16_t));
#endif
} else {
hdef->pfn_digest_(digest, t, strlen(t));
}
Expand Down
21 changes: 15 additions & 6 deletions src/srclib/bf.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef _MSC_VER
#include <ctype.h>
#include <string.h>
#include <uchar.h>
char *_strrev(char *str);
#endif

Expand All @@ -37,6 +38,12 @@ char *_strrev(char *str);
#define MAXBYTE 0xFF
#endif

#ifdef _MSC_VER
#define WIDE_CHAR wchar_t
#else
#define WIDE_CHAR char16_t
#endif

typedef struct brute_force_ctx_t {
const unsigned char *dict_;
size_t dict_len_;
Expand All @@ -46,7 +53,7 @@ typedef struct brute_force_ctx_t {

typedef struct tread_ctx_t {
unsigned char *pass_;
wchar_t *wide_pass_;
WIDE_CHAR *wide_pass_;
size_t *chars_indexes_;
uint64_t num_of_attempts_;
size_t thread_num_;
Expand Down Expand Up @@ -245,7 +252,7 @@ char *bf_brute_force(const uint32_t passmin, const uint32_t passmax, const char
thd_ctx[i]->work_thread_ = 1;
thd_ctx[i]->thread_num_ = i + 1;
thd_ctx[i]->pass_ = (unsigned char *)apr_pcalloc(pool, sizeof(unsigned char) * ((size_t)passmax + 1));
thd_ctx[i]->wide_pass_ = (wchar_t *)apr_pcalloc(pool, sizeof(wchar_t) * ((size_t)passmax + 1));
thd_ctx[i]->wide_pass_ = (WIDE_CHAR *)apr_pcalloc(pool, sizeof(WIDE_CHAR) * ((size_t)passmax + 1));
thd_ctx[i]->chars_indexes_ = (size_t *)apr_pcalloc(pool, (size_t)passmax * sizeof(size_t));
thd_ctx[i]->pass_length_ = passmin;
thd_ctx[i]->num_of_threads = num_of_threads;
Expand Down Expand Up @@ -304,8 +311,11 @@ char *bf_brute_force(const uint32_t passmin, const uint32_t passmax, const char

if (thd_ctx[i]->use_wide_pass_) {
if (thd_ctx[i]->wide_pass_ != NULL) {
// TODO: make correct implementation on Linux
#ifdef _MSC_VER
pass = (unsigned char *)enc_from_unicode_to_ansi(thd_ctx[i]->wide_pass_, pool);
#else
pass = (unsigned char *)enc_wide_chars_to_ansi(thd_ctx[i]->wide_pass_, pool);
#endif
}
} else {
if (thd_ctx[i]->pass_ != NULL) {
Expand Down Expand Up @@ -352,7 +362,6 @@ void *APR_THREAD_FUNC prbf_cpu_thread_func(apr_thread_t *thd, void *data) {
goto result;
}
} else {

if (prbf_make_cpu_attempt(tc, alphabet_hash)) {
goto result;
}
Expand Down Expand Up @@ -573,7 +582,7 @@ BOOL prbf_make_cpu_attempt_wide(tread_ctx_t *ctx, int *alphabet_hash) {
const uint32_t pass_len = ctx->passmax_;
const uint32_t dict_len = g_brute_force_ctx->dict_len_;
const unsigned char *dict = g_brute_force_ctx->dict_;
wchar_t *attempt = ctx->wide_pass_;
WIDE_CHAR *attempt = ctx->wide_pass_;

// ti - text index (on probing it's the index of the attempt's last char)
// li - ABC index
Expand Down Expand Up @@ -604,7 +613,7 @@ BOOL prbf_make_cpu_attempt_wide(tread_ctx_t *ctx, int *alphabet_hash) {

if (pass_min <= pass_len - skip &&
g_brute_force_ctx->pfn_hash_compare_(g_brute_force_ctx->hash_to_find_, attempt,
(pass_len - skip) * sizeof(wchar_t))) {
(pass_len - skip) * sizeof(WIDE_CHAR))) {
apr_atomic_set32(&g_already_found, TRUE);
ctx->wide_pass_ += skip;
return TRUE;
Expand Down
35 changes: 35 additions & 0 deletions src/srclib/encoding.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,41 @@ char16_t *enc_from_ansi_to_wide_chars(const char *from, apr_pool_t *pool) {
}
return wide;
}

size_t strlen16(const char16_t* strarg)
{
if(!strarg)
return -1; //strarg is NULL pointer
char16_t* str = strarg;
for(;*str;++str)
; // empty body
return str-strarg;
}

/*!
* IMPORTANT: Memory allocated for result must be freed up by caller
*/
char *enc_wide_chars_to_ansi(const char16_t *from, apr_pool_t *pool) {
size_t len = strlen16(from);
mbstate_t state = { 0 };
char16_t* str = from;
char* narrow = (char *)apr_pcalloc(pool, (len * MB_LEN_MAX + 1) * sizeof(char));
size_t j = 0;
for (size_t i = 0; i < len; ++i) {
char out[MB_LEN_MAX] = { 0 };
size_t rc = c16rtomb(out, from[i], &state);
if (rc != (size_t) - 1) {
for(size_t k = 0; k < MB_LEN_MAX; ++k) {
if (out[k]) {
narrow[j++] = out[k];
} else {
break;
}
}
}
}
return narrow;
}
#endif

/*!
Expand Down
5 changes: 5 additions & 0 deletions src/srclib/encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ wchar_t *enc_from_ansi_to_unicode(const char *from, apr_pool_t *pool);
* IMPORTANT: Memory allocated for result must be freed up by caller
*/
char16_t *enc_from_ansi_to_wide_chars(const char *from, apr_pool_t *pool);

/*!
* IMPORTANT: Memory allocated for result must be freed up by caller
*/
char *enc_wide_chars_to_ansi(const char16_t *from, apr_pool_t *pool);
#endif

/*!
Expand Down

0 comments on commit 51d1ba2

Please sign in to comment.