How to decrypt wpa 2 psk with openssl, programming in c - c

I need to decrypt wpa 2 psk programming in c. Assuming that i alredy have the TK (need to decrypt only unicast) I'm trying to decrypt packets whit the following code (with no luck actually):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/pem.h>
#include <openssl/bn.h>
#include <openssl/aes.h>
struct ctr_state {
unsigned char ivec[128];
unsigned int num;
unsigned char ecount[128];
};
void init_ctr(struct ctr_state *state, const unsigned char iv[16]){ //
state->num = 0;
memset(state->ecount, 0, 128);
memset(state->ivec, 0, 128);
memcpy(state->ivec, iv, 16);
}
char * extochar(char * in, int inLen){
int i,k;
int resInt[inLen/2];
char * resChar=malloc(inLen/2);
k=0;
for(i=0; i<inLen/2; i=i++){
resInt[k]=chartoint(in[i*2])<<4;
resInt[k]+=chartoint(in[(i*2)+1]);
k++;
}
for(k=0; k<inLen/2;k++){
resChar[k]=(char)resInt[k];
}
return resChar;
}
int chartoint(char car){
int intero = 0;
intero = car - '0';
if(intero < 10 && intero > -1)
return intero;
else
return car - 'a' + 10;
}
void main(){
unsigned char * po = extochar("00",2);
unsigned char * a2 = extochar("0012f0be7301",12);
unsigned char * pn = extochar("000000000052",12);
unsigned char * nonce= malloc(13);
char * hextk= "15b1657878b1d12c93b4e073e42b629a";
unsigned char * tk= extochar(hexstr, strlen(hextk));
init_ctr(&status, nonce);
nonce[0]=po[0];
nonce[1]=a2[0];
nonce[2]=a2[1];
nonce[3]=a2[2];
nonce[4]=a2[3];
nonce[5]=a2[4];
nonce[6]=a2[5];
nonce[7]=pn[0];
nonce[8]=pn[1];
nonce[9]=pn[2];
nonce[10]=pn[3];
nonce[11]=pn[4];
nonce[12]=pn[5];
AES_KEY aes_key;
if(AES_set_encrypt_key(tk, 128, &aes_key))
exit(-1);
//encrypted payload
char * ext_crypt = "146a056e3b20ece434594373a0e4fcbc83114c9a1bc158ecc4ca6bb449d6ec8468c8e08af3f4f33ce961f7b42c7651e22042e0bf39bd864a1b5f1035af5a54986183ee79446e3fb80a6f9bbb7a0177f557ce192c5515bd3a671b73464b9cf0fb817fd614987b65c0e20d753dedab8bf1934294e112cb865effb14724a2c66fcc7956f8fcfb0f7f2e539fbbf4e30c08fc18d10eb143510eae8b88e911c1cee773b73cdaf6d45151ad01fb2e2f5aa014510a";
int msg_len= strlen(ext_crypt)/2 - 12;
unsigned char * crypt = extochar(ext_crypt, strlen(ext_crypt));
AES_ctr128_encrypt(crypt, cleartxt, msg_len, &aes_key, status.ivec, status.ecount, &status.num);
}
The output should be something like that:
-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 2
ST: urn:schemas-upnp-org:service:WANPPPConnection:1
I pasted the source of the encrypted packet here: http://pastebin.com/RvkfSt54
are there any problems in the code or in the data, and how can I solve them?
thanks a lot!

