动态调试
在我们运行POC之前,首先使用windbg对srv2!Srv2DecompressData函数下好断点,时候运行系统,运行POC。程序段下来之后在
srvnet!SmbCompressionDecompress函数处下个断点,运行。
通过上一篇文章的静态分析我们知道了srvnet!SmbCompressionDecompress的参数如下所示:
1.压缩算法 | ecx | 1 | 导致最后调用nt!RtlDecompressBufferLZNT1这个解压算法。 | |
2.压缩数据的开始位置 | Compress_header_address+0x10+offset | rdx | 越界 | |
3.压缩数据的长度 | Compress_packet_length-0x10-offset | r8 | 0x401 | Compress_packet_length为0x401运算时把offset当作-1 |
4.解压后的数据存放的位置 | 分配内存后偏移0x18处存放的值+offset | r9 | 越界 | |
5.压缩数据的原始大小 | originalsize | r14 | 0x400 |
从下图中我们可以看到,在压缩函数开始的位置参数二、参数四已经越界,解压后的数据的存放位置也越界了。
接着进一步分析srvnet!SmbCompressionDecompress函数,返现最终通过调用RtlDecompressBuffer对数据进行解压。进入
RtlDecompressBuffer函数后发现根据压缩算法进入不同的解压函数。
最终进入nt!RtlDecompressBufferLZNT1函数中
根据前面的分析我们知道在下图的nt!RtlDecompressBufferLZNT1+0x57的位置会发生错误,错误如下图所示。
rsi是0x00000001406E8D75位置的r8传入,而r8则是Compress_header_address+0x10+offset,所以存在越界错误。
从上图中我们可以看到在nt!RtlDecompressBufferLZNT1对数据进行压缩的时候,读取第一个值时发生了越界读。