Search code examples
csecuritybuffer-overflowexploit

Exploit on a C program with fgets()


This is a question from my exam, which happened earlier in the day:

Consider the code snippet below. The goal of the attacker is to execute code of the attacker’s choosing, for example, to spawn a shell, or to erase the contents of the file system.


/* barfoo is called with a non-zero value if the user is 
authenticated. Else it is called with 0.*/

void barfoo (int authstatus) {
      char packet[1024];
      fgets (packet, 1023, stdin);
      if(authstatus != 0) system (packet);
      else syslog ("Not authorised to process packet");
      return; 
}

Q1: Suppose that I were to compile this program with stack canaries enabled. Assume that libc is not compiled with stack canaries enabled. Would the attacker be able to exploit this program?

Q2: Suppose that I were to compile this program with stack canaries (return-address protection) enabled. Assume that libc is compiled with stack canaries enabled. Would the attacker be able to exploit this program?

Q3: Suppose that I were to run this program on a system that has non-executable pages (i.e., W-xor-X protection) enabled. Would the attacker be able to exploit this program?

The answer to all three of them are apparently yes, but I don't see how.

In Q1 and Q2, in order to do a buffer overflow, we'd have to overwrite the canary, which would raise an exception when the code executes.

We could try to use ROP (return oriented programming) attacks, but to execute that we'd need to point to the start of the buffer and hence, we would need to overwrite the return address on the stack. Neither do I see how we could do format string exploit or something similar.

Also , in this case that since we are using fgets() instead of gets() to read the input, it will stop reading after 1022 characters here, then how else could we possibly exploit the program?

I read in the original ROP paper that we could use a frame pointer overwrite, but I am not sure what that means or how exactly would that work here.

Any directions would be helpful, thank you.


Solution

  • Like other commenters I'm pretty sure the fgets call itself is not exploitable. But look at the arguments for syslog https://linux.die.net/man/3/syslog:

    void syslog(int priority, const char *format, ...);
    //versus
    syslog ("Not authorised to process packet");
    

    If it starts looking for its format string somewhere on the stack I wonder if it could be persuaded to try the contents of packet.