使用 fgets() 利用 C 程序

Exploit on a C program with fgets()

这是我今天早些时候的考试题目:

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?

他们三个的答案显然都是肯定的,但我不知道如何。

在第一季度和第二季度,为了缓冲区溢出,我们必须覆盖金丝雀,这会在代码执行时引发异常。

我们可以尝试使用 ROP(return 面向编程)攻击,但要执行它,我们需要指向缓冲区的开头,因此,我们需要覆盖 return 栈上的地址。我也看不出我们如何进行格式化字符串利用或类似的东西。

此外,在这种情况下,由于我们使用 fgets() 而不是 gets() 来读取输入,它将在此处读取 1022 个字符后停止读取,那么我们还能如何利用该程序?

我在原始 ROP 论文中读到我们可以使用帧指针覆盖,但我不确定这意味着什么,也不知道它在这里究竟如何工作。

任何指示都会有所帮助,谢谢。

像其他评论者一样,我很确定 fgets 调用本身是不可利用的。但是看看 syslog https://linux.die.net/man/3/syslog:

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

如果它开始在堆栈的某处寻找它的格式字符串,我想知道是否可以说服它尝试 packet.

的内容

stdin 是一个 FILE 结构,可以被覆盖,通过 vtable 指针触发函数调用(如果它被操纵)

https://seb-sec.github.io/2020/04/29/file_exploitation.html https://github.com/CptGibbon/House-of-Corrosion

这假定其他基元可用并且已经被使用。