Malloc error when comparing arrays of bytes - c

I can't figure out where my code is going wrong. I know there is allocation error in my function getit() but I can't figure out why! Any help is appreciated.
What my program does is hash a message into one array. Then, I have a random word generator that makes a string and hashes them. My program will then compare the hashes and keep making words until the hash matches the origional.
#include <stdio.h>
#include <openssl/evp.h>
#include <string.h>
void randString(int length, char* s);
void getit(unsigned char rando[], unsigned char hash[]);
char* mess1 = "Test Message";
unsigned char match[3];
int boolean = 0;
unsigned char orHash[3];
unsigned char raHash[3];
int counter = 0;
int main(int argc, char *argv[])
{
srand(time(NULL));
EVP_MD_CTX *mdctx;
const EVP_MD *md;
unsigned char md_value[EVP_MAX_MD_SIZE];
int md_len, i;
OpenSSL_add_all_digests();
md = EVP_get_digestbyname("SHA256");
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, mess1, strlen(mess1));
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_destroy(mdctx);
strcpy(match,md_value);
strcpy(orHash,match);
printf("Digest is: ");
for (i = 0; i < 3; i++)
printf("%02x", match[i]);
printf("\n");
while(boolean < 3){
char* qt = malloc(strlen(mess1) * sizeof(char));
randString(strlen(mess1),qt);
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, qt, strlen(mess1));
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_destroy(mdctx);
strcpy(raHash,md_value);
getit(raHash, orHash);
}
exit(0);
}
void randString(int length, char* s) {
const char alpha[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < length; i++){
s[i] = alpha[rand()%(int)(sizeof(alpha) -1)];
}
s[length] = '\0';
}
void getit(unsigned char rando[], unsigned char hash[]){
counter += 1;
for (int i = 0; i < 3; i++)
printf("%02x", rando[i]);
for(int i = 0; i < 3; i++){
if (rando[i] != hash[i]){
printf("%d: The hashes don't match\n", counter);
boolean = 0;
break;
}
boolean += 1;
if(boolean == 3){
printf("Match Found!");
}
}
}
The Error I get is as follows:
hash: malloc.c:2392: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
The code breaks at trial 505 everytime (finished comparing trial 504) trying the see if the two arrays match so that might help.

There is no need to dynamic allocation in any of this. The whole point of this exercise it to brute-force generating random, equal-length alpha-numeric strings, digesting them, and stopping when you fine one that matches the first three octets.
No string conversions are required
One like-sized message buffer (matching the size of your test message) can be used.
You can reuse the digest context. No need to keep allocating and destroying it.
getit is ultimately pointless except to tally up a counter.
The result is something like this:
Code
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
void randString(size_t length, char* s);
int main()
{
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned char md_test[EVP_MAX_MD_SIZE];
unsigned int md_len, i;
char msg[] = "Test Message";
srand((unsigned)time(NULL));
OpenSSL_add_all_digests();
const EVP_MD *md = EVP_get_digestbyname("SHA256");
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, msg, sizeof msg-1);
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
printf("Digest is: ");
for (i = 0; i < md_len; i++)
printf("%02x", md_value[i]);
printf("\n");
int counter = 0;
while (1)
{
++counter;
char rand_msg[sizeof msg];
randString(sizeof msg - 1, rand_msg);
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, rand_msg, sizeof rand_msg - 1);
EVP_DigestFinal_ex(mdctx, md_test, &md_len);
if (memcmp(md_test, md_value, 3) == 0)
{
printf("Match found: %s\nAttempts: %d\n", rand_msg, counter);
printf("Digest is: ");
for (i = 0; i < md_len; i++)
printf("%02x", md_test[i]);
printf("\n");
break;
}
}
return 0;
}
Sample Output (varies, obviously)
Digest is: b67d1b3ab0d839eb8bc1156b8717bb441c897fcab323374e2ae530a40632feba
Match found: nPbeGgsZcNoo
Attempts: 9570596
Digest is: b67d1bcdab5d05a8712a8cd4c99b5bf683fdcefcf43fc453f852f4ff14b28a39

Friends I figured it out.
I never used free(qt) so eventually, it ran out of memory to allocate after looping!

Related

Why is the integer in the struct a garbage values even though it was changed?

