0

I am learning C and decided to play around with the code, but not being able to find out where is the vulnerabity in this code.

I have pasted my code here:

#include <stdio.h>
 
char getPasswd() {
  int trigger = 'K';
  char data[100];
  gets(data);
  return (char) trigger;
}
void login() {
  printf("inside!\n");
  exit(0);
}
void main() {
  printf("enter ");
  if (getdata() == 'G') {
    login();
  } else {
    printf("wrong.\n");
    exit(1);
  }
}

If any more info is required please let me know. What I think is vulnerbility is in gets() line 6 since its not safe to use that. I am new so not sure any help is appreciated.

  • on the left of your keyboard, above the caps lock, there is this key with the name "tab" please for the love of god....use it to indent your code – Luke_ Sep 23 '20 at 10:16
  • @Luke_ I edited it, sorry about that –  Sep 23 '20 at 10:20
  • Don't need to "think" `gets` is a vulnerability. It absolutely is. So much so it was deprecated, and ultimately removed from the C standard library. If you use it, it's not only not safe it's also no longer standard compliant with recent standard libraries. Don't have to even read your code (which I wouldn't, since off-site links to code for questions is off-topic; if you have code, post it in your question). – WhozCraig Sep 23 '20 at 10:24
  • @WhozCraig I have pasted my code on SO now could you please have a look and let me know if I am right or there is more vulnerbility in my code as in buffer overflow? Thanks –  Sep 23 '20 at 10:27
  • What happens if you pass a string with 101 characters to `gets`? You can read [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/q/1694036/6865932) if you don't know the answer. – anastaciu Sep 23 '20 at 10:31
  • Discounting being non-standard from inception (using `gets` and `main` returning `void` rather than the mandated `int` type) the only vulnerability here is that `gets` call (which is, indeed, a potential buffer overflow waiting to happen). Fyi, `exit` is defined in `stdlib.h` not `stdio.h`, so you're also have a missing include header. – WhozCraig Sep 23 '20 at 10:34
  • @WhozCraig I see. I understand it now. Also, how can I make it print logged in as I believe the password is wrong –  Sep 23 '20 at 10:39
  • Questions should be self contained and not depend on external links. Edit rolled back. – klutt Sep 23 '20 at 11:26

2 Answers2

0

The vulnerability is indeed in the gets function. you do:

char passwd[100];
gets(passwd);

The buffer is in this case 100 bytes long, so if someone inputs a string longer then 100 characters, your passwd buffer will overflow and possibly overwrite some important data that is stored after that password. to stop this from happening, you could use (fgets(buffer, sizeof(buffer), stdin);

So your piece of code would change into:

char passwd[100];
fgets(passwd, 100, stdin);
Luke_
  • 745
  • 10
  • 23
  • I see. I understand it. How can I print the 'logged in' statement as well? WIll it print after changing the code to what you did as I wanna do by not want to modify return address –  Sep 23 '20 at 10:35
  • passwd will be an array of chars, also known as a string, so what you could do is something like printf("%s", passwd); @Sky – Luke_ Sep 23 '20 at 12:31
  • Sorry, I meant how can I figure out the password by changing the return address? –  Sep 25 '20 at 10:01
0

gets() has no bounds checking. So technically you can enter a password larger than 100 bytes and corrupt the stack.

For example on my machine, I could enter a password of

TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT

(108 characters), overwriting the (possibly) adjacent variable trigger from 'F' to 'T', thereby making your code print the "logged in" message.

But this heavily depends on which platform you are running and your compiler, etc..

th33lf
  • 2,177
  • 11
  • 15
  • Did you mean If I write T more than 100 times it will print logged in? –  Sep 23 '20 at 10:43
  • Depends on your machine, but usually if you are on an x64 and compile with gcc, it should be exactly 108 'T's (more specifically the 108th character should be T, others can be anything) to cause it to happen. – th33lf Sep 23 '20 at 10:45
  • Is it not possible to do the same on x32 bits machine? –  Sep 23 '20 at 10:46
  • I try doing that but even with 108 charcter T it does not print that –  Sep 23 '20 at 10:49
  • Like I said, the exact string depends on how the stack is laid out on your specific machine. But in general the idea is to use a larger number than the buffer size until you finally hit it. Try with values from 100 to say 116, increasing by one each time. – th33lf Sep 23 '20 at 10:50
  • So I shall add T at 101, 102 and so on until it works? –  Sep 23 '20 at 10:51
  • Is it not possible to change the return adress in my code and make it work? –  Sep 23 '20 at 10:52
  • When it goes more than 104 charcters it says `*** stack smashing detected ***: ./a.out terminated Aborted (core dumped) ` –  Sep 23 '20 at 10:55
  • Return address also depends on your machine. And you have to know the address of `login`, replace it at the right location on the stack, which will be even more difficult. In a machine with ASLR this will be near impossible. This is the easier hack. – th33lf Sep 23 '20 at 10:55
  • So you mean I cant print that with changing the return address? –  Sep 23 '20 at 10:56
  • Like I said before, it depends. It is impossible to know without knowing what machine, what OS with what confirguration, what compiler, what build options etc. you are using. – th33lf Sep 23 '20 at 10:58
  • If I am using linux and 32 bit and using normal shell –  Sep 23 '20 at 11:00
  • Yes but do you have ASLR enabled? Which compiler are you using? Does your compiler have stack checking of some sort implemented? Did you try with 104 Ts? That should usually have worked on a 32 bit machine. – th33lf Sep 23 '20 at 11:21
  • I tested with this online IDE, and a password of 108 'T' characters works here: https://repl.it/repls/SvelteImpishMedian – th33lf Sep 23 '20 at 11:25
  • The ASLR is off. But I don't mind to try with when it is ON as I am trying to test with on and off both. The stack checking is off and I am using just command line thats on linux. –  Sep 23 '20 at 11:31
  • Yes I tried with 104 as well it did not worked –  Sep 23 '20 at 11:31
  • Can you move this to chat please? –  Sep 23 '20 at 11:32
  • It did work and I was able to print that. I asked another question but no one is able to figure out the password for that. If you could please have a look? https://stackoverflow.com/questions/64042652/is-printf-unsafe-to-use-in-c/64042731?noredirect=1#comment113249405_64042731 –  Sep 24 '20 at 09:41
  • @Sky if this is the answer that you expected, and it works for you, please make it the accepted answer so that it is useful for others. – th33lf Sep 28 '20 at 08:16