-
Notifications
You must be signed in to change notification settings - Fork 1k
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 Libsodium sodium support for sha256 filehashes #1381
base: master
Are you sure you want to change the base?
Changes from 1 commit
523acdb
e1468ea
201bc61
1fa3d1e
26c27e1
a9e725b
a5452f9
882058b
09b44ce
fbcd126
7e91526
a556191
bd9fa4d
fb1ac49
ce552d3
765b499
9b339f8
a978513
b728cf5
da38953
3dbaf31
c75e255
98b4e64
54cdbd4
1134eaa
9b1b3eb
e7e4b1a
a166003
2dfc8d6
4910ca6
80a960a
d0b0050
69945bd
de70834
17470fd
2d488e1
6fe831a
40815a3
8e5401c
241817e
c323f46
fd65186
d1ca9f3
869d653
54b5df1
1df3fb7
01a28e7
53c586c
e053db8
a451d8e
efe31a5
258fe5d
9d74ff7
4f044a3
e16624b
e98f71c
02ff1ba
274b56b
7990e9e
4df6e64
7a9f8a8
fc54a34
cd7831c
6dfc111
827a62a
a157c31
db2c5b7
e8d7873
b2923f6
bb3a7e7
51f61ee
1edbff1
028ac28
992f532
bd7cf0a
fdadbef
b3088db
50aa923
4347d84
3a230d7
a36f047
1682c31
80381a0
e63681a
ae89927
6835e83
a5244f9
16effe5
72d0ffb
6252474
6302c1c
792dea6
5d5e806
b2af210
a38f439
c02f109
ab95af3
e6f2fd5
00b6de1
9b5ddc7
f803934
4e2b2bf
5b6f673
fe1dd8f
bd5cc78
136e7f3
5092227
823a0e4
86f23ff
425391c
0cc90b4
3082ed5
17e2a2b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
lots of devug left in, need to free file_sums or change how it's being handled plenty of other cleanups available. sleep now. code later
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -93,42 +93,19 @@ int OS_MD5_SHA1_File(const char *fname, const char *prefilter_cmd, os_md5 md5out | |
} | ||
|
||
#ifdef LIBSODIUM_ENABLED | ||
int OS_Hash_File(const char *fname, const char *prefilter_cmd, struct hash_output file_output, int mode, char *hash1_alg, char *hash2_alg) | ||
int OS_Hash_File(const char *fname, const char *prefilter_cmd, struct hash_output *file_output, int mode) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Following along with the logic from above, SHA1 is supposed to be checked, but this function deals with MD5 and SHA256 only far as i see. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's been a long day, so I might be misunderstanding you. Bear with me and be gentle. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the confusion, it looks to me as though these changes would depend on both functions - since MD5 and SHA1 are always checked, which seems a bit redundant in the first place, but very much so if we run 3 (4 if MD5 happens once in each function being called) hash passes. If in fact the new function is being called instead, then it won't deal with the SHA1 piece, which still needs to be verified. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought I had made it so only OS_Hash_File() gets called if libsodium support is added. I'll have to double check. |
||
{ | ||
|
||
size_t n; | ||
FILE *fp; | ||
unsigned char buf[2048 + 2]; | ||
unsigned char sha1_digest[SHA_DIGEST_LENGTH]; | ||
unsigned char md5_digest[16]; | ||
|
||
int c_sha1 = 0, c_md5 = 0, c_sha256 = 0, al = 0; | ||
if((strncmp(hash1_alg, "md5", 3) == 0 || strncmp(hash1_alg, | ||
"MD5", 3) == 0)) { | ||
c_md5 = 1; | ||
file_output.md5output[0] = '\0'; | ||
} else if((strncmp(hash2_alg, "sha1", 4) == 0 || strncmp(hash2_alg, | ||
"SHA1", 4) == 0)) { | ||
c_sha1 = 1; | ||
file_output.sha1output[0] = '\0'; | ||
} else if((strncmp(hash2_alg, "sha256", 6) == 0 || strncmp(hash2_alg, | ||
"SHA256", 6) == 0)) { | ||
c_sha256 = 1; | ||
file_output.sha256output[0] = '\0'; | ||
} | ||
|
||
if(c_sha1 == 1 && c_sha256 == 1) { | ||
//merror("syscheckd: sha1 and sha256 enabled, disabling sha1."); | ||
c_sha1 = 0; | ||
} | ||
|
||
|
||
SHA_CTX sha1_ctx; | ||
MD5_CTX md5_ctx; | ||
|
||
/* Initialize libsodium */ | ||
unsigned char sha256_digest[crypto_hash_sha256_BYTES]; | ||
if(sodium_init() < 0) { | ||
//merror("Hash failed: (%d) %s", errno, strerror(errno)); | ||
exit(errno); // XXX - doesn't seem right | ||
} | ||
crypto_hash_sha256_state sha256_state; | ||
|
@@ -156,75 +133,38 @@ int OS_Hash_File(const char *fname, const char *prefilter_cmd, struct hash_outpu | |
} | ||
|
||
/* Initialize both hashes */ | ||
if(c_md5 > 0) { | ||
MD5Init(&md5_ctx); | ||
snprintf(file_output.hash1, 4, "MD5="); | ||
file_output.hash1[4] = '\0'; | ||
} | ||
if(c_sha1 > 0) { | ||
SHA1_Init(&sha1_ctx); | ||
snprintf(file_output.hash2, 5, "SHA1="); | ||
file_output.hash2[5] = '\0'; | ||
} | ||
MD5Init(&md5_ctx); | ||
snprintf(file_output->hash1, 4, "MD5="); | ||
file_output->hash1[4] = '\0'; | ||
|
||
/* Update for each hash */ | ||
while ((n = fread(buf, 1, 2048, fp)) > 0) { | ||
buf[n] = '\0'; | ||
if(c_sha1 > 0) { | ||
SHA1_Update(&sha1_ctx, buf, n); | ||
} | ||
if(c_md5 > 0) { | ||
MD5Update(&md5_ctx, buf, (unsigned)n); | ||
} | ||
if(c_sha256 > 0) { | ||
crypto_hash_sha256_update(&sha256_state, buf, n); | ||
} | ||
MD5Update(&md5_ctx, buf, (unsigned)n); | ||
crypto_hash_sha256_update(&sha256_state, buf, n); | ||
} | ||
|
||
if(c_sha1 > 0) { | ||
SHA1_Final(&(sha1_digest[0]), &sha1_ctx); | ||
} | ||
if(c_md5 > 0) { | ||
MD5Final(md5_digest, &md5_ctx); | ||
} | ||
if(c_sha256 > 0) { | ||
crypto_hash_sha256_final(&sha256_state, sha256_digest); | ||
} | ||
MD5Final(md5_digest, &md5_ctx); | ||
crypto_hash_sha256_final(&sha256_state, sha256_digest); | ||
|
||
/* Set output for MD5 */ | ||
if(c_md5 > 0) { | ||
for (n = 0; n < 16; n++) { | ||
if(n == 0) { | ||
snprintf(file_output.md5output, 3, "%02x", md5_digest[n]); | ||
} else { | ||
snprintf(file_output.md5output, strnlen(file_output.md5output, 33) + 3, "%s%02x", file_output.md5output, md5_digest[n]); | ||
} | ||
snprintf(file_output.hash1, strnlen(file_output.hash1, 37) + 3, "%s%02x", file_output.hash1, md5_digest[n]); | ||
} | ||
} | ||
|
||
/* Set output for SHA-1 */ | ||
if(c_sha1 > 0) { | ||
for (n = 0; n < SHA_DIGEST_LENGTH; n++) { | ||
if(n == 0) { | ||
snprintf(file_output.sha1output, 3, "%02x", sha1_digest[n]); | ||
} else { | ||
snprintf(file_output.sha1output, strnlen(file_output.sha1output, 65) + 3, "%s%02x", file_output.sha1output, sha1_digest[n]); | ||
} | ||
snprintf(file_output.hash2, strnlen(file_output.hash2, 65) + 3, "%s%02x", file_output.hash2, sha1_digest[n]); | ||
for (n = 0; n < 16; n++) { | ||
if(n == 0) { | ||
snprintf(file_output->md5output, 3, "%02x", md5_digest[n]); | ||
} else { | ||
snprintf(file_output->md5output, strnlen(file_output->md5output, 33) + 3, "%s%02x", file_output->md5output, md5_digest[n]); | ||
} | ||
snprintf(file_output->hash1, strnlen(file_output->hash1, 37) + 3, "%s%02x", file_output->hash1, md5_digest[n]); | ||
} | ||
|
||
/* Set output for SHA256 */ | ||
if(c_sha256 > 0) { | ||
for (n = 0; n < crypto_hash_sha256_BYTES; n++) { | ||
if(n == 0) { | ||
snprintf(file_output.sha256output, 3, "%02x", sha256_digest[n]); | ||
} else { | ||
snprintf(file_output.sha256output, strnlen(file_output.sha256output, 66) + 3, "%s%02x", file_output.sha256output, sha256_digest[n]); | ||
} | ||
snprintf(file_output.hash2, strnlen(file_output.hash2, 66) + 3, "%s%02x", file_output.hash2, sha256_digest[n]); | ||
for (n = 0; n < crypto_hash_sha256_BYTES; n++) { | ||
if(n == 0) { | ||
snprintf(file_output->sha256output, 3, "%02x", sha256_digest[n]); | ||
} else { | ||
snprintf(file_output->sha256output, strnlen(file_output->sha256output, 66) + 3, "%s%02x", file_output->sha256output, sha256_digest[n]); | ||
} | ||
snprintf(file_output->hash2, strnlen(file_output->hash2, 66) + 3, "%s%02x", file_output->hash2, sha256_digest[n]); | ||
} | ||
|
||
/* Close it */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having MD5 and SHA1 together makes some sense as both can have collisions, but dual-mode collisions are much less likely. SHA256 on the other hand is already computationally expensive, and not determined to have predictable collisions far as i know. Would it make more sense to
so as to avoid the redundancy in processing and storage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not against that, I was just continuing the tradition of using 2 hashes. I hope to replace md5 with blake2b (or whatever libsodium has as default at that point) in the future. md5 and sha256 give an analyst more opportunities to compare the hashes to "known bad" files out there. I've seen plenty of Indicators of Compromise reports still using md5.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, and some still use sha1, which sounds like "we might want them all." Maybe a semantic in which we store one hash and create other-algo-derived hashes on a change event for the alert would address that? Users could configure generation of event hashes in the fmt used by their malware engine, or just to pass the unk file to viper or whatever they're using for sample management to let another component deal with that rabbit hole.