So, I implemented split in C, now I know strtok exists, but I wanted to implement it, so my function returns a struct that has the string array and the length, which is decided by the number of times the delimiter occurs and whether it's the first value or not, here's the code.
split.h
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int count_delm(char *, char);
char *make_str(char);
struct split_output {
char **arr;
int size;
};
typedef struct split_output split_arr;
split_arr *split(char *, char);
split.c
#include "split.h"
int count_delm(char *str, char delm) {
register int lpvar = 0;
register int counter = 0;
while (str[lpvar] != '\0') {
if (str[lpvar] == delm) {
counter++;
}
lpvar++;
}
return counter;
}
char *make_str(char ch) {
char *ret_str = (char *)malloc(2);
ret_str[0] = ch;
ret_str[1] = '\0';
return ret_str;
}
split_arr *split(char *str, char delm) {
int num_delm = count_delm(str, delm);
char **final_arr;
register int lpvar = 0;
register int arr_counter = 0;
char *concat_str = (char *)malloc(2);
int ret_size = 0;
if (str[0] == delm) {
concat_str = make_str(str[1]);
final_arr = (char **)malloc(sizeof(char *) * (num_delm));
ret_size = num_delm;
lpvar++;
} else {
concat_str = make_str(str[0]);
final_arr = (char **)malloc(sizeof(char *) * (num_delm + 1));
ret_size = num_delm + 1;
}
while (1) {
if (str[lpvar + 1] != '\0') {
if (str[lpvar + 1] != delm) {
concat_str = strcat(concat_str, make_str(str[lpvar + 1]));
lpvar++;
} else {
final_arr[arr_counter] = concat_str;
arr_counter++;
if (str[lpvar + 2] != '\0') {
lpvar++;
lpvar++;
concat_str = make_str(str[lpvar]);
}
}
} else {
arr_counter++;
final_arr[arr_counter] = concat_str;
printf("%s is the last at pos %d\n", concat_str, arr_counter);
break;
}
}
split_arr *ret_struct = (split_arr *)malloc(sizeof(split_arr));
(*ret_struct).size = ret_size;
(*ret_struct).arr = final_arr;
return ret_struct;
}
That was the code of the split implementation, here's the code that tests it.
test.c
#include "split.h"
int main() {
char *x = "lryabruahsdfads";
split_arr output = *(split(x, 'a'));
char **read = output.arr;
int len = output.size;
int loop = 0;
printf("size: %d", len - 1);
for (loop = 0; loop < len; loop++) {
puts(*(read + loop));
}
return 0;
}
Here's the output when executed:
ds is the last at pos 4
size: 3lry
bru
hsdf
Segmentation fault (core dumped)
Why is output.size 3lry? I de-referenced the struct pointer to get the struct so there's nothing wrong with that. I can't find the error, I've been trying to debug for almost an hour.
In your split.c file over here:
else{
arr_counter++; //comment this line
final_arr[arr_counter]=concat_str;
printf("%s is the last at pos %d\n",concat_str,arr_counter);
break;
}
You are incrementing variable arr_counter which you should not because you already incremented it inside the if. Just comment out this line and your code works fine.
And your output is fine just add a line return to the printf statements like:
printf("size: %d \n",len-1);

OpenSSL MD5 gives a different hash every time