Aside from the code being uncommented and somewhat poorly formatted... your question whether there are "any problems in the code" can be answered by your compiler, if you enable warnings (which you should always do):
test.c: In function ‘extochar’:
test.c:28:26: warning: operation on ‘i’ may be undefined
test.c:29:13: warning: implicit declaration of function ‘chartoint’
test.c: At top level:
test.c:40:5: error: conflicting types for ‘chartoint’
test.c:40:1: note: an argument type that has a default promotion can’t match an empty parameter name list declaration
test.c:29:23: note: previous implicit declaration of ‘chartoint’ was here
test.c:49:6: warning: return type of ‘main’ is not ‘int’
test.c: In function ‘main’:
test.c:51:26: warning: pointer targets in initialization differ in signedness
test.c:52:26: warning: pointer targets in initialization differ in signedness
test.c:53:26: warning: pointer targets in initialization differ in signedness
test.c:56:34: error: ‘hexstr’ undeclared (first use in this function)
test.c:56:34: note: each undeclared identifier is reported only once for each function it appears in
test.c:57:15: error: ‘status’ undeclared (first use in this function)
test.c:79:30: warning: pointer targets in initialization differ in signedness
test.c:80:31: error: ‘cleartxt’ undeclared (first use in this function)

Related

C, conflicting types on a function that takes in chars and returns chars when it's been declared already? Then sudden loop only supported in c99

I am getting these two following error messages on 2 parts of the code that's been marked as comments.
But why do these error messages happen? I have declared the decrypt function before main haven't I? and is this not how you implement a for loop in C?
#include <stdio.h>
#include <stdlib.h>
#include <conf.h>
#include <evp.h>
#include <err.h>
#include <string.h>
#include <ctype.h>
unsigned char *readWord(FILE *fp);
char *decrypt(unsigned char *Ciphertext, unsigned char *key,unsigned char *iv);
int main (void)
{
char *key = NULL;
char *iv = "aabbccddeeff00998877665544332211";
char *Plaintext = "This is a top secret.";
char *Ciphertext = "764aa26b55a4da654df6b19e4bce00f4ed05e09346fb0e762583cb7da2ac93a2";
char *checker;
FILE *words = (fopen("words", "r"));
while(1) {
key = readWord(words);
if (!key){
printf("the key was not found");
break;
}
else{
checker = decrypt(Ciphertext,key,iv);
if(strcmp(checker,Plaintext)){
printf("the correct key is ");
printf(key);
}
free(key);
free(checker);
}
}
return 0;
}
char *decrypt(unsigned char *Ciphertext, unsigned char *key, unsigned char *iv) //here it's correctly declared right?
{
EVP_CIPHER_CTX *ctx; //could not be resolved not sure why
unsigned char *plainText = malloc(sizeof(unsigned char) * 64);
int len;
int plaintext_len;
if(!(ctx = EVP_CIPHER_CTX_new()))
handleErrors(); //why error here it's fine below
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
handleErrors();
if(1 != EVP_DecryptUpdate(ctx, plainText, &len, Ciphertext, plaintext_len))
handleErrors();
plaintext_len += len;
if(1 != EVP_DecryptFinal_ex(ctx, plainText + len, &len))
handleErrors();
plaintext_len += len;
EVP_CIPHER_CTX_free(ctx);
int checkLen = (2 * len) + 1;
char *checker2 = malloc(sizeof(char) * (checkLen));
for(int i = 0; i < len; ++i) //for loop only allowed in C99 mode what?
{
sprintf(checker2 + (i*2),"%02x",plainText[i]);
}
free(plainText);
return checker2;
}
This is the complete error messages on the console.
Info: Configuration "Debug" uses tool-chain "Cygwin GCC" that is unsupported on this system, attempting to build anyway.
make all
'Building file: ../src/try.c'
'Invoking: Cygwin C Compiler'
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/try.d" -MT"src/try.o" -o "src/try.o" "../src/try.c"
../src/try.c: In function 'main':
../src/try.c:30:10: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
../src/try.c:36:7: warning: pointer targets in passing argument 1 of 'decrypt' differ in signedness [-Wpointer-sign]
../src/try.c:18:7: note: expected 'unsigned char *' but argument is of type 'char *'
../src/try.c:36:7: warning: pointer targets in passing argument 2 of 'decrypt' differ in signedness [-Wpointer-sign]
../src/try.c:18:7: note: expected 'unsigned char *' but argument is of type 'char *'
../src/try.c:36:7: warning: pointer targets in passing argument 3 of 'decrypt' differ in signedness [-Wpointer-sign]
../src/try.c:18:7: note: expected 'unsigned char *' but argument is of type 'char *'
../src/try.c: In function 'decrypt':
../src/try.c:59:9: warning: implicit declaration of function 'handleErrors' [-Wimplicit-function-declaration]
../src/try.c:67:5: warning: pointer targets in passing argument 2 of 'EVP_DecryptUpdate' differ in signedness [-Wpointer-sign]
In file included from ../src/try.c:13:0:
c:\users\marcu\gcc\bin\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/evp.h:635:5: note: expected 'unsigned char *' but argument is of type 'char *'
../src/try.c:72:5: warning: pointer targets in passing argument 2 of 'EVP_DecryptFinal_ex' differ in signedness [-Wpointer-sign]
In file included from ../src/try.c:13:0:
c:\users\marcu\gcc\bin\../lib/gcc/x86_64-w64-mingw32/4.7.0/../../../../x86_64-w64-mingw32/include/evp.h:638:5: note: expected 'unsigned char *' but argument is of type 'char *'
../src/try.c:80:5: error: 'for' loop initial declarations are only allowed in C99 mode
../src/try.c:80:5: note: use option -std=c99 or -std=gnu99 to compile your code
make: *** [src/try.o] Error 1
"make all" terminated with exit code 2. Build might be incomplete.
This happens because declaring variables inside a for loop wasn't valid C until C99(which is the standard of C published in 1999), you can either declare your counter outside the for as pointed out by others or use the -std=c99 flag to tell the compiler explicitly that you're using this standard and it should interpret it as such.
You can init i variable like this.
int i;
for(i = 0; i < len; ++i) //for loop only allowed in C99 mode what?
{
sprintf(checker2 + (i*2),"%02x",plainText[i]);
}

