我看到下面的代码使用memcpy,我可以使用它来利用这个程序并导致缓冲区溢出,但我似乎无法使它崩溃。不管我给它传递什么字符参数,我都会得到“打开数据包文件时出错”。有什么办法吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>

#define MAX_ADDR_LEN 128

#define ADDR_LENGTH_OFFSET 4
#define ADDR_OFFSET 8

typedef unsigned char shsize_t;

typedef struct{
  char addr[MAX_ADDR_LEN];
  shsize_t len;
} arp_addr;

void
print_address(char *packet)
{
  arp_addr hwaddr;
  int i;

  hwaddr.len = (shsize_t) *(packet + ADDR_LENGTH_OFFSET);
  memcpy(hwaddr.addr, packet + ADDR_OFFSET, hwaddr.len);

  printf("Sender hardware address: ");
  for (i = 0; i < hwaddr.len - 1; i ++)
    printf("%02hhx::", hwaddr.addr[i]);
  printf("%02hhx\n", hwaddr.addr[hwaddr.len - 1]);

  return;
}

int main(int argc, char *argv[])
{
  struct stat sbuf;
  char *packet;
  int fd;

  if (argc != 2){
    printf("Usage: %s <packet file>\n", argv[0]);
    return EXIT_FAILURE;
  }

  if ((stat(argv[1], &sbuf)) < 0){
    printf("Error opening packet file\n");
    return EXIT_FAILURE;
  }

  if ((fd = open(argv[1], O_RDONLY)) < 0){
    printf("Error opening packet file\n");
    return EXIT_FAILURE;
  }

  if ((packet = (char *)malloc(sbuf.st_size * sizeof(char))) == NULL){
    printf("Error allocating memory\n");
    return EXIT_FAILURE;
  }

  if (read(fd, packet, sbuf.st_size) < 0){
    printf("Error reading packet from file\n");
    return EXIT_FAILURE;
  }
  close(fd);
  print_address(packet);
  free(packet);
  return EXIT_SUCCESS;
}

最佳答案

当你在缓冲区的末尾写东西时,不能保证程序会崩溃。这被称为未定义的行为,字面意思是你不能对将要发生的事情做出合理的假设。
程序本身表现得比较好。只要len计算正确,我就看不出有任何方法可以通过输入导致溢出。程序使用memcpy并不意味着它容易受到攻击。我看到的唯一攻击向量是,如果您将精心编制的文件传递给它,从而导致长度计算错误:

hwaddr.len = (shsize_t) *(packet + ADDR_LENGTH_OFFSET)

在这一行中,程序从ADDR_LENGTH_OFFSET的地址读取packet字节以获得数据长度。显然,如果您为头文件中的数据长度(即数据长度>MAX_ADDR_LEN)创建了一个值错误的文件,那么这是有问题的。
顺便说一下,参数是一个文件,而不是一个字符。您将无法通过无意义输入进行任何操作,因为read将失败。

关于c - 如何在此程序上引起段错误? (以帮助我找到缓冲区溢出漏洞利用),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9658147/

10-11 21:58
查看更多