I'm trying to create a certain modular code using OpenSSL's EVP API for MD5 by passing the EVP_MD object within functions as shown below.
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
EVP_MD* md5_digest_init() {
OpenSSL_add_all_digests();
EVP_MD *md = EVP_get_digestbyname("MD5");
if(!md) {
printf("Unable to init MD5 digest\n");
exit(1);
}
return md;
}
unsigned char *md5_digest_process(EVP_MD* md, unsigned char *input_text) {
EVP_MD_CTX mdctx;
unsigned char hash[EVP_MAX_MD_SIZE];
int hash_len;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
EVP_DigestUpdate(&mdctx, input_text, strlen(input_text)+1);
EVP_DigestFinal_ex(&mdctx, hash, &hash_len);
EVP_MD_CTX_cleanup(&mdctx);
return hash;
}
int main() {
EVP_MD *md;
md = md5_digest_init();
unsigned char* res;
res = md5_digest_process(md, "foobar");
printf("%02x", res);
return 0;
}
The problem is that on executing the code every time, I obtain a different hash value for the same text.
Such as
585c64a0
554454a0
5f75a4a0, etc
MD5 is deterministic and such an issue should not exist. Any reason why such as error exists? Also, the passing of the EVP_MD object within functions is important to me.
EDIT:
Replacing the final printf with the following code
for(int i = 0; i < 16; ++i)
printf("%02x", res[i]);
I get the following output.
b4000000000000000100000000000000
However, this stays the same for all executions. But I'm guessing that this hash isn't right.
As stated in comments, md5_digest_process() is returning a pointer to a local variable that goes out of scope when the function exits, leaving the pointer dangling as it is left pointing to invalid memory.
But that doesn't matter to your issue, because you are printing the memory address that the pointer is pointing at, not the data that it is pointing at. So your printed output is displaying whatever random memory address the local hash variable existed at when the function was called. That is why you are seeing inconsistent values in your output. As stated in comments, you need to dereference the pointer in order to print the data that is being pointed at.
If you want to return a pointer to memory that outlives the function, you have to allocate the memory dynamically:
unsigned char* md5_digest_process(EVP_MD* md, unsigned char *input_text, int *hash_len) {
unsigned char *hash = (unsigned char *) malloc(EVP_MAX_MD_SIZE);
if (!hash) return NULL;
EVP_MD_CTX mdctx;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
EVP_DigestUpdate(&mdctx, input_text, strlen(input_text)+1);
EVP_DigestFinal_ex(&mdctx, hash, hash_len);
EVP_MD_CTX_cleanup(&mdctx);
return hash;
}
int main() {
EVP_MD *md = md5_digest_init();
int hash_len = 0;
unsigned char* res = md5_digest_process(md, "foobar", &hash_len);
if (res) {
for(int i = 0; i < hash_len; ++i) {
printf("%02x", res[i]);
}
free(res)
}
return 0;
}
Otherwise, the caller will have to allocate the memory and pass it into the function to fill in:
int md5_digest_process(EVP_MD* md, unsigned char *input_text, unsigned char* hash) {
EVP_MD_CTX mdctx;
int hash_len = 0;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
EVP_DigestUpdate(&mdctx, input_text, strlen(input_text)+1);
EVP_DigestFinal_ex(&mdctx, hash, &hash_len);
EVP_MD_CTX_cleanup(&mdctx);
return hash_len;
}
int main() {
EVP_MD *md = md5_digest_init();
unsigned char hash[EVP_MAX_MD_SIZE];
int hash_len = md5_digest_process(md, "foobar", hash);
for(int i = 0; i < hash_len; ++i) {
printf("%02x", res[i]);
}
return 0;
}
I think you are close. I would probably change md5_digest_process to:
/* md_digest is declared as unsigned char md_digest[EVP_MAX_MD_SIZE] */
unsigned int md5_digest_process(EVP_MD* md, unsigned char *input_text, unsigned int input_len, unsigned char* md_digest)
{
int hash_len;
EVP_MD_CTX mdctx;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
EVP_DigestUpdate(&mdctx, input_text, input_len);
EVP_DigestFinal_ex(&mdctx, md_digest, &hash_len);
EVP_MD_CTX_cleanup(&mdctx);
return hash_len;
}
Then, print md_digest with:
int main()
{
EVP_MD *md;
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int hash_len;
md = md5_digest_init();
hash_len = md5_digest_process(md, "foobar", 6, hash);
for(unsigned int i=0; i<hash_len; i++)
printf("%02x", hash[i]);
printf("\n");
return 0;
}
You should also add some error checking.

msgpack packing char array in C