"error: conflicting types" when trying to return a character-array reference [duplicate]

This question already has an answer here:
note: previous implicit declaration of ‘point_forward’ was here
(1 answer)
Closed 1 year ago.
In an effort to learn C and string operations, I'm making a small program that simply generates random IP addresses as strings and outputs it. From what I've gathered from various tutorials as well as examples here on stackoverflow, the below would be one way of doing so, but returning the character array reference is what stumps me, as it doesn't compile:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *testip = randip();
printf("%s", testip);
free(testip);
return 0;
}
// get rand IP
char* randip()
{
char *ip = malloc(16);
int a = randint(1,254);
int b = randint(0,254);
int c = randint(0,254);
int d = randint(0,254);
sprintf(ip, "%d.%d.%d.%d", a, b, c, d);
printf("D> randip generated %s", ip);
return ip;
}
// generate rand int
int randint(unsigned int min, unsigned int max)
{
double scaled = (double)rand()/RAND_MAX;
return (max - min +1)*scaled + min;
}
gcc output:
test.c: In function ‘main’:
test.c:8:18: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c: At top level:
test.c:17:7: error: conflicting types for ‘randip’
test.c:8:18: note: previous implicit declaration of ‘randip’ was here
I am unable to see which types are incompatible? Did I accidentally return, call, or miscast a type I didn't intend for?
Note: Yes, I know my randomness isn't very random, and there are probably better way of handling that part, but that's outside of the scope of this question.
You need the function prototype before it is called.
If the function does not take parameters declare it as char* randip(void)
Use the correct main signature. In this case int main(void)
int randint(unsigned int min, unsigned int max);
char* randip(void);
int main(void)
{
/* ...*/
}
char* randip(void)
{
/* ...*/
}
// generate rand int
int randint(unsigned int min, unsigned int max)
{
/* ...*/
}

How do I take a mixture of string literals and floats and concatenate them into one string in C?

