CINXE.COM
Project Zero: January 2021
<!DOCTYPE html> <html class='v2' dir='ltr' lang='en' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'> <head> <link href='https://www.blogger.com/static/v1/widgets/3566091532-css_bundle_v2.css' rel='stylesheet' type='text/css'/> <meta content='width=1100' name='viewport'/> <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/> <meta content='blogger' name='generator'/> <link href='https://googleprojectzero.blogspot.com/favicon.ico' rel='icon' type='image/x-icon'/> <link href='https://googleprojectzero.blogspot.com/2021/01/' rel='canonical'/> <link rel="alternate" type="application/atom+xml" title="Project Zero - Atom" href="https://googleprojectzero.blogspot.com/feeds/posts/default" /> <link rel="alternate" type="application/rss+xml" title="Project Zero - RSS" href="https://googleprojectzero.blogspot.com/feeds/posts/default?alt=rss" /> <link rel="service.post" type="application/atom+xml" title="Project Zero - Atom" href="https://www.blogger.com/feeds/4838136820032157985/posts/default" /> <!--Can't find substitution for tag [blog.ieCssRetrofitLinks]--> <meta content='https://googleprojectzero.blogspot.com/2021/01/' property='og:url'/> <meta content='Project Zero' property='og:title'/> <meta content='News and updates from the Project Zero team at Google' property='og:description'/> <title>Project Zero: January 2021</title> <style type='text/css'>@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(//fonts.gstatic.com/s/opensans/v40/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVY.eot);}</style> <style id='page-skin-1' type='text/css'><!-- /* ----------------------------------------------- Blogger Template Style Name: Simple Designer: Blogger URL: www.blogger.com ----------------------------------------------- */ /* Variable definitions ==================== <Variable name="keycolor" description="Main Color" type="color" default="#66bbdd"/> <Group description="Page Text" selector="body"> <Variable name="body.font" description="Font" type="font" default="normal normal 12px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="body.text.color" description="Text Color" type="color" default="#222222"/> </Group> <Group description="Backgrounds" selector=".body-fauxcolumns-outer"> <Variable name="body.background.color" description="Outer Background" type="color" default="#66bbdd"/> <Variable name="content.background.color" description="Main Background" type="color" default="#ffffff"/> <Variable name="header.background.color" description="Header Background" type="color" default="transparent"/> </Group> <Group description="Links" selector=".main-outer"> <Variable name="link.color" description="Link Color" type="color" default="#2288bb"/> <Variable name="link.visited.color" description="Visited Color" type="color" default="#888888"/> <Variable name="link.hover.color" description="Hover Color" type="color" default="#33aaff"/> </Group> <Group description="Blog Title" selector=".header h1"> <Variable name="header.font" description="Font" type="font" default="normal normal 60px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="header.text.color" description="Title Color" type="color" default="#3399bb" /> </Group> <Group description="Blog Description" selector=".header .description"> <Variable name="description.text.color" description="Description Color" type="color" default="#777777" /> </Group> <Group description="Tabs Text" selector=".tabs-inner .widget li a"> <Variable name="tabs.font" description="Font" type="font" default="normal normal 14px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="tabs.text.color" description="Text Color" type="color" default="#999999"/> <Variable name="tabs.selected.text.color" description="Selected Color" type="color" default="#000000"/> </Group> <Group description="Tabs Background" selector=".tabs-outer .PageList"> <Variable name="tabs.background.color" description="Background Color" type="color" default="#f5f5f5"/> <Variable name="tabs.selected.background.color" description="Selected Color" type="color" default="#eeeeee"/> </Group> <Group description="Post Title" selector="h3.post-title, .comments h4"> <Variable name="post.title.font" description="Font" type="font" default="normal normal 22px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> </Group> <Group description="Date Header" selector=".date-header"> <Variable name="date.header.color" description="Text Color" type="color" default="#000000"/> <Variable name="date.header.background.color" description="Background Color" type="color" default="transparent"/> <Variable name="date.header.font" description="Text Font" type="font" default="normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="date.header.padding" description="Date Header Padding" type="string" default="inherit"/> <Variable name="date.header.letterspacing" description="Date Header Letter Spacing" type="string" default="inherit"/> <Variable name="date.header.margin" description="Date Header Margin" type="string" default="inherit"/> </Group> <Group description="Post Footer" selector=".post-footer"> <Variable name="post.footer.text.color" description="Text Color" type="color" default="#666666"/> <Variable name="post.footer.background.color" description="Background Color" type="color" default="#f9f9f9"/> <Variable name="post.footer.border.color" description="Shadow Color" type="color" default="#eeeeee"/> </Group> <Group description="Gadgets" selector="h2"> <Variable name="widget.title.font" description="Title Font" type="font" default="normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="widget.title.text.color" description="Title Color" type="color" default="#000000"/> <Variable name="widget.alternate.text.color" description="Alternate Color" type="color" default="#999999"/> </Group> <Group description="Images" selector=".main-inner"> <Variable name="image.background.color" description="Background Color" type="color" default="#ffffff"/> <Variable name="image.border.color" description="Border Color" type="color" default="#eeeeee"/> <Variable name="image.text.color" description="Caption Text Color" type="color" default="#000000"/> </Group> <Group description="Accents" selector=".content-inner"> <Variable name="body.rule.color" description="Separator Line Color" type="color" default="#eeeeee"/> <Variable name="tabs.border.color" description="Tabs Border Color" type="color" default="transparent"/> </Group> <Variable name="body.background" description="Body Background" type="background" color="#eeeeee" default="$(color) none repeat scroll top left"/> <Variable name="body.background.override" description="Body Background Override" type="string" default=""/> <Variable name="body.background.gradient.cap" description="Body Gradient Cap" type="url" default="url(https://resources.blogblog.com/blogblog/data/1kt/simple/gradients_light.png)"/> <Variable name="body.background.gradient.tile" description="Body Gradient Tile" type="url" default="url(https://resources.blogblog.com/blogblog/data/1kt/simple/body_gradient_tile_light.png)"/> <Variable name="content.background.color.selector" description="Content Background Color Selector" type="string" default=".content-inner"/> <Variable name="content.padding" description="Content Padding" type="length" default="10px" min="0" max="100px"/> <Variable name="content.padding.horizontal" description="Content Horizontal Padding" type="length" default="10px" min="0" max="100px"/> <Variable name="content.shadow.spread" description="Content Shadow Spread" type="length" default="40px" min="0" max="100px"/> <Variable name="content.shadow.spread.webkit" description="Content Shadow Spread (WebKit)" type="length" default="5px" min="0" max="100px"/> <Variable name="content.shadow.spread.ie" description="Content Shadow Spread (IE)" type="length" default="10px" min="0" max="100px"/> <Variable name="main.border.width" description="Main Border Width" type="length" default="0" min="0" max="10px"/> <Variable name="header.background.gradient" description="Header Gradient" type="url" default="none"/> <Variable name="header.shadow.offset.left" description="Header Shadow Offset Left" type="length" default="-1px" min="-50px" max="50px"/> <Variable name="header.shadow.offset.top" description="Header Shadow Offset Top" type="length" default="-1px" min="-50px" max="50px"/> <Variable name="header.shadow.spread" description="Header Shadow Spread" type="length" default="1px" min="0" max="100px"/> <Variable name="header.padding" description="Header Padding" type="length" default="30px" min="0" max="100px"/> <Variable name="header.border.size" description="Header Border Size" type="length" default="1px" min="0" max="10px"/> <Variable name="header.bottom.border.size" description="Header Bottom Border Size" type="length" default="1px" min="0" max="10px"/> <Variable name="header.border.horizontalsize" description="Header Horizontal Border Size" type="length" default="0" min="0" max="10px"/> <Variable name="description.text.size" description="Description Text Size" type="string" default="140%"/> <Variable name="tabs.margin.top" description="Tabs Margin Top" type="length" default="0" min="0" max="100px"/> <Variable name="tabs.margin.side" description="Tabs Side Margin" type="length" default="30px" min="0" max="100px"/> <Variable name="tabs.background.gradient" description="Tabs Background Gradient" type="url" default="url(https://resources.blogblog.com/blogblog/data/1kt/simple/gradients_light.png)"/> <Variable name="tabs.border.width" description="Tabs Border Width" type="length" default="1px" min="0" max="10px"/> <Variable name="tabs.bevel.border.width" description="Tabs Bevel Border Width" type="length" default="1px" min="0" max="10px"/> <Variable name="post.margin.bottom" description="Post Bottom Margin" type="length" default="25px" min="0" max="100px"/> <Variable name="image.border.small.size" description="Image Border Small Size" type="length" default="2px" min="0" max="10px"/> <Variable name="image.border.large.size" description="Image Border Large Size" type="length" default="5px" min="0" max="10px"/> <Variable name="page.width.selector" description="Page Width Selector" type="string" default=".region-inner"/> <Variable name="page.width" description="Page Width" type="string" default="auto"/> <Variable name="main.section.margin" description="Main Section Margin" type="length" default="15px" min="0" max="100px"/> <Variable name="main.padding" description="Main Padding" type="length" default="15px" min="0" max="100px"/> <Variable name="main.padding.top" description="Main Padding Top" type="length" default="30px" min="0" max="100px"/> <Variable name="main.padding.bottom" description="Main Padding Bottom" type="length" default="30px" min="0" max="100px"/> <Variable name="paging.background" color="#ffffff" description="Background of blog paging area" type="background" default="transparent none no-repeat scroll top center"/> <Variable name="footer.bevel" description="Bevel border length of footer" type="length" default="0" min="0" max="10px"/> <Variable name="mobile.background.overlay" description="Mobile Background Overlay" type="string" default="transparent none repeat scroll top left"/> <Variable name="mobile.background.size" description="Mobile Background Size" type="string" default="auto"/> <Variable name="mobile.button.color" description="Mobile Button Color" type="color" default="#ffffff" /> <Variable name="startSide" description="Side where text starts in blog language" type="automatic" default="left"/> <Variable name="endSide" description="Side where text ends in blog language" type="automatic" default="right"/> */ /* Content ----------------------------------------------- */ body { font: normal normal 12px Open Sans; color: #000000; background: #eeeeee none repeat scroll top left; padding: 0 0 0 0; } html body .region-inner { min-width: 0; max-width: 100%; width: auto; } h2 { font-size: 22px; } a:link { text-decoration:none; color: #2288bb; } a:visited { text-decoration:none; color: #888888; } a:hover { text-decoration:underline; color: #33aaff; } .body-fauxcolumn-outer .fauxcolumn-inner { background: transparent none repeat scroll top left; _background-image: none; } .body-fauxcolumn-outer .cap-top { position: absolute; z-index: 1; height: 400px; width: 100%; } .body-fauxcolumn-outer .cap-top .cap-left { width: 100%; background: transparent none repeat-x scroll top left; _background-image: none; } .content-outer { -moz-box-shadow: 0 0 0 rgba(0, 0, 0, .15); -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .15); -goog-ms-box-shadow: 0 0 0 #333333; box-shadow: 0 0 0 rgba(0, 0, 0, .15); margin-bottom: 1px; } .content-inner { padding: 10px 40px; } .content-inner { background-color: #ffffff; } /* Header ----------------------------------------------- */ .header-outer { background: transparent none repeat-x scroll 0 -400px; _background-image: none; } .Header h1 { font: normal normal 40px Open Sans; color: #000000; text-shadow: 0 0 0 rgba(0, 0, 0, .2); } .Header h1 a { color: #000000; } .Header .description { font-size: 18px; color: #000000; } .header-inner .Header .titlewrapper { padding: 22px 0; } .header-inner .Header .descriptionwrapper { padding: 0 0; } /* Tabs ----------------------------------------------- */ .tabs-inner .section:first-child { border-top: 0 solid #dddddd; } .tabs-inner .section:first-child ul { margin-top: -1px; border-top: 1px solid #dddddd; border-left: 1px solid #dddddd; border-right: 1px solid #dddddd; } .tabs-inner .widget ul { background: transparent none repeat-x scroll 0 -800px; _background-image: none; border-bottom: 1px solid #dddddd; margin-top: 0; margin-left: -30px; margin-right: -30px; } .tabs-inner .widget li a { display: inline-block; padding: .6em 1em; font: normal normal 12px Open Sans; color: #000000; border-left: 1px solid #ffffff; border-right: 1px solid #dddddd; } .tabs-inner .widget li:first-child a { border-left: none; } .tabs-inner .widget li.selected a, .tabs-inner .widget li a:hover { color: #000000; background-color: #eeeeee; text-decoration: none; } /* Columns ----------------------------------------------- */ .main-outer { border-top: 0 solid transparent; } .fauxcolumn-left-outer .fauxcolumn-inner { border-right: 1px solid transparent; } .fauxcolumn-right-outer .fauxcolumn-inner { border-left: 1px solid transparent; } /* Headings ----------------------------------------------- */ div.widget > h2, div.widget h2.title { margin: 0 0 1em 0; font: normal bold 11px 'Trebuchet MS',Trebuchet,Verdana,sans-serif; color: #000000; } /* Widgets ----------------------------------------------- */ .widget .zippy { color: #999999; text-shadow: 2px 2px 1px rgba(0, 0, 0, .1); } .widget .popular-posts ul { list-style: none; } /* Posts ----------------------------------------------- */ h2.date-header { font: normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif; } .date-header span { background-color: #bbbbbb; color: #ffffff; padding: 0.4em; letter-spacing: 3px; margin: inherit; } .main-inner { padding-top: 35px; padding-bottom: 65px; } .main-inner .column-center-inner { padding: 0 0; } .main-inner .column-center-inner .section { margin: 0 1em; } .post { margin: 0 0 45px 0; } h3.post-title, .comments h4 { font: normal normal 22px Open Sans; margin: .75em 0 0; } .post-body { font-size: 110%; line-height: 1.4; position: relative; } .post-body img, .post-body .tr-caption-container, .Profile img, .Image img, .BlogList .item-thumbnail img { padding: 2px; background: #ffffff; border: 1px solid #eeeeee; -moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); } .post-body img, .post-body .tr-caption-container { padding: 5px; } .post-body .tr-caption-container { color: #666666; } .post-body .tr-caption-container img { padding: 0; background: transparent; border: none; -moz-box-shadow: 0 0 0 rgba(0, 0, 0, .1); -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .1); box-shadow: 0 0 0 rgba(0, 0, 0, .1); } .post-header { margin: 0 0 1.5em; line-height: 1.6; font-size: 90%; } .post-footer { margin: 20px -2px 0; padding: 5px 10px; color: #666666; background-color: #eeeeee; border-bottom: 1px solid #eeeeee; line-height: 1.6; font-size: 90%; } #comments .comment-author { padding-top: 1.5em; border-top: 1px solid transparent; background-position: 0 1.5em; } #comments .comment-author:first-child { padding-top: 0; border-top: none; } .avatar-image-container { margin: .2em 0 0; } #comments .avatar-image-container img { border: 1px solid #eeeeee; } /* Comments ----------------------------------------------- */ .comments .comments-content .icon.blog-author { background-repeat: no-repeat; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9sLFwMeCjjhcOMAAAD+SURBVDjLtZSvTgNBEIe/WRRnm3U8RC1neQdsm1zSBIU9VVF1FkUguQQsD9ITmD7ECZIJSE4OZo9stoVjC/zc7ky+zH9hXwVwDpTAWWLrgS3QAe8AZgaAJI5zYAmc8r0G4AHYHQKVwII8PZrZFsBFkeRCABYiMh9BRUhnSkPTNCtVXYXURi1FpBDgArj8QU1eVXUzfnjv7yP7kwu1mYrkWlU33vs1QNu2qU8pwN0UpKoqokjWwCztrMuBhEhmh8bD5UDqur75asbcX0BGUB9/HAMB+r32hznJgXy2v0sGLBcyAJ1EK3LFcbo1s91JeLwAbwGYu7TP/3ZGfnXYPgAVNngtqatUNgAAAABJRU5ErkJggg==); } .comments .comments-content .loadmore a { border-top: 1px solid #999999; border-bottom: 1px solid #999999; } .comments .comment-thread.inline-thread { background-color: #eeeeee; } .comments .continue { border-top: 2px solid #999999; } /* Accents ---------------------------------------------- */ .section-columns td.columns-cell { border-left: 1px solid transparent; } .blog-pager { background: transparent url(//www.blogblog.com/1kt/simple/paging_dot.png) repeat-x scroll top center; } .blog-pager-older-link, .home-link, .blog-pager-newer-link { background-color: #ffffff; padding: 5px; } .footer-outer { border-top: 1px dashed #bbbbbb; } /* Mobile ----------------------------------------------- */ body.mobile { background-size: auto; } .mobile .body-fauxcolumn-outer { background: transparent none repeat scroll top left; } .mobile .body-fauxcolumn-outer .cap-top { background-size: 100% auto; } .mobile .content-outer { -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, .15); box-shadow: 0 0 3px rgba(0, 0, 0, .15); } .mobile .tabs-inner .widget ul { margin-left: 0; margin-right: 0; } .mobile .post { margin: 0; } .mobile .main-inner .column-center-inner .section { margin: 0; } .mobile .date-header span { padding: 0.1em 10px; margin: 0 -10px; } .mobile h3.post-title { margin: 0; } .mobile .blog-pager { background: transparent none no-repeat scroll top center; } .mobile .footer-outer { border-top: none; } .mobile .main-inner, .mobile .footer-inner { background-color: #ffffff; } .mobile-index-contents { color: #000000; } .mobile-link-button { background-color: #2288bb; } .mobile-link-button a:link, .mobile-link-button a:visited { color: #ffffff; } .mobile .tabs-inner .section:first-child { border-top: none; } .mobile .tabs-inner .PageList .widget-content { background-color: #eeeeee; color: #000000; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; } .mobile .tabs-inner .PageList .widget-content .pagelist-arrow { border-left: 1px solid #dddddd; } --></style> <style id='template-skin-1' type='text/css'><!-- body { min-width: 1120px; } .content-outer, .content-fauxcolumn-outer, .region-inner { min-width: 1120px; max-width: 1120px; _width: 1120px; } .main-inner .columns { padding-left: 0; padding-right: 310px; } .main-inner .fauxcolumn-center-outer { left: 0; right: 310px; /* IE6 does not respect left and right together */ _width: expression(this.parentNode.offsetWidth - parseInt("0") - parseInt("310px") + 'px'); } .main-inner .fauxcolumn-left-outer { width: 0; } .main-inner .fauxcolumn-right-outer { width: 310px; } .main-inner .column-left-outer { width: 0; right: 100%; margin-left: -0; } .main-inner .column-right-outer { width: 310px; margin-right: -310px; } #layout { min-width: 0; } #layout .content-outer { min-width: 0; width: 800px; } #layout .region-inner { min-width: 0; width: auto; } body#layout div.add_widget { padding: 8px; } body#layout div.add_widget a { margin-left: 32px; } --></style> <script type='text/javascript'> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-240546891-1', 'auto', 'blogger'); ga('blogger.send', 'pageview'); </script> <link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=4838136820032157985&zx=9e014bfb-e50c-4ece-bb2f-ed942adb173a' media='none' onload='if(media!='all')media='all'' rel='stylesheet'/><noscript><link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=4838136820032157985&zx=9e014bfb-e50c-4ece-bb2f-ed942adb173a' rel='stylesheet'/></noscript> <meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/> <meta name='google-adsense-platform-domain' content='blogspot.com'/> </head> <body class='loading'> <div class='navbar section' id='navbar' name='Navbar'><div class='widget Navbar' data-version='1' id='Navbar1'><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/platform.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar/4838136820032157985?origin\x3dhttps://googleprojectzero.blogspot.com', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script><script type="text/javascript"> (function() { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = '//pagead2.googlesyndication.com/pagead/js/google_top_exp.js'; var head = document.getElementsByTagName('head')[0]; if (head) { head.appendChild(script); }})(); </script> </div></div> <div class='body-fauxcolumns'> <div class='fauxcolumn-outer body-fauxcolumn-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <div class='content'> <div class='content-fauxcolumns'> <div class='fauxcolumn-outer content-fauxcolumn-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <div class='content-outer'> <div class='content-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left content-fauxborder-left'> <div class='fauxborder-right content-fauxborder-right'></div> <div class='content-inner'> <header> <div class='header-outer'> <div class='header-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left header-fauxborder-left'> <div class='fauxborder-right header-fauxborder-right'></div> <div class='region-inner header-inner'> <div class='header section' id='header' name='Header'><div class='widget Header' data-version='1' id='Header1'> <div id='header-inner'> <div class='titlewrapper'> <h1 class='title'> <a href='https://googleprojectzero.blogspot.com/'> Project Zero </a> </h1> </div> <div class='descriptionwrapper'> <p class='description'><span>News and updates from the Project Zero team at Google</span></p> </div> </div> </div></div> </div> </div> <div class='header-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </header> <div class='tabs-outer'> <div class='tabs-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left tabs-fauxborder-left'> <div class='fauxborder-right tabs-fauxborder-right'></div> <div class='region-inner tabs-inner'> <div class='tabs no-items section' id='crosscol' name='Cross-Column'></div> <div class='tabs no-items section' id='crosscol-overflow' name='Cross-Column 2'></div> </div> </div> <div class='tabs-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='main-outer'> <div class='main-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left main-fauxborder-left'> <div class='fauxborder-right main-fauxborder-right'></div> <div class='region-inner main-inner'> <div class='columns fauxcolumns'> <div class='fauxcolumn-outer fauxcolumn-center-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='fauxcolumn-outer fauxcolumn-left-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='fauxcolumn-outer fauxcolumn-right-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <!-- corrects IE6 width calculation --> <div class='columns-inner'> <div class='column-center-outer'> <div class='column-center-inner'> <div class='main section' id='main' name='Main'><div class='widget Blog' data-version='1' id='Blog1'> <div class='blog-posts hfeed'> <div class="date-outer"> <h2 class='date-header'><span>Thursday, January 28, 2021</span></h2> <div class="date-posts"> <div class='post-outer'> <div class='post hentry uncustomized-post-template' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWbfjpXKVDVZfZasnzWXN02AH5-A4Nw1229VrO2_FG1otEQSw_r0uRNkB8TedmfA-__gncfPoZ_aa5YE1Ac1_8kzmqKi2Iyj4l47OgN7o9K6Ue8JtRN42XdwHZyBJCg1U26pscYx2ObqwWrouGS9uoZizPZmxvpYwX3PDLanDgdDcOuicfmRwIbRMi/s623/image1%282%29.png' itemprop='image_url'/> <meta content='4838136820032157985' itemprop='blogId'/> <meta content='405547501763334781' itemprop='postId'/> <a name='405547501763334781'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='https://googleprojectzero.blogspot.com/2021/01/a-look-at-imessage-in-ios-14.html'>A Look at iMessage in iOS 14</a> </h3> <div class='post-header'> <div class='post-header-line-1'></div> </div> <div class='post-body entry-content' id='post-body-405547501763334781' itemprop='description articleBody'> <style type="text/css">@import url('https://themes.googleusercontent.com/fonts/css?kit=cGvuclDC_Z1vE_cnVEU6Ae_NZQ7StBcqH_vXVqoPMX0');ol.lst-kix_ezf2mrk385uq-4.start{counter-reset:lst-ctn-kix_ezf2mrk385uq-4 0}ol.lst-kix_ct3zb543qdjl-5{list-style-type:none}ol.lst-kix_ct3zb543qdjl-4{list-style-type:none}ol.lst-kix_ct3zb543qdjl-7{list-style-type:none}ol.lst-kix_ct3zb543qdjl-6{list-style-type:none}ol.lst-kix_ct3zb543qdjl-1{list-style-type:none}ol.lst-kix_ct3zb543qdjl-0{list-style-type:none}ol.lst-kix_ct3zb543qdjl-3{list-style-type:none}ol.lst-kix_ct3zb543qdjl-2{list-style-type:none}ol.lst-kix_aue93cd1tacp-8{list-style-type:none}.lst-kix_ezf2mrk385uq-8>li{counter-increment:lst-ctn-kix_ezf2mrk385uq-8}ol.lst-kix_ha0mdd7f5mn8-8.start{counter-reset:lst-ctn-kix_ha0mdd7f5mn8-8 0}ol.lst-kix_hisa166i97g-1.start{counter-reset:lst-ctn-kix_hisa166i97g-1 0}ol.lst-kix_ct3zb543qdjl-8{list-style-type:none}.lst-kix_f1zwtsa21lze-6>li{counter-increment:lst-ctn-kix_f1zwtsa21lze-6}ol.lst-kix_aue93cd1tacp-6.start{counter-reset:lst-ctn-kix_aue93cd1tacp-6 0}ol.lst-kix_2zj51yim977x-4.start{counter-reset:lst-ctn-kix_2zj51yim977x-4 0}ol.lst-kix_ct3zb543qdjl-5.start{counter-reset:lst-ctn-kix_ct3zb543qdjl-5 0}.lst-kix_aue93cd1tacp-8>li{counter-increment:lst-ctn-kix_aue93cd1tacp-8}.lst-kix_ezf2mrk385uq-4>li{counter-increment:lst-ctn-kix_ezf2mrk385uq-4}.lst-kix_hmo7gyj5poo-3>li{counter-increment:lst-ctn-kix_hmo7gyj5poo-3}ol.lst-kix_aue93cd1tacp-3{list-style-type:none}ol.lst-kix_aue93cd1tacp-2{list-style-type:none}ol.lst-kix_aue93cd1tacp-1{list-style-type:none}ol.lst-kix_aue93cd1tacp-0{list-style-type:none}.lst-kix_hisa166i97g-0>li{counter-increment:lst-ctn-kix_hisa166i97g-0}ol.lst-kix_aue93cd1tacp-7{list-style-type:none}ol.lst-kix_aue93cd1tacp-6{list-style-type:none}ol.lst-kix_aue93cd1tacp-5{list-style-type:none}ol.lst-kix_aue93cd1tacp-4{list-style-type:none}ol.lst-kix_hisa166i97g-6.start{counter-reset:lst-ctn-kix_hisa166i97g-6 0}ol.lst-kix_ct3zb543qdjl-0.start{counter-reset:lst-ctn-kix_ct3zb543qdjl-0 0}ol.lst-kix_aue93cd1tacp-1.start{counter-reset:lst-ctn-kix_aue93cd1tacp-1 0}ol.lst-kix_hmo7gyj5poo-4.start{counter-reset:lst-ctn-kix_hmo7gyj5poo-4 0}.lst-kix_ju6nxsiwjdzc-0>li:before{content:"\0025cf "}.lst-kix_33m87cusbobo-0>li:before{content:"\0025cf "}.lst-kix_ct3zb543qdjl-2>li{counter-increment:lst-ctn-kix_ct3zb543qdjl-2}.lst-kix_ha0mdd7f5mn8-1>li:before{content:"" counter(lst-ctn-kix_ha0mdd7f5mn8-1,lower-latin) ") "}.lst-kix_ha0mdd7f5mn8-3>li:before{content:"(" counter(lst-ctn-kix_ha0mdd7f5mn8-3,decimal) ") "}.lst-kix_ju6nxsiwjdzc-1>li:before{content:"\0025cb "}.lst-kix_33m87cusbobo-2>li:before{content:"\0025a0 "}.lst-kix_hmo7gyj5poo-6>li:before{content:"" counter(lst-ctn-kix_hmo7gyj5poo-6,decimal) ". "}.lst-kix_hmo7gyj5poo-6>li{counter-increment:lst-ctn-kix_hmo7gyj5poo-6}.lst-kix_hmo7gyj5poo-4>li:before{content:"" counter(lst-ctn-kix_hmo7gyj5poo-4,lower-latin) ". "}.lst-kix_hmo7gyj5poo-8>li:before{content:"" counter(lst-ctn-kix_hmo7gyj5poo-8,lower-roman) ". "}.lst-kix_ju6nxsiwjdzc-3>li:before{content:"\0025cf "}.lst-kix_33m87cusbobo-4>li:before{content:"\0025cb "}.lst-kix_ju6nxsiwjdzc-5>li:before{content:"\0025a0 "}.lst-kix_hisa166i97g-3>li{counter-increment:lst-ctn-kix_hisa166i97g-3}.lst-kix_33m87cusbobo-6>li:before{content:"\0025cf "}ol.lst-kix_ezf2mrk385uq-8{list-style-type:none}.lst-kix_ju6nxsiwjdzc-7>li:before{content:"\0025cb "}.lst-kix_33m87cusbobo-8>li:before{content:"\0025a0 "}ol.lst-kix_ezf2mrk385uq-6{list-style-type:none}.lst-kix_ezf2mrk385uq-0>li{counter-increment:lst-ctn-kix_ezf2mrk385uq-0}ol.lst-kix_ezf2mrk385uq-7{list-style-type:none}ol.lst-kix_ezf2mrk385uq-4{list-style-type:none}ol.lst-kix_ezf2mrk385uq-5{list-style-type:none}ol.lst-kix_ezf2mrk385uq-2{list-style-type:none}ol.lst-kix_ezf2mrk385uq-3{list-style-type:none}ol.lst-kix_ezf2mrk385uq-0{list-style-type:none}ol.lst-kix_ezf2mrk385uq-1{list-style-type:none}.lst-kix_ha0mdd7f5mn8-7>li:before{content:"" counter(lst-ctn-kix_ha0mdd7f5mn8-7,lower-latin) ". "}.lst-kix_ha0mdd7f5mn8-5>li:before{content:"(" counter(lst-ctn-kix_ha0mdd7f5mn8-5,lower-roman) ") "}.lst-kix_ct3zb543qdjl-1>li{counter-increment:lst-ctn-kix_ct3zb543qdjl-1}ol.lst-kix_ezf2mrk385uq-6.start{counter-reset:lst-ctn-kix_ezf2mrk385uq-6 0}ol.lst-kix_f1zwtsa21lze-6.start{counter-reset:lst-ctn-kix_f1zwtsa21lze-6 0}.lst-kix_2zj51yim977x-2>li{counter-increment:lst-ctn-kix_2zj51yim977x-2}.lst-kix_mqtiiergx266-0>li:before{content:"\0025cf "}.lst-kix_mqtiiergx266-4>li:before{content:"\0025cb "}.lst-kix_yvc47pi19nhn-4>li:before{content:"\0025cb "}.lst-kix_yvc47pi19nhn-8>li:before{content:"\0025a0 "}.lst-kix_u10h5r66zlog-4>li:before{content:"\0025cb "}.lst-kix_mqtiiergx266-2>li:before{content:"\0025a0 "}.lst-kix_yvc47pi19nhn-2>li:before{content:"\0025a0 "}.lst-kix_yvc47pi19nhn-0>li:before{content:"\0025cf "}.lst-kix_2zj51yim977x-3>li{counter-increment:lst-ctn-kix_2zj51yim977x-3}.lst-kix_u10h5r66zlog-6>li:before{content:"\0025cf "}.lst-kix_gavezx7jyt0h-4>li:before{content:"\0025cb "}ol.lst-kix_hisa166i97g-4.start{counter-reset:lst-ctn-kix_hisa166i97g-4 0}.lst-kix_u10h5r66zlog-8>li:before{content:"\0025a0 "}.lst-kix_gavezx7jyt0h-6>li:before{content:"\0025cf "}.lst-kix_hisa166i97g-4>li{counter-increment:lst-ctn-kix_hisa166i97g-4}.lst-kix_aue93cd1tacp-1>li{counter-increment:lst-ctn-kix_aue93cd1tacp-1}.lst-kix_hmo7gyj5poo-0>li:before{content:"" counter(lst-ctn-kix_hmo7gyj5poo-0,decimal) ". "}.lst-kix_hmo7gyj5poo-7>li{counter-increment:lst-ctn-kix_hmo7gyj5poo-7}ol.lst-kix_hmo7gyj5poo-1.start{counter-reset:lst-ctn-kix_hmo7gyj5poo-1 0}.lst-kix_hmo7gyj5poo-2>li:before{content:"" counter(lst-ctn-kix_hmo7gyj5poo-2,lower-roman) ". "}ol.lst-kix_f1zwtsa21lze-8.start{counter-reset:lst-ctn-kix_f1zwtsa21lze-8 0}.lst-kix_gavezx7jyt0h-2>li:before{content:"\0025a0 "}ol.lst-kix_ct3zb543qdjl-3.start{counter-reset:lst-ctn-kix_ct3zb543qdjl-3 0}ol.lst-kix_hisa166i97g-3.start{counter-reset:lst-ctn-kix_hisa166i97g-3 0}.lst-kix_u10h5r66zlog-2>li:before{content:"\0025a0 "}.lst-kix_gavezx7jyt0h-0>li:before{content:"\0025cf "}.lst-kix_f1zwtsa21lze-6>li:before{content:"" counter(lst-ctn-kix_f1zwtsa21lze-6,decimal) ". "}.lst-kix_mqtiiergx266-8>li:before{content:"\0025a0 "}.lst-kix_u10h5r66zlog-0>li:before{content:"\0025cf "}.lst-kix_f1zwtsa21lze-8>li:before{content:"" counter(lst-ctn-kix_f1zwtsa21lze-8,lower-roman) ". "}.lst-kix_ha0mdd7f5mn8-6>li{counter-increment:lst-ctn-kix_ha0mdd7f5mn8-6}.lst-kix_mqtiiergx266-6>li:before{content:"\0025cf "}.lst-kix_yvc47pi19nhn-6>li:before{content:"\0025cf "}.lst-kix_ezf2mrk385uq-5>li:before{content:"" counter(lst-ctn-kix_ezf2mrk385uq-5,lower-roman) ". "}.lst-kix_ezf2mrk385uq-7>li{counter-increment:lst-ctn-kix_ezf2mrk385uq-7}.lst-kix_ct3zb543qdjl-8>li{counter-increment:lst-ctn-kix_ct3zb543qdjl-8}.lst-kix_f1zwtsa21lze-2>li:before{content:"" counter(lst-ctn-kix_f1zwtsa21lze-2,lower-roman) ". "}.lst-kix_ezf2mrk385uq-4>li:before{content:"" counter(lst-ctn-kix_ezf2mrk385uq-4,lower-latin) ". "}ol.lst-kix_2zj51yim977x-1.start{counter-reset:lst-ctn-kix_2zj51yim977x-1 0}.lst-kix_ezf2mrk385uq-1>li:before{content:"" counter(lst-ctn-kix_ezf2mrk385uq-1,lower-latin) ". "}ol.lst-kix_f1zwtsa21lze-5.start{counter-reset:lst-ctn-kix_f1zwtsa21lze-5 0}.lst-kix_f1zwtsa21lze-1>li:before{content:"" counter(lst-ctn-kix_f1zwtsa21lze-1,lower-latin) ". "}ol.lst-kix_ha0mdd7f5mn8-5.start{counter-reset:lst-ctn-kix_ha0mdd7f5mn8-5 0}.lst-kix_ezf2mrk385uq-0>li:before{content:"" counter(lst-ctn-kix_ezf2mrk385uq-0,decimal) ". "}.lst-kix_hmo7gyj5poo-0>li{counter-increment:lst-ctn-kix_hmo7gyj5poo-0}.lst-kix_gavezx7jyt0h-7>li:before{content:"\0025cb "}.lst-kix_2zj51yim977x-0>li{counter-increment:lst-ctn-kix_2zj51yim977x-0}.lst-kix_ha0mdd7f5mn8-7>li{counter-increment:lst-ctn-kix_ha0mdd7f5mn8-7}ol.lst-kix_ct3zb543qdjl-8.start{counter-reset:lst-ctn-kix_ct3zb543qdjl-8 0}ol.lst-kix_f1zwtsa21lze-0{list-style-type:none}ol.lst-kix_f1zwtsa21lze-1{list-style-type:none}ol.lst-kix_f1zwtsa21lze-2{list-style-type:none}ol.lst-kix_f1zwtsa21lze-3{list-style-type:none}ol.lst-kix_2zj51yim977x-7.start{counter-reset:lst-ctn-kix_2zj51yim977x-7 0}ol.lst-kix_f1zwtsa21lze-4{list-style-type:none}.lst-kix_ezf2mrk385uq-8>li:before{content:"" counter(lst-ctn-kix_ezf2mrk385uq-8,lower-roman) ". "}ol.lst-kix_f1zwtsa21lze-5{list-style-type:none}ol.lst-kix_f1zwtsa21lze-6{list-style-type:none}ol.lst-kix_f1zwtsa21lze-7{list-style-type:none}ol.lst-kix_aue93cd1tacp-3.start{counter-reset:lst-ctn-kix_aue93cd1tacp-3 0}ol.lst-kix_f1zwtsa21lze-8{list-style-type:none}ol.lst-kix_aue93cd1tacp-2.start{counter-reset:lst-ctn-kix_aue93cd1tacp-2 0}.lst-kix_2zj51yim977x-1>li:before{content:"" counter(lst-ctn-kix_2zj51yim977x-1,lower-latin) ". "}.lst-kix_2zj51yim977x-0>li:before{content:"" counter(lst-ctn-kix_2zj51yim977x-0,decimal) ". "}ol.lst-kix_ha0mdd7f5mn8-0.start{counter-reset:lst-ctn-kix_ha0mdd7f5mn8-0 0}ol.lst-kix_ezf2mrk385uq-2.start{counter-reset:lst-ctn-kix_ezf2mrk385uq-2 0}ul.lst-kix_33m87cusbobo-1{list-style-type:none}ul.lst-kix_33m87cusbobo-0{list-style-type:none}ol.lst-kix_2zj51yim977x-2.start{counter-reset:lst-ctn-kix_2zj51yim977x-2 0}.lst-kix_2zj51yim977x-8>li:before{content:"" counter(lst-ctn-kix_2zj51yim977x-8,lower-roman) ". "}ol.lst-kix_ct3zb543qdjl-7.start{counter-reset:lst-ctn-kix_ct3zb543qdjl-7 0}ol.lst-kix_f1zwtsa21lze-4.start{counter-reset:lst-ctn-kix_f1zwtsa21lze-4 0}ul.lst-kix_mqtiiergx266-4{list-style-type:none}ul.lst-kix_mqtiiergx266-3{list-style-type:none}ol.lst-kix_ezf2mrk385uq-1.start{counter-reset:lst-ctn-kix_ezf2mrk385uq-1 0}ol.lst-kix_ha0mdd7f5mn8-6.start{counter-reset:lst-ctn-kix_ha0mdd7f5mn8-6 0}ul.lst-kix_mqtiiergx266-2{list-style-type:none}ul.lst-kix_mqtiiergx266-1{list-style-type:none}ul.lst-kix_mqtiiergx266-0{list-style-type:none}.lst-kix_2zj51yim977x-4>li:before{content:"" counter(lst-ctn-kix_2zj51yim977x-4,lower-latin) ". "}.lst-kix_2zj51yim977x-7>li{counter-increment:lst-ctn-kix_2zj51yim977x-7}ul.lst-kix_33m87cusbobo-7{list-style-type:none}ul.lst-kix_33m87cusbobo-6{list-style-type:none}.lst-kix_2zj51yim977x-5>li:before{content:"" counter(lst-ctn-kix_2zj51yim977x-5,lower-roman) ". "}ol.lst-kix_aue93cd1tacp-8.start{counter-reset:lst-ctn-kix_aue93cd1tacp-8 0}ul.lst-kix_33m87cusbobo-8{list-style-type:none}ul.lst-kix_mqtiiergx266-8{list-style-type:none}ul.lst-kix_33m87cusbobo-3{list-style-type:none}ul.lst-kix_mqtiiergx266-7{list-style-type:none}ul.lst-kix_33m87cusbobo-2{list-style-type:none}ul.lst-kix_mqtiiergx266-6{list-style-type:none}ul.lst-kix_33m87cusbobo-5{list-style-type:none}ul.lst-kix_mqtiiergx266-5{list-style-type:none}ul.lst-kix_33m87cusbobo-4{list-style-type:none}.lst-kix_a7picbopwap5-4>li:before{content:"\0025cb "}.lst-kix_ha0mdd7f5mn8-2>li:before{content:"" counter(lst-ctn-kix_ha0mdd7f5mn8-2,lower-roman) ") "}ol.lst-kix_aue93cd1tacp-4.start{counter-reset:lst-ctn-kix_aue93cd1tacp-4 0}.lst-kix_xkot2rd1rwjd-2>li:before{content:"\0025a0 "}.lst-kix_xkot2rd1rwjd-6>li:before{content:"\0025cf "}.lst-kix_f1zwtsa21lze-1>li{counter-increment:lst-ctn-kix_f1zwtsa21lze-1}.lst-kix_a7picbopwap5-0>li:before{content:"\0025cf "}.lst-kix_a7picbopwap5-8>li:before{content:"\0025a0 "}.lst-kix_hisa166i97g-2>li{counter-increment:lst-ctn-kix_hisa166i97g-2}ol.lst-kix_2zj51yim977x-5.start{counter-reset:lst-ctn-kix_2zj51yim977x-5 0}.lst-kix_33m87cusbobo-1>li:before{content:"\0025cb "}.lst-kix_2zj51yim977x-5>li{counter-increment:lst-ctn-kix_2zj51yim977x-5}.lst-kix_5fvsno8h94t-3>li:before{content:"\0025cf "}.lst-kix_ju6nxsiwjdzc-2>li:before{content:"\0025a0 "}.lst-kix_33m87cusbobo-5>li:before{content:"\0025a0 "}ol.lst-kix_ezf2mrk385uq-0.start{counter-reset:lst-ctn-kix_ezf2mrk385uq-0 0}.lst-kix_ezf2mrk385uq-2>li{counter-increment:lst-ctn-kix_ezf2mrk385uq-2}.lst-kix_ju6nxsiwjdzc-6>li:before{content:"\0025cf "}ol.lst-kix_aue93cd1tacp-7.start{counter-reset:lst-ctn-kix_aue93cd1tacp-7 0}ol.lst-kix_2zj51yim977x-8.start{counter-reset:lst-ctn-kix_2zj51yim977x-8 0}.lst-kix_hmo7gyj5poo-7>li:before{content:"" counter(lst-ctn-kix_hmo7gyj5poo-7,lower-latin) ". "}.lst-kix_f1zwtsa21lze-3>li{counter-increment:lst-ctn-kix_f1zwtsa21lze-3}.lst-kix_5fvsno8h94t-7>li:before{content:"\0025cb "}ul.lst-kix_gavezx7jyt0h-8{list-style-type:none}.lst-kix_ha0mdd7f5mn8-4>li{counter-increment:lst-ctn-kix_ha0mdd7f5mn8-4}ul.lst-kix_gavezx7jyt0h-4{list-style-type:none}ul.lst-kix_gavezx7jyt0h-5{list-style-type:none}.lst-kix_ha0mdd7f5mn8-2>li{counter-increment:lst-ctn-kix_ha0mdd7f5mn8-2}ul.lst-kix_gavezx7jyt0h-6{list-style-type:none}ul.lst-kix_gavezx7jyt0h-7{list-style-type:none}ul.lst-kix_gavezx7jyt0h-0{list-style-type:none}ul.lst-kix_gavezx7jyt0h-1{list-style-type:none}ul.lst-kix_gavezx7jyt0h-2{list-style-type:none}ul.lst-kix_gavezx7jyt0h-3{list-style-type:none}ol.lst-kix_f1zwtsa21lze-3.start{counter-reset:lst-ctn-kix_f1zwtsa21lze-3 0}.lst-kix_ha0mdd7f5mn8-6>li:before{content:"" counter(lst-ctn-kix_ha0mdd7f5mn8-6,decimal) ". "}.lst-kix_hmo7gyj5poo-5>li{counter-increment:lst-ctn-kix_hmo7gyj5poo-5}ol.lst-kix_ha0mdd7f5mn8-1.start{counter-reset:lst-ctn-kix_ha0mdd7f5mn8-1 0}ol.lst-kix_hisa166i97g-8.start{counter-reset:lst-ctn-kix_hisa166i97g-8 0}.lst-kix_mqtiiergx266-1>li:before{content:"\0025cb "}.lst-kix_yvc47pi19nhn-7>li:before{content:"\0025cb "}.lst-kix_ct3zb543qdjl-5>li{counter-increment:lst-ctn-kix_ct3zb543qdjl-5}ol.lst-kix_ha0mdd7f5mn8-4.start{counter-reset:lst-ctn-kix_ha0mdd7f5mn8-4 0}.lst-kix_yvc47pi19nhn-3>li:before{content:"\0025cf "}ol.lst-kix_f1zwtsa21lze-0.start{counter-reset:lst-ctn-kix_f1zwtsa21lze-0 0}.lst-kix_u10h5r66zlog-3>li:before{content:"\0025cf "}ol.lst-kix_2zj51yim977x-6.start{counter-reset:lst-ctn-kix_2zj51yim977x-6 0}.lst-kix_gavezx7jyt0h-3>li:before{content:"\0025cf "}.lst-kix_u10h5r66zlog-7>li:before{content:"\0025cb "}.lst-kix_ct3zb543qdjl-7>li:before{content:"" counter(lst-ctn-kix_ct3zb543qdjl-7,lower-latin) ". "}ol.lst-kix_ha0mdd7f5mn8-3.start{counter-reset:lst-ctn-kix_ha0mdd7f5mn8-3 0}ol.lst-kix_f1zwtsa21lze-1.start{counter-reset:lst-ctn-kix_f1zwtsa21lze-1 0}.lst-kix_aue93cd1tacp-4>li{counter-increment:lst-ctn-kix_aue93cd1tacp-4}ol.lst-kix_aue93cd1tacp-5.start{counter-reset:lst-ctn-kix_aue93cd1tacp-5 0}.lst-kix_hisa166i97g-7>li{counter-increment:lst-ctn-kix_hisa166i97g-7}.lst-kix_hmo7gyj5poo-3>li:before{content:"" counter(lst-ctn-kix_hmo7gyj5poo-3,decimal) ". "}.lst-kix_f1zwtsa21lze-5>li:before{content:"" counter(lst-ctn-kix_f1zwtsa21lze-5,lower-roman) ". "}.lst-kix_n1wl50guyz1t-2>li:before{content:"\0025a0 "}.lst-kix_n1wl50guyz1t-6>li:before{content:"\0025cf "}.lst-kix_ct3zb543qdjl-3>li:before{content:"" counter(lst-ctn-kix_ct3zb543qdjl-3,decimal) ". "}.lst-kix_mqtiiergx266-5>li:before{content:"\0025a0 "}ol.lst-kix_2zj51yim977x-1{list-style-type:none}ol.lst-kix_2zj51yim977x-2{list-style-type:none}ol.lst-kix_2zj51yim977x-3{list-style-type:none}.lst-kix_aue93cd1tacp-1>li:before{content:"" counter(lst-ctn-kix_aue93cd1tacp-1,lower-latin) ". "}ol.lst-kix_2zj51yim977x-4{list-style-type:none}ol.lst-kix_2zj51yim977x-5{list-style-type:none}ol.lst-kix_2zj51yim977x-6{list-style-type:none}ol.lst-kix_2zj51yim977x-7{list-style-type:none}.lst-kix_aue93cd1tacp-2>li:before{content:"" counter(lst-ctn-kix_aue93cd1tacp-2,lower-roman) ". "}ol.lst-kix_2zj51yim977x-8{list-style-type:none}.lst-kix_1alpl2noeu5i-1>li:before{content:"\0025cb "}ol.lst-kix_hmo7gyj5poo-5.start{counter-reset:lst-ctn-kix_hmo7gyj5poo-5 0}.lst-kix_aue93cd1tacp-3>li:before{content:"" counter(lst-ctn-kix_aue93cd1tacp-3,decimal) ". "}.lst-kix_aue93cd1tacp-5>li:before{content:"" counter(lst-ctn-kix_aue93cd1tacp-5,lower-roman) ". "}.lst-kix_1alpl2noeu5i-2>li:before{content:"\0025a0 "}.lst-kix_1alpl2noeu5i-3>li:before{content:"\0025cf "}.lst-kix_aue93cd1tacp-4>li:before{content:"" counter(lst-ctn-kix_aue93cd1tacp-4,lower-latin) ". "}ol.lst-kix_2zj51yim977x-0{list-style-type:none}.lst-kix_ha0mdd7f5mn8-8>li{counter-increment:lst-ctn-kix_ha0mdd7f5mn8-8}.lst-kix_ezf2mrk385uq-6>li{counter-increment:lst-ctn-kix_ezf2mrk385uq-6}ul.lst-kix_1alpl2noeu5i-1{list-style-type:none}ul.lst-kix_1alpl2noeu5i-0{list-style-type:none}.lst-kix_f1zwtsa21lze-8>li{counter-increment:lst-ctn-kix_f1zwtsa21lze-8}ol.lst-kix_ha0mdd7f5mn8-2.start{counter-reset:lst-ctn-kix_ha0mdd7f5mn8-2 0}.lst-kix_1alpl2noeu5i-0>li:before{content:"\0025cf "}ol.lst-kix_f1zwtsa21lze-2.start{counter-reset:lst-ctn-kix_f1zwtsa21lze-2 0}ul.lst-kix_u10h5r66zlog-6{list-style-type:none}ul.lst-kix_u10h5r66zlog-7{list-style-type:none}ul.lst-kix_u10h5r66zlog-8{list-style-type:none}.lst-kix_aue93cd1tacp-0>li:before{content:"" counter(lst-ctn-kix_aue93cd1tacp-0,decimal) ". "}ul.lst-kix_u10h5r66zlog-2{list-style-type:none}ul.lst-kix_u10h5r66zlog-3{list-style-type:none}ul.lst-kix_u10h5r66zlog-4{list-style-type:none}ul.lst-kix_u10h5r66zlog-5{list-style-type:none}ul.lst-kix_u10h5r66zlog-0{list-style-type:none}ul.lst-kix_u10h5r66zlog-1{list-style-type:none}ol.lst-kix_aue93cd1tacp-0.start{counter-reset:lst-ctn-kix_aue93cd1tacp-0 0}.lst-kix_1alpl2noeu5i-4>li:before{content:"\0025cb "}.lst-kix_1alpl2noeu5i-5>li:before{content:"\0025a0 "}.lst-kix_aue93cd1tacp-7>li:before{content:"" counter(lst-ctn-kix_aue93cd1tacp-7,lower-latin) ". "}.lst-kix_ct3zb543qdjl-7>li{counter-increment:lst-ctn-kix_ct3zb543qdjl-7}.lst-kix_aue93cd1tacp-6>li:before{content:"" counter(lst-ctn-kix_aue93cd1tacp-6,decimal) ". "}.lst-kix_1alpl2noeu5i-8>li:before{content:"\0025a0 "}.lst-kix_1alpl2noeu5i-6>li:before{content:"\0025cf "}.lst-kix_1alpl2noeu5i-7>li:before{content:"\0025cb "}.lst-kix_aue93cd1tacp-8>li:before{content:"" counter(lst-ctn-kix_aue93cd1tacp-8,lower-roman) ". "}ol.lst-kix_hisa166i97g-0.start{counter-reset:lst-ctn-kix_hisa166i97g-0 0}ol.lst-kix_2zj51yim977x-3.start{counter-reset:lst-ctn-kix_2zj51yim977x-3 0}ol.lst-kix_hisa166i97g-7.start{counter-reset:lst-ctn-kix_hisa166i97g-7 0}.lst-kix_f1zwtsa21lze-4>li{counter-increment:lst-ctn-kix_f1zwtsa21lze-4}ol.lst-kix_ct3zb543qdjl-6.start{counter-reset:lst-ctn-kix_ct3zb543qdjl-6 0}.lst-kix_ct3zb543qdjl-0>li{counter-increment:lst-ctn-kix_ct3zb543qdjl-0}ol.lst-kix_ha0mdd7f5mn8-7.start{counter-reset:lst-ctn-kix_ha0mdd7f5mn8-7 0}.lst-kix_hisa166i97g-8>li:before{content:"" counter(lst-ctn-kix_hisa166i97g-8,lower-roman) ". "}.lst-kix_aue93cd1tacp-6>li{counter-increment:lst-ctn-kix_aue93cd1tacp-6}.lst-kix_ha0mdd7f5mn8-1>li{counter-increment:lst-ctn-kix_ha0mdd7f5mn8-1}.lst-kix_hisa166i97g-1>li:before{content:"" counter(lst-ctn-kix_hisa166i97g-1,lower-latin) ". "}.lst-kix_hisa166i97g-2>li:before{content:"" counter(lst-ctn-kix_hisa166i97g-2,lower-roman) ". "}.lst-kix_hisa166i97g-0>li:before{content:"" counter(lst-ctn-kix_hisa166i97g-0,decimal) ". "}.lst-kix_hisa166i97g-4>li:before{content:"" counter(lst-ctn-kix_hisa166i97g-4,lower-latin) ". "}.lst-kix_hisa166i97g-5>li:before{content:"" counter(lst-ctn-kix_hisa166i97g-5,lower-roman) ". "}ul.lst-kix_ju6nxsiwjdzc-7{list-style-type:none}ul.lst-kix_ju6nxsiwjdzc-6{list-style-type:none}ul.lst-kix_ju6nxsiwjdzc-8{list-style-type:none}.lst-kix_hisa166i97g-7>li:before{content:"" counter(lst-ctn-kix_hisa166i97g-7,lower-latin) ". "}ul.lst-kix_ju6nxsiwjdzc-3{list-style-type:none}ul.lst-kix_ju6nxsiwjdzc-2{list-style-type:none}.lst-kix_hisa166i97g-6>li:before{content:"" counter(lst-ctn-kix_hisa166i97g-6,decimal) ". "}ul.lst-kix_ju6nxsiwjdzc-5{list-style-type:none}ul.lst-kix_ju6nxsiwjdzc-4{list-style-type:none}ol.lst-kix_ha0mdd7f5mn8-8{list-style-type:none}ul.lst-kix_ju6nxsiwjdzc-1{list-style-type:none}ul.lst-kix_ju6nxsiwjdzc-0{list-style-type:none}ol.lst-kix_ha0mdd7f5mn8-0{list-style-type:none}ol.lst-kix_ha0mdd7f5mn8-1{list-style-type:none}ol.lst-kix_ha0mdd7f5mn8-2{list-style-type:none}ol.lst-kix_ha0mdd7f5mn8-3{list-style-type:none}ol.lst-kix_ha0mdd7f5mn8-4{list-style-type:none}ol.lst-kix_ha0mdd7f5mn8-5{list-style-type:none}.lst-kix_hisa166i97g-3>li:before{content:"" counter(lst-ctn-kix_hisa166i97g-3,decimal) ". "}ol.lst-kix_ha0mdd7f5mn8-6{list-style-type:none}ol.lst-kix_ha0mdd7f5mn8-7{list-style-type:none}.lst-kix_2zj51yim977x-1>li{counter-increment:lst-ctn-kix_2zj51yim977x-1}.lst-kix_a7picbopwap5-5>li:before{content:"\0025a0 "}.lst-kix_xkot2rd1rwjd-3>li:before{content:"\0025cf "}.lst-kix_xkot2rd1rwjd-5>li:before{content:"\0025a0 "}ol.lst-kix_hisa166i97g-0{list-style-type:none}.lst-kix_aue93cd1tacp-2>li{counter-increment:lst-ctn-kix_aue93cd1tacp-2}.lst-kix_a7picbopwap5-1>li:before{content:"\0025cb "}.lst-kix_5fvsno8h94t-0>li:before{content:"\0025cf "}ol.lst-kix_hisa166i97g-5.start{counter-reset:lst-ctn-kix_hisa166i97g-5 0}.lst-kix_a7picbopwap5-7>li:before{content:"\0025cb "}.lst-kix_5fvsno8h94t-2>li:before{content:"\0025a0 "}.lst-kix_5fvsno8h94t-4>li:before{content:"\0025cb "}ol.lst-kix_hisa166i97g-2.start{counter-reset:lst-ctn-kix_hisa166i97g-2 0}ol.lst-kix_ct3zb543qdjl-4.start{counter-reset:lst-ctn-kix_ct3zb543qdjl-4 0}ul.lst-kix_a7picbopwap5-1{list-style-type:none}ol.lst-kix_hisa166i97g-4{list-style-type:none}ul.lst-kix_a7picbopwap5-2{list-style-type:none}ol.lst-kix_hisa166i97g-3{list-style-type:none}ol.lst-kix_ct3zb543qdjl-1.start{counter-reset:lst-ctn-kix_ct3zb543qdjl-1 0}ol.lst-kix_hisa166i97g-2{list-style-type:none}.lst-kix_ct3zb543qdjl-3>li{counter-increment:lst-ctn-kix_ct3zb543qdjl-3}.lst-kix_xkot2rd1rwjd-1>li:before{content:"\0025cb "}ul.lst-kix_a7picbopwap5-0{list-style-type:none}ol.lst-kix_hisa166i97g-1{list-style-type:none}.lst-kix_a7picbopwap5-3>li:before{content:"\0025cf "}ol.lst-kix_hisa166i97g-8{list-style-type:none}ol.lst-kix_hisa166i97g-7{list-style-type:none}ol.lst-kix_hisa166i97g-6{list-style-type:none}ol.lst-kix_hisa166i97g-5{list-style-type:none}ul.lst-kix_a7picbopwap5-7{list-style-type:none}ul.lst-kix_a7picbopwap5-8{list-style-type:none}ol.lst-kix_ezf2mrk385uq-3.start{counter-reset:lst-ctn-kix_ezf2mrk385uq-3 0}ul.lst-kix_a7picbopwap5-5{list-style-type:none}ul.lst-kix_a7picbopwap5-6{list-style-type:none}.lst-kix_f1zwtsa21lze-0>li{counter-increment:lst-ctn-kix_f1zwtsa21lze-0}ul.lst-kix_a7picbopwap5-3{list-style-type:none}ul.lst-kix_a7picbopwap5-4{list-style-type:none}.lst-kix_5fvsno8h94t-6>li:before{content:"\0025cf "}.lst-kix_5fvsno8h94t-8>li:before{content:"\0025a0 "}ol.lst-kix_hmo7gyj5poo-3.start{counter-reset:lst-ctn-kix_hmo7gyj5poo-3 0}.lst-kix_hisa166i97g-5>li{counter-increment:lst-ctn-kix_hisa166i97g-5}.lst-kix_hmo7gyj5poo-8>li{counter-increment:lst-ctn-kix_hmo7gyj5poo-8}.lst-kix_xkot2rd1rwjd-7>li:before{content:"\0025cb "}ol.lst-kix_hmo7gyj5poo-0.start{counter-reset:lst-ctn-kix_hmo7gyj5poo-0 0}ol.lst-kix_f1zwtsa21lze-7.start{counter-reset:lst-ctn-kix_f1zwtsa21lze-7 0}.lst-kix_2zj51yim977x-8>li{counter-increment:lst-ctn-kix_2zj51yim977x-8}.lst-kix_ha0mdd7f5mn8-0>li{counter-increment:lst-ctn-kix_ha0mdd7f5mn8-0}.lst-kix_f1zwtsa21lze-5>li{counter-increment:lst-ctn-kix_f1zwtsa21lze-5}ol.lst-kix_2zj51yim977x-0.start{counter-reset:lst-ctn-kix_2zj51yim977x-0 0}.lst-kix_hmo7gyj5poo-1>li{counter-increment:lst-ctn-kix_hmo7gyj5poo-1}ol.lst-kix_ezf2mrk385uq-5.start{counter-reset:lst-ctn-kix_ezf2mrk385uq-5 0}.lst-kix_ct3zb543qdjl-6>li:before{content:"" counter(lst-ctn-kix_ct3zb543qdjl-6,decimal) ". "}ul.lst-kix_1alpl2noeu5i-5{list-style-type:none}ul.lst-kix_1alpl2noeu5i-4{list-style-type:none}ul.lst-kix_1alpl2noeu5i-3{list-style-type:none}.lst-kix_aue93cd1tacp-7>li{counter-increment:lst-ctn-kix_aue93cd1tacp-7}ul.lst-kix_1alpl2noeu5i-2{list-style-type:none}ul.lst-kix_1alpl2noeu5i-8{list-style-type:none}.lst-kix_n1wl50guyz1t-7>li:before{content:"\0025cb "}.lst-kix_ct3zb543qdjl-0>li:before{content:"" counter(lst-ctn-kix_ct3zb543qdjl-0,decimal) ". "}.lst-kix_ct3zb543qdjl-8>li:before{content:"" counter(lst-ctn-kix_ct3zb543qdjl-8,lower-roman) ". "}ul.lst-kix_1alpl2noeu5i-7{list-style-type:none}ul.lst-kix_1alpl2noeu5i-6{list-style-type:none}.lst-kix_n1wl50guyz1t-1>li:before{content:"\0025cb "}.lst-kix_n1wl50guyz1t-5>li:before{content:"\0025a0 "}.lst-kix_ct3zb543qdjl-2>li:before{content:"" counter(lst-ctn-kix_ct3zb543qdjl-2,lower-roman) ". "}.lst-kix_n1wl50guyz1t-3>li:before{content:"\0025cf "}.lst-kix_ct3zb543qdjl-4>li:before{content:"" counter(lst-ctn-kix_ct3zb543qdjl-4,lower-latin) ". "}.lst-kix_ezf2mrk385uq-6>li:before{content:"" counter(lst-ctn-kix_ezf2mrk385uq-6,decimal) ". "}.lst-kix_f1zwtsa21lze-7>li{counter-increment:lst-ctn-kix_f1zwtsa21lze-7}.lst-kix_ezf2mrk385uq-2>li:before{content:"" counter(lst-ctn-kix_ezf2mrk385uq-2,lower-roman) ". "}.lst-kix_f1zwtsa21lze-3>li:before{content:"" counter(lst-ctn-kix_f1zwtsa21lze-3,decimal) ". "}.lst-kix_f1zwtsa21lze-4>li:before{content:"" counter(lst-ctn-kix_f1zwtsa21lze-4,lower-latin) ". "}.lst-kix_ezf2mrk385uq-3>li:before{content:"" counter(lst-ctn-kix_ezf2mrk385uq-3,decimal) ". "}ol.lst-kix_ezf2mrk385uq-7.start{counter-reset:lst-ctn-kix_ezf2mrk385uq-7 0}.lst-kix_f1zwtsa21lze-0>li:before{content:"" counter(lst-ctn-kix_f1zwtsa21lze-0,decimal) ". "}ol.lst-kix_hmo7gyj5poo-2.start{counter-reset:lst-ctn-kix_hmo7gyj5poo-2 0}.lst-kix_gavezx7jyt0h-8>li:before{content:"\0025a0 "}.lst-kix_ezf2mrk385uq-5>li{counter-increment:lst-ctn-kix_ezf2mrk385uq-5}ol.lst-kix_ct3zb543qdjl-2.start{counter-reset:lst-ctn-kix_ct3zb543qdjl-2 0}.lst-kix_hisa166i97g-8>li{counter-increment:lst-ctn-kix_hisa166i97g-8}.lst-kix_hmo7gyj5poo-2>li{counter-increment:lst-ctn-kix_hmo7gyj5poo-2}.lst-kix_ezf2mrk385uq-7>li:before{content:"" counter(lst-ctn-kix_ezf2mrk385uq-7,lower-latin) ". "}ol.lst-kix_hmo7gyj5poo-6{list-style-type:none}ul.lst-kix_yvc47pi19nhn-0{list-style-type:none}ol.lst-kix_hmo7gyj5poo-5{list-style-type:none}ul.lst-kix_yvc47pi19nhn-1{list-style-type:none}ol.lst-kix_hmo7gyj5poo-8{list-style-type:none}ul.lst-kix_yvc47pi19nhn-2{list-style-type:none}ol.lst-kix_hmo7gyj5poo-7{list-style-type:none}ul.lst-kix_yvc47pi19nhn-3{list-style-type:none}ul.lst-kix_yvc47pi19nhn-4{list-style-type:none}ul.lst-kix_yvc47pi19nhn-5{list-style-type:none}ul.lst-kix_yvc47pi19nhn-6{list-style-type:none}ol.lst-kix_hmo7gyj5poo-0{list-style-type:none}ol.lst-kix_hmo7gyj5poo-2{list-style-type:none}ol.lst-kix_hmo7gyj5poo-1{list-style-type:none}ol.lst-kix_hmo7gyj5poo-4{list-style-type:none}ol.lst-kix_hmo7gyj5poo-3{list-style-type:none}.lst-kix_ha0mdd7f5mn8-5>li{counter-increment:lst-ctn-kix_ha0mdd7f5mn8-5}.lst-kix_hisa166i97g-6>li{counter-increment:lst-ctn-kix_hisa166i97g-6}ul.lst-kix_yvc47pi19nhn-7{list-style-type:none}ul.lst-kix_yvc47pi19nhn-8{list-style-type:none}.lst-kix_aue93cd1tacp-0>li{counter-increment:lst-ctn-kix_aue93cd1tacp-0}.lst-kix_ct3zb543qdjl-6>li{counter-increment:lst-ctn-kix_ct3zb543qdjl-6}ol.lst-kix_ezf2mrk385uq-8.start{counter-reset:lst-ctn-kix_ezf2mrk385uq-8 0}.lst-kix_2zj51yim977x-2>li:before{content:"" counter(lst-ctn-kix_2zj51yim977x-2,lower-roman) ". "}.lst-kix_2zj51yim977x-3>li:before{content:"" counter(lst-ctn-kix_2zj51yim977x-3,decimal) ". "}.lst-kix_2zj51yim977x-4>li{counter-increment:lst-ctn-kix_2zj51yim977x-4}.lst-kix_2zj51yim977x-6>li:before{content:"" counter(lst-ctn-kix_2zj51yim977x-6,decimal) ". "}.lst-kix_2zj51yim977x-7>li:before{content:"" counter(lst-ctn-kix_2zj51yim977x-7,lower-latin) ". "}.lst-kix_ezf2mrk385uq-1>li{counter-increment:lst-ctn-kix_ezf2mrk385uq-1}.lst-kix_ha0mdd7f5mn8-0>li:before{content:"" counter(lst-ctn-kix_ha0mdd7f5mn8-0,decimal) ") "}ul.lst-kix_xkot2rd1rwjd-0{list-style-type:none}.lst-kix_a7picbopwap5-6>li:before{content:"\0025cf "}ul.lst-kix_xkot2rd1rwjd-2{list-style-type:none}ul.lst-kix_xkot2rd1rwjd-1{list-style-type:none}ul.lst-kix_xkot2rd1rwjd-4{list-style-type:none}ul.lst-kix_xkot2rd1rwjd-3{list-style-type:none}ul.lst-kix_xkot2rd1rwjd-6{list-style-type:none}ul.lst-kix_xkot2rd1rwjd-5{list-style-type:none}ul.lst-kix_xkot2rd1rwjd-8{list-style-type:none}ul.lst-kix_xkot2rd1rwjd-7{list-style-type:none}.lst-kix_xkot2rd1rwjd-4>li:before{content:"\0025cb "}.lst-kix_f1zwtsa21lze-2>li{counter-increment:lst-ctn-kix_f1zwtsa21lze-2}.lst-kix_aue93cd1tacp-3>li{counter-increment:lst-ctn-kix_aue93cd1tacp-3}.lst-kix_33m87cusbobo-3>li:before{content:"\0025cf "}.lst-kix_5fvsno8h94t-1>li:before{content:"\0025cb "}.lst-kix_5fvsno8h94t-5>li:before{content:"\0025a0 "}.lst-kix_ju6nxsiwjdzc-4>li:before{content:"\0025cb "}.lst-kix_hmo7gyj5poo-5>li:before{content:"" counter(lst-ctn-kix_hmo7gyj5poo-5,lower-roman) ". "}.lst-kix_a7picbopwap5-2>li:before{content:"\0025a0 "}.lst-kix_2zj51yim977x-6>li{counter-increment:lst-ctn-kix_2zj51yim977x-6}.lst-kix_33m87cusbobo-7>li:before{content:"\0025cb "}.lst-kix_xkot2rd1rwjd-0>li:before{content:"\0025cf "}ol.lst-kix_hmo7gyj5poo-6.start{counter-reset:lst-ctn-kix_hmo7gyj5poo-6 0}.lst-kix_ju6nxsiwjdzc-8>li:before{content:"\0025a0 "}.lst-kix_ha0mdd7f5mn8-8>li:before{content:"" counter(lst-ctn-kix_ha0mdd7f5mn8-8,lower-roman) ". "}.lst-kix_ct3zb543qdjl-4>li{counter-increment:lst-ctn-kix_ct3zb543qdjl-4}.lst-kix_ha0mdd7f5mn8-4>li:before{content:"(" counter(lst-ctn-kix_ha0mdd7f5mn8-4,lower-latin) ") "}.lst-kix_aue93cd1tacp-5>li{counter-increment:lst-ctn-kix_aue93cd1tacp-5}.lst-kix_xkot2rd1rwjd-8>li:before{content:"\0025a0 "}.lst-kix_yvc47pi19nhn-5>li:before{content:"\0025a0 "}.lst-kix_n1wl50guyz1t-0>li:before{content:"\0025cf "}.lst-kix_yvc47pi19nhn-1>li:before{content:"\0025cb "}.lst-kix_mqtiiergx266-3>li:before{content:"\0025cf "}ul.lst-kix_n1wl50guyz1t-1{list-style-type:none}ul.lst-kix_n1wl50guyz1t-0{list-style-type:none}ul.lst-kix_n1wl50guyz1t-3{list-style-type:none}ul.lst-kix_n1wl50guyz1t-2{list-style-type:none}.lst-kix_ezf2mrk385uq-3>li{counter-increment:lst-ctn-kix_ezf2mrk385uq-3}.lst-kix_u10h5r66zlog-5>li:before{content:"\0025a0 "}ul.lst-kix_n1wl50guyz1t-8{list-style-type:none}ul.lst-kix_n1wl50guyz1t-5{list-style-type:none}ul.lst-kix_n1wl50guyz1t-4{list-style-type:none}ol.lst-kix_hmo7gyj5poo-7.start{counter-reset:lst-ctn-kix_hmo7gyj5poo-7 0}ul.lst-kix_n1wl50guyz1t-7{list-style-type:none}.lst-kix_gavezx7jyt0h-5>li:before{content:"\0025a0 "}ul.lst-kix_n1wl50guyz1t-6{list-style-type:none}ul.lst-kix_5fvsno8h94t-4{list-style-type:none}ul.lst-kix_5fvsno8h94t-3{list-style-type:none}ul.lst-kix_5fvsno8h94t-6{list-style-type:none}ul.lst-kix_5fvsno8h94t-5{list-style-type:none}ul.lst-kix_5fvsno8h94t-0{list-style-type:none}.lst-kix_ct3zb543qdjl-5>li:before{content:"" counter(lst-ctn-kix_ct3zb543qdjl-5,lower-roman) ". "}ul.lst-kix_5fvsno8h94t-2{list-style-type:none}.lst-kix_hmo7gyj5poo-1>li:before{content:"" counter(lst-ctn-kix_hmo7gyj5poo-1,lower-latin) ". "}ul.lst-kix_5fvsno8h94t-1{list-style-type:none}.lst-kix_hisa166i97g-1>li{counter-increment:lst-ctn-kix_hisa166i97g-1}.lst-kix_n1wl50guyz1t-8>li:before{content:"\0025a0 "}ul.lst-kix_5fvsno8h94t-8{list-style-type:none}ul.lst-kix_5fvsno8h94t-7{list-style-type:none}.lst-kix_hmo7gyj5poo-4>li{counter-increment:lst-ctn-kix_hmo7gyj5poo-4}li.li-bullet-0:before{margin-left:-18pt;white-space:nowrap;display:inline-block;min-width:18pt}.lst-kix_gavezx7jyt0h-1>li:before{content:"\0025cb "}.lst-kix_n1wl50guyz1t-4>li:before{content:"\0025cb "}.lst-kix_f1zwtsa21lze-7>li:before{content:"" counter(lst-ctn-kix_f1zwtsa21lze-7,lower-latin) ". "}.lst-kix_ct3zb543qdjl-1>li:before{content:"" counter(lst-ctn-kix_ct3zb543qdjl-1,lower-latin) ". "}.lst-kix_u10h5r66zlog-1>li:before{content:"\0025cb "}ol.lst-kix_hmo7gyj5poo-8.start{counter-reset:lst-ctn-kix_hmo7gyj5poo-8 0}.lst-kix_mqtiiergx266-7>li:before{content:"\0025cb "}.lst-kix_ha0mdd7f5mn8-3>li{counter-increment:lst-ctn-kix_ha0mdd7f5mn8-3}ol{margin:0;padding:0}table td,table th{padding:0}.c9{background-color:#ffffff;padding-top:0pt;padding-bottom:0pt;line-height:1.38;orphans:2;widows:2;text-align:left}.c2{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:normal}.c0{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:Consolas,"Courier New";font-style:normal}.c3{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:8pt;font-family:Consolas,"Courier New";font-style:normal}.c5{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:20pt;font-family:"Arial";font-style:normal}.c13{padding-top:20pt;padding-bottom:6pt;line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}.c14{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:16pt;font-family:"Arial";font-style:normal}.c17{padding-top:18pt;padding-bottom:6pt;line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}.c26{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial"}.c1{padding-top:0pt;padding-bottom:0pt;line-height:1.5;orphans:2;widows:2;text-align:left}.c21{color:#000000;text-decoration:none;vertical-align:baseline;font-size:12pt;font-style:normal}.c8{padding-top:0pt;padding-bottom:0pt;line-height:1.0;text-align:left}.c7{text-decoration-skip-ink:none;-webkit-text-decoration-skip:none;color:#1155cc;text-decoration:underline}.c19{text-decoration:none;vertical-align:baseline;font-size:11pt;font-style:normal}.c29{color:#000000;font-weight:700;font-family:Consolas,"Courier New"}.c27{text-decoration:none;vertical-align:baseline;font-style:normal}.c28{border:1px solid black;margin:5px}.c10{background-color:#efefef;font-size:10pt}.c30{max-width:468pt;padding:72pt 72pt 72pt 72pt}.c16{color:inherit;text-decoration:inherit}.c22{font-size:12pt;color:#999999}.c11{margin-left:36pt;padding-left:0pt}.c15{padding:0;margin:0}.c6{font-weight:400;font-family:Consolas,"Courier New"}.c31{color:#000000}.c4{height:11pt}.c23{background-color:#efefef}.c12{color:#666666}.c18{background-color:#ffffff}.c20{font-size:10pt}.c24{font-size:12pt}.c25{font-style:italic}.title{padding-top:0pt;color:#000000;font-size:26pt;padding-bottom:3pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}.subtitle{padding-top:0pt;color:#666666;font-size:15pt;padding-bottom:16pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}li{color:#000000;font-size:11pt;font-family:"Arial"}p{margin:0;color:#000000;font-size:11pt;font-family:"Arial"}h1{padding-top:20pt;color:#000000;font-size:20pt;padding-bottom:6pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}h2{padding-top:18pt;color:#000000;font-size:16pt;padding-bottom:6pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}h3{padding-top:16pt;color:#434343;font-size:14pt;padding-bottom:4pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}h4{padding-top:14pt;color:#666666;font-size:12pt;padding-bottom:4pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}h5{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;orphans:2;widows:2;text-align:left}h6{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.5;page-break-after:avoid;font-style:italic;orphans:2;widows:2;text-align:left}</style></head><body class="c18 c30"> <p class="c1"><span class="c2">Posted By Samuel Groß, Project Zero</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>On December 20, Citizenlab published “</span><span class="c7"><a class="c161" href="https://citizenlab.ca/2020/12/the-great-ipwn-journalists-hacked-with-suspected-nso-group-imessage-zero-click-exploit/">The Great iPwn</a></span><span>”, detailing how </span><span>“Journalists [were] Hacked with Suspected NSO Group iMessage ‘Zero-Click’ Exploit”</span><span>. Of particular interest is the following note: “We do not believe that [the exploit] works against iOS 14 and above, which includes new security protections''. Given that it is also now almost exactly one year ago since we published the </span><span class="c7"><a class="c161" href="https://googleprojectzero.blogspot.com/2020/01/remote-iphone-exploitation-part-1.html">Remote iPhone Exploitation</a></span><span> blog post series</span><span class="c2">, in which we described how an iMessage 0-click exploit can work in practice and gave a number of suggestions on how similar attacks could be prevented in the future, now seemed like a great time to dig into the security improvements in iOS 14 in more detail and explore how Apple has hardened their platform against 0-click attacks.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">The content of this blog post is the result of a roughly one-week reverse engineering project, mostly performed on a M1 Mac Mini running macOS 11.1, with the results, where possible, verified to also apply to iOS 14.3, running on an iPhone XS. Due to the nature of this project and the limited timeframe, it is possible that I have missed some relevant changes or made mistakes interpreting some results. Where possible, I’ve tried to describe the steps necessary to verify the presented results, and would appreciate any corrections or additions.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">The blog post will start with an overview of the major changes Apple implemented in iOS 14 which affect the security of iMessage. Afterwards, and mostly for the readers interested in the technical details, each of the major improvements is described in more detail while also providing a walkthrough of how it was reverse engineered. At least for the technical details, it is recommended to briefly review the blog post series from last year for a basic introduction to iMessage and the exploitation techniques used to attack it.</span></p><h1 class="c13" id="h.2ep7vgcii9xa"><span class="c5">Overview</span></h1> <p class="c1"><span class="c2">Memory corruption based 0-click exploits typically require at least the following pieces:</span></p><ol class="c15 lst-kix_2zj51yim977x-0 start" start="1"><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">A memory corruption vulnerability, reachable without user interaction and ideally without triggering any user notifications</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>A way to break </span><span class="c2">ASLR remotely</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">A way to turn the vulnerability into remote code execution</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>(</span><span>Likely</span><span class="c2">) A way to break out of any sandbox, typically by exploiting a separate vulnerability in another operating system component (e.g. a userspace service or the kernel)</span></li></ol> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">With iOS 14, Apple shipped a significant refactoring of iMessage processing, and made all four parts of the attack harder. This is mainly due to three central changes:</span></p><h2 class="c17" id="h.xlynwox5rkc7"><span class="c14">1. The BlastDoor Service</span></h2> <p class="c1"><span>One of the major changes in iOS 14 is the introduction of a new, tightly sandboxed “BlastDoor” service which is now responsible for almost all parsing of untrusted data in iMessages (for example, </span><span class="c7"><a class="c161" href="https://bugs.chromium.org/p/project-zero/issues/detail?id=1858">NSKeyedArchiver payloads</a></span><span>). Furthermore, this service is written in </span><span class="c7"><a class="c161" href="https://developer.apple.com/swift/">Swift</a></span><span>,</span><span class="c2"> a (mostly) memory safe language which makes it significantly harder to introduce classic memory corruption vulnerabilities into the code base.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">The following diagram shows the rough new iMessage processing pipeline, with the name of the respective service process shown at the top of each box.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"></p> <p class="c1"><span class="c25 c26"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWbfjpXKVDVZfZasnzWXN02AH5-A4Nw1229VrO2_FG1otEQSw_r0uRNkB8TedmfA-__gncfPoZ_aa5YE1Ac1_8kzmqKi2Iyj4l47OgN7o9K6Ue8JtRN42XdwHZyBJCg1U26pscYx2ObqwWrouGS9uoZizPZmxvpYwX3PDLanDgdDcOuicfmRwIbRMi/s623/image1%282%29.png" style="display: block; padding: 1em 0;text-align: center;"><img alt="The iMessage processing pipeline in iOS 14 and macOS Big Sur. An iMessage arrives in apsd as a push notification from Apple’s servers. From there, it is first passed to identityservicesd, which decrypts its payload using the local iMessage private key, then to imagent. Imagent then delegates the majority of the parsing work to the BlastDoor service. Afterwards, if the iMessage contains any attachments, they are downloaded from iCloud servers by IMTransferAgent. If the iMessage contains plugin data (such as a URL with a preview image), the serialized plugin data is again processed by the BlastDoor service and a preview message is generated from it. Finally, IMDPersistenceAgent stores the iMessage into the messages database, triggers a user notification, and returns to imagent, which sends the delivery receipt to the iMessage servers and thus to the sender." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWbfjpXKVDVZfZasnzWXN02AH5-A4Nw1229VrO2_FG1otEQSw_r0uRNkB8TedmfA-__gncfPoZ_aa5YE1Ac1_8kzmqKi2Iyj4l47OgN7o9K6Ue8JtRN42XdwHZyBJCg1U26pscYx2ObqwWrouGS9uoZizPZmxvpYwX3PDLanDgdDcOuicfmRwIbRMi/s623/image1%282%29.png" style="max-height: 750; max-width: 600px;" /></a></span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>As can be seen, the majority of the processing of complex, untrusted data has been moved into the new BlastDoor service. Furthermore, this design with its 7+ involved services allows fine-grained sandboxing rules to be applied, for example, only the </span><span class="c6">IMTransferAgent</span><span> and </span><span class="c6">apsd</span><span> processes are required to perform network operations. As such, all services in this pipeline are now properly sandboxed (with the BlastDoor service arguably being sandboxed the strongest).</span></p><h2 class="c17" id="h.i6ctyzs304y5"><span class="c14">2. Re-randomization of the Dyld Shared Cache Region</span></h2> <p class="c1"><span>Historically, ASLR on Apple’s platforms had one architectural weakness: the </span><span class="c7"><a class="c161" href="https://iphonedevwiki.net/index.php/Dyld_shared_cache">shared cache region</a></span><span>, containing most of the system libraries in a single prelinked blob, was only randomized per boot, and so would stay at the same address across all processes. This turned out to be especially critical in the context of 0-click attacks, as </span><span class="c7"><a class="c161" href="https://googleprojectzero.blogspot.com/2020/01/remote-iphone-exploitation-part-2.html">it allowed an attacker, able to remotely observe process crashes (e.g. through timing of automatic delivery receipts), to infer the base address of the shared cache</a></span><span class="c2"> and as such break ASLR, a prerequisite for subsequent exploitation steps. </span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>However, with iOS 14, Apple has added logic to </span><span class="c25">specifically</span><span class="c2"> detect this kind of attack, in which case the shared cache is re-randomized for the targeted service the next time it is started, thus rendering this technique useless. This should make bypassing ASLR in a 0-click attack context significantly harder or even impossible (apart from brute force) depending on the concrete vulnerability.</span></p><h2 class="c17" id="h.jbwmwscsj1ir"><span class="c14">3. Exponential Throttling to Slow Down Brute Force Attacks</span></h2> <p class="c1"><span>To limit an attacker’s ability to retry exploits or brute force ASLR, the BlastDoor and imagent services are now subject to a newly introduced </span><span>exponential throttling mechanism enforced by </span><span class="c6">launchd</span><span class="c2">, causing the interval between restarts after a crash to double with every subsequent crash (up to an apparent maximum of 20 minutes). With this change, an exploit that relied on repeatedly crashing the attacked service would now likely require in the order of multiple hours to roughly half a day to complete instead of a few minutes.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">The remainder of this blog post will now look at each of these three changes in greater depths.</span></p> <p class="c1 c4"><span class="c2"></span></p><h1 class="c13" id="h.wft5qr5guboi"><span class="c5">The BlastDoor Service</span></h1> <p class="c1"><span>The new BlastDoor service and its role in the processing of iMessages can be studied by following the flow of an incoming iMessage. On the wire, a simple text iMessage would look something like this, encoded as binary </span><span class="c7"><a class="c161" href="https://en.wikipedia.org/wiki/Property_list">plist</a></span><span class="c2">:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c9"><span class="c21 c6">{</span></p> <p class="c9"><span class="c6 c24"> </span><span class="c22 c6 c27">// Group UUID</span></p> <p class="c9"><span class="c21 c6"> gid = "008412B9-A4F7-4B96-96C3-70C4276CB2BE";</span></p> <p class="c9"><span class="c6 c24"> </span><span class="c27 c22 c6">// Group protocol version</span></p> <p class="c9"><span class="c21 c6"> gv = 8;</span></p> <p class="c9"><span class="c6 c24"> </span><span class="c27 c22 c6">// Chat participants</span></p> <p class="c9"><span class="c21 c6"> p = (</span></p> <p class="c9"><span class="c21 c6"> "mailto:sender@foo.bar",</span></p> <p class="c9"><span class="c21 c6"> "mailto:receiver@foo.bar"</span></p> <p class="c9"><span class="c21 c6"> );</span></p> <p class="c9"><span class="c6 c24"> </span><span class="c27 c22 c6">// Participants version</span></p> <p class="c9"><span class="c21 c6"> pv = 0;</span></p> <p class="c9"><span class="c6 c24"> </span><span class="c22 c6">// Message being replied to, usually the last message in the chat</span><span class="c21 c6"> </span></p> <p class="c9"><span class="c21 c6"> r = "6401430E-CDD3-4BC7-A377-7611706B431F";</span></p> <p class="c9"><span class="c6 c24"> </span><span class="c27 c22 c6">// The plain text content</span></p> <p class="c9"><span class="c21 c6"> t = "Hello World!";</span></p> <p class="c9"><span class="c6 c24"> </span><span class="c27 c22 c6">// Probably some other version number</span></p> <p class="c9"><span class="c6 c21"> v = 1;</span></p> <p class="c9"><span class="c6 c24"> </span><span class="c6 c22">// The rich text content </span><span class="c21 c6"> </span></p> <p class="c9"><span class="c21 c6"> x = "<html><body>Hello World!</body></html>"; </span></p> <p class="c9"><span class="c6 c24">}</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">As such, the minimal steps required to parse it are:</span></p> <p class="c1 c4"><span class="c2"></span></p><ol class="c15 lst-kix_hisa166i97g-0 start" start="1"><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">If necessary, decompress the binary data</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">Decode the plist from its binary serialization format</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">Extract its various fields and ensure they have the correct type</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>Decode the `</span><span class="c6">x</span><span class="c2">` key if present, using an XML decoder</span></li></ol> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>Previously, all of this work happened in imagent. With iOS 14, however, it all moved into the new BlastDoor service. While the main processing flow still starts in </span><span class="c6">imagent</span><span>, which receives the raw but unencrypted payload bytes from </span><span class="c6">identityservicesd</span><span> (part of the IDS framework) in </span><span class="c10 c6">-[IMDiMessageIDSDelegate service:account:incomingTopLevelMessage:fromID:messageContext:]</span><span>, messages </span><span>are then more or less immediately forwarded to the BlastDoor service through </span><span class="c10 c6">+[IMBlastdoor sendDictionary:withCompletionBlock:]</span><span class="c20"> </span><span>which creates the reply handler block and then calls </span><span class="c10 c6">-[IMMessagesBlastDoorInterface diffuseTopLevelDictionary:resultHandler:]</span><span class="c2">. At that point processing ends up in Swift code that deserializes the binary payload and sends it to the BlastDoor service over XPC.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">Inside BlastDoor, the work mostly happens in BlastDoor.framework and MessagesBlastDoorService. As most of it is written in Swift, it is fairly unpleasant to statically reverse engineer it (no symbols, many virtual calls, swift runtime code sprinkled all over the place), but fortunately, that is also not really necessary for the purpose of this blog post. However, it is worth noting that while the high level control flow logic is written in Swift, some of the parsing steps still involve the existing ObjectiveC or C implementations. For example, XML is being parsed by libxml, and the NSKeyedArchiver payloads by the ObjectiveC implementation of NSKeyedUnarchiver.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>The responses from BlastDoor can be seen by breaking on the reply handler function in imagent (the function can be found in </span><span class="c6 c23">+[IMBlastdoor sendDictionary:withCompletionBlock:]</span><span> or </span><span>by searching for XREFs to the string “</span><span class="c6">Blastdoor response %p received (command: %hhu, guid: %@)</span><span class="c2">” in IMDaemonCore.framework). A typical BlastDoor response for a simple text message is shown below:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">(lldb) po $x2</span></p> <p class="c1"><span class="c0">TextMessage(</span></p> <p class="c1"><span class="c0"> metadata: BlastDoor.Metadata(</span></p> <p class="c1"><span class="c0"> messageGUID: D391CC96-9CC6-44C6-B827-1DEB0F252529,</span></p> <p class="c1"><span class="c0"> timestamp: Optional(1610108299117662350),</span></p> <p class="c1"><span class="c0"> wantsDeliveryReceipt: true,</span></p> <p class="c1"><span class="c0"> wantsCheckpointing: false,</span></p> <p class="c1"><span class="c0"> storageContext: BlastDoor.Metadata.StorageContext(</span></p> <p class="c1"><span class="c0"> isFromStorage: false, isLastFromStorage: false</span></p> <p class="c1"><span class="c0"> )</span></p> <p class="c1"><span class="c0"> ),</span></p> <p class="c1"><span class="c0"> messageSubType: MessageType.textMessage(BlastDoor.Message(</span></p> <p class="c1"><span class="c0"> plainTextBody: Optional("Hello World"),</span></p> <p class="c1"><span class="c0"> plainTextSubject: nil,</span></p> <p class="c1"><span class="c0"> content: Optional(BlastDoor.AttributedString(</span></p> <p class="c1"><span class="c0"> attributes: [</span></p> <p class="c1"><span class="c0"> BlastDoor.BaseWritingDirectionAttribute(</span></p> <p class="c1"><span class="c0"> range: Range(0..<11), direction: WritingDirection.natural</span></p> <p class="c1"><span class="c0"> ), </span></p> <p class="c1"><span class="c0"> BlastDoor.MessagePartAttribute(</span></p> <p class="c1"><span class="c0"> range: Range(0..<11), partNumber: 0</span></p> <p class="c1"><span class="c0"> )</span></p> <p class="c1"><span class="c0"> ], </span></p> <p class="c1"><span class="c0"> string: "Hello World"</span></p> <p class="c1"><span class="c0"> )),</span></p> <p class="c1"><span class="c0"> _participantDestinationIdentifiers: [</span></p> <p class="c1"><span class="c0"> "mailto:sender@foo.bar",</span></p> <p class="c1"><span class="c0"> "mailto:receiver@foo.bar"</span></p> <p class="c1"><span class="c0"> ], </span></p> <p class="c1"><span class="c0"> attributionInfo: []</span></p> <p class="c1"><span class="c0"> )),</span></p> <p class="c1"><span class="c0"> encryptionType: BlastDoor.TextMessage.EncryptionType.pair_ec, </span></p> <p class="c1"><span class="c0"> replyToGUID: Optional(6401430E-CDD3-4BC7-A377-7611706B431F), </span></p> <p class="c1"><span class="c0"> _threadIdentifierGUID: nil, </span></p> <p class="c1"><span class="c0"> _expressiveSendStyleIdentifier: nil, </span></p> <p class="c1"><span class="c0"> _groupID: Optional("008412B9-A4F7-4B96-96C3-70C4276CB2BE"), </span></p> <p class="c1"><span class="c0"> currentGroupName: nil, </span></p> <p class="c1"><span class="c0"> groupParticipantVersion: Optional(0),</span></p> <p class="c1"><span class="c0"> groupProtocolVersion: Optional(8),</span></p> <p class="c1"><span class="c0"> groupPhotoCreationTime: nil, </span></p> <p class="c1"><span class="c0"> messageSummaryInfo: nil, </span></p> <p class="c1"><span class="c0"> nicknameInformation: nil, </span></p> <p class="c1"><span class="c0"> truncatedNicknameRecordKey: nil</span></p> <p class="c1"><span class="c0">)</span></p> <p class="c1 c4"><span class="c0"></span></p> <p class="c1"><span>One can roughly associate every field in this data structure with parts of the on-wire iMessage format. For example, the </span><span class="c6">plainTextBody</span><span> field contains the content of the `t` field, while the </span><span class="c6">content</span><span class="c2"> field corresponds to the content of the `x` field.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>Besides simple text messages, iMessages can additionally contain attachments (essentially arbitrary files which are encrypted and temporarily uploaded to iCloud) as well as rather complex serialized </span><span class="c7"><a class="c161" href="https://developer.apple.com/documentation/foundation/nskeyedarchiver">NSKeyedArchiver</a></span><span> archives, which </span><span class="c7"><a class="c161" href="https://googleprojectzero.blogspot.com/2019/08/the-fully-remote-attack-surface-of.html">have been the source of bugs in the past</a></span><span class="c2">.</span></p> <p class="c1"><span class="c2">For these types of iMessages, the following additional parsing steps are necessary:</span></p> <p class="c1 c4"><span class="c2"></span></p><ol class="c15 lst-kix_ezf2mrk385uq-0 start" start="1"><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">Unpack attachment metadata (NSKeyedArchiver format)</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">Download attachments from iCloud server</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">Deserialize NSKeyedArchiver plugin archives and generate a preview for the notification</span></li></ol> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>As an example, consider what happens when a user sends a link to a website over iMessage. In that case, the sending device will first render a preview of the webpage and collect some metadata about it (such as the title and page description), then pack those fields into an NSKeyedArchiver archive. This archive is then encrypted with a temporary key and uploaded to the iCloud servers. Finally, the link as well as the decryption key are sent to the receiver as part of the iMessage. In order to create a useful user notification about the incoming iMessage, this data has to be processed by the receiver on a 0-click code path. As that again involves a fair amount of complexity, it is also done inside BlastDoor: after receiving the BlastDoor reply from above and realizing that the message contains an attachment, </span><span class="c6">imagent</span><span> first instructs </span><span class="c6">IMTransferAgent</span><span> to download and decrypt the iCloud attachment. Afterwards, it will call into </span><span class="c10 c6">-[IMTranscodeController decodeiMessageAppPayload:bundleID:completionBlock:blockUntilReply:]</span><span> w</span><span>hich forwards the relevant data to the</span><span> IMTranscoderAgent, which then proceeds into </span><span class="c10 c6">+[IMAttachmentBlastdoor sendBalloonPluginPayloadData:withBundleIdentifier:completionBlock:]</span><span class="c6 c20"> </span><span>a</span><span>nd finally calls </span><span class="c10 c6">-[IMMessagesBlastDoorInterface defuseBalloonPluginPayload:withIdentifier:resultHandler:]</span><span>.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>In the </span><span>BlastDoor service, the plugin data decoding is then again performed in Swift, and dispatched to the corresponding plugin type, as determined by the plugin id. For RichLinks (plugin id com.apple.messages.URLBalloonProvider), processing ends up in </span><span class="c6 c10">LinkPresentation.MessagesPayload.init(dataRepresentation:)</span><span class="c2">, which deserializes the NSKeyedArchiver payload and to extract the preview image and URL metadata from it in order to generate a preview message.</span></p><h2 class="c17" id="h.v7m4aqoict2j"><span class="c14">Sandboxing</span></h2> <p class="c1"><span>The sandbox profile can be found in </span><span>System/Library/Sandbox/Profiles/blastdoor.sb</span><span> and is also attached at the end of this blog post. It appears to be identical on iOS and macOS. The profile can be studied statically, and for that purpose is attached at the bottom of this blogpost, or dynamically, for example by using the </span><span class="c6">sandbox-exec</span><span class="c2"> tool:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">> echo "(allow process-exec (literal \"$(pwd)/test\"))" >> ./blastdoor.sb</span></p> <p class="c1"><span class="c0">> clang -o test test.c # try to open files, network connections, etc.</span></p> <p class="c1"><span class="c0">> sandbox-exec -f ./blastdoor.sb ./test</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">The sandbox profile states: </span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">;;; This profile contains the rules necessary to make BlastDoor as close to</span></p> <p class="c1"><span class="c0">;;; compute-only as possible, while still remaining functional.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">And indeed, the sandbox profile is quite tight:</span></p><ul style="padding: 0;" class="c15 lst-kix_xkot2rd1rwjd-0 start"><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>only a handful of local IPC services, namely </span><span class="c6">diagnosticd</span><span>, </span><span class="c6">logd</span><span>, </span><span class="c6">opendirectoryd</span><span>, </span><span class="c6">syslogd</span><span>, and </span><span class="c6">notifyd</span><span class="c2">, can be reached</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">almost all file system interaction is blocked</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">any interaction with IOKit drivers (historically a big source of vulnerabilities) is forbidden</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>outbound </span><span>network access is denied</span></li></ul> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">Furthermore, the profile makes use of syscall filtering to restrict the interactions with the core kernel. However, as of now the syscall filter seems to be in “permissive” mode: </span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">;; To be uncommented once the system call whitelist is complete...</span></p> <p class="c1"><span class="c0">;; (deny syscall-unix (with send-signal SIGKILL))</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">As such, the BlastDoor service is still allowed to perform any syscall, but it is to be expected that the syscall filtering will soon be put into “enforcement mode”, which would further boost its effectiveness.</span></p> <p class="c1 c4"><span class="c2"></span></p><h2 class="c17" id="h.rdbm0q1mrv2k"><span class="c14">Crash Monitoring?</span></h2> <p class="c1"><span>An interesting side effect of the new processing pipeline is that </span><span class="c6">imagent</span><span> is now able to detect when an incoming message caused a crash in BlastDoor (it will receive an XPC error). Even more interesting is the fact that </span><span class="c6">imagent</span><span> appears to be informing Apple’s servers about such events, as can be seen by setting a breakpoint on </span><span class="c6 c23">-[APSConnectionServer handleSendOutgoingMessage:]</span><span> in </span><span class="c6">apsd</span><span class="c2">, the daemon responsible for implementing Apple’s push services (on top of which iMessage is built). Displaying the outgoing message will show the following:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">(lldb) po [$x2 dictionaryRepresentation]</span></p> <p class="c1"><span class="c0">{</span></p> <p class="c1"><span class="c0"> APSCritical = 1;</span></p> <p class="c1"><span class="c0"> APSMessageID = 543;</span></p> <p class="c1"><span class="c0"> APSMessageIdentifier = 1520040396;</span></p> <p class="c1"><span class="c0"> APSMessageTopic = "com.apple.madrid";</span></p> <p class="c1"><span class="c0"> APSMessageUserInfo = {</span></p> <p class="c1"><span class="c0"> c = 115;</span></p> <p class="c1"><span class="c0"> fR = 13500;</span></p> <p class="c1"><span class="c6"> </span><span class="c19 c29">fRM = "c-100-BlastDoor.Explosion-1-com.apple.BlastDoor.XPC-ServiceCrashed";</span></p> <p class="c1"><span class="c0"> fU = {length = 16, bytes = 0x3a4912626c9645f98cb26c7c2d439520};</span></p> <p class="c1"><span class="c0"> i = 1520040396;</span></p> <p class="c1"><span class="c0"> nr = 1;</span></p> <p class="c1"><span class="c0"> t = {length = 32, bytes = ... };</span></p> <p class="c1"><span class="c6"> ua = "[macOS,11.1,20C69,Macmini9,1]";</span></p> <p class="c1"><span class="c0"> v = 7;</span></p> <p class="c1"><span class="c0"> };</span></p> <p class="c1"><span class="c0"> APSOutgoingMessageSenderTokenName = 501;</span></p> <p class="c1"><span class="c0"> APSPayloadFormat = 1;</span></p> <p class="c1"><span class="c0"> APSTimeout = 120;</span></p> <p class="c1"><span class="c0"> APSTimestamp = "2021-01-06 19:52:10 +0000";</span></p> <p class="c1"><span class="c6">}</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>As can be seen, </span><span class="c6">imagent</span><span> is apparently informing the iMessage servers that the message with the UUID 0x3a4912626c9645f98cb26c7c2d439520 (</span><span class="c6">fU</span><span class="c2"> key) has caused a crash in BlastDoor.</span></p> <p class="c1"><span class="c2">It is unclear what the purpose of this is without access to the server’s code. While these notifications may simply be used for statistical purposes, they would also give Apple a fairly clear signal about attacks against iMessage involving brute-force and a somewhat weaker signal about any failed exploits against the BlastDoor service.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>In my experiments, after observing one of these crash notifications, the server would start directly sending delivery receipts to the sender for messages that hadn't actually been processed by the receiver yet. Possibly this is another, independent effort to break the crash oracle technique by confusing the sender, but that is hard to verify without access to the code running on the server. In any case, it is worth noting that this “spoofing” of delivery receipts by the server is generally possible as the message UUID, which is more or less the only content of a delivery receipt, is part of the non-end2end encrypted payload and is thus known to the server (break on </span><span class="c6 c23">-[APSConnectionServer handleSendOutgoingMessage:]</span><span> and inspect outgoing iMessages to verify this, the UUID will be in the </span><span class="c6">U</span><span> key, while the e2e-encrypted data will be in the </span><span class="c6">P</span><span> key)</span><span class="c2">. This is most likely necessary so the server can track which messages have already been delivered and which ones it still needs to keep around for delivery in the future.</span></p> <p class="c1 c4"><span class="c2"></span></p><h1 class="c13" id="h.tev8uvvac7bs"><span class="c5">Shared Cache Resliding</span></h1> <p class="c1"><span>Previously, when exploiting an iMessage memory corruption bug, a “crash oracle” could be used to reveal the location of the shared cache region in memory: the attacker would trigger the memory corruption bug in a way that would cause an access to a memory location somewhere in the region 0x180000000 - 0x280000000 (where the shared cache can be mapped). If the memory was valid, no crash would occur and </span><span class="c6">imagent</span><span class="c2"> would then send a delivery receipt to the attacker. However, If a crash occurred, no such receipt would be delivered, informing the attacker that the address was unmapped. Through clever selection of the queried addresses, the location of the shared cache could be revealed in logarithmic time, with only about 20 messages.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">However, with iOS 14 Apple has added a mechanism to re-randomize the location of the shared cache region for an “attacked” process, thus breaking a fundamental assumption of this technique and rendering it ineffective. This is significant as the crash oracle technique was one of very few, if not the only, fairly generic ASLR bypass techniques usable in 0-click iMessage attacks.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>To understand how the shared cache resliding works, one can start by looking at the kernel. In iOS 14, the kernel can now have </span><span class="c25">two</span><span> active shared cache regions: the “regular” region and </span><span class="c7"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/osfmk/vm/vm_shared_region.h#L224">a “reslided” region</a></span><span class="c2">. During an attack, the following then happens:</span></p> <p class="c1 c4"><span class="c2"></span></p><ol class="c15 lst-kix_hmo7gyj5poo-0 start" start="1"><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">When an attacker attempts to use a crash-oracle-based technique, the attacked process would quickly end up accessing unmapped memory in the range 0x180000000 - 0x280000000 (where the shared cache is mapped) and crashes</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>The kernel handles the segmentation fault generated by the CPU, and </span><span class="c7"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/bsd/kern/kern_sig.c#L2009">sets a specific flag in the crash info</a></span><span class="c2"> that signals that the crash happened inside the shared cache region</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>At the same time, the kernel will </span><span class="c7"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/bsd/kern/kern_sig.c#L2040">mark the currently active reslided shared cache region (if one exists) as stale</a></span><span class="c2">, causing it to be recreated and thus re-randomized the next time it is used</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c6">launchd</span><span> (as the parent process of the crashed service) receives the crash info, notices the </span><span class="c6">OS_REASON_FLAG_SHAREDREGION_FAULT</span><span> flag, and sets the </span><span class="c6">ReslideSharedCache</span><span> property on the service associated with the crashed process (see `</span><span class="c6">launchctl procinfo $pid</span><span>` and search for `</span><span class="c6">reslide shared cache = 1</span><span class="c2">`)</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>The next time the service is restarted, </span><span class="c6">launchd</span><span> then adds the </span><span class="c7 c6"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/bsd/sys/spawn.h#L78">POSIX_SPAWN_RESLIDE</a></span><span> attribute for </span><span class="c7 c6"><a class="c161" href="https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/posix_spawn.2.html">posix_spawn</a></span><span> due to the </span><span class="c6">ReslideSharedCache</span><span> property</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>In the kernel, this flag now causes the newly created process to be given the </span><span class="c7"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/osfmk/vm/vm_shared_region.h#L224">reslided shared cache image</a></span><span>. However, as no active reslided region currently exists (the previous one was marked as stale in step 3.), a new one is created at a newly randomized address.</span></li></ol> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>The result of this is that whenever an attacker attempts to use a crash-oracle to break ASLR, the attacked service would receive a different shared cache region every time it is launched, thus preventing the attack from succeeding. For the time being, this feature appears to </span><span class="c7"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/bsd/kern/kern_exec.c#L205">only be active on iOS</a></span><span> though</span><span class="c2">, but it would be expected to come to macOS as well.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>While this mechanism would in principle also protect 3rd party apps from similar attacks, protection for those is currently somewhat weaker, likely in order to first evaluate the real-world performance impact of this change (the shared cache is a significant performance optimization of the OS). In particular, step 3 is currently only performed if the crashing process is a </span><span class="c7"><a class="c161" href="https://developer.apple.com/documentation/endpointsecurity/es_process_t/3228979-is_platform_binary">platform binary</a></span><span> (essentially binaries that ship with the OS and are directly signed by Apple) such as the services handling iMessages. However, for 3rd party processes, it would only happen if the global </span><span class="c7 c6"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/bsd/kern/kern_exec.c#L217">vm_shared_region_reslide_restrict</a></span><span class="c2"> is set to zero:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">/*</span></p> <p class="c1"><span class="c0"> * Flag to control what processes should get shared cache randomize resliding</span></p> <p class="c1"><span class="c0"> * after a fault in the shared cache region:</span></p> <p class="c1"><span class="c0"> *</span></p> <p class="c1"><span class="c0"> * 0 - all processes get a new randomized slide</span></p> <p class="c1"><span class="c0"> * 1 - only platform processes get a new randomized slide</span></p> <p class="c1"><span class="c6"> */</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>Which is </span><span class="c7"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/bsd/kern/kern_exec.c#L6397">controlled by the </a></span><span class="c7 c6"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/bsd/kern/kern_exec.c#L6397">vm_shared_region_reslide_restrict</a></span><span class="c7"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/bsd/kern/kern_exec.c#L6397"> bootarg</a></span><span class="c2">. This currently seems to be set to one. In essence, for 3rd party apps this means:</span></p> <p class="c1 c4"><span class="c2"></span></p><ol class="c15 lst-kix_aue93cd1tacp-0 start" start="1"><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>When the attacked process first crashes, the kernel will still set the </span><span class="c6">OS_REASON_FLAG_SHAREDREGION_FAULT</span><span> flag, and </span><span class="c6">launchd</span><span> will add the </span><span class="c6">ReslideSharedCache</span><span class="c2"> property, but the current reslided region won’t be invalidated</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">The restarted service is then restarted and now uses the “reslided” shared cache region</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">When the service crashes the next time, and if that service is the only one currently using the reslided shared cache region (which should usually be the case, but could possibly be influenced by the attacker), the region’s refcount drops to zero, and the shared cache region is marked for removal.</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span>However, removal will only actually happen </span><span class="c7"><a class="c161" href="https://github.com/apple/darwin-xnu/blob/d4061fb0260b3ed486147341b72468f836ed6c8f/osfmk/vm/vm_shared_region.c#L144">after two minutes</a></span><span class="c2">. As such, if the service is restarted within two minutes, it will receive the same shared cache region at the same location in memory.</span></li></ol> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>As a result, a third-party app could still be attacked through a crash-oracle technique if it automatically sends some form of delivery receipt to the sender and restarts quickly enough after a crash. This could, however, be prevented for example by enabling </span><span class="c6">ExponentialThrottling</span><span class="c2"> for these services. Ideally, and assuming that the performance penalty is reasonable, Apple would enable re-randomization for all apps in the future.</span></p><h1 class="c13" id="h.g73ammr1eqa3"><span class="c5">Exponential Throttling</span></h1> <p class="c1"><span>Another thing we suggested back in 2019 was to limit the number of attempts an attacker gets when attempting to exploit a vulnerability. This was mostly important to defend against the crash-oracle technique, but would also help to prevent brute force attacks (e.g., given enough attempts, one could simply brute force the location of the shared cache region).</span><span class="c18"> The new ExponentialThrottling feature in </span><span class="c6 c18">launchd</span><span class="c2 c18"> seems to achieve just that.</span></p> <p class="c1 c4"><span class="c2 c18"></span></p> <p class="c1"><span class="c18">To use it, a system daemon or agent has to opt-in by setting</span><span class="c2"> "_ExponentialThrottling = 1” in its Info.plist (essentially the service metadata), as can be seen below for the BlastDoor service:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">> plutil -p /System/Library/PrivateFrameworks/MessagesBlastDoorSupport.framework/Versions/A/XPCServices/MessagesBlastDoorService.xpc/Contents/Info.plist</span></p> <p class="c1"><span class="c0">{</span></p> <p class="c1"><span class="c0"> "CFBundleDisplayName" => "MessagesBlastDoorService"</span></p> <p class="c1"><span class="c0"> "CFBundleExecutable" => "MessagesBlastDoorService"</span></p> <p class="c1"><span class="c0"> "CFBundleIdentifier" => "com.apple.MessagesBlastDoorService"</span></p> <p class="c1"><span class="c0"> ...</span></p> <p class="c1"><span class="c0"> "XPCService" => {</span></p> <p class="c1"><span class="c19 c29"> "_ExponentialThrottling" => 1</span></p> <p class="c1"><span class="c0"> }</span></p> <p class="c1"><span class="c0">}</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">Apart from the BlastDoor service, it is also used for imagent:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">> plutil -p /System/Library/LaunchAgents/com.apple.imagent.plist</span></p> <p class="c1"><span class="c0">{</span></p> <p class="c1"><span class="c0"> "_ExponentialThrottling" => 1</span></p> <p class="c1"><span class="c0"> ...</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>but doesn’t appear to be used for any other service, as can, for example, be seen by looking at the output of the </span><span class="c6">launchctl dumpstate</span><span> command, which will only show “</span><span class="c6">exponential throttling = 1”</span><span> for </span><span class="c6">com.apple.imagent</span><span> and </span><span class="c6">com.apple.MessagesBlastDoorService.</span></p> <p class="c1 c4"><span class="c0"></span></p> <p class="c1"><span>Presumably, the </span><span class="c6">_ExponentialThrottling</span><span> property instructs launchd (the macOS and iOS init process), to delay subsequent restarts of a crashing service. While it is somewhat challenging to statically reverse engineer launchd due to the lack of source code or binary symbols, it is fortunately fairly easy to experimentally determine the impact of the </span><span class="c6">_ExponentialThrottling</span><span> property, for example by installing a custom daemon that writes the current timestamp to a file before crashing. By default, so </span><span class="c25">without</span><span class="c2"> ExponentialThrottling, one would see the following:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 13:56:03 2021</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 13:56:13 2021</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 13:56:23 2021</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 13:56:33 2021</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>As can be seen, by default, a service is, at the earliest, restarted ten seconds after it was previously started. However, using the following service plist which enables ExponentialThrottling:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">> # Start service with</span></p> <p class="c1"><span class="c0">> # launchctl bootstrap system /Library/LaunchDaemons/net.saelo.test.plist</span></p> <p class="c1"><span class="c0">> plutil -p /Library/LaunchDaemons/net.saelo.test.plist</span></p> <p class="c1"><span class="c0">{</span></p> <p class="c1"><span class="c0"> "_ExponentialThrottling" => 1</span></p> <p class="c1"><span class="c0"> "KeepAlive" => 1</span></p> <p class="c1"><span class="c0"> "Label" => "net.saelo.test"</span></p> <p class="c1"><span class="c0"> "POSIXSpawnType" => "Interactive"</span></p> <p class="c1"><span class="c0"> "Program" => "/path/to/program"</span></p> <p class="c1"><span class="c6">}</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>One can observe the following:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 10:42:43 2021</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 10:42:53 2021 (+10s)</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 10:43:03 2021 (+10s)</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 10:43:13 2021 (+10s)</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 10:43:33 2021 (+20s)</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 10:44:13 2021 (+40s)</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 10:45:33 2021 (+80s)</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 10:48:13 2021 (+160s [~2.5m])</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 10:53:33 2021 (+320s [~5m])</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 11:04:13 2021 (+640s [~10m])</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 11:24:13 2021 (+20m)</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 11:44:13 2021 (+20m)</span></p> <p class="c1"><span class="c0">Service started on Wed Jan 6 12:04:13 2021 (+20m)</span></p> <p class="c1 c4"><span class="c0"></span></p> <p class="c1"><span>Here, the exponential increase in the time between subsequent restarts is clearly visible, and goes up to an apparent maximum of 20 minutes. And indeed, </span><span class="c6">launchd</span><span class="c2"> does contain the following bit of code in a function presumably responsible for computing the next restart delay (search for XREFs to the string "%s: service throttled by %llu seconds"):</span></p> <p class="c1 c4"><span class="c0"></span></p> <p class="c1"><span class="c0"> if ( delay >= 1200 )</span></p> <p class="c1"><span class="c0"> result = 1200LL; // 20 minutes</span></p> <p class="c1"><span class="c0"> else</span></p> <p class="c1"><span class="c0"> result = delay;</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c2">With this change, an exploit that relied on brute force would now only get one attempt every 20 minutes instead of every 10 seconds.</span></p><h1 class="c13" id="h.mfarwae35i5h"><span class="c5">(Upcoming?) ObjectiveC ISA PAC</span></h1> <p class="c1"><span>The PoC exploit against iMessage on iOS 12.4 relied heavily on faking ObjectiveC objects to gain a form of arbitrary code execution despite the presence of </span><span class="c7"><a class="c161" href="https://support.apple.com/guide/security/pointer-authentication-codes-seca5759bf02/web">pointer authentication (PAC)</a></span><span>. This was mainly possible because the ISA field, containing the pointer to the Class object and thus making a piece of memory appear like a valid ObjectiveC object, was not protected through PAC and could thus be faked. With iOS 14, this now seems to be changing: while previously, the </span><span class="c7"><a class="c161" href="https://github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/objc-private.h#L93">top 19 bits of the ISA value contained the inline refcount</a></span><span>, it now appears that this field has been reduced to 9 bits (of which the LSB appears to be reserved for some purpose, leaving an </span><span>8-bit inline refcount</span><span>, see the bit shifting logic in </span><span class="c6">objc_release</span><span> or </span><span class="c6">objc_retain</span><span>), while the freed-up bits now hold a PAC, as can be seen in </span><span class="c6">objc_rootAllocWithZone</span><span class="c2"> in libobjc.dylib:</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span class="c6 c12 c19"> ; Allocate the object</span></p> <p class="c1"><span class="c0"> BL j__calloc_3</span></p> <p class="c1"><span class="c0"> CBZ X0, loc_1953DA434</span></p> <p class="c1"><span class="c0"> MOV X8, X0</span></p> <p class="c1"><span class="c19 c6 c12"> ; “Tag” the address with a constant to get a PAC modifier value</span></p> <p class="c1"><span class="c0"> MOVK X8, #0x6AE1,LSL#48 </span></p> <p class="c1"><span class="c0"> MOV X9, X19</span></p> <p class="c1"><span class="c19 c6 c12"> ; Compute PAC of Class pointer with tagged object address as modifier</span></p> <p class="c1"><span class="c0"> PACDA X9, X8 </span></p> <p class="c1"><span class="c6"> </span><span class="c6 c12">; Clear top 9 bits (inline refcnt) and bottom 3 bits (other bitfields)</span><span class="c0"> </span></p> <p class="c1"><span class="c0"> AND X8, X9, #0x7FFFFFFFFFFFF8</span></p> <p class="c1"><span class="c6"> </span><span class="c19 c6 c12">; Set LSB and inline refcount to one</span></p> <p class="c1"><span class="c0"> MOV X9, #0x100000000000001</span></p> <p class="c1"><span class="c0"> ORR X9, X8, X9</span></p> <p class="c1"><span class="c6 c12"> ; Presumably, the refcnt isn’t used for all types of classes...</span></p> <p class="c1"><span class="c0"> TST W20, #0x2000</span></p> <p class="c1"><span class="c6 c12"> </span><span class="c0">CSEL X8, X9, X8, EQ</span></p> <p class="c1"><span class="c6"> </span><span class="c19 c6 c12">; Store the resulting value into the ISA field</span></p> <p class="c1"><span class="c0"> STR X8, [X0]</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>However, currently the ISA PAC appears to never be checked, as such, it doesn’t yet affect any exploits. The most likely reason for this is that the ISA PAC feature is being rolled out in multiple phases, with the current implementation meant to allow in-depth performance evaluation, in particular of the reduced size of the inline refcount, which will likely cause more objects to use the more expensive out-of-line refcounting (used </span><span class="c7"><a class="c161" href="https://github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/objc-object.h#L392">once the inline refcount saturates</a></span><span>). With that, it can be expected that, in the absence of major performance issues, future releases of iOS and macOS will use PAC for the ObjC ISA field, thus likely breaking exploits that have to rely on faking ObjectiveC objects to achieve arbitrary code execution.</span></p><h1 class="c13" id="h.hdmcsd8tb0pt"><span class="c5">Conclusion</span></h1> <p class="c1"><span class="c2">This blog post discussed three improvements in iOS 14 affecting iMessage security: the BlastDoor service, resliding of the shared cache, and exponential throttling. Overall, these changes are probably very close to the best that could’ve been done given the need for backwards compatibility, and they should have a significant impact on the security of iMessage and the platform as a whole. It’s great to see Apple putting aside the resources for these kinds of large refactorings to improve end users’ security. Furthermore, these changes also highlight the value of offensive security work: not just single bugs were fixed, but instead structural improvements were made based on insights gained from exploit development work.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>As for the alleged NSO iMessage exploit, it may have been prevented from working against iOS 14 by any of the following</span><span class="c2">:</span></p> <p class="c1 c4"><span class="c2"></span></p><ul style="padding: 0;" class="c15 lst-kix_ju6nxsiwjdzc-0 start"><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">The bug was fixed in iOS 14, for example due to the rewrite of large parts of the iMessage processing pipeline in Swift</span></li></ul><ul style="padding: 0;" class="c15 lst-kix_u10h5r66zlog-0 start"><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">The mere fact that processing happens in a different process, which could for example break a heap layouting primitive</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">The shared cache resliding would break their exploit if their exploit relied on some form of crash oracle to break ASLR</span></li><li style="margin-left: 46pt;" class="c1 c11 li-bullet-0"><span class="c2">The stronger sandbox of the BlastDoor service, which could prevent the exploitation of a privilege escalation vulnerability after compromising the BlastDoor process</span></li></ul> <p class="c1 c4"><span class="c2"></span></p> <p class="c1"><span>While these are some possible scenarios, and </span><span class="c2">it could be the case that the exploit “just” needs some re-engineering to function again, the fact that these security improvements were shipped is certainly a positive outcome.</span></p> <p class="c1 c4"><span class="c2"></span></p> <p class="c1 c4"><span class="c2"></span></p><h1 class="c13" id="h.4kqlsylg7dt0"><span>Attachment 1: blastdoor.sb</span></h1> <p class="c1"><span class="c3">;;; This profile contains the rules necessary to make BlastDoor as close to</span></p> <p class="c1"><span class="c3">;;; compute-only as possible, while still remaining functional.</span></p> <p class="c1"><span class="c3">;;;</span></p> <p class="c1"><span class="c3">;;; For all platforms: /System/Library/PrivateFrameworks/MessagesBlastDoorSupport.framework/XPCServices/MessagesBlastDoorService.xpc/MessagesBlastDoorService</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">(version 1)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;;; -------------------------------------------------------------------------------------------- ;;;</span></p> <p class="c1"><span class="c3">;;; Basic Rules</span></p> <p class="c1"><span class="c3">;;; -------------------------------------------------------------------------------------------- ;;;</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Deny all default rules.</span></p> <p class="c1"><span class="c3">(deny default)</span></p> <p class="c1"><span class="c3">(deny file-map-executable process-info* nvram*)</span></p> <p class="c1"><span class="c3">(deny dynamic-code-generation)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Rules copied from system.sb. Ones that we've deemed overly permissive</span></p> <p class="c1"><span class="c3">;; or unnecessary for BlastDoor have been removed.</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Allow read access to standard system paths.</span></p> <p class="c1"><span class="c3">(allow file-read*</span></p> <p class="c1"><span class="c3"> (require-all (file-mode #o0004)</span></p> <p class="c1"><span class="c3"> (require-any (subpath "/System")</span></p> <p class="c1"><span class="c3"> (subpath "/usr/lib")</span></p> <p class="c1"><span class="c3"> (subpath "/usr/share")</span></p> <p class="c1"><span class="c3"> (subpath "/private/var/db/dyld"))))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">(allow file-map-executable</span></p> <p class="c1"><span class="c3"> (subpath "/System/Library/CoreServices/RawCamera.bundle")</span></p> <p class="c1"><span class="c3"> (subpath "/usr/lib")</span></p> <p class="c1"><span class="c3"> (subpath "/System/Library/Frameworks"))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">(allow file-test-existence (subpath "/System"))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">(allow file-read-metadata</span></p> <p class="c1"><span class="c3"> (literal "/etc")</span></p> <p class="c1"><span class="c3"> (literal "/tmp")</span></p> <p class="c1"><span class="c3"> (literal "/var")</span></p> <p class="c1"><span class="c3"> (literal "/private/etc/localtime"))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Allow access to standard special files.</span></p> <p class="c1"><span class="c3">(allow file-read*</span></p> <p class="c1"><span class="c3"> (literal "/dev/random")</span></p> <p class="c1"><span class="c3"> (literal "/dev/urandom"))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">(allow file-read* file-write-data</span></p> <p class="c1"><span class="c3"> (literal "/dev/null")</span></p> <p class="c1"><span class="c3"> (literal "/dev/zero"))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">(allow file-read* file-write-data file-ioctl</span></p> <p class="c1"><span class="c3"> (literal "/dev/dtracehelper"))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; TODO: Don't allow core dumps to be written out unless this is on a dev</span></p> <p class="c1"><span class="c3">;; fused device?</span></p> <p class="c1"><span class="c3">(allow file-write*</span></p> <p class="c1"><span class="c3"> (require-all (regex #"^/cores/")</span></p> <p class="c1"><span class="c3"> (require-not (file-mode 0))))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Allow IPC to standard system agents.</span></p> <p class="c1"><span class="c3">(allow mach-lookup</span></p> <p class="c1"><span class="c3"> (global-name "com.apple.diagnosticd")</span></p> <p class="c1"><span class="c3"> (global-name "com.apple.logd")</span></p> <p class="c1"><span class="c3"> (global-name "com.apple.system.DirectoryService.libinfo_v1")</span></p> <p class="c1"><span class="c3"> (global-name "com.apple.system.logger")</span></p> <p class="c1"><span class="c3"> (global-name "com.apple.system.notification_center"))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Allow mostly harmless operations.</span></p> <p class="c1"><span class="c3">(allow signal process-info-dirtycontrol process-info-pidinfo</span></p> <p class="c1"><span class="c3"> (target self))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Temporarily allow sysctl-read with reporting to see if this is</span></p> <p class="c1"><span class="c3">;; used for anything.</span></p> <p class="c1"><span class="c3">(allow (with report) sysctl-read)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; We don't need to post any darwin notifications.</span></p> <p class="c1"><span class="c3">(deny darwin-notification-post)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; We shouldn't allow any other file operations not covered under</span></p> <p class="c1"><span class="c3">;; the default of deny above.</span></p> <p class="c1"><span class="c3">(deny file-clone file-link)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Don't deny file-test-existence: <rdar://problem/59611011></span></p> <p class="c1"><span class="c3">;; (deny file-test-existence)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Don't allow access to any IOKit properties.</span></p> <p class="c1"><span class="c3">(deny iokit-get-properties)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">(deny mach-cross-domain-lookup)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Don't allow BlastDoor to spawn any other XPC services other than</span></p> <p class="c1"><span class="c3">;; ones that we can intentionally whitelist later.</span></p> <p class="c1"><span class="c3">(deny mach-lookup (xpc-service-name-regex #".*"))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Don't allow any commands on sockets.</span></p> <p class="c1"><span class="c3">(deny socket-ioctl)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Denying this should have no ill effects for our use case.</span></p> <p class="c1"><span class="c3">(deny system-privilege)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; To be uncommented once the system call whitelist is complete...</span></p> <p class="c1"><span class="c3">;; (deny syscall-unix (with send-signal SIGKILL))</span></p> <p class="c1"><span class="c3">(allow syscall-unix</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_exit)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_kevent_qos)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_kevent_id)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_thread_selfid)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_bsdthread_ctl)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_kdebug_trace64)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_getattrlist)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_sigsuspend_nocancel)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_proc_info)</span></p> <p class="c1"><span class="c3"> </span></p> <p class="c1"><span class="c3"> (syscall-number SYS___disable_threadsignal)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS___pthread_sigmask)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS___mac_syscall)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS___semwait_signal_nocancel)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_abort_with_payload)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_access)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_bsdthread_create)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_bsdthread_terminate)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_close)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_close_nocancel)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_connect)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_csops_audittoken)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_csrctl)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_fcntl)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_fsgetpath)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_fstat64)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_fstatfs64)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_getdirentries64)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_geteuid)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_getfsstat64)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_getgid)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_getrlimit)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_getuid)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_ioctl)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_issetugid)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_lstat64)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_madvise)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_mmap)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_munmap)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_mprotect)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_mremap_encrypted)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_open)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_open_nocancel)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_openat)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_pathconf)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_pread)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_read)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_readlink)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_shm_open)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_socket)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_stat64)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_statfs64)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_sysctl)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_sysctlbyname)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_workq_kernreturn)</span></p> <p class="c1"><span class="c3"> (syscall-number SYS_workq_open)</span></p> <p class="c1"><span class="c3">)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Still allow the system call but report in log.</span></p> <p class="c1"><span class="c3">(allow (with report) syscall-unix)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; For validating the entitlements of clients. This is so only entitled</span></p> <p class="c1"><span class="c3">;; clients can pass data into a BlastDoor instance.</span></p> <p class="c1"><span class="c3">(allow process-info-codesignature)</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;;; -------------------------------------------------------------------------------------------- ;;;</span></p> <p class="c1"><span class="c3">;;; Reading Files</span></p> <p class="c1"><span class="c3">;;; -------------------------------------------------------------------------------------------- ;;;</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; Support for BlastDoor receiving sandbox extensions from clients to either read files, or</span></p> <p class="c1"><span class="c3">;; write to a target location.</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; com.apple.app-sandbox.read</span></p> <p class="c1"><span class="c3">(allow file-read*</span></p> <p class="c1"><span class="c3"> (extension "com.apple.app-sandbox.read"))</span></p> <p class="c1 c4"><span class="c3"></span></p> <p class="c1"><span class="c3">;; com.apple.app-sandbox.read-write</span></p> <p class="c1"><span class="c3">(allow file-read* file-write*</span></p> <p class="c1"><span class="c3"> (extension "com.apple.app-sandbox.read-write"))</span></p> <p class="c1 c4"><span class="c0"></span></p> <p class="c1 c4"><span class="c2"></span></p> <div style='clear: both;'></div> </div> <div class='post-footer'> <div class='post-footer-line post-footer-line-1'> <span class='post-author vcard'> Posted by <span class='fn' itemprop='author' itemscope='itemscope' itemtype='http://schema.org/Person'> <span itemprop='name'>Anonymous</span> </span> </span> <span class='post-timestamp'> at <meta content='https://googleprojectzero.blogspot.com/2021/01/a-look-at-imessage-in-ios-14.html' itemprop='url'/> <a class='timestamp-link' href='https://googleprojectzero.blogspot.com/2021/01/a-look-at-imessage-in-ios-14.html' rel='bookmark' title='permanent link'><abbr class='published' itemprop='datePublished' title='2021-01-28T11:47:00-08:00'>11:47 AM</abbr></a> </span> <span class='post-comment-link'> <a class='comment-link' href='https://googleprojectzero.blogspot.com/2021/01/a-look-at-imessage-in-ios-14.html#comment-form' onclick=''> No comments: </a> </span> <span class='post-icons'> <span class='item-control blog-admin pid-145400864'> <a href='https://www.blogger.com/post-edit.g?blogID=4838136820032157985&postID=405547501763334781&from=pencil' title='Edit Post'> <img alt='' class='icon-action' height='18' src='https://resources.blogblog.com/img/icon18_edit_allbkg.gif' width='18'/> </a> </span> </span> <div class='post-share-buttons goog-inline-block'> <a class='goog-inline-block share-button sb-email' href='https://www.blogger.com/share-post.g?blogID=4838136820032157985&postID=405547501763334781&target=email' target='_blank' title='Email This'><span class='share-button-link-text'>Email This</span></a><a class='goog-inline-block share-button sb-blog' href='https://www.blogger.com/share-post.g?blogID=4838136820032157985&postID=405547501763334781&target=blog' onclick='window.open(this.href, "_blank", "height=270,width=475"); return false;' target='_blank' title='BlogThis!'><span class='share-button-link-text'>BlogThis!</span></a><a class='goog-inline-block share-button sb-twitter' href='https://www.blogger.com/share-post.g?blogID=4838136820032157985&postID=405547501763334781&target=twitter' target='_blank' title='Share to X'><span class='share-button-link-text'>Share to X</span></a><a class='goog-inline-block share-button sb-facebook' href='https://www.blogger.com/share-post.g?blogID=4838136820032157985&postID=405547501763334781&target=facebook' onclick='window.open(this.href, "_blank", "height=430,width=640"); return false;' target='_blank' title='Share to Facebook'><span class='share-button-link-text'>Share to Facebook</span></a><a class='goog-inline-block share-button sb-pinterest' href='https://www.blogger.com/share-post.g?blogID=4838136820032157985&postID=405547501763334781&target=pinterest' target='_blank' title='Share to Pinterest'><span class='share-button-link-text'>Share to Pinterest</span></a> </div> </div> <div class='post-footer-line post-footer-line-2'> <span class='post-labels'> </span> </div> <div class='post-footer-line post-footer-line-3'> <span class='post-location'> </span> </div> </div> </div> </div> </div></div> </div> <div class='blog-pager' id='blog-pager'> <span id='blog-pager-newer-link'> <a class='blog-pager-newer-link' href='https://googleprojectzero.blogspot.com/search?updated-max=2021-03-18T09:45:00-07:00&max-results=1&reverse-paginate=true' id='Blog1_blog-pager-newer-link' title='Newer Posts'>Newer Posts</a> </span> <span id='blog-pager-older-link'> <a class='blog-pager-older-link' href='https://googleprojectzero.blogspot.com/search?updated-max=2021-01-28T11:47:00-08:00&max-results=1' id='Blog1_blog-pager-older-link' title='Older Posts'>Older Posts</a> </span> <a class='home-link' href='https://googleprojectzero.blogspot.com/'>Home</a> </div> <div class='clear'></div> <div class='blog-feeds'> <div class='feed-links'> Subscribe to: <a class='feed-link' href='https://googleprojectzero.blogspot.com/feeds/posts/default' target='_blank' type='application/atom+xml'>Posts (Atom)</a> </div> </div> </div></div> </div> </div> <div class='column-left-outer'> <div class='column-left-inner'> <aside> </aside> </div> </div> <div class='column-right-outer'> <div class='column-right-inner'> <aside> <div class='sidebar section' id='sidebar-right-1'><div class='widget BlogSearch' data-version='1' id='BlogSearch1'> <h2 class='title'>Search This Blog</h2> <div class='widget-content'> <div id='BlogSearch1_form'> <form action='https://googleprojectzero.blogspot.com/search' class='gsc-search-box' target='_top'> <table cellpadding='0' cellspacing='0' class='gsc-search-box'> <tbody> <tr> <td class='gsc-input'> <input autocomplete='off' class='gsc-input' name='q' size='10' title='search' type='text' value=''/> </td> <td class='gsc-search-button'> <input class='gsc-search-button' title='search' type='submit' value='Search'/> </td> </tr> </tbody> </table> </form> </div> </div> <div class='clear'></div> </div><div class='widget PageList' data-version='1' id='PageList1'> <h2>Pages</h2> <div class='widget-content'> <ul> <li> <a href='https://googleprojectzero.blogspot.com/p/about-project-zero.html'>About Project Zero</a> </li> <li> <a href='https://googleprojectzero.blogspot.com/p/working-at-project-zero.html'>Working at Project Zero</a> </li> <li> <a href='https://googleprojectzero.blogspot.com/p/0day.html'>0day "In the Wild"</a> </li> <li> <a href='https://googleprojectzero.github.io/0days-in-the-wild/rca.html'>0day Exploit Root Cause Analyses</a> </li> <li> <a href='https://googleprojectzero.blogspot.com/p/vulnerability-disclosure-faq.html'>Vulnerability Disclosure FAQ</a> </li> </ul> <div class='clear'></div> </div> </div><div class='widget BlogArchive' data-version='1' id='BlogArchive1'> <h2>Archives</h2> <div class='widget-content'> <div id='ArchiveList'> <div id='BlogArchive1_ArchiveList'> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2025/'> 2025 </a> <span class='post-count' dir='ltr'>(2)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2025/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/'> 2024 </a> <span class='post-count' dir='ltr'>(12)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/12/'> December </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/11/'> November </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/10/'> October </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/06/'> June </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2024/04/'> April </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/'> 2023 </a> <span class='post-count' dir='ltr'>(11)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/08/'> August </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2023/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/'> 2022 </a> <span class='post-count' dir='ltr'>(17)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/12/'> December </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/11/'> November </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/06/'> June </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2022/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> ▼  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/'> 2021 </a> <span class='post-count' dir='ltr'>(24)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/10/'> October </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> ▼  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2021/01/'> January </a> <span class='post-count' dir='ltr'>(10)</span> <ul class='posts'> <li><a href='https://googleprojectzero.blogspot.com/2021/01/a-look-at-imessage-in-ios-14.html'>A Look at iMessage in iOS 14</a></li> <li><a href='https://googleprojectzero.blogspot.com/2021/01/windows-exploitation-tricks-trapping.html'>Windows Exploitation Tricks: Trapping Virtual Memo...</a></li> <li><a href='https://googleprojectzero.blogspot.com/2021/01/the-state-of-state-machines.html'>The State of State Machines</a></li> <li><a href='https://googleprojectzero.blogspot.com/2021/01/hunting-for-bugs-in-windows-mini-filter.html'>Hunting for Bugs in Windows Mini-Filter Drivers</a></li> <li><a href='https://googleprojectzero.blogspot.com/2021/01/in-wild-series-android-exploits.html'>In-the-Wild Series: Android Exploits</a></li> <li><a href='https://googleprojectzero.blogspot.com/2021/01/in-wild-series-android-post-exploitation.html'>In-the-Wild Series: Android Post-Exploitation</a></li> <li><a href='https://googleprojectzero.blogspot.com/2021/01/in-wild-series-windows-exploits.html'>In-the-Wild Series: Windows Exploits</a></li> <li><a href='https://googleprojectzero.blogspot.com/2021/01/in-wild-series-chrome-exploits.html'>In-the-Wild Series: Chrome Exploits</a></li> <li><a href='https://googleprojectzero.blogspot.com/2021/01/in-wild-series-chrome-infinity-bug.html'>In-the-Wild Series: Chrome Infinity Bug</a></li> <li><a href='https://googleprojectzero.blogspot.com/2021/01/introducing-in-wild-series.html'>Introducing the In-the-Wild Series</a></li> </ul> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/'> 2020 </a> <span class='post-count' dir='ltr'>(36)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/10/'> October </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/09/'> September </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/08/'> August </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/07/'> July </a> <span class='post-count' dir='ltr'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/06/'> June </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/02/'> February </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2020/01/'> January </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/'> 2019 </a> <span class='post-count' dir='ltr'>(27)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/10/'> October </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/08/'> August </a> <span class='post-count' dir='ltr'>(11)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/02/'> February </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2019/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/'> 2018 </a> <span class='post-count' dir='ltr'>(22)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/12/'> December </a> <span class='post-count' dir='ltr'>(7)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/10/'> October </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/09/'> September </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/08/'> August </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/07/'> July </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2018/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/'> 2017 </a> <span class='post-count' dir='ltr'>(19)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/12/'> December </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/10/'> October </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/09/'> September </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/08/'> August </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/07/'> July </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/04/'> April </a> <span class='post-count' dir='ltr'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2017/02/'> February </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/'> 2016 </a> <span class='post-count' dir='ltr'>(17)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/09/'> September </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/07/'> July </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/06/'> June </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/03/'> March </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/02/'> February </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2016/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/'> 2015 </a> <span class='post-count' dir='ltr'>(33)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/11/'> November </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/09/'> September </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/08/'> August </a> <span class='post-count' dir='ltr'>(6)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/07/'> July </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/06/'> June </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/02/'> February </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2015/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/'> 2014 </a> <span class='post-count' dir='ltr'>(11)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/12/'> December </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/11/'> November </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/10/'> October </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/08/'> August </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='https://googleprojectzero.blogspot.com/2014/07/'> July </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> </li> </ul> </div> </div> <script type='text/javascript'> //<![CDATA[ (function(){ let archive_list = document.getElementById('ArchiveList'); if (archive_list == null) return; let cur_year = archive_list.querySelector('.post-count-link').innerText.trim() - 0; let last_year = 2014; let elements = []; const MONTHS = ',Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','); let parent = document.getElementById('ArchiveList'); while (parent.childNodes.length) parent.removeChild(parent.childNodes[0]); function fetch_next_year() { let url = 'https://googleprojectzero.blogspot.com/?action=getTitles&widgetId=BlogArchive1&widgetType=BlogArchive&responseType=js&path=https%3A%2F%2Fgoogleprojectzero.blogspot.com%2F'+cur_year; fetch(url).then(resp => { if (!resp.ok) { console.log('http error'); return; } resp.text().then(text => { let scope = { _WidgetManager: { _HandleControllerResult: (name, method, results) => { elements.push(document.createElement('hr')); let year_header = document.createElement('div'); year_header.appendChild(document.createTextNode(cur_year)); year_header.style.fontSize = 'large'; elements.push(year_header); let list = document.createElement('ul'); elements.push(list); for (let obj of results.posts) { let link_parts = obj.url.split('/'); let year = link_parts[3]; let month = link_parts[4]; let el = document.createElement(/*'div'*/'li'); el.style.listStyleType = 'square'; el.style.listStylePosition = 'inside'; let link = document.createElement('a'); el.appendChild(link); link.appendChild(document.createTextNode(obj.title)); link.href = obj.url; let date_trailer = document.createElement('span'); el.appendChild(date_trailer); //date_trailer.appendChild(document.createTextNode(' ('+year+'-'+month+')')); date_trailer.appendChild(document.createTextNode(' ('+MONTHS[parseInt(month, 10)]+')')); //date_trailer.style.textAlign = 'right'; //elements.push(el); list.appendChild(el); } } } }; with (scope) { eval(text); } if (cur_year == last_year) { finish(); } else { cur_year--; fetch_next_year(); } }); }); } fetch_next_year(); function finish() { for (let obj of elements) { parent.appendChild(obj); } console.log(elements); } })(); //]]> </script> <div class='clear'></div> </div> </div></div> <table border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'> <tbody> <tr> <td class='first columns-cell'> <div class='sidebar no-items section' id='sidebar-right-2-1'></div> </td> <td class='columns-cell'> <div class='sidebar no-items section' id='sidebar-right-2-2'></div> </td> </tr> </tbody> </table> <div class='sidebar no-items section' id='sidebar-right-3'></div> </aside> </div> </div> </div> <div style='clear: both'></div> <!-- columns --> </div> <!-- main --> </div> </div> <div class='main-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <footer> <div class='footer-outer'> <div class='footer-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left footer-fauxborder-left'> <div class='fauxborder-right footer-fauxborder-right'></div> <div class='region-inner footer-inner'> <div class='foot no-items section' id='footer-1'></div> <table border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'> <tbody> <tr> <td class='first columns-cell'> <div class='foot no-items section' id='footer-2-1'></div> </td> <td class='columns-cell'> <div class='foot no-items section' id='footer-2-2'></div> </td> </tr> </tbody> </table> <!-- outside of the include in order to lock Attribution widget --> <div class='foot section' id='footer-3' name='Footer'><div class='widget Attribution' data-version='1' id='Attribution1'> <div class='widget-content' style='text-align: center;'> Powered by <a href='https://www.blogger.com' target='_blank'>Blogger</a>. </div> <div class='clear'></div> </div></div> </div> </div> <div class='footer-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </footer> <!-- content --> </div> </div> <div class='content-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <script type='text/javascript'> window.setTimeout(function() { document.body.className = document.body.className.replace('loading', ''); }, 10); </script> <script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/1704033933-widgets.js"></script> <script type='text/javascript'> window['__wavt'] = 'AOuZoY7hVtQh2I91xyRHLScN0FBxsiiFsw:1740162836415';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d4838136820032157985','//googleprojectzero.blogspot.com/2021/01/','4838136820032157985'); _WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '4838136820032157985', 'title': 'Project Zero', 'url': 'https://googleprojectzero.blogspot.com/2021/01/', 'canonicalUrl': 'https://googleprojectzero.blogspot.com/2021/01/', 'homepageUrl': 'https://googleprojectzero.blogspot.com/', 'searchUrl': 'https://googleprojectzero.blogspot.com/search', 'canonicalHomepageUrl': 'https://googleprojectzero.blogspot.com/', 'blogspotFaviconUrl': 'https://googleprojectzero.blogspot.com/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': false, 'httpsEnabled': true, 'enabledCommentProfileImages': true, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': 'UA-240546891-1', 'encoding': 'UTF-8', 'locale': 'en', 'localeUnderscoreDelimited': 'en', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': false, 'isMobileRequest': false, 'mobileClass': '', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Project Zero - Atom\x22 href\x3d\x22https://googleprojectzero.blogspot.com/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22Project Zero - RSS\x22 href\x3d\x22https://googleprojectzero.blogspot.com/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Project Zero - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/4838136820032157985/posts/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/c320e3f9c6626331', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'X', 'key': 'twitter', 'shareMessage': 'Share to X', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'archive', 'pageName': 'January 2021', 'pageTitle': 'Project Zero: January 2021'}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard!', 'ok': 'Ok', 'postLink': 'Post Link'}}, {'name': 'template', 'data': {'name': 'custom', 'localizedName': 'Custom', 'isResponsive': false, 'isAlternateRendering': false, 'isCustom': true}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': false, 'title': 'Project Zero', 'description': 'News and updates from the Project Zero team at Google', 'url': 'https://googleprojectzero.blogspot.com/2021/01/', 'type': 'feed', 'isSingleItem': false, 'isMultipleItems': true, 'isError': false, 'isPage': false, 'isPost': false, 'isHomepage': false, 'isArchive': true, 'isLabelSearch': false, 'archive': {'year': 2021, 'month': 1, 'rangeMessage': 'Showing posts from January, 2021'}}}]); _WidgetManager._RegisterWidget('_NavbarView', new _WidgetInfo('Navbar1', 'navbar', document.getElementById('Navbar1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'header', document.getElementById('Header1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false, 'lightboxEnabled': true, 'lightboxModuleUrl': 'https://www.blogger.com/static/v1/jsbin/2332438401-lbx.js', 'lightboxCssUrl': 'https://www.blogger.com/static/v1/v-css/1964470060-lightbox_bundle.css'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogSearchView', new _WidgetInfo('BlogSearch1', 'sidebar-right-1', document.getElementById('BlogSearch1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_PageListView', new _WidgetInfo('PageList1', 'sidebar-right-1', document.getElementById('PageList1'), {'title': 'Pages', 'links': [{'isCurrentPage': false, 'href': 'https://googleprojectzero.blogspot.com/p/about-project-zero.html', 'id': '4384467920505278144', 'title': 'About Project Zero'}, {'isCurrentPage': false, 'href': 'https://googleprojectzero.blogspot.com/p/working-at-project-zero.html', 'id': '2459334498880008057', 'title': 'Working at Project Zero'}, {'isCurrentPage': false, 'href': 'https://googleprojectzero.blogspot.com/p/0day.html', 'id': '3414239791814532209', 'title': '0day \x22In the Wild\x22'}, {'isCurrentPage': false, 'href': 'https://googleprojectzero.github.io/0days-in-the-wild/rca.html', 'title': '0day Exploit Root Cause Analyses'}, {'isCurrentPage': false, 'href': 'https://googleprojectzero.blogspot.com/p/vulnerability-disclosure-faq.html', 'id': '2935252455704572784', 'title': 'Vulnerability Disclosure FAQ'}], 'mobile': false, 'showPlaceholder': true, 'hasCurrentPage': false}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogArchiveView', new _WidgetInfo('BlogArchive1', 'sidebar-right-1', document.getElementById('BlogArchive1'), {'languageDirection': 'ltr', 'loadingMessage': 'Loading\x26hellip;'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_AttributionView', new _WidgetInfo('Attribution1', 'footer-3', document.getElementById('Attribution1'), {}, 'displayModeFull')); </script> </body> </html>