详解为何特殊字符串可导致iOS 11.2.5瞬间崩溃 - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

详解为何特殊字符串可导致iOS 11.2.5瞬间崩溃

luochicun 新闻 2018-02-28 11:20:37
186961
收藏

导语:iOS系统两周前发现的印度语漏洞加速了iOS的发布进程,苹果很快发布了iOS 11.2.6,这个漏洞同样存在于苹果的其他操作系统上,包括macOS 10.13.4、watchOS 4.3和tvOS 11.3。

u=2087296409,1630789425&fm=11&gp=0.jpg

前言

iOS系统两周前发现的印度语漏洞加速了iOS的发布进程,苹果很快于上周发布了iOS 11.2.6,而这已经是对iOS 11操作系统的第11次正式更新了,这也是让业界吐槽iOS 11是史上问题最多和更新最频繁的系统的原因。然而事实上,这个漏洞同样存在于苹果的其他操作系统上,包括macOS 10.13.4、watchOS 4.3和tvOS 11.3。

据报道,如果在iPhone、iPad上发送一个Telugu(泰鲁固语,在印度东部的德拉维拉使用)符号,则会造成信息APP(iMessage、WhatsApp、Twitter等)闪退和崩溃,用户必须重新打开甚至是重启设备。

上周苹果推出的iOS 11.2.6版本系统,已经解决了这一问题,提醒苹果用户赶紧更新。在发布iOS 11.2.6版本更新的同时,苹果还为macOS 10.13.3, watchOS 4.2.3以及tvOS 11.2.6发布了补充更新。

iOS正式版用户可以直接通过OTA进行升级,另外除了通过OTA升级之外,也可以下载相应的固件通过iTunes升级,具体方法是下载固件后在桌面端打开最新版iTunes,同时按下“Shift+更新”选取将要刷入的固件即可。

可以升级的设备包括iPhone X、iPhone8、iPhone8 Plus、iPhone7、iPhone7 Plus、iPhone5s、iPhone SE、iPhone6/Plus、iPhone6s/Plus;9.7英寸iPad、iPad Air、iPad Air 2、iPad Pro(9.7/12.9一二代、10.5英寸)、iPad mini 2、iPad mini 3、iPad mini 4,iPod方面仅有iPod Touch 6一款设备。

本次苹果主要修复的问题便是特殊字符串的漏洞,另外还有某些第三方应用无法连接到外部附件的问题。

对崩溃过程的技术还原

在对崩溃过程进行测试时,我是把这些泰鲁固语复制到Spotlight中进行测试的,所以我的浏览器不会因这些特殊字符串的运行而崩溃,Spotlight是一款非常轻量级的远程监控工具。

我在测试时用的泰鲁固语的字符串序列是U+0C1C U+0C4D U+0C1E U+200C U+0C3E,它是一串泰鲁固语字符序列,这个序列的顺序是辅音 ja (జ),virama ( ్ ),辅音nya (ఞ),ZWNJ(zero-width non-joiner)和元音aa( ా)。许多婆罗米系文本都有类似符号,一般称为virama.泰米尔文几乎都用可以看到的puḷḷi来识别一个不带元音的辅音。

当看到这个字符串序列时,我首先认为<ja,virama,nya>序列是造成系统崩溃的原因。因为该序列在许多印度文的脚本中代表一个特殊的字符,通常该字符会被认为是一个梵文字母——ज्ञ。

还有第二种可能,在测试中我发现,只要元音不是 ై (ai),这个漏洞似乎就会发生在任何一对带有元音的泰鲁固语的辅音中。

另外还有第三种可能,特殊字符ZWNJ(zero-width non-joiner)是个不可见的特殊字符,在数据库中往往会被保存为乱码,所以通常情况下要被过滤掉。而iOS 11.2.5中ZWNJ没有被删掉,我认为问题也可能出在这里。<辅音,virama,辅音,元音>是任何印度语中都相当常见的序列;但是在元音之前的ZWNJ对大多数脚本来说并不是非常有用(除了孟加拉语和奥里亚语)。

不过在测试中,我看到了孟加拉语中有一个类似的字符串序列也崩溃了。这个序列是U+09B8 U+09CD U+09B0 U+200C U+09C1,它的字符串序列是这样的:辅音“so”(স),virama(্),辅音“ro”(র),ZWNJ和元音 u (  ু)。

