如何验证接收到的字节数组的长度,该数组不是以 null 结尾的?
我有一个 C\C++ 代码,它通过网络接收以下形式的结构:
struct DataStruct
{
int DataLen;
BYTE* Data;
}
我在 DataLen
次循环中运行 Data
的代码并处理数据。
...问题:
在代码交给安全专家进行渗透测试后,他们准备了一个伪造的应用程序,该应用程序发送的DataLen
结构比的实际长度大>数据
。当然,这会导致访问冲突异常。
所以,问题是 - 如何验证接收到的数据的真实长度?不改变结构可以吗?
提前致谢。
I have a C\C++ code that receives a structure over the network, from this form:
struct DataStruct
{
int DataLen;
BYTE* Data;
}
The code I have runs over Data
in a loop of DataLen
times and processes the data.
...The problem:
After the code came to security experts for penetration tests, they prepared a fake application which sends this struct with DataLen
bigger than the real length of Data
. This causes, of course, an access violation exception.
So, the question is - how can I validate the real length of the received Data
? Is it possible without changing the structure?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不改变结构是不可能的。从 TCP/IP 套接字接收的数据是纯流。从逻辑上讲,它不被分成数据包。物理数据包可能包含一个或多个DataStruct实例,一个DataStruct实例可以分为两个或多个物理数据包。只有在不存在通信错误或无效数据包的情况下,才能使用当前的信息结构。
It is impossible without changing the structure. Data received from TCP/IP socket is plain stream. Logically, it is not divided into packets. Physical packet may contain one or more DataStruct instances, one DataStruct instance can be divided to two or more physical packets. Current information structure can be used only if there are no communication errors or invalid packets.
如果没有任何内在限制,腐败就很容易。
一些保护机制是:
realloc()
缓冲区(如果Data
是动态的)signal(2)
、signal(7)
和setjmp(2)
中的SIGSEGV
执行一些有用的操作try/catch 代码结构。请参阅 组合 setjmp()/longjmp( )和信号处理,了解有关此主题的快速介绍。使用 sigaction(2) 更深入(通过获取错误地址)。Corruption is easy if you haven't any intrinsic limitation.
Some protection mechanisms would be:
realloc()
the buffer, within some acceptable size (ifData
is dynamic)SIGSEGV
insignal(2)
,signal(7)
andsetjmp(2)
to do some useful try/catch code structure. See Combining setjmp()/longjmp() and Signal Handling for a quick introduction on this topic. Usesigaction(2)
to go deeper (by getting the faulty address;).好心的安全专家!我希望我的公司有一个这样的部门。
每当从网络接收数据时,网络 IO 都会报告实际写入缓冲区的字节数,无论您使用的是 read(2)、recv(2) 还是
boost::asio::async_read
或我见过的任何其他内容。当数据结构的标头中有“要跟随的字节数”字段时,典型的用例是重复调用 read/recv/etc 直到收到那么多字节(或直到发生错误),然后才应该构造并返回您的 DataStruct (或报告错误)。Nice security experts! I wish my company had a department like that.
Whenever data is received from the network, the network IO reports the number of bytes actually written to the buffer, whether you used
read(2)
,recv(2)
, orboost::asio::async_read
or anything else I've seen. Typical use case when there's a "number of bytes to follow" field in the header of your data structure, is to repeatedly call read/recv/etc until that many bytes were received (or until error occurred), and only then it should construct and return your DataStruct (or report error).您知道收到了多少字节,因此只需将其与
DataLen
进行比较即可。You know how much bytes you have received, so just compare it with
DataLen
.