用默认设置下的IPv6漏洞攻击Windows系统

译文
安全
如果大家看过太空堡垒卡拉狄加这部美剧,回想一下吧,它清楚地告诉我们,六这个数字可不是省油的灯。看起来很美,但在大家忙忙碌碌、按部就班地工作时,它却悄悄将身形隐藏在其目标之下。没人意识到出了什么状况,直到后果已经严重到无法挽回。

【51CTO.com 独家译稿】默认设置下的IPv6漏洞导致Windows系统计算机遭受入侵

如果大家看过太空堡垒卡拉狄加这部美剧,回想一下吧,它清楚地告诉我们,“六”这个数字可不是省油的灯。看起来很美,但在大家忙忙碌碌、按部就班地工作时,它却悄悄将身形隐藏在其目标之下。没人意识到出了什么状况,直到后果已经严重到无法挽回。

互联网上也有类似的六号现象,IPv6(新一代的IPng-IP)。眼下最新的操作系统通过它来进行数据传输,一般情况下它都可以算是默认配置了,但普及速度相对来说仍然非常缓慢。原因种种,不胜枚举,目前的情况是它尚处于休眠期,等待着机会一鸣惊人,进而一举推翻IPv4并彻底统治网络。

本文介绍的是一项关于IPv6概念层面的有趣应用。我会在接下来的内容中向大家展示,一个攻击者如何对IPv6覆盖之下的纯IPv4网络进行攻击,而借助这一点,中间人攻击(简称MITM)将能够顺利对IPv4的网络数据流展开侵袭。

这种新的无状态自动地址分配(简称SLAAC)攻击,如果大家接受这种称呼,正是根据其产生过程而得名。

IPv6背景知识介绍

除了增加IP地址数量之外,IPv6在很多关键性的处理领域与IPv4可以说采用了完全不同的机制。本文并不打算对IPv6进行过多的探讨,但我会把与网络攻击有关的主要特点向大家做出说明。

首先,IPv6没有使用ARP--而代替其功能的是一组称为相邻计算机发现协议(neighbour discovery protocols)的工具,当我们执行ICMPv6时,它允许主机发现本地连接中的其它物理地址。此外,具备无线功能的路由器也可以通过本地连接上的路由通告(Router Advertisement,简称RA)中的信息来探知其它计算机,借以实现同样的功能。

当一台应用IPv6的主机接收到路由通告时,它可以通过一系列处理为其创建一个进程,并为其分配一个有效的IPv6路由地址,这一过程即被称为"无状态地址自动配置(简称SLAAC)"。主机将根据路由通告所使用的源地址为其设置默认网关。

通过对这种自动的主机地址分配机制的分析,我们可以看到,SLAAC的执行原理更像是IPv4中的DHCP的处理方式。然而,单单SLAAC本身的话,是无法为接入的主机提供所有必要的配置参数信息(例如DNS服务器等详细内容)的,DHCPv6仍需要借助其它工具的帮助,才能正确填写所有的匹配资料。事实证明,它所需要的数据可以由路由通告中的信息提供,SLAAC和DHCPv6相结合的话可以为IPv6实现DHCP能为IPv4所做的全部配置工作,但那又是另一回事,不在本文的讨论范围中。

操作原理

这种概念层面上的证明,我只在Windows 7系统的主机上实践过,但理论上应该适用于任何安装并默认执行IPv6以管理其网络数据传输的操作系统。让我们从一幅网络目标示意图开始思考:

整个流程都是IPv4处理方式

这幅图其实相当直观,整个流程都是IPv4处理方式,边界路由器所在执行的也是常见的网址解析(简称NAT)及防火墙任务。对于这种方式,我们也可以假设,如果各种安全措施都是针对IPv4中间人攻击,例如ARP欺骗,这类危害所部署的。

现在我们要做的是引入一个物理路由器,向目标网络发送恶意接收请求。恶意接收请求具有两个网络端口--恶意信息所针对的只是IPv6端口,而网络连接则只通过IPv4端口。我们的目的正是通过发送恶意接收请求,在IPv6所覆盖的网络下创建一个寄生的端口。这个端口可以由我们完全控制,具体情况如下图所示:

