использовать границу переполнения memcpy? (разбивая стек) - PullRequest
0 голосов
/ 08 марта 2011

Я пытаюсь выяснить, может ли это быть как-то переполнено:

void print_address(char *p)
{
  arp_ hw;
  int i;

  hw.length = (size) *(p + _OFFSET1); //189 + 4 = 193
  memcpy(hw.addr, packet + _OFFSET2, hw.length);


  return;
}

, где пакет - это входной файл, считанный из файла .txt?

Ответы [ 6 ]

2 голосов
/ 08 марта 2011

Да, это может быть переполнено; если значение смещения 4 в пакете больше 128, вы переполните поле addr в hwaddr.

0 голосов
/ 08 марта 2011

hwaddr.len - это неподписанный символ, имеющий диапазон от 0 до 255. Таким образом, злоумышленник может отправить вам пакет, который объявляет длину 255. Поскольку hwaddr.addr объявлен как 128-байтовый буфер, злоумышленник может затем доставить полезную нагрузку.из 127 байтов.Достаточно ли этого?

Обычное соглашение о вызовах x86 заключается в отправке адреса возврата, рассылке аргументов и последующем переходе, после чего вызываемый объект будет выделять каждую переменную в объявленном порядке.Таким образом, начиная с начала hwaddr, hwaddr.len будет на 128 байт выше указателя стека, packet будет на 129 байт выше, а адрес возврата будет 129 + sizeof(char *), что составляет не более 137 байт даже на64-битная система.Итак, да, злоумышленник может перезаписать ваш обратный адрес и дополнительно доставить 118 байт шелл-кода.

Редактировать Я только что выяснил путаницу ОП.Когда вы кодируете длину как unsigned char, это означает, что не означает, что вы используете ASCII для представления длины.То есть вы не читаете этот байт, вызываете на нем atoi() и получаете однозначное число в диапазоне от 0 до 9. Вы просто используете восемь битов, как очень узкий тип int, где каждый бит представляетдвоичный символ.

0 голосов
/ 08 марта 2011

Посмотрим ... Вы принимаете пакет как массив символов, в котором четвертый символ является размером пакета. Символы являются 8-битными, поэтому при использовании в качестве числа без знака оно охватывает значения 0-255. Длина вашего буфера установлена ​​на 128. Это переполнится, вам нужно выполнить какую-то проверку _LENGTH.

0 голосов
/ 08 марта 2011

Главное, что бросается в глаза, это:

#define _LENGTH 128
...
typedef struct{
    char addr[_LENGTH];
...

Затем:

hwaddr.len = (shsize_t) *(packet + _OFFSET1); //189 + 4 = 193
memcpy(hwaddr.addr, packet + _OFFSET2, hwaddr.len);

Это кажется опасным.Вы только выделили 128 байтов для addr и не проверили, чтобы убедиться, что длина копируемой информации <= _LENGTH. </p>

Возможно, вы захотите динамически распределить это, когда вы знаете длину данныхвходить (если возможно) или проверить, чтобы убедиться, что вы не копируете дополнительные данные в массив char addr:

if (hwaddr.len <= _LENGTH) {
    memcpy(...);
}
0 голосов
/ 08 марта 2011

Абсолютно.Вы никогда даже не убедитесь, что входной буфер достаточно велик.

0 голосов
/ 08 марта 2011

Да.

Например, если строка начинается с "nnnn\xff", это разобьет стек.

...