How do I work with msgpack_pack_raw and msgpack_pack_raw_body to send an unsigned char array to more importantly, how to retrieve (unpack) it?
What I have done is as follows:
msgpack_sbuffer* buffer = msgpack_sbuffer_new();
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
msgpack_sbuffer_clear(buffer);
msgpack_pack_array(pk, 10);
unsigned char a[10] = "0123456789";
msgpack_pack_raw(pk, 10);
msgpack_pack_raw_body(pk,a,10);
and in the receiver part I have:
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
msgpack_unpack_next(&msg, buffer->data, buffer->size, NULL);
msgpack_object obj = msg.data;
msgpack_object* p = obj.via.array.ptr;
int length = (*p).via.raw.size;
IDPRINT(length);
unsigned char* b = (unsigned char*) malloc(length);
memcpy(b,(*p).via.raw.ptr,length);
But it throws seg fault when executing "int length = (*p).via.raw.size;".
Any idea why?
Any idea why?
This is because msgpack_pack_array(pk, 10); is not required here, since you pack your data as a raw buffer of a given size. In other words msgpack_pack_raw and msgpack_pack_raw_body are sufficient.
At unpack time, you must access its fields as follow:
length: obj.via.raw.size
data: obj.via.raw.ptr
see: msgpack_object_raw in object.h.
Here's a recap of how to proceed:
#include <stdio.h>
#include <assert.h>
#include <msgpack.h>
int main(void) {
unsigned char a[10] = "0123456789";
char *buf = NULL;
int size;
/* -- PACK -- */
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pck;
msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write);
msgpack_pack_raw(&pck, 10);
msgpack_pack_raw_body(&pck, a, 10);
size = sbuf.size;
buf = malloc(sbuf.size);
memcpy(buf, sbuf.data, sbuf.size);
msgpack_sbuffer_destroy(&sbuf);
/* -- UNPACK -- */
unsigned char *b = NULL;
int bsize = -1;
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
if (msgpack_unpack_next(&msg, buf, size, NULL)) {
msgpack_object root = msg.data;
if (root.type == MSGPACK_OBJECT_RAW) {
bsize = root.via.raw.size;
b = malloc(bsize);
memcpy(b, root.via.raw.ptr, bsize);
}
}
/* -- CHECK -- */
assert(bsize == 10);
assert(b != NULL);
for (int i = 0; i < bsize; i++)
assert(b[i] == a[i]);
printf("ok\n");
free(buf);
free(b);
return 0;
}