I'm a little rusty with C, and I want to concatenate several strings and floats together. In particular, I want to make the string "AbC" where A and C are string literals and b is a float. I understand I must turn the float into a string, but my code is not compiling. Below is my code, followed by the output of gcc. Any suggestions on how to fix my code?
My Program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
double b = 0.5;
char mystring[16];
strcpy(mystring,"A");
strcat(mystring,ftoa(b));
strcat(mystring,"C");
printf("%s",mystring);
return 0;
}
GCC Output:
test2.c: In function ‘main’:
test2.c:11:1: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [enabled by default]
strcat(mystring,ftoa(b));
^
In file included from test2.c:3:0:
/usr/include/string.h:137:14: note: expected ‘const char * __restrict__’ but argument is of type ‘int’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^
/tmp/cc77EVEN.o: In function `main':
test2.c:(.text+0x42): undefined reference to `ftoa'
collect2: error: ld returned 1 exit status
What you are looking for is snprintf:
snprintf(mystring, sizeof mystring, "A%.1fC", b);
You could replace all of your lines with just:
sprintf(mystring, "A%gC", b);
And to be safe (prevent overwritting past the end of your array):
snprintf(mystring, sizeof(mystring), "A%gC", b);
There is no ftoa function in the C standard library.
The easiest way to do what you were trying to do, given only the functionality of standard C, is with snprintf:
#include <stdio.h>
int main(void)
{
double b = 0.5;
char mystring[16];
snprintf(mystring, 16, "A%gC", b);
puts(mystring);
return 0;
}
If your C library has the nonstandard function asprintf, that frees you from having to figure out how big to make the buffer:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
double b = 0.5;
char *mystring = 0;
if (asprintf(&mystring, "A%gC", b) == -1)
{
perror("asprintf");
return 1;
}
puts(mystring);
free(mystring);
return 0;
}

In which situation does function prototype have to include parameter names?