在深入分析这个字符串序列为何会发生崩溃之前,我们先来了解一下带有印度语的脚本是如何运行的?

印度语脚本群和辅音群

印度语脚本是abugidas(一种字母文字系统);这意味着脚本字母是辅音,你可以用它来改变元音。默认情况下,辅音有一个基础元音。例如,क是“kuh”(kə,通常写为“ka”),但我可以改变它的元音使 के(“ok”中的“ka”)成为कका(“kaa”类似于“car “)。

通常情况下,默认元音是ə的发音,但在孟加拉语中它更像是发o的音。

由于默认元音的存在,你需要一种组合辅音的方式。例如,如果你想写“ski”这个词,你不能把它写成स+की(sa + ki =“saki”),你必须把它写成字符串。但转变成字符串后,它的元音自动消失了,并附加了की形成一个辅音连缀群。

你也可以把它写成स्की, स被称为“virama”,它的意思是“删除这个元音”。如果没有简单的方法将这些字符连接成字符串时,就会出现明显的virama。例如ङ्ठ,就不是简单的ङ和ठ的连接。一些脚本也更喜欢明显的virama,例如马拉雅拉姆语中的“ski”就被写为“സ്കീ”,其中的小月牙形状就是明确的virama。

在unicode中,virama字符总是会形成辅音群。因此,स्की被写为<स,्,क,ी>或<sa,virama,ka,i>。如果这些字符支持集群,则它将显示为连字符,否则将使用显式virama。

对于梵文和孟加拉语,通常来说,在辅音群中,第一个辅音会被略微省去,第二个辅音则会保持完整。不过也有例外,有时辅音群会形成一个全新的字形(क+ष=क्ष),有时两个字形都将会改变(ड+ड=ड्ड,द+म=द्म,द+ब=द्ब)。最后一个应该是这样的:

1.png

孟加拉语环境导致的系统崩溃

有趣的是,与泰鲁固语的崩溃不同,孟加拉语的崩溃似乎只发生在第二个辅音——র (“ro”)。但是,除了当元音是 ো (o)或  ৌ (au)时,我可以选择第一个辅音或元来触发র (“ro”)。

现在,在一些印度语脚本中,র 是一个有趣的辅音,包括梵文。在梵文里,它看起来像र(“ra”)。但是,它在形成群时却会产生各种字符上的变化。如果你将它放在群中的另一个辅音之前,它会形成र्क(rka)一样的字符。在马拉地语中,该字符看起就像是र्क。作为后缀辅音,它可能会形成 क्र (kra)这样的字符。对于没有垂直笔划的字母来说,如ठ(tha),它就会变成ठ्र (thra)。

虽然大多数辅音在群内部仍会保留一些最初的形式,但 र 却是个例外。还有一件更特别的事情是,即使र 是群中第二个辅音时也会发生这种情况。正如我之前提到的,对于大多数辅音群来说,第二辅音完好无损。虽然也有例外,但它们通常是针对特定的群的,只有र 出现时群才会发生这种情况。

孟加拉语র 的情况也与र相似,因为第二个辅音在现有的辅音上增加了一些字符。例如,প + র (po + ro) 形成প্র (pro)。

但是,在孟加拉语中不但有র 还有辅音“jo”。 প + য (po + jo)形成প্য(pjo),য 转化为 “jophola”的波浪线。

经过测试后,我发现孟加拉语的崩溃也发生在য上。因此,孟加拉语的字符序列崩溃的一般情况是<辅音,virama, র OR য, ZWN,元音>,其中元音不是 ো or  ৌ。

加入辅音的后缀

现在我已经差不多找到字符串崩溃的原因了,至少对于孟加拉语来说,崩溃就发生在第二个辅音,且它通常与第一个辅音结合且没有修改其字符形式。

事实上,泰鲁固语也是如此。在泰鲁固语中的辅音群通常会通过保留原有的辅音来让崩溃发生,且会把第二个辅音字母串起来。

例如,原始的crashy字符串包含群జ+ఞ,看起来像జ్ఞ。可以看到第一个字母没有修改过,但第二个字母发生了变化。

由此,我可以猜测,这也将发生在梵文与र的结合中。U+0915 U+094D U+0930 U+200C U+093E就是一个这样的序列,即<क,  ्, र, zwnj,  ा> (< ka, virama, ra, zwnj, aa >)就是让程序崩溃 的字符串序列。