Segmentation fault on mcrypt (probably something to do with the buffer) [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I'm trying to build my own crypter in c using AES to encrypt the shellcode. Now I've already made a PoC of the crypter in one program which can be found below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* MCrypt API available online:
* http://linux.die.net/man/3/mcrypt
*/
#include <mcrypt.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
int encrypt(
void* buffer,
int buffer_len, /* Because the plaintext could include null bytes*/
char* IV,
char* key,
int key_len
){
MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
int blocksize = mcrypt_enc_get_block_size(td);
if( buffer_len % blocksize != 0 ){return 1;}
mcrypt_generic_init(td, key, key_len, IV);
mcrypt_generic(td, buffer, buffer_len);
mcrypt_generic_deinit (td);
mcrypt_module_close(td);
return 0;
}
int decrypt(
void* buffer,
int buffer_len,
char* IV,
char* key,
int key_len
){
MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
int blocksize = mcrypt_enc_get_block_size(td);
if( buffer_len % blocksize != 0 ){return 1;}
mcrypt_generic_init(td, key, key_len, IV);
mdecrypt_generic(td, buffer, buffer_len);
mcrypt_generic_deinit (td);
mcrypt_module_close(td);
return 0;
}
int main()
{
{
MCRYPT td, td2;
unsigned char * plaintext = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
char* IV = "AAAAAAAAAAAAAAAA";
char *key = "0123456789abcdef";
int keysize = 16; /* 128 bits */
unsigned char buffer[32];
int counter;
int buffer_len = 32;
for ( counter = 0; counter < buffer_len; counter++){
buffer[counter]=0x90;
}
strncpy(buffer, plaintext, buffer_len);
int plain_len = strlen(plaintext);
printf("==Plain Binary==\n");
for ( counter = 0; counter < plain_len; counter++){
printf("%02x",plaintext[counter]);
}
encrypt(buffer, buffer_len, IV, key, keysize);
printf("\n==Encrypted Binary==\n");
for ( counter = 0; counter < buffer_len; counter++){
printf("\\x%02x",buffer[counter]);
}
decrypt(buffer, buffer_len, IV, key, keysize);
printf("\n==decrypted Binary==\n");
for ( counter = 0; counter < buffer_len; counter++){
if (buffer[counter] == 0){
buffer[counter] = 0x90;
}
printf("\\x%02x",buffer[counter]);
}
printf("\n");
printf("Shellcode Length: %d\n", strlen(buffer));
int (*ret)() = (int(*)())buffer;
ret();
return 0;
}
My goal is to take the encrypted shellcode, decrypt it and run it. However it seems I'm getting a segmentation fault when I try to initialize mcrypt with the mcrypt_generic_init(td, key, key_len, IV); function. I'm really unsure what is causing the segmentation fault. If anyone has an idea?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* MCrypt API available online:
* http://linux.die.net/man/3/mcrypt
*/
#include <mcrypt.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
int decrypt(
void* buffer,
int buffer_len,
char* IV,
char* key,
int key_len
){
MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
int blocksize = mcrypt_enc_get_block_size(td);
if( buffer_len % blocksize != 0 ){return 1;}
printf("proceeding to mcrypt\n");
mcrypt_generic_init(td, key, key_len, IV);
printf("initiated mcrypt") ;
mdecrypt_generic(td, buffer, buffer_len);
printf("proceeding to mcrypt\n");
mcrypt_generic_deinit (td);
printf("proceeding to mcrypt\n");
mcrypt_module_close(td);
printf("returning from mcrypt\n");
return 0;
}
int main()
{
MCRYPT td,td2;
char* IV = "AAAAAAAAAAAAAAAA";
char *key = "0123456789abcdef";
int keysize = 16; /* 128 bits */
unsigned char* buffer = "\x5c\xd8\xcf\x9e\x8f\x3a\x9f\x52\x2e\x3d\x51\x06\x00\xde\xa6\x64\x45\x5f\x62\x53\x75\xab\xbd\xe1\x33\xc1\x69\xbf\xed\xc8\x5c\xaa";
int buffer_len = 32;
int counter;
decrypt(buffer, buffer_len, IV, key, keysize);
for ( counter = 0; counter < buffer_len; counter++){
printf("0x%02x",buffer[counter]);
}
printf("\n");
printf("Shellcode Length: %d\n", strlen(buffer));
int (*ret)() = (int(*)())buffer;
ret();
return 0;
}
You are trying to write in a literal string. This is wrong because compilers are allowed to allocate literal strings in read-only memory (and they really do that).
Change this:
char *buffer = "..."
into this:
char buffer[] = "..."
The latter will allocate an array on the stack (hence modifiable) and dynamically fill it with the data from the literal string (done anew each time the function is entered).

How to build char* from array of char*

Please have a look at the following code:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
const char * cmd;
const char * help;
} CmdEnum;
static CmdEnum cmd_enum[] = {
{"help", "This help..."},
{"first", "The first command"},
{"second", "The second command"},
};
void main()
{
int i,n;
char *out = "";
n = sizeof(cmd_enum) / sizeof(CmdEnum);
for (i=0; i<n; i++)
{
char *oldOut = out;
CmdEnum cmd = cmd_enum[i];
asprintf(&out, "%s%s -> %s\n", oldOut, cmd.cmd, cmd.help);
if(i>0) free(oldOut);
}
printf("%s", out);
printf("Done.\n");
}
Is this a good way to build a text from the CmdEnum?
Is there a "nicer" way do define cmd in the first place as to avoid the if(i>0) free...?
Or am I doing something entirely wrong?
EDIT:
After reading larsmans' answer I modified main to:
int main()
{
int i,n, copied, siz;
char *out, *cursor;
siz = 1;// 1 for NUL char
n = sizeof(cmd_enum) / sizeof(CmdEnum);
for (i=0; i<n; i++)
{
siz += strlen(cmd_enum[i].cmd) + strlen(cmd_enum[i].help) + strlen(":\n\t\n\n");
}
out = malloc(siz);
if(!out)
{
printf("Could not alloc!\n");
return 1;
}
cursor = out;
for (i=0; i<n; i++)
{
copied = snprintf(cursor, siz, "%s:\n\t%s\n\n", cmd_enum[i].cmd, cmd_enum[i].help);
if(copied < 0 || copied >= siz)
{
printf("snprintf failed: %i chars copied.\n", copied);
return 1;
}
cursor += copied;
siz -= copied;
}
printf("%s", out);
printf("Done.\n");
free(out);
return 0;
}
(Note: I also changed the output format...)
Is this a good way to build a text from the CmdEnum?
Yes, except that asprintf is not portable (although you can define it easily in terms of snprintf for platforms that don't have it) and you're not checking error returns. void main isn't valid C btw.
Is there a "nicer" way do define cmd in the first place as to avoid the if(i>0) free...?
You could allocate the whole string beforehand.
size_t i, siz = 1; // 1 for NUL char
for (i=0; i<n; i++)
siz += strlen(cmd_enum[i].cmd) + strlen(cmd_enum[i].help) + strlen(" -> \n");
char *out = malloc(siz);
// check for errors
then build the string with snprintf. This saves you some malloc'ing and error checking in the loop.

Resources