我有一个通过网络接收结构的 C\C++ 代码,来自这种形式:
struct DataStruct
{
int DataLen;
BYTE* Data;
}
我的代码Data
循环运行DataLen
并处理数据。
...问题:
在代码交给安全专家进行渗透测试后,他们准备了一个假应用程序,该应用程序发送这个结构DataLen
的长度大于Data
. 这当然会导致访问冲突异常。
所以,问题是 - 我怎样才能验证收到的真实长度Data
?不改变结构可以吗?
提前致谢。
我有一个通过网络接收结构的 C\C++ 代码,来自这种形式:
struct DataStruct
{
int DataLen;
BYTE* Data;
}
我的代码Data
循环运行DataLen
并处理数据。
...问题:
在代码交给安全专家进行渗透测试后,他们准备了一个假应用程序,该应用程序发送这个结构DataLen
的长度大于Data
. 这当然会导致访问冲突异常。
所以,问题是 - 我怎样才能验证收到的真实长度Data
?不改变结构可以吗?
提前致谢。
不错的安全专家!我希望我的公司有这样的部门。
每当从网络接收到数据时,网络 IO 都会报告实际写入缓冲区的字节数,无论您使用read(2)
的是 、recv(2)
还是boost::asio::async_read
我见过的其他任何东西。当数据结构的标头中有“要遵循的字节数”字段时,典型用例是重复调用 read/recv/etc 直到收到那么多字节(或直到发生错误),然后才应该构造并返回您的 DataStruct(或报告错误)。
你知道你收到了多少字节,所以只需将它与DataLen
.
不改变结构是不可能的。从 TCP/IP 套接字接收的数据是纯流。从逻辑上讲,它没有被分成数据包。物理包可能包含一个或多个 DataStruct 实例,一个 DataStruct 实例可以分为两个或多个物理包。只有在没有通信错误或无效数据包的情况下,才能使用当前信息结构。
如果您没有任何内在限制,腐败很容易。
一些保护机制将是:
realloc()
缓冲区,在一些可接受的大小内(如果Data
是动态的)SIGSEGV
insignal(2)
和signal(7)
做setjmp(2)
一些有用的try/catch代码结构。有关此主题的快速介绍,请参阅组合 setjmp()/longjmp() 和信号处理。使用sigaction(2)
更深入(通过获取错误地址;)。