恶意接收请求现在已经搭建了一道由IPv6目标端口到IPv4互联网端口的桥梁

恶意接收请求将向本地网络发送路由通告,这将导致主机为其创建IPv6路由功能所匹配的IP地址。它还配备了DHCPv6服务来为我们提供DNS服务器信息,而这一切都在我们的控制之下(恶意的DNS服务器如上图所示)。我们还无法做到的是将IPv6所管理的网络直接通过IPv6连接到互联网--恶意接收请求只能通过目标计算机上的IPv4来接入互联网。#p#

所谓Special Sauce

通过引入恶意接收请求所造成的影响目前来看还算是良性的。感谢恶意接收请求所提供的路由通告信息,所有目标主机都在其IPv4的可经路由发送的地址之外,同时提供了IPv6的地址,并且包含DNS服务器信息。但这些还远远不够,要进行实用性操作,我们还需要在攻击中加入其它内容,以使其取得更大的进展。

这种称为"Special Sauce(特别酱料)"的工具属于附带协议转换器的网络地址转换器(以帮助IPv6与IPv4节点间互相连通,简称NAT-PT)。NAT-PT方案已经在实际应用中被攻击得千疮百孔、不成人形。它是由互联网工程任务组(简称IETF)所研发,用现在的眼光来看,它已经被彻底丢进了历史的垃圾桶。但无论如何,尽管它既过时又乱七八糟,但并不代表它毫无可取之处。

NAT-PT是众多IPv4到IPv6过渡机制中的一款,用来解决从旧有处理方式到新型方案的过渡问题。它的作用是将应用IPv6的主机与应用IPv4的主机之间的数据交互进行处理,即将IPv6地址转换为IPv4形式,反之亦然。单击此处可以查看其运作原理的书面说明。这正是NAT-PT的功能,允许我们通过攻击IPv6端口来将恶意接收请求传输到用以连接互联网的IPv4端口上。

要使用NAT-PT,我们首先需要定义一个非链接的/96前缀;它可以是任何通过经由路由器发出的,你乐于采用的前缀形式。任何被NAT-PT所发现的目标地址,其所匹配的前缀名称若是可以由IPv6的地址所解析,即会根据其末尾的三十二位字节内容转化为相应的IPv4地址。

举例说明,我可能会告知自己的NAT-PT,我所选用的前缀名为2001:6f8:608:ace::/96。我们通过DHCPv6为IPv6所提供的DNS服务器地址是2001:6f8:608:ace::c0a8:5802--这个地址与指定的前缀是完全匹配的,因此如果NAT-PT根据其最后三十二位字节检索到了数据传输指向(即c0a8:5802),相应内容将会被提取并发送到真正的DNS服务器的IPv4地址192.168.88.2并进行转换。

以Special Sauce为起点进一步尝试

我们离成功只有一步之遥。有NAT-PT保驾护航,恶意接收请求现在已经搭建了一道由IPv6目标端口到IPv4互联网端口的桥梁。如果我们能够使通过IPv6的数据流同样通过恶意请求(而不是通过合法途径发送到IPv4的边界路由器),我们就能够享受自己的SLAAC攻击所带来的乐趣了。事实证明,这一步骤实行起来其实也非常容易。 

感谢恶意接收请求,我们的目标端口同时具备IPv4及IPv6地址;它们是"重叠的",即同时存在的。只要可能,具备这种重叠特性的主机会更倾向于使用本地的IPv6地址,因此可以说我们的计划已经成功了一半。而在最后的尝试中,指引我们走完剩下的路途并最终到达终点的伙伴是DNS。