但这还不是崩溃发生的根本原因,例如,以上的字符串结合发生在孟加拉语中的“kro”+ zwnj +元音中,而在“kro”中(ক্র=ক+র= ko + ro),所产生的群涉及到前缀和后缀的转换。但是,这个崩溃不会发生在द्ब或ड्ड上。

更深层次的原因是,对于许多字体(可能是使用的字体),这些辅音在形成virama之前会形成“加入辅音的后缀(suffix joining consonants)”(这是我自定义的一个术语)。这就类似于pstf OpenType功能以及vatu

例如,序列virama +क 形成 ्क,即形成一个带有क占位符的virama。

但是,对于我来说,रvirama +र会形成  ्र,如下图所示。

2.png

事实上,其他辅音也是如此。对于我来说, ्र  ্র  ্য  ్ఞ  ్క 就是一个“加入辅音的后缀”:梵文virama-ra,孟加拉语virama-ro,孟加拉语virama-jo,泰鲁固语virama-nya,泰鲁固语virama-ka。

3.png

注意,所有泰鲁固语的辅音都是如此。

有趣的是,由于 र-virama-र使用了第一个र (र्र)的前缀加入形式,所以<र,virama,र,zwnj,vowel>不会发生崩溃。

坎那达语也有“加入辅音的后缀”,但由于某种原因,我无法用它触发崩溃,果鲁穆奇语的Ya也是如此。

ZWNJ

字符ZWNJ是个不可见的特殊字符,没有它就不会发生崩溃,但正如我在提到ZWNJ之前所讲的,元音对于大多数印度语脚本没有什么实际意义。在印度语脚本中,如果在virama之后使用ZWNJ,则可以使用ZWNJ明确突出virama,但这不是它在此处使用的方式。

在孟加拉语和奥里亚语中,ZWNJ可以用于在元音之前强制使用不同的元音形式(例如রুvsরু)。异常元音很有趣,它们基本上都是由两个字形组成的元音。Philippe Verdy表示:

为什么这个错误不会发生在某些元音中,这是因为这些元音是由两部分组成的,它们首先被分解为两个单独的字形,在字形缓冲区中重新排序,而其它元音则不需要这种先前的映射,并保持其初始字体,这意味着漏洞的发生与ZWNJ在字形缓冲区中查找元音的字形的方式有关,而不是在初始代码点缓冲区中,这说明字符的映射有一些不同步,更可能是未初始化的数据字段没有进行元音分解。

崩溃结果的总结

因此,最终造成这次字符串崩溃的全部原因是:在梵文,孟加拉语和泰鲁固语中的任何<consonant1,virama,consonant2,ZWNJ,vowel>序列都会导致崩溃。其中consonant2是加入(pstf/vatu)的后缀字母,即 र, র, য, ৰ和所有的泰鲁固语辅音,而consonant1不是一个类似于र/র (或如ৰ的变体)的reph-forming字母,而vowel则表示不是由两个字形组成的,它即不是  ై, ো也不是   ৌ。

这就又引出了一个问题:为什么该原因不适用于坎那达语?在高棉语中,一个类似于virama的的字符叫“coeng”

有没有在所有语言环境中都能发生崩溃的字符串?要发生崩溃,就要满足以下条件:

1.所有呈现的字符串都是有效的,最初的泰鲁固语是“knowledge”这个词的根源(因为这个原因,我把这个本次的漏洞称为“forbidden knowledge”);

2.在泰鲁固语和梵文中,在元音之前没有使用ZWNJ。ZWNJ本不应该在那里,人们不会在常用的语言中用到它;

3.在孟加拉语(也叫Oriya)中,在一些元音之前放置一个ZWNJ可以防止它们的字符变形;

4.在所有这些脚本中,在virama之后放置一个ZWNJ可以用来强制显示一个连字符的virama。这不是ZWNJ在这里使用的位置,但它暗示这可能是错误的。至少对于梵文来说,这样做也很少见;

5.Android在其键盘上为这些语言提供了明确的ZWNJ键,紧挨着空格键;

所以这些崩溃的字符串通常情况下都是无效的,但如果发生了,则是罕见情况。

@FakeUnicode举了“For/k”的字符输入错误的例子,“For/k”很容易被错误输入为“Foŕk”。上面的斜线并不是你要输入的内容,其实是生成的字符串乱码。

  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务