Как проверить длину полученного байтового массива, который не заканчивается нулем? - PullRequest
1 голос
/ 31 августа 2010

У меня есть код C \ C ++, который получает структуру по сети, из этой формы:

struct DataStruct
{
int DataLen;
BYTE* Data;
}

Код, который у меня работает, Data выполняется в цикле DataLen раз и обрабатываетданные.

... Проблема:

После того, как код пришел к экспертам по безопасности для тестов на проникновение, они подготовили поддельное приложение, которое отправляет эту структуру с DataLen больше реальной длины Data.Это вызывает, конечно, исключение нарушения прав доступа.

Итак, вопрос в том, как я могу проверить реальную длину полученного Data?Возможно ли это без изменения структуры?

Заранее спасибо.

Ответы [ 4 ]

4 голосов
/ 31 августа 2010

Хорошие эксперты по безопасности! Я бы хотел, чтобы в моей компании был такой отдел.

Всякий раз, когда данные поступают из сети, сетевой IO сообщает о количестве байтов, фактически записанных в буфер, независимо от того, использовали ли вы read(2), recv(2) или boost::asio::async_read или что-либо еще, что я видел. Типичным случаем использования, когда в заголовке вашей структуры данных есть поле «число байт для следования», является многократный вызов read / recv / etc до тех пор, пока не будет получено столько байтов (или пока не произошла ошибка), и только тогда он должен создать и верните свой DataStruct (или сообщите об ошибке).

2 голосов
/ 31 августа 2010

Вы знаете, сколько байтов вы получили, поэтому просто сравните его с DataLen.

1 голос
/ 31 августа 2010

Это невозможно без изменения структуры.Данные, полученные из сокета TCP / IP, представляют собой простой поток.По логике это не делится на пакеты.Физический пакет может содержать один или несколько экземпляров DataStruct, один экземпляр DataStruct может быть разделен на два или более физических пакетов.Текущая структура информации может использоваться только в том случае, если отсутствуют ошибки связи или недопустимые пакеты.

0 голосов
/ 03 сентября 2010

Коррупция - это легко, если у вас нет внутренних ограничений.

Некоторые механизмы защиты:

  • Попробуйте realloc() буфер, в пределах некоторого приемлемого размера (если Data является динамическим)
  • Исключения являются друзьями: используйте SIGSEGV в signal(2), signal(7) и setjmp(2) для создания полезной try / catch структуры кода.См. Объединение setjmp () / longjmp () и обработки сигналов для быстрого ознакомления с этой темой.Используйте sigaction(2), чтобы углубиться (получив неверный адрес;).
...