具备重叠特性的目标端口既有一个IPv4的DNS服务器(由DHCP服务器合法提供)又有一个IPv6的DNS服务器(由恶意接收请求通过DHCPv6服务器提供)。当目标端口中的某一个试图查询谷歌网站时,它会向其IPv6的DNS服务器发出一个DNS查询指令,即A(IPv4)以及AAAA(IPv6)。如果IPv6的DNS服务器能够足够迅速地返回查询结果,那么目标端口将会优先采纳IPv6所提供的地址,而不是IPv4。而我们所要做的,正是利用这种机制,将来自网络的数据流转移到恶意接收请求那边。而实现这一计划的前提是,我们IPv6的DNS服务器响应速度一定要快--否则过长的响应返回时间会令目标端口转而使用IPv4的DNS服务器作为替代,这样一来让数据流通过恶意接收请求的计划也就破产了。

但我们要如何才能确保任何指定的DNS查询都能通过IPv6地址加以响应?

NAT-PT自有一套妙招,该方案通常包含一组应用层面的网关(简称ALGs),它的作用是在应用层面对IP地址的通信协议进行检查。DNS即是一个协议内容基于ALG的实例,同文件传输协议(简称FTP)一样。通过下面的内容,让我们一起来看看IPv6如何与NAT-PT协同合作,而DNS ALG又是如何玩弄它的欺骗把戏的:

#p#

需要注意的事项:

◆目标端口DNS服务器的地址必须与恶意接收请求上的NAT-PT前缀名称相匹配,也就是说最后三十二位字节的内容必须包含DNS服务器的IPv4地址。

◆NAT-PT能够将IPv6及IPv4分别作为数据源及目的地进行转换,且此转换过程可逆。

◆DNS ALG会将目标端口的IPv6 地址的AAAA查询转换为IPv4地址的A查询,此过程同样可逆。

◆DNS ALG也会将IPv4地址的响应转换为IPv6地址类型,以与NAT-PT的前缀名称相匹配。

而目前关于目标端口,www.google.com 通过IPv6段位2001:6f8:608:ace::d155:8f63已经可以连接了。这样一来IPv4就完全无法发挥作用了,而目标端口将以如下图所示的方式连接到谷歌网站:

这样一来,恶意接收请求如今已经取得目标端口与谷歌网站之间的中间人身份。

让我们总结一下迄今为止所做的工作:

◆我们没有对IPv4网络机制的目标端口进行攻击或执行控制,而这正是要对通过IPv4端口的数据流实施中间人攻击的前提。我们甚至不需要从DHCP服务器处获取IPv4地址。

◆我们没有对现有的IPv6网络进行攻击,因为在我们进行本次测试之前,目标计算机是没有IPv6地址的。

◆我们没有对任何目标主机进行攻击(至少目前来说还没有)。每台计算机都是根据其自身设定来优先选择IPv6而非IPv4的。

◆我们确实设法消除了目标主机使用IPv4机制的潜在可能性,使其在处理网络数据流时只使用IPv6机制。

攻击活动同样有充分的理由被偷偷执行,因为:

◆我们正在设定一条新的互联网访问通路。任何与IPv4网络边界协议相冲突或受监控的行为都会失效,并进而导致攻击失败。

◆这种可能性依然存在,即目标端口的安全系统(例如主机防火墙、网络主入侵预防系统(简称HIPS)、安全信息与事件管理(简称SIEM)工具箱等等)会无法处理IPv6下的数据流。IPv6对这类安全保障体系的支持远不及IPv4。

◆因为目标端口"没有用到IPv6",因此利用IPv6的特性进行攻击也就成了纸上谈兵了。

◆如果上述情况真的出现了,有一种办法可以帮我们处理,并且既不需要专业培训、也不要求太多的IPv6使用经验。

恶意接收请求的建立

恶意接收请求的执行并不复杂。必需的工具包只有三个,即radvd,dhcp6s以及naptd。要启动及运行这些工具,我们需要建立自己的网络端口。在下面的这个例子中,eth0是面向互联网的IPv4端口,而我将假设它可以从DHCP服务器处获得一个合法的地址。eth1则是使用IPv6的端口,具体配置方案如下:

root@evil-rtr:~# ifconfig eth1 inet6 add 2001:6f8:608:fab::1/64
root@evil-rtr:~# ifup eth1
root@evil-rtr:~# ifconfig eth1
eth1      Link encap:Ethernet  HWaddr 00:25:4b:fd:91:73
inet6 addr: 2001:6f8:608:fab::1/64 Scope:Global
UP BROADCAST MULTICAST  MTU:1500  Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