I am studying the C programming language by K&R and there is a exercise as below:
Exercise 3-5: Write the function itob(n, s, b) that converts the integer n into a base b character representation in the string s. In particular, itob(n, s, 16) formats n as a hexadecimal integer in s.
So I wrote program like this:
#include <stdio.h>
#include <string.h>
#define MAXLINE 1000
void reverse(char );
void itob(int , char , int );
main()
{
char line[MAXLINE];
int n, i;
printf("integer: ");
scanf_s("%d",&n);
printf("base: ");
scanf_s("%d",&i);
itob(n, line, i);
printf("%s", line);
}
void itob(int n, char s[], int b)
{
int i, sign;
if ((sign = n) < 0)
n = -n;
i = 0;
do
{
n % b < 10 ? (s[i++] = n % b + '0') : (s[i++] = n % b + '7');
}
while ((n /= b) > 0);
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
void reverse(char s[])
{
int c, i, j;
for (i = 0, j = strlen(s)-1; i < j; i++, j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
I thought everything was OK. But when I ran the program, I got error after I input integer and base values, like below:
Unhandled exception at 0x10022050 (msvcr110d.dll) in Exercise 3-5.exe:
0xC0000005: Access violation reading location 0x000000EC.
So the program had trouble with function itob call.
And then after about 2 hour struggle for debugging, I found the cause was the function prototype of reverse need to include parameter name like this:
void reverse(char s[]);
void itob(int , char , int );
The only change I made was I added s[] in the function prototype of reverse and then program worked properly.
I am confused because all I learned is that parameter names of function prototype are optional. Why does the parameter name have to include in function prototype of reverse? And why does function prototype of itob not need parameter name and there is not pop-up error? My IDE is Visual Studio 2012.
Thanks for everyone's time and help.
The code in your question has a number of bugs, many of which your compiler should have at least warned you about.
When I copied the code and compiled it using gcc, even without any additional arguments, the first error message was:
c.c: In function ‘main’:
c.c:16:5: warning: passing argument 2 of ‘itob’ makes integer from pointer without a cast [enabled by default]
itob(n, line, i);
^
c.c:6:6: note: expected ‘char’ but argument is of type ‘char *’
void itob(int , char , int );
^
The error message is correct. You declared itob with a second parameter of type char, then called it with a second parameter of type char* (resulting from the implicit conversion of the array line).
Later, you define itob with a second parameter of type char[] (which, since it's a parameter, is really of type char*). This is incompatible with the earlier declaration, and it should also have been flagged by your compiler.
To answer the question in your title, in a standalone prototype (one that's not part of the function definition), parameter names are optional. These two prototypes are equivalent and valid:
void itob(int, char, int);
and
void itob(int x, char y, int z);
Personally I like to specify parameter names just because it makes the code clearer.
For a prototype that's part of a function definition, the names are required, because that's how the parameter objects are defined.
But first, fix the errors in your code.

SHA1 error implementation in C

I have been working on getting the sha1() function working from openssl/sha.h however I am getting random output and some warning. I have read quite a bit and tried some of the example codes but I get warning on all of it and it doesn't display correctly.
Here is code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <openssl/sha.h>
int main()
{
const unsigned char data[] = "Hello, World";
unsigned long length = sizeof(data);
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1(data, length, hash);
printf("%02x \n", hash);
return 0;
}
Below is the warning I am getting:
sha.c: In function ‘main’:
sha.c:12: warning: ‘SHA1’ is deprecated (declared at /usr/include/openssl/sha.h:124)
sha.c:13: warning: format ‘%02x’ expects type ‘unsigned int’, but argument 2 has type ‘unsigned char *’
sha.c:13: warning: format ‘%02x’ expects type ‘unsigned int’, but argument 2 has type ‘unsigned char *’
When I run it and I get the output:
62652b34
Any help would be great!
It also took me a while before I figured it all out. The best way is to use EVP, it provides generic functions for almost everything.
#include <openssl/evp.h>
You need to call this im main before calling you hash function. To initialize your hashes. Otherwise openssl will complain that the algorithm is not available.
OpenSSL_add_all_algorithms();
mode must be "SHA256", "SHA512", "SHA1" as string.
dataToHash is the input, dataSize is the size of the input,
outHashed should already be allocated, the hash will be written there
unsigned int hash(const char *mode, const char* dataToHash, size_t dataSize, unsigned char* outHashed) {
unsigned int md_len = -1;
const EVP_MD *md = EVP_get_digestbyname(mode);
if(NULL != md) {
EVP_MD_CTX mdctx;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
EVP_DigestUpdate(&mdctx, dataToHash, dataSize);
EVP_DigestFinal_ex(&mdctx, outHashed, &md_len);
EVP_MD_CTX_cleanup(&mdctx);
}
return md_len;
}
A use example (this is not tested, I use the above code in a c++ wrapper)
const char *inData = "test data2";
unsigned char outHash[20]; // output is already allocated
hash("SHA1", inData, 10, outHash);
You shouldn't use the SHA1 method directly it is deprecated (your code could blow up with the next version).
If you want to use your version you need to print each char as hex:
int i;
for(i=0; i<SHA_DIGEST_LENGTH; i++) {
printf("%02x", hash[i]);
}
You can't dump the entire buffer that way. you need to loop it, such as below. The value you're getting for your output is actually the address of the hash buffer, which is clearly not what you're looking for. You want the hex-bytes in the buffer dumped as text
So...
int main()
{
const unsigned char data[] = "Hello, World";
unsigned long length = sizeof(data);
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1(data, length, hash);
int i=0;
for (;i< sizeof(hash)/sizeof(hash[0]);++i)
printf("%02x \n", hash[i]);
return 0;
}
Regarding your warnings, the deprecation is because this interface is out-dated for performing the crypto-op you're attempting (SHA1). There are newer interfaces in OpenSSL that are current. Consider the EVP interface specifically.
printf("%02u \n", hash);
Remove warnings by printing unsigned char

Resources