标签:sse 接下来 inter nta ios ase 处理 如何 cas
OriginalCompressedSegmentSize
+ Offset/Length
之和进行检查,导致整型溢出,SrvNetAllocateBuffer
对于size小于0x1100的情况默认申请了0x1200,虽然没有导致缓冲区溢出,但由于内存布局的特殊性,我们可以覆盖位于其中的指向保存解压后数据的指针OriginalCompressedSegmentSize
为0xffffffff
,Offset/Length
为8时(其实offset长度就是我们最后任意写的长度,具体原因后面分析),此时就会发生整型溢出srvnet!SrvNetAllocateBuffer
中的分配逻辑,经过分析可以看到当申请的内存大小小于0x1100
时,默认分配了0x1278
字节SrvNetAllocateBuffer
返回的内存地址并不是上面srvnet!SrvNetAllocateBuffer
中调用ExAllocatePoolWithTag
返回的地址(这里称为bufferA
),而是位于bufferA + 0x1150
偏移的地方(这里称为bufferB
),且bufferB + 0x18
的位置存放的是bufferA + 0x50
srvnet!SmbCompressionDecompress
,其中存放解压数据的缓冲区为*(bufferB + 0x18) + SMB2 COMPRESSION_TRANSFORM_HEADER.offset
,分析后面的memmove
可以知道这是为SMB2 COMPRESSION_TRANSFORM_HEADER
和compressed data
之间的数据保留空间Offset/Length (4 bytes): If SMB2_COMPRESSION_FLAG_CHAINED is set in Flags field, this field MUST be interpreted as Length. The length, in bytes, of the compressed payload. Otherwise, this field MUST be interpreted as Offset. The offset, in bytes, from the end of this structure to the start of compressed data segment.
经过上面的分析,其实如何实现任意地址任意写已经很明显了,我们可以通过覆盖位于bufferB + 0x18
处的指针为我们想要写的地址,在 SMB2 COMPRESSION_TRANSFORM_HEADER
和compressed data
之间填充我们想要写的数据,通过上面的memmove
实现任意地址任意写
因此可以通过compressed data segment
覆盖bufferB + 0x18
的位置,因为memmove
的目的地址就是bufferB + 0x18
,而memmove
的源地址和长度分别是someData
和Offset/Length
,所以我们就可以通过构造这几个位置的数据来达到任意地址任意写。
布置任意地址写的位置是通过Offset/Length来计算的,因为srvnet!SmbCompressionDecompress
会为someData
预留Offset/Length
大小的位置,所以计算方法为AR_Write_addr_offset = 0x1150 - 0x50 + 0x18 - Offset
,代码实现为:
NetBIOS
头的StreamProtocolLength
也要修正Token
地址https://paper.seebug.org/1164/
https://ricercasecurity.blogspot.com/2020/04/ill-ask-your-body-smbghost-pre-auth-rce.html
标签:sse 接下来 inter nta ios ase 处理 如何 cas
原文地址:https://www.cnblogs.com/DreamoneOnly/p/12781899.html