#p#

我们还需要确保IPv6的转发功能处于启用状态:

root@evil-rtr:~# sysctl -w net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.forwarding = 1

好的,现在我们就可以安装上面提到的那些IPv6小工具啦。

radvd

这个工具包负责向我们的目标主机发送路由通告,点击这里获取。配置文件可谓相当简单:

interface eth1 {
AdvSendAdvert on;
AdvOtherConfigFlag on;
MinRtrAdvInterval 3;
MaxRtrAdvInterval 10;
prefix 2001:06f8:0608:fab::/64 {
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr on;
};
};

最重要的部分是前缀连接以及AdvOtherConfigFlag的设置。将这一项设为"开启"状态,会向路由通告中发送O标记。这个O标记的作用是通知客户端,使其尽量与DHCPv6相连通,以完成下一步的设定。根据说明文档的提示启动radvd,然后转到…

dhcp6s

我从这里下载到了WIDE DHCPv6。我们打算通过DHCPv6所实现的操作内容其实很少,因此配置文件也就只有如下所示的短短两行:

option domain-name-servers 2001:6f8:608:ace::c0a8:5802;
option domain-name "pwned.by.v6";

设置完成,运行工具,然后转到…

naptd

点击这里获取该工具。根据其自带的详尽说明文本,我们只需要如下图所示来配置iptables以及ip6tables:

root@evil-rtr:~# ip6tables -A OUTPUT -p icmpv6 --icmpv6-type 1 -j DROP
root@evil-rtr:~# ip6tables -A FORWARD -d 2001:6f8:608:ace:: -j DROP
root@evil-rtr:~# iptables -A INPUT -i lo -j ACCEPT
root@evil-rtr:~# iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
root@evil-rtr:~# iptables -A INPUT -m state --state NEW -p tcp -m tcp --dport 22 -j ACCEPT
root@evil-rtr:~# iptables -A INPUT -j DROP

接下来我们运行 napt-confmaker。我依照默认的答案认真回答了几乎所有的问题,除了端口选择以及NAT-PT前缀名称。

到这里,准备工作已经基本完成,一旦naptd开始运作,我们所精心布置的陷阱就要发挥作用了。

攻击

