-
Notifications
You must be signed in to change notification settings - Fork 621
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add: smb_cmac_aes_signature, smb_gmac_aes_signature
For an easier handling of smb packets new functions the functions: - smb_cmac_aes_signature, - smb_gmac_aes_signature got introduced for aes cmac and gmac handling. To use the functions you need a 64 byte long buffer and a key (with either 16 bytes for AES-129, 24 bytes for AES-192 or 32 bytes for AES-256) both functions will return the packet including the first 16 bytes of the signature (therefore AES-128 should be prefered). As an example you can create a `smb-packet-sign.nasl`: ``` key = "764efa883dda1e11"; neg_prot = raw_string( 0xfe, 0x53, 0x4d, 0x42 ); # Protocol Identifier neg_prot += raw_string( 0x40, 0x00 ); # Structure Size neg_prot += raw_string( 0x01, 0x00 ); # CreditCharge neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00 ); # Status neg_prot += raw_string( 0x00, 0x00 ); # Negotiate Protocol Command neg_prot += raw_string( 0x00, 0x00 ); # Credit Request neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00 ); # Flags neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00 ); # Next Command --> Compound Request neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ); # Message ID neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00 ); # Reserved neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00 ); # TreeID neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 ); # SessionID neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ); # Signature neg_prot += raw_string( 0x42, 0x42 ); # Structure Size neg_prot += raw_string( 0x04, 0x00 ); # Dialect Count neg_prot += raw_string( 0x01, 0x00 ); # Security Mode neg_prot += raw_string( 0x00, 0x00 ); # Reserved neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00 ); # Capabilities TBD add Encyrption neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ); # Client GUID neg_prot += raw_string( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ); # Different depending on dialect neg_prot += raw_string( 0x02, 0x02 ); # SMB 2.0.2 neg_prot += raw_string( 0x10, 0x02 ); # SMB 2.1 neg_prot += raw_string( 0x00, 0x03 ); # SMB 3.0 neg_prot += raw_string( 0x02, 0x03 ); # SMB 3.0.2 display("Original:"); display(hexstr(neg_prot)); display("SHA256 (cut to 16):"); sha256sig = get_smb2_signature( buf:neg_prot, key:key ); display(hexstr(sha256sig)); display("smb_cmac_aes_signature (128 => 16 keylen):"); cmac_aes = smb_cmac_aes_signature( buf:neg_prot, key:key ); display(hexstr(cmac_aes)); display("smb_gmac_aes_signature (128 => 16 keylen):"); gmac_aes = smb_cmac_aes_signature( buf:neg_prot, key:key ); display(hexstr(gmac_aes)); ``` The corresponding hash will be between `4242`.
- Loading branch information
1 parent
375969a
commit 45d777c
Showing
8 changed files
with
280 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ build/ | |
nasl/nasl_grammar.output | ||
nasl/nasl_grammar.tab.c | ||
nasl/nasl_grammar.tab.h | ||
.cache/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
#include "../misc//support.h" | ||
#include "nasl_crypto_helper.h" | ||
#include "nasl_debug.h" | ||
|
||
#include <assert.h> | ||
#include <ctype.h> | ||
#include <gcrypt.h> | ||
#include <glib.h> | ||
#include <gpg-error.h> | ||
#include <gvm/base/logging.h> | ||
#include <stddef.h> | ||
#include <stdlib.h> | ||
|
||
void * | ||
hmac_md5_for_prf (const void *key, int keylen, const void *buf, int buflen) | ||
{ | ||
void *signature = g_malloc0 (16); | ||
gsize signlen = 16; | ||
GHmac *hmac; | ||
|
||
hmac = g_hmac_new (G_CHECKSUM_MD5, key, keylen); | ||
g_hmac_update (hmac, buf, buflen); | ||
g_hmac_get_digest (hmac, signature, &signlen); | ||
g_hmac_unref (hmac); | ||
return signature; | ||
} | ||
|
||
void * | ||
hmac_sha1 (const void *key, int keylen, const void *buf, int buflen) | ||
{ | ||
void *signature = g_malloc0 (20); | ||
gsize signlen = 20; | ||
GHmac *hmac; | ||
|
||
hmac = g_hmac_new (G_CHECKSUM_SHA1, key, keylen); | ||
g_hmac_update (hmac, buf, buflen); | ||
g_hmac_get_digest (hmac, signature, &signlen); | ||
g_hmac_unref (hmac); | ||
return signature; | ||
} | ||
|
||
void * | ||
hmac_sha256 (const void *key, int keylen, const void *buf, int buflen) | ||
{ | ||
void *signature = g_malloc0 (32); | ||
gsize signlen = 32; | ||
GHmac *hmac; | ||
|
||
hmac = g_hmac_new (G_CHECKSUM_SHA256, key, keylen); | ||
g_hmac_update (hmac, buf, buflen); | ||
g_hmac_get_digest (hmac, signature, &signlen); | ||
g_hmac_unref (hmac); | ||
return signature; | ||
} | ||
|
||
void * | ||
hmac_sha384 (const void *key, int keylen, const void *buf, int buflen) | ||
{ | ||
gcry_md_hd_t hd; | ||
gcry_error_t err; | ||
void *ret; | ||
|
||
if (!buf || buflen <= 0) | ||
return NULL; | ||
|
||
err = gcry_md_open (&hd, GCRY_MD_SHA384, key ? GCRY_MD_FLAG_HMAC : 0); | ||
if (err) | ||
{ | ||
g_message ("nasl_gcrypt_hash(): gcry_md_open failed: %s/%s", | ||
gcry_strsource (err), gcry_strerror (err)); | ||
return NULL; | ||
} | ||
|
||
if (key) | ||
{ | ||
err = gcry_md_setkey (hd, key, keylen); | ||
if (err) | ||
{ | ||
g_message ("nasl_gcrypt_hash(): gcry_md_setkey failed: %s/%s", | ||
gcry_strsource (err), gcry_strerror (err)); | ||
return NULL; | ||
} | ||
} | ||
|
||
gcry_md_write (hd, buf, buflen); | ||
ret = g_memdup2 (gcry_md_read (hd, 0), 48); | ||
gcry_md_close (hd); | ||
return ret; | ||
} | ||
|
||
gpg_err_code_t | ||
mac (const char *key, const size_t key_len, const char *data, | ||
const size_t data_len, const char *iv, const size_t iv_len, int algo, | ||
int flags, char **out, size_t *out_len) | ||
{ | ||
// guardian | ||
gpg_err_code_t result = 0; | ||
gcry_mac_hd_t hd; | ||
if (key == NULL || key_len < 1) | ||
return GPG_ERR_MISSING_KEY; | ||
if (data == NULL || data_len < 1) | ||
return GPG_ERR_MISSING_VALUE; | ||
if (out == NULL) | ||
{ | ||
return GPG_ERR_GENERAL; | ||
} | ||
if ((result = gcry_mac_open (&hd, algo, flags, NULL))) | ||
return result; | ||
if ((result = gcry_mac_setkey (hd, key, key_len))) | ||
goto cexit; | ||
if (iv && (result = gcry_mac_setiv (hd, iv, iv_len))) | ||
goto cexit; | ||
if ((result = gcry_mac_write (hd, data, data_len))) | ||
goto cexit; | ||
|
||
*out_len = gcry_mac_get_algo_maclen (algo); | ||
if ((*out = calloc (*out_len, sizeof (*out))) == NULL) | ||
{ | ||
result = GPG_ERR_ENOMEM; | ||
goto cexit; | ||
} | ||
if ((result = gcry_mac_read (hd, *out, out_len))) | ||
goto cexit; | ||
|
||
cexit: | ||
gcry_mac_close (hd); | ||
return result; | ||
} | ||
|
||
static gcry_error_t | ||
smb_sign (const int algo, const char *key, const size_t key_len, char *buf, | ||
const size_t buf_len, char **out) | ||
{ | ||
gcry_error_t error = GPG_ERR_NO_ERROR; | ||
char *signature = NULL; | ||
size_t signature_len; | ||
if (buf == NULL || buf_len < 64) | ||
{ | ||
return GPG_ERR_NO_VALUE; | ||
} | ||
if (key == NULL || key_len < 16) | ||
return GPG_ERR_NO_KEY; | ||
memset ((char *) buf + 48, 0, 16); | ||
switch (algo) | ||
{ | ||
case GCRY_MAC_GMAC_AES: | ||
case GCRY_MAC_CMAC_AES: | ||
if ((error = mac (key, key_len, buf, buf_len, NULL, 0, algo, | ||
GCRY_MAC_FLAG_SECURE, &signature, &signature_len))) | ||
goto exit; | ||
break; | ||
case G_CHECKSUM_SHA256: | ||
signature = hmac_sha256 (key, key_len, buf, buf_len); | ||
break; | ||
default: | ||
// not defined; | ||
error = GPG_ERR_UNKNOWN_ALGORITHM; | ||
goto exit; | ||
} | ||
// TODO is 16 hard coded or should it be signature_len? | ||
*out = g_malloc0 (buf_len); | ||
memcpy (*out, buf, buf_len); | ||
memcpy (*out + 48, signature, 16); | ||
free (signature); | ||
exit: | ||
return error; | ||
} | ||
|
||
tree_cell * | ||
nasl_smb_sign (const int algo, lex_ctxt *lexic) | ||
{ | ||
char *key, *buf, *res; | ||
int keylen, buflen; | ||
gcry_error_t error; | ||
tree_cell *retc = NULL; | ||
|
||
key = get_str_var_by_name (lexic, "key"); | ||
buf = get_str_var_by_name (lexic, "buf"); | ||
keylen = get_var_size_by_name (lexic, "key"); | ||
buflen = get_var_size_by_name (lexic, "buf"); | ||
|
||
switch ((error = smb_sign (algo, key, keylen, buf, buflen, &res))) | ||
{ | ||
case GPG_ERR_NO_ERROR: | ||
retc = alloc_typed_cell (CONST_DATA); | ||
retc->x.str_val = res; | ||
retc->size = buflen; | ||
break; | ||
case GPG_ERR_MISSING_KEY: | ||
case GPG_ERR_MISSING_VALUE: | ||
nasl_perror (lexic, "Syntax: nasl_mac: Missing key, or data argument"); | ||
break; | ||
default: | ||
nasl_perror (lexic, "Internal: %s.", gcry_strerror (error)); | ||
} | ||
|
||
return retc; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.