下图向我们展示了在被恶意接收请求寄生的IPv6端口连通互联网之前,目标主机的ip配置文件的输出结果:

Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix  . :
Description . . . . . . . . . . . : Atheros AR8131 PCI-E Gigabit Ethernet Controller (NDIS 6.20)
Physical Address. . . . . . . . . : 00-26-9E-47-4E-0F
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::119c:ea76:23d4:290d%10(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.0.2(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Lease Obtained. . . . . . . . . . : 30 March 2011 23:23:08
Lease Expires . . . . . . . . . . : 31 March 2011 13:55:33
Default Gateway . . . . . . . . . : 192.168.0.251
DHCP Server . . . . . . . . . . . : 192.168.0.251
DHCPv6 IAID . . . . . . . . . . . : 285221771
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-12-52-C9-D5-00-26-9E-47-4E-0F
DNS Servers . . . . . . . . . . . : 192.168.0.251
NetBIOS over Tcpip. . . . . . . . : Enabled

#p#

本地连接状态中所显示出的IPv6地址,表明主机目前已经在采用IPv6机制了。一旦我们连接到恶意接收请求所在的eth1端口,目标主机就会收到路由通告,并从中为自身获取一个IPv6地址,然后是向DHCPv6发送查询请求以进一步进行配置。而几乎在同一时间,ip配置文件的输出结果已经改变成如下图所示:

Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix  . : pwned.by.v6
Description . . . . . . . . . . . : Atheros AR8131 PCI-E Gigabit Ethernet Controller (NDIS 6.20)
Physical Address. . . . . . . . . : 00-26-9E-47-4E-0F
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
IPv6 Address. . . . . . . . . . . : 2001:6f8:608:fab:119c:ea76:23d4:290d(Preferred)
Temporary IPv6 Address. . . . . . : 2001:6f8:608:fab:687a:83f:caa7:8f9c(Preferred)
Link-local IPv6 Address . . . . . : fe80::119c:ea76:23d4:290d%10(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.0.2(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Lease Obtained. . . . . . . . . . : 30 March 2011 23:23:08
Lease Expires . . . . . . . . . . : 31 March 2011 13:55:33
Default Gateway . . . . . . . . . : fe80::225:4bff:fefd:9173%10
192.168.0.251
DHCP Server . . . . . . . . . . . : 192.168.0.251
DHCPv6 IAID . . . . . . . . . . . : 285221771
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-12-52-C9-D5-00-26-9E-47-4E-0F
DNS Servers . . . . . . . . . . . : 2001:6f8:608:ace::c0a8:5802
192.168.0.251
NetBIOS over Tcpip. . . . . . . . : Enabled
Connection-specific DNS Suffix Search List : pwned.by.v6

这下可怜的目标主机彻底完蛋了:

◆它具备自己的可经路由发送的IPv6地址

◆它具备IPv6的默认网关,而该网关实际上正是恶意接收连接eth1端口的本地连接地址,而并非我们之前手动为其分配的地址。

◆它具备一个与IPv6的DNS服务器地址相匹配的NAT-PT前缀名(由naptd所使用),而这正是我们的恶意DNS服务器所要进行的IPv4地址类型转换的关键。

我们已经成功使目标主机优先采用IPv6所接入的网络数据而不是IPv4。在实现这一目标的过程中,我们没有用到任何口令或采取任何黑客及暴力手段。我们所要做的只是引导,将目标一步步指向预期的方向。

运行动态

当目标主机浏览谷歌网站时,恶意接收请求的IPv6 eth1端口将接收到如下信息 (下载地址单击此处):

在这里我们可以看到通过IPv6发往恶意DNS服务器的DNS查询指令;IPv4的A型及IPv6的AAAA型查询指令都被发出了,而响应也分别返回。注意,返回的IPv6地址能够与我们的NAT-PT前缀相匹配,表明其中包含一个嵌入的IPv4地址。而目标主机一定会选择IPv6返回的信息而非IPv4;恶意接收请求在这里则扮演了中间攻击者的角色。#p#

恶意接收请求在IPv4的eth0端口上所进行的相同转换过程则如下图所示(下载地址单击此处):

请注意,所有的IP地址都是IPv4形式的,而所有的DNS查询指令都以A的形式加以记录,而非A与AAAA的组合形式,这就是eth1端口所反馈的情况。

进一步发动攻势

要发动进一步的攻势,我们有以下几种选择:

◆鉴于这一攻击需要进行硬件植入,我们采取这套方案的可能性非常非常小,但具体内容仍然值得一提。Gumstix是一款很理想的执行平台;它体积小巧,运行于Linux环境下,并且在硬件支持方面有许多备选方案。一款OveroEarth,一款Tobi加上一块USB型的3G网卡以及以太网接口,这个精致的硬件平台组合就能为我们提供与目标网络连接的全部前提条件。我之前已经用过Gumstix;一旦大家将这套运行环境建立起来,广大的网络世界可谓尽在掌握。

◆由于恶意DNS服务器是由我们控制的,因此我们可以通过设置使其返回任何指定的IP地址,正如前面对谷歌网站所做的一样。通过这种手段,我们能够制造许多钓鱼的机会。

◆就目前的状态看,恶意接收请求会以中间人攻击的形式对全部DNS查询指令的返回网络数据流进行侵袭,这还不够精确。如果我们能够让恶意DNS有选择性地只对某些网站返回地址,那么攻击的效果就会好得多了。这种想法可以通过一种协议来实现,即我们使恶意DNS服务器忽略掉那些我们不感兴趣的DNS查询指令,这样被忽略的目标端口信息会转接入其IPv4服务端,而该过程中的网络数据也是以正常路径进行传输的。

◆由于我们扮演的是中间攻击者的角色,因此我们绝对有机会侵入客户端与服务器之间的往来数据流。具体方法是,我们通过将新的https://链接更改为过时的http://链接等形式来向网页应用框架(即iframes)注入恶意信息。

◆当然,上述只是一些我想到的办法。无限的拓展性现在就把握在大家手中,想怎么做就看你的啦。

如何抵御恶意接收请求

这种攻击很可能出现,因为我们能够将恶意信息注入到应用IPv6的主机的路由通告中——这类攻击与其它类似的攻击之间的主要区别在于,我们不需要试图改变现有的IPv6网络;我们所要做的只是建立一条新的合法传输路线。不过,我们的恶意路由通告是攻击得以成功展开的关键。一旦传输路线被封堵,这类攻击将无法实现。

在大部分情况下,恶意路由通告最多只能算是一种"侵犯"行为,基本上跟开启Windows中的网络连接共享功能所造成的后果差不多。然而,对于IETF组织来说,这种情形已经相当严重了,因此他们发布了RFC6104警示文件——"IPv6路由通告盗用问题状况说明"。这份文件更专注于讨论由路由通告被"盗用及篡改"所导致的破坏,而不是由此带来的安全问题,但第三节中还是给出了一份有用的应对技术方案清单。遗憾的是,其中提及的大部分应用在实际执行方面对于普通使用者来说难度过高、缺乏可操作性(参见"发送"项目中的内容)并且所要求的相关硬件过于苛刻(参见路由通告指南及ACL开关项目中的内容)。思科公司也就这类安全问题提供了一些提示说明,具体信息请单击此处此处进行查看。

如果RFC6104文件中的内容无法使我们成功阻止攻击的发生,也许将它检测定位也可以算是比较积极的备选应对方案。NDPMon正是这么一款相当于IPv6中的ArpWatch的工具,其设计目的在于帮助我们侦测来自网上邻居或是路由器端的可疑数据流。

无论如何,无论是RFC6104还是NDPMon都无法有效地帮助我们抵御SLAAC类型的攻击。为什么在部署应对IPv6所带来的各种安全问题的同时,就没有人站出来建议"不使用"IPv6机制呢?SLAAC攻击的目标只能是由IPv6管理的IPv4网络,而无法作用原生的IPv6型或双协议型网络。由此可见,最简单有效的防御手段,就是在所有的主机上禁用IPv6机制(只要没有特殊的业务方面要求):

这种解决方案完全契合了"网络防御"一文中所提到的"最小化"安全保障成本这一概念,虽然它对于尽快普及IPv6机制产生了些许不利的影响。不过管它呢,我们都了解哪种方法最适合自己。

原文链接:http://resources.infosecinstitute.com/slaac-attack/

【51CTO.com独家译稿,非经授权谢绝转载!合作媒体转载请注明原文出处及出处!】

【编辑推荐】

  1. IPv6或诱发垃圾邮件和病毒爆发
  2. BreakingPoint推出全新方案替代IPv4/IPv6双堆栈协议测试
  3. 浅析IPv6的安全威胁
  4. Hillstone山石网科喜获IPv6 Ready认证

 

 

责任编辑:佟健 来源: 51CTO.com
相关推荐

2011-04-28 19:54:26

2020-10-15 10:54:31

安全漏洞微软

2010-05-27 15:44:00

卸载IPv6协议

2013-12-23 09:53:34

ubuntu12.04设置IPv6

2010-06-11 17:20:28

2012-11-01 16:11:31

2010-06-07 16:58:51

linuxIPv6协议栈

2012-06-14 16:56:25

2012-06-14 09:16:33

2010-05-26 12:45:21

IPv6访问故障

2010-08-11 16:07:14

IPv6协议H3C

2010-05-31 10:16:31

禁用IPv6协议

2010-06-07 12:29:06

如何安装IPv6

2012-11-20 09:14:52

IPv6CNGI网络Web

2012-05-24 19:08:13

2012-12-17 11:22:25

2010-06-07 12:06:48

验证ipv6网络

2010-06-02 16:07:54

IPv6路由广播

2011-05-13 14:20:19

2015-10-27 13:58:45

点赞
收藏

51CTO技术栈公众号