<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="https://knight.sc/atom.xml" rel="self" type="application/atom+xml" /><link href="https://knight.sc/" rel="alternate" type="text/html" /><updated>2023-04-12T11:16:27+00:00</updated><id>https://knight.sc/atom.xml</id><title type="html">Scott Knight</title><subtitle>Reverse engineering and debugging.</subtitle><author><name>Scott Knight</name></author><entry><title type="html">Securely configuring your AWS account</title><link href="https://knight.sc/security/2020/09/11/securely-configuring-aws-account.html" rel="alternate" type="text/html" title="Securely configuring your AWS account" /><published>2020-09-11T00:00:00+00:00</published><updated>2020-09-11T00:00:00+00:00</updated><id>https://knight.sc/security/2020/09/11/securely-configuring-aws-account</id><content type="html" xml:base="https://knight.sc/security/2020/09/11/securely-configuring-aws-account.html">&lt;p&gt;Recently I decided to sit down and futher lock down my personal AWS account. I haven’t used it for much other than S3 storage of macOS installers and in turn had not configured things as securely as I would have liked. The following post walks you through how to lock down an AWS account that is used by a single user. A lot of the recommendations apply just as much to an account with multiple users as well.&lt;/p&gt;

&lt;p&gt;First just a quick note. Amazon has a lot of documentation for AWS. Everything I cover here can be found in their guides and documentation but you have to wade through a lot of different documents. My goal here is to provide a short easy to follow guide. The two following documents are foundational to what I cover and would be useful to read over.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.aws.amazon.com/general/latest&quot; target=&quot;_blank&quot;&gt;AWS General Reference&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide&quot; target=&quot;_blank&quot;&gt;AWS Identity and Access Management&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;aws-root-user&quot;&gt;AWS root user&lt;/h1&gt;

&lt;p&gt;When you first sign up for AWS you start with a single root user account that has complete access to all AWS services and resources. This root user account should only be used for setting up your first IAM user or the small handful of tasks that require root user access. With that said the following steps should be taken to lock down access to the root user account:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Ensure the root user has a &lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_change-root.html&quot; target=&quot;_blank&quot;&gt;strong password set&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa&quot; target=&quot;_blank&quot;&gt;Enable Multi-factor authentication (MFA)&lt;/a&gt; for the root user.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_delete-key&quot; target=&quot;_blank&quot;&gt;Delete any access keys&lt;/a&gt; you might have for the root user.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;iam-policies&quot;&gt;IAM Policies&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html&quot; target=&quot;_blank&quot;&gt;IAM policies&lt;/a&gt; allow you to define permissions. In order to grant permissions to users or services you need to first create some policies. Alternatively there are a lot of standard policies that are provided in AWS already that you can use. For example there is an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AdministratorAccess&lt;/code&gt; policy that provides full access to all AWS services and resources. You use policies by attaching them to IAM identities (users, groups or roles). We’re going to &lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html&quot; target=&quot;_blank&quot;&gt;create&lt;/a&gt; three different policies for our setup.&lt;/p&gt;

&lt;h2 id=&quot;iamrequiremfa&quot;&gt;IAMRequireMFA&lt;/h2&gt;

&lt;p&gt;The first policy, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IAMRequireMFA&lt;/code&gt;, will be used to allow all IAM users the ability to set set a password and configure MFA on their IAM user account. It will ensure that MFA is required for any other action the user wants to take.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2012-10-17&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Statement&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ListMiscAccountInformation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:GetAccountPasswordPolicy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:GetAccountSummary&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:ListAccountAliases&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;AllowAllUsersToListUserAccounts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:ListUsers&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::*:user/&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;AllowIndividualUserToChangeTheirPassword&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:ChangePassword&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::*:user/${aws:username}&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;AllowIndividualUserToListTheirMFA&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:ListVirtualMFADevices&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:ListMFADevices&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::*:mfa/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::*:user/${aws:username}&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;AllowIndividualUserToManageTheirMFA&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:CreateVirtualMFADevice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:DeleteVirtualMFADevice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:EnableMFADevice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:ResyncMFADevice&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::*:mfa/${aws:username}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::*:user/${aws:username}&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;RequireMFAForUserToManageRemainderOfAccount&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:CreateLoginProfile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:DeleteLoginProfile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:GetLoginProfile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:UpdateLoginProfile&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::*:user/${aws:username}&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Condition&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Bool&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;aws:MultiFactorAuthPresent&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;RequireMFAToDeactivateTheirOwnVirtualMFADevice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:DeactivateMFADevice&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::*:mfa/${aws:username}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::*:user/${aws:username}&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Condition&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Bool&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;aws:MultiFactorAuthPresent&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;DoNotAllowAnythingOtherThanAboveUnlessMFA&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Deny&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;NotAction&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iam:*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Condition&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Null&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;aws:MultiFactorAuthAge&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;assumeadminrole&quot;&gt;AssumeAdminRole&lt;/h2&gt;

&lt;p&gt;The second policy, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AssumeAdminRole&lt;/code&gt;, will only be used by users that you want to grant admin privileges to. We haven’t discussed IAM roles yet so just make note that this policy grants permission to assume a role named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AdminRole&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2012-10-17&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Statement&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sts:AssumeRole&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::*:role/AdminRole&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Condition&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Bool&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;aws:MultiFactorAuthPresent&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;aws:SecureTransport&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;NumericLessThan&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;aws:MultiFactorAuthAge&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;3600&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;adminpolicy&quot;&gt;AdminPolicy&lt;/h2&gt;

&lt;p&gt;The final policy, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AdminPolicy&lt;/code&gt;, we define will be used to specify admin privleges. This policy will be specific to your needs but for now you can set up your policy exactly the same as the built in AWS &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AdministratorAccess&lt;/code&gt; policy. Please take care though, this policy grants access to everything in the AWS account.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2012-10-17&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Statement&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;iam-roles&quot;&gt;IAM Roles&lt;/h1&gt;

&lt;p&gt;An &lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html&quot; target=&quot;_blank&quot;&gt;IAM role&lt;/a&gt; is an identity that you can attach IAM policies to. You can use roles to delegate access to different AWS services. An IAM user can log in and then &lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-console.html&quot; target=&quot;_blank&quot;&gt;switch to a different role&lt;/a&gt; to perform the actions they need. This is called “assuming a role”. The advantage of assuming a role is that when do, a set of temporary short lived credentials are transparently issued to your user and those are used to perform the action. This means if the credentials were ever somehow compromised they only are useful for an hour or two. In our case we’re going to &lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html&quot; target=&quot;_blank&quot;&gt;create a single role&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;adminrole&quot;&gt;AdminRole&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AdminRole&lt;/code&gt; will have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AdminPolicy&lt;/code&gt; attached to it. If you’re creating the role from the AWS console simply choose the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Another AWS account&lt;/code&gt; option but use your own account ID when setting it up. You can check the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Require MFA&lt;/code&gt; checkbox if you want but our policies above should also ensure that MFA is required in order to assume the role.&lt;/p&gt;

&lt;h1 id=&quot;iam-groups&quot;&gt;IAM Groups&lt;/h1&gt;

&lt;p&gt;IAM groups are another type of identity that policies can be attached to. IAM users can be added to groups and then a single policy can apply to all users of the group at once. We’re going to &lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups_create.html&quot; target=&quot;_blank&quot;&gt;create&lt;/a&gt; two separate groups.&lt;/p&gt;

&lt;h2 id=&quot;users&quot;&gt;Users&lt;/h2&gt;

&lt;p&gt;Any new IAM user should be added to this group. The permissions you attach here are meant to apply to all users. In our case we’re going to attach the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IAMRequireMFA&lt;/code&gt; policy to this group.&lt;/p&gt;

&lt;h2 id=&quot;administrators&quot;&gt;Administrators&lt;/h2&gt;

&lt;p&gt;Only certain users should be granted administrative access to your account. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AdminPolicy&lt;/code&gt; should be attached to this group.&lt;/p&gt;

&lt;h1 id=&quot;iam-users&quot;&gt;IAM Users&lt;/h1&gt;

&lt;p&gt;With our policies, roles and groups set up we can now finally &lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html&quot; target=&quot;_blank&quot;&gt;create a new IAM user&lt;/a&gt;. You can give your user whatever user name you want. For our usage go ahead and check the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Programatic access&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AWS Management Console access&lt;/code&gt; check boxes. Add the user to both the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Users&lt;/code&gt; group and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Administrators&lt;/code&gt; group. Click through and finish creating the user. When prompted make sure to save your newly created access keys somewhere secure.&lt;/p&gt;

&lt;h1 id=&quot;aws-cli&quot;&gt;AWS CLI&lt;/h1&gt;

&lt;p&gt;Finally we can &lt;a href=&quot;https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html&quot; target=&quot;_blank&quot;&gt;install&lt;/a&gt; and &lt;a href=&quot;https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html&quot; target=&quot;_blank&quot;&gt;configure&lt;/a&gt; the AWS command line interface. The Amazon docs do a good job of covering all this so I’ll just cover how you set things up to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AdminRole&lt;/code&gt; we created.&lt;/p&gt;

&lt;h2 id=&quot;awscredentials&quot;&gt;~/.aws/credentials&lt;/h2&gt;

&lt;p&gt;Add the access keys you saved after creating your IAM user into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;credentials&lt;/code&gt; file.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;awsprofile&quot;&gt;~/.aws/profile&lt;/h2&gt;

&lt;p&gt;In the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;profile&lt;/code&gt; we’re going to &lt;a href=&quot;https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html&quot; target=&quot;_blank&quot;&gt;configure the IAM role&lt;/a&gt; we created earlier.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[profile admin]
role_arn = arn:aws:iam::123456789012:role/AdminRole
source_profile = default
mfa_serial = arn:aws:iam::123456789012:mfa/username
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Make sure to change &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;123456789012&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;username&lt;/code&gt; to your account ID and the user name you created earlier.&lt;/p&gt;

&lt;h1 id=&quot;testing-it-out&quot;&gt;Testing it out&lt;/h1&gt;

&lt;p&gt;Finally we can test things out. Running an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aws&lt;/code&gt; command will use our default access keys and only have access to assume the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AdminRole&lt;/code&gt;. If we try to list IAM groups we’ll get an error.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;aws iam list-groups

An error occurred &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;AccessDenied&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; when calling the ListGroups operation: User: arn:aws:iam::123456789012:user/username is not authorized to perform: iam:ListGroups on resource: arn:aws:iam::123456789012:group/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we instead add the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--profile admin&lt;/code&gt; argument to our command we’ll be asked to authorize with our configured MFA and then the command can run.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;aws iam list-groups &lt;span class=&quot;nt&quot;&gt;--profile&lt;/span&gt; admin
Enter MFA code &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;arn:aws:iam::123456789012:mfa/username:
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;Groups&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;Path&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;/&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;GroupName&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Administrators&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;GroupId&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;ABPAQDWXIEOQBGZSQSWBN&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;Arn&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::123456789012:group/Administrators&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;CreateDate&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;2020-09-09T14:38:41Z&quot;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
        &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;Path&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;/&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;GroupName&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Users&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;GroupId&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;ABPAQDWXIEOQLAFJFH43Y&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;Arn&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::123456789012:group/Users&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;CreateDate&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;2020-09-09T14:20:32Z&quot;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;It does take a bit of work to set all of this up but ultimately I think it provides a good set up for a personal account. As a review we’ve done the following.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Locked down the root user with MFA and no access keys.&lt;/li&gt;
  &lt;li&gt;Created an IAM user who only has permission to do the following:
    &lt;ul&gt;
      &lt;li&gt;Set a password&lt;/li&gt;
      &lt;li&gt;Configure MFA&lt;/li&gt;
      &lt;li&gt;Assume the role we setup&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Created a role with admin permissions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This set up ensures that when making use of our admin permissions we assume the role and need to enter a MFA token in order for it to work. The assumed role uses transparent temporary credentials that are only good for one hour. If our IAM users access keys are compromised we’ve made sure they don’t have permission to do any harm and the attacker would need our MFA device in order to assume the admin role. I think this set up strikes a good balance between security and usability.&lt;/p&gt;</content><author><name>Scott Knight</name></author><category term="Security" /><category term="AWS" /><category term="Cloud" /><summary type="html">Recently I decided to sit down and futher lock down my personal AWS account. I haven’t used it for much other than S3 storage of macOS installers and in turn had not configured things as securely as I would have liked. The following post walks you through how to lock down an AWS account that is used by a single user. A lot of the recommendations apply just as much to an account with multiple users as well.</summary></entry><entry><title type="html">INIT 29</title><link href="https://knight.sc/malware/2020/05/02/init-29.html" rel="alternate" type="text/html" title="INIT 29" /><published>2020-05-02T00:00:00+00:00</published><updated>2020-05-02T00:00:00+00:00</updated><id>https://knight.sc/malware/2020/05/02/init-29</id><content type="html" xml:base="https://knight.sc/malware/2020/05/02/init-29.html">&lt;p&gt;In my &lt;a href=&quot;/software/2020/04/19/classic-macos-development.html&quot; target=&quot;_blank&quot;&gt;previous post&lt;/a&gt; I covered my “Classic” Mac OS emulator set up. One of my goals of getting the emulator set up was to be able to look at and analyze viruses that affected older versions of Mac OS. I think taking a look at old viruses is interesting for two reasons. First, it provides a good overview of 68k assembly. Second, it provides an interesting perspective on the history of malicious software. The first virus I decided to look at is called INIT 29.&lt;/p&gt;

&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;

&lt;p&gt;The Disinfectant 3.7.1 help file has a good short description of the virus:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The INIT 29 virus first appeared in late 1988. We do not know much about its origin. A second minor variant appeared in March, 1994. There are no significant difference between the two strains. The original strain is called “INIT 29 A”. The variant is called “INIT 29 B”.&lt;/p&gt;

  &lt;p&gt;INIT 29 is extremely virulent. It spreads very rapidly. Unlike Scores and nVIR, you do not have to run an application for it to become infected. Also, unlike Scores and nVIR, INIT 29 can and will infect almost any file, including applications, system files, and document files. Document files are infected, but they are not contagious. The virus can only spread via system files and application files.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;infected-application&quot;&gt;Infected application&lt;/h1&gt;

&lt;p&gt;An application infected with the INIT 29 virus can be easily identified using  &lt;a href=&quot;https://en.wikipedia.org/wiki/ResEdit&quot; target=&quot;_blank&quot;&gt;ResEdit&lt;/a&gt;. See an example in the screenshot below:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/init-29-3.png&quot; alt=&quot;App Jump Table&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The first indicator is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CODE&lt;/code&gt; resource of exactly 712 bytes. The second indicator can be seen in the jump  table. Each executable has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CODE&lt;/code&gt; resource with ID 0 that contains the jump table. If it’s a small application it might only have one or two entries in the table. Normally when the compiler builds an application it would create &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CODE&lt;/code&gt; resources sequentially and similarly the jump table would also be laid out in a linear fashion. The first entry in the jump table points to the main entry point for the executable. In the case of the jump table above, the first entry in the jump table actually points to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CODE&lt;/code&gt; resource with ID 3. You can see based on the resource names that ID 1 has a name of “Main” and is the largest section of code. This should be the entry point to the application but the INIT 29 virus has modified the jump table entry to point to itself instead.&lt;/p&gt;

&lt;p&gt;The image below shows a section of the virus code. You can see how it has saved the original jump table entry to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CODE&lt;/code&gt; resource with ID 1.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/init-29-4.png&quot; alt=&quot;App Virus CODE Resource&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When an infected application is run it will call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UseResFile&lt;/code&gt; passing in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;refNum&lt;/code&gt; value of zero. This will retrieve the System resource file. It will then create a new entry in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INIT&lt;/code&gt; resource section with an ID of 29. This is where the name of the virus comes from. The virus copies all 712 bytes of itself into this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INIT&lt;/code&gt; resource. This code will then be executed when the system starts up next.&lt;/p&gt;

&lt;h1 id=&quot;infected-system-file&quot;&gt;Infected system file&lt;/h1&gt;

&lt;p&gt;An infected System file is also easy to identify using ResEdit. We can run an infected application in our emulator and then use ResEdit to compare the system file before and after detonation.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/init-29-1.png&quot; alt=&quot;System File Infection&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The left side of the image above is before running the infected application and the right side is after. You can see that after the infected application is run there is now a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INIT&lt;/code&gt; resource with the ID 29 and a size of exactly 712 bytes. If we disassemble the virus code we can see the following:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/init-29-2.png&quot; alt=&quot;INIT 29 Code&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INIT&lt;/code&gt; code is fairly short. It calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetTrapAddress&lt;/code&gt; passing in $A997 to get the address of the current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OpenResFile&lt;/code&gt; function. It checks to see if it’s already been patched and if it hasn’t it will save a pointer to the original function. Then it allocates 712 bytes on the system heap and makes a copy of itself there. Finally it calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetTrapAddress&lt;/code&gt; to install itself as the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OpenResFile&lt;/code&gt; function.&lt;/p&gt;

&lt;h1 id=&quot;hijacked-openresfile&quot;&gt;Hijacked OpenResFile&lt;/h1&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OpenResFile&lt;/code&gt; is an important system API. Any time the Finder has to open a file or run an executable it will make use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OpenResFile&lt;/code&gt; to find out information about the file. Since it’s used so often it makes a great hook point for the virus to infect other files. The hijacked version of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OpenResFile&lt;/code&gt; first calls into the original operating system version of the function. This will load the resource file and set it as the current resource. The virus then looks to see if the file has any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CODE&lt;/code&gt; resources or not. If the file doesn’t have any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CODE&lt;/code&gt; resources then the virus creates an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INIT&lt;/code&gt; resource with ID 29 and copies it’s  712 bytes into it. This results in document files that contain the virus code but can’t infect anything else. If the opened resource does have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CODE&lt;/code&gt; resource then the virus attempts to find a free ID to use. It will use the lowest free ID to create a new resource entry and copy it’s 712 bytes into it. After that it opens the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CODE&lt;/code&gt; resource with ID 0 and patches the jump table to point to the new resource that it just created. This results in the application running the virus code the next time it starts attempting to infect the System file.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;With the INIT 29 virus attempting to infect every single resource file opened it’s easy to see why the Disinfectant help file called the virus “extremely virulent”. For the most part the virus is harmless and simply infects files. However, since it does hijack the startup of applications it is possible to notice a  slow down when launching programs. It’s especially interesting to see just how much the virus accomplishes using only 712 bytes of code.&lt;/p&gt;

&lt;h1 id=&quot;iocs&quot;&gt;IOCs&lt;/h1&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Indicator&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Context&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.virustotal.com/gui/file/36ff546b093706c98524657e69b124b4bb8ff763b02ee5a7df3281d5ff7a8d91/detection&quot; target=&quot;_blank&quot;&gt;36ff546b093706c98524657e69b124b4bb8ff763b02ee5a7df3281d5ff7a8d91&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;SHA256&lt;/td&gt;
      &lt;td&gt;Init29.A&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.virustotal.com/gui/file/b40e63e0ae669ed362370e0b05e20067c1e3d285f2532927ee58a5dea275571a/detection&quot; target=&quot;_blank&quot;&gt;b40e63e0ae669ed362370e0b05e20067c1e3d285f2532927ee58a5dea275571a&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;SHA256&lt;/td&gt;
      &lt;td&gt;Init29.C&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.virustotal.com/gui/file/b0318fa75edd599ca739e774fe7a4dcacd2b5e60bcf7830ed45adbbaaacad83a/detection&quot; target=&quot;_blank&quot;&gt;b0318fa75edd599ca739e774fe7a4dcacd2b5e60bcf7830ed45adbbaaacad83a&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;SHA256&lt;/td&gt;
      &lt;td&gt;Init29.C&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.virustotal.com/gui/file/2c08b750c30cbd36827f2ccc01546e4fe3aa5ef86b4fd7a9b65038540849feb8/detection&quot; target=&quot;_blank&quot;&gt;2c08b750c30cbd36827f2ccc01546e4fe3aa5ef86b4fd7a9b65038540849feb8&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;SHA256&lt;/td&gt;
      &lt;td&gt;Init29.C&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;</content><author><name>Scott Knight</name></author><category term="Malware" /><category term="68k" /><category term="Assembly" /><category term="macOS" /><summary type="html">In my previous post I covered my “Classic” Mac OS emulator set up. One of my goals of getting the emulator set up was to be able to look at and analyze viruses that affected older versions of Mac OS. I think taking a look at old viruses is interesting for two reasons. First, it provides a good overview of 68k assembly. Second, it provides an interesting perspective on the history of malicious software. The first virus I decided to look at is called INIT 29.</summary></entry><entry><title type="html">Classic Mac OS development</title><link href="https://knight.sc/software/2020/04/19/classic-macos-development.html" rel="alternate" type="text/html" title="Classic Mac OS development" /><published>2020-04-19T00:00:00+00:00</published><updated>2020-04-19T00:00:00+00:00</updated><id>https://knight.sc/software/2020/04/19/classic-macos-development</id><content type="html" xml:base="https://knight.sc/software/2020/04/19/classic-macos-development.html">&lt;p&gt;Before macOS, and before OS X, there was just Mac OS. This is often referred to as “Classic” Mac OS. It includes System 1 all the way up to Mac OS 9.x. I started using a Mac with System 6 on a Macintosh Classic. Then I moved up to a Macintosh IIsi running System 7. Finally, after the PowerPC transition, I used a Power Macintosh 8500 which ran all of the later versions of “Classic” Mac OS. I was recently having a conversation with another developer who grew up using Macintosh computers and we were both reminiscing about some of our early development experiences on Mac. While System 6 was the first Mac OS version I used, I didn’t start really writing Mac apps until the Mac OS 8 era. This got me thinking that it might be interesting to spend some time re-learning “Classic” Mac OS app development.&lt;/p&gt;

&lt;p&gt;As I mentioned previously I didn’t really start programming until Mac OS 8 and by then CodeWarrior had solidly cemented itself as the IDE of choice for Mac developers. I decided for this exploration that I wanted to stick to early Mac software as much as possible. I chose to only look for tools that were available for Mac prior to the 1990s.&lt;/p&gt;

&lt;h1 id=&quot;emulation&quot;&gt;Emulation&lt;/h1&gt;

&lt;p&gt;Since I no longer have any physical “Classic” Mac hardware I decided to turn to emulation. I’ll go over some of the more populator emulators and why I chose the one I did.&lt;/p&gt;

&lt;h2 id=&quot;sheepshaver&quot;&gt;SheepShaver&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://sheepshaver.cebix.net/&quot; target=&quot;_blank&quot;&gt;https://sheepshaver.cebix.net/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SheepShaver emulates a Power PC Macintosh. It was originally created for BeOS back in 1998. Since then, it has become an open source project. It’s capable of running Mac OS 7.5.2 through 9.0.4. If you’re interested in running the more recent versions of “Classic” Mac OS this is probably the emulator you should choose. Mac OS 7.5.2 was released in 1995 and in turn SheepShaver doesn’t fit my criteria of sticking to software and tools available prior to the 1990s.&lt;/p&gt;

&lt;h2 id=&quot;basilisk-ii&quot;&gt;Basilisk II&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://basilisk.cebix.net/&quot; target=&quot;_blank&quot;&gt;https://basilisk.cebix.net/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basilisk II emulates a 68k Macintosh. Originally released in 1997 by the same developer as SheepShaver. It’s capable of running up to Mac OS 8.1. This is another very popular emulator and a lot of people looking to emulate 68k Macintoshes choose this one. It is also open source, however it is no longer being maintained.&lt;/p&gt;

&lt;h2 id=&quot;mini-vmac&quot;&gt;Mini vMac&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.gryphel.com/c/minivmac/&quot; target=&quot;_blank&quot;&gt;https://www.gryphel.com/c/minivmac/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mini vMac is a spinoff of the &lt;a href=&quot;http://www.vmac.org/&quot; target=&quot;_blank&quot;&gt;vMac&lt;/a&gt; project. It also emulates a 68k Macintosh. It has a focus on the early Macs with the default build emulating a Macintosh Plus. Mini vMac is capable of emulating up to Mac OS 7.5.5. It’s also open source and unlike Basilisk II is still being maintained.&lt;/p&gt;

&lt;p&gt;So what’s the difference between Mini vMac and Basilisk II? The FAQ page for Mini vMac has a great explanation.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The biggest current difference is that Mini vMac emulates the earliest Macs, while Basilisk II emulates later 680x0 Macs. The fundamental technical difference is that Basilisk II doesn’t emulate hardware, but patches the drivers in ROM, while Mini vMac emulates the hardware (with the exception of the floppy drive).&lt;/p&gt;

  &lt;p&gt;The consequences are that some of the earliest Mac software will run in Mini vMac and not Basilisk II, while much of the later software will run in Basilisk II and not Mini vMac. For software that will run in either, the emulation in Mini vMac can be more accurate, while Basilisk II offers many more features (including color, larger screen, more memory, network access, and more host integration).&lt;/p&gt;

  &lt;p&gt;Mini vMac aims to stay simple and maintainable. So Mini vMac only has compile time preferences, where as Basilisk II has many run time preferences. And Mini vMac uses a rather simple emulation of the processor, compared to Basilisk II, which could make Mini vMac slower.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The fact that Mini vMac focuses on early Macs and ealy Mac software it fit my criteria well. It has a good &lt;a href=&quot;https://www.gryphel.com/c/minivmac/start.html&quot; target=&quot;_blank&quot;&gt;Getting Started&lt;/a&gt; page as well as a collection of other &lt;a href=&quot;https://www.gryphel.com/c/minivmac/recipes/index.html&quot; target=&quot;_blank&quot;&gt;Tutorials&lt;/a&gt; to help you get system software and get up and running. I went through all of the tutorials and now have a working emulated Mac Plus running System 6.0.8.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/classic-macos-development-1.png&quot; alt=&quot;Mini vMac Screenshot&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;software&quot;&gt;Software&lt;/h1&gt;

&lt;p&gt;With an emulator up and running I next needed to find software. Luckily, there are a few sites that host repositories of software for old Mac OS versions. The following sites have been some of the most helpful in terms of finding old software:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.gryphel.com/c/sw/index.html&quot; target=&quot;_blank&quot;&gt;https://www.gryphel.com/c/sw/index.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://macintoshgarden.org/&quot; target=&quot;_blank&quot;&gt;https://macintoshgarden.org/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.macintoshrepository.org/&quot; target=&quot;_blank&quot;&gt;https://www.macintoshrepository.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;ides&quot;&gt;IDEs&lt;/h1&gt;

&lt;p&gt;I mentioned earlier that CodeWarrior was the IDE of choice when I started Mac development but since it came out in the 90s it didn’t fit my criteria for early Mac development. Additionally while C/C++ had become the language of choice for the Mac in the 90s, back in the 80s Pascal was by far more common. I also needed an IDE that supported System 6.&lt;/p&gt;

&lt;p&gt;While looking for Pascal compilers I came across two main contenders: Borland Turbo Pascal and THINK Pascal. Both seemed like good potential candidates. They had versions that came out in the late 80s and supported System 6. THINK Pascal seemed to be fairly popular during the era.&lt;/p&gt;

&lt;p&gt;An alternative, that I had used a handful of times before CodeWarrior, was the Macintosh Programmer’s Workshop (MPW). MPW was the development environment provided by Apple. In the 80s it was quite expensive. It had a 68k assembler, a pascal compiler, and (new for MPW 2.0) a C compiler as well. This seemed like a fun choice because of the range of languages supported but also because it was the official offerring provided by Apple. After downloading MPW 2.0 from the software links above I had a working development environment.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/classic-macos-development-2.png&quot; alt=&quot;Mini vMac Screenshot&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;books&quot;&gt;Books&lt;/h1&gt;

&lt;p&gt;The last thing I needed were some good programming books from the time period. I found a wonderful resource in the Vintage Apple website.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://vintageapple.org/macprogramming/&quot; target=&quot;_blank&quot;&gt;https://vintageapple.org/macprogramming/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s a list of the books I’ve found most useful so far:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://vintageapple.org/inside_o/pdf/Inside_Macintosh_Volume_I_1985.pdf&quot; target=&quot;_blank&quot;&gt;Inside Macintosh Volume I&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://vintageapple.org/inside_o/pdf/Inside_Macintosh_Volume_II_1985.pdf&quot; target=&quot;_blank&quot;&gt;Inside Macintosh Volume II&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://vintageapple.org/inside_o/pdf/Inside_Macintosh_Volume_III_1985.pdf&quot; target=&quot;_blank&quot;&gt;Inside Macintosh Volume III&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://vintageapple.org/inside_o/pdf/Inside_Macintosh_Volume_IV_1986.pdf&quot; target=&quot;_blank&quot;&gt;Inside Macintosh Volume IV&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://vintageapple.org/macprogramming/pdf/MPW_and_Assembly_Language_Programming_for_the_Macintosh_1987.pdf&quot; target=&quot;_blank&quot;&gt;MPW and Assembly Language Programming for the Macintosh&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://vintageapple.org/macprogramming/pdf/Programming_With_Macintosh_Programmers_Workshop_1987.pdf&quot; target=&quot;_blank&quot;&gt;Programming with Macintosh Programmers Workshop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inside Macintosh Volumes I - III cover everything you would ever want to know about the early Mac and how it worked. It also covers all of the OS managers and their API’s as well. Inside Macintosh Volume IV covers changes for the Macintosh Plus, which is helpful since Mini vMac emulates a Macintosh Plus. The other two books have some good information about MPW itself and how it works as well as some okay intro to Mac programming.&lt;/p&gt;

&lt;h1 id=&quot;whats-next&quot;&gt;What’s Next?&lt;/h1&gt;

&lt;p&gt;With an emulated Mac configured and an IDE chosen I’ve started to write some little test programs in Pascal. While I’ve never written a Mac program in Pascal, I have written many Delphi applications on Windows. I’ve also started to search out some old Mac viruses from the 80s to take a look at how they worked. Overall, I find it a nice change of pace to be able to boot into System 6, do some coding, play some old games and remember a time when computers were a lot less complicated to use.&lt;/p&gt;</content><author><name>Scott Knight</name></author><category term="Software" /><category term="68k" /><category term="Assembly" /><category term="macOS" /><category term="Pascal" /><summary type="html">Before macOS, and before OS X, there was just Mac OS. This is often referred to as “Classic” Mac OS. It includes System 1 all the way up to Mac OS 9.x. I started using a Mac with System 6 on a Macintosh Classic. Then I moved up to a Macintosh IIsi running System 7. Finally, after the PowerPC transition, I used a Power Macintosh 8500 which ran all of the later versions of “Classic” Mac OS. I was recently having a conversation with another developer who grew up using Macintosh computers and we were both reminiscing about some of our early development experiences on Mac. While System 6 was the first Mac OS version I used, I didn’t start really writing Mac apps until the Mac OS 8 era. This got me thinking that it might be interesting to spend some time re-learning “Classic” Mac OS app development.</summary></entry><entry><title type="html">Audit tokens explained</title><link href="https://knight.sc/reverse%20engineering/2020/03/20/audit-tokens-explained.html" rel="alternate" type="text/html" title="Audit tokens explained" /><published>2020-03-20T00:00:00+00:00</published><updated>2020-03-20T00:00:00+00:00</updated><id>https://knight.sc/reverse%20engineering/2020/03/20/audit-tokens-explained</id><content type="html" xml:base="https://knight.sc/reverse%20engineering/2020/03/20/audit-tokens-explained.html">&lt;p&gt;The recent &lt;a href=&quot;https://objectivebythesea.com/v3/content.html&quot; target=&quot;_blank&quot;&gt;Objective by the Sea v3.0&lt;/a&gt; conference had a lot of great talks. Two that stood out to me were &lt;a href=&quot;https://www.securing.biz/en/abusing-securing-xpc-in-macos-apps/index.html&quot; target=&quot;_blank&quot;&gt;&lt;em&gt;Abusing and Securing XPC in macOS Apps&lt;/em&gt;&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/_r3ggi&quot; target=&quot;_blank&quot;&gt;Wojciech Reguła&lt;/a&gt; and &lt;a href=&quot;https://speakerdeck.com/vashchenko/job-s-bless-us-privileged-operations-on-macos&quot; target=&quot;_blank&quot;&gt;&lt;em&gt;Job(s) Bless Us! Privileged Operations on macOS&lt;/em&gt;&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/iaronskaya&quot; target=&quot;_blank&quot;&gt;Julia Vashchenko&lt;/a&gt;. Both talks discussed different aspects of XPC services and the types of security bugs that can occur in them. There were some great best practice recommendations that both speakers shared for securing your own XPC services. One of those recommendations was to use the audit token rather than PID when checking the connecting process. Since the audit token APIs aren’t public I thought it would be interesting to take a closer look at what audit tokens actually are and where they come from.&lt;/p&gt;

&lt;h1 id=&quot;pid-vs-audit-token&quot;&gt;PID vs. audit token&lt;/h1&gt;

&lt;p&gt;I think it’s worth brielfy covering the XPC best practice around PID vs. audit token before diving into the history and internals of the audit token itself. A XPC service listener has the chance to accept or deny an incoming connections. The most common way to validate the incoming connection is to make use of the &lt;a href=&quot;https://developer.apple.com/documentation/security&quot; target=&quot;_blank&quot;&gt;Security framework&lt;/a&gt; provided by Apple. This framework provides a way to access the code signing information of the remote process and you can then check to make sure the calling process is validly signed by your own company. A common way to get access to the code signing information is to do something like the following:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;SecCodeRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;NSDictionary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;kSecGuestAttributePid:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;processIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SecCodeCopyGuestWithAttributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kSecCSDefaultFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The issue with this is since it only uses PID to locate the process, and PIDs wrap around and can be reused, it’s possible to race the code signing verification and trick it into checking a different binary. &lt;a href=&quot;https://twitter.com/i41nbeer&quot; target=&quot;_blank&quot;&gt;Ian Beer&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/5aelo&quot; target=&quot;_blank&quot;&gt;Samuel Groß&lt;/a&gt; both have some good descriptions of this issue:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://bugs.chromium.org/p/project-zero/issues/detail?id=1223&quot; target=&quot;_blank&quot;&gt;https://bugs.chromium.org/p/project-zero/issues/detail?id=1223&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://saelo.github.io/presentations/warcon18_dont_trust_the_pid.pdf&quot; target=&quot;_blank&quot;&gt;https://saelo.github.io/presentations/warcon18_dont_trust_the_pid.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fix for the code above is to do the following:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;SecCodeRef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;NSDictionary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;kSecGuestAttributeAudit:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auditToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SecCodeCopyGuestWithAttributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kSecCSDefaultFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There’s one catch with this updated code. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auditToken&lt;/code&gt; property is not a public property of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSXPCConnection&lt;/code&gt;. &lt;a href=&quot;https://twitter.com/_r3ggi&quot; target=&quot;_blank&quot;&gt;Wojciech Reguła&lt;/a&gt; has a great &lt;a href=&quot;https://github.com/securing/SimpleXPCApp/blob/master/SimpleXPCService/AuditTokenHack.h#L5&quot; target=&quot;_blank&quot;&gt;sample XPC application&lt;/a&gt; that shows an easy way to access this private property. As we’ll see shortly, making use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auditToken&lt;/code&gt; allows the &lt;a href=&quot;https://developer.apple.com/documentation/security&quot; target=&quot;_blank&quot;&gt;Security framework&lt;/a&gt; to use the internal fields to ensure the connecting process is the one the XPC service thinks it is.&lt;/p&gt;

&lt;h1 id=&quot;the-history-of-audit-tokens&quot;&gt;The history of audit tokens&lt;/h1&gt;

&lt;p&gt;The audit token mentioned above is actually part of the &lt;a href=&quot;https://github.com/openbsm/openbsm&quot; target=&quot;_blank&quot;&gt;OpenBSM&lt;/a&gt; subsytem in macOS. OpenBSM is an open source implementation of Sun’s Basic Security Module (BSM) security audit API and file format. Back in 2003 Apple decided to submit macOS to the National Information Assurance Partnership (NIAP) for &lt;a href=&quot;https://www.commoncriteriaportal.org&quot; target=&quot;_blank&quot;&gt;Common Criteria&lt;/a&gt; certification. As part of preparing for this certification Apple contracted McAfee to port the Solaris BSM implementation to macOS.&lt;/p&gt;

&lt;p&gt;The BSM code can be seen in the XNU kernel as far back as &lt;a href=&quot;https://opensource.apple.com/tarballs/xnu/xnu-517.tar.gz&quot; target=&quot;_blank&quot;&gt;xnu-517&lt;/a&gt; which was released in October of 2003 as part of macOS 10.3.0. It wasn’t until more than a year later in November of 2004 when macOS 10.3.6 was released that end users could actually optionaly install the ported BSM code to enable auditing on their macOS systems. Shortly after the macOS 10.3.6 release Apple did &lt;a href=&quot;https://web.archive.org/web/20060524215244/http://niap.nist.gov/cc-scheme/st/ST_VID4012.html&quot; target=&quot;_blank&quot;&gt;officially receive&lt;/a&gt; Common Criteria certification. This certification validated macOS for high security uses such as by the U.S. Government.&lt;/p&gt;

&lt;p&gt;Apple eventualy relicensed their BSM port under the BSD license to allow integration into FreeBSD and other systems. This code base is what eventually became the &lt;a href=&quot;https://github.com/openbsm/openbsm&quot; target=&quot;_blank&quot;&gt;OpenBSM&lt;/a&gt; project.&lt;/p&gt;

&lt;h1 id=&quot;kernel-implementation&quot;&gt;Kernel implementation&lt;/h1&gt;

&lt;p&gt;Now that we know some of the history behind the audit token lets actually take a look at what it is and how the kernel implements and stores it. We start be taking a look at the definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; itself.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/*
 * The audit token is an opaque token which identifies
 * Mach tasks and senders of Mach messages as subjects
 * to the BSM audit system.  Only the appropriate BSM
 * library routines should be used to interpret the
 * contents of the audit token as the representation
 * of the subject identity within the token may change
 * over time.
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;                  &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;audit_token_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can already start to see why the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auditToken&lt;/code&gt; property of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSXPCConnection&lt;/code&gt; is marked as private. The comment explicitly mentions that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; structure is meant to be opaque and only the appropriatee BSM library routines should be used to interpret its contents.&lt;/p&gt;

&lt;h2 id=&quot;task-structure&quot;&gt;task structure&lt;/h2&gt;

&lt;p&gt;Continuing on in the kernel code if we search for other structures that make use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; we find the following:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/* Synchronization/destruction information */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;decl_lck_mtx_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;               &lt;span class=&quot;cm&quot;&gt;/* Task's lock */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;os_refcnt_t&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;ref_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;cm&quot;&gt;/* Number of references to me */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;boolean_t&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;         &lt;span class=&quot;cm&quot;&gt;/* Task has not been terminated */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;boolean_t&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;halting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;cm&quot;&gt;/* Task is being halted */&lt;/span&gt;    
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;

    &lt;span class=&quot;cm&quot;&gt;/* Task security and audit tokens */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;security_token_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sec_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;audit_token_t&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&lt;/code&gt; is one of the fundamental structures of the Mach portion of the XNU kernel. It represents a collection of resources, virtual address space, and a port name space. It contains a queue of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thread&lt;/code&gt; structures which are what are actually responsible for running code. Searching further through the code we can find the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int set_security_token_task_internal(proc_t p, void *t)&lt;/code&gt; function which actually sets the fields of the audit token. Here’s an excerpt from that function:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;my_cred&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kauth_cred_proc_ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;my_pcred&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;posix_cred_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_cred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
 * The current layout of the Mach audit token explicitly
 * adds these fields.  But nobody should rely on such
 * a literal representation.  Instead, the BSM library
 * provides a function to convert an audit token into
 * a BSM subject.  Use of that mechanism will isolate
 * the user of the trailer from future representation
 * changes.
 */&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_cred&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cr_audit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_aia_p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ai_auid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_pcred&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cr_uid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_pcred&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cr_gid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_pcred&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cr_ruid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_pcred&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cr_rgid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p_pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_cred&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cr_audit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_aia_p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ai_asid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p_idversion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Again, we see mention in the comments that only the appropriate BSM library functions should be used to interpret an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; structure. If we look in the OpenBSM code, we can see that the function &lt;a href=&quot;https://github.com/openbsm/openbsm/blob/master/libbsm/bsm_wrappers.c#L470&quot; target=&quot;_blank&quot;&gt;audit_token_to_au32&lt;/a&gt; is the function that should be used to extract the contents out of an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; structure.&lt;/p&gt;

&lt;p&gt;Now that we know a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tasks&lt;/code&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token&lt;/code&gt; field is set from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_security_token_task_internal&lt;/code&gt; lets continue further to see where this code is actually called from. There are three functions that call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_security_token_task_internal&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exec_handle_sugid&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_session_join_internal&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_security_token&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll ignore the first two and instead focus on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_security_token&lt;/code&gt; for now. Searching for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_security_token&lt;/code&gt; we see the following call sites:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;load_init_program_at_path&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fork1&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setuid&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;seteuid&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setreuid&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setgid&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setegid&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setregid&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setgroups_internal&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;persona_proc_adopt&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_session_setaia&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;load_init_program_at_path&lt;/code&gt; is responsible for starting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;launchd&lt;/code&gt;. The call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_security_token&lt;/code&gt; here ensures that even the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;launchd&lt;/code&gt; process has an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token&lt;/code&gt; set on its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&lt;/code&gt; structure. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fork1&lt;/code&gt; function is eventually called from either the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fork&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vfork&lt;/code&gt; system calls. Since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fork&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vfork&lt;/code&gt; are responsible for creating new processes in the system it ensures all new processes also have an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token&lt;/code&gt; set on their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&lt;/code&gt; structure. All of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setXXX&lt;/code&gt; functions are responsible for changing a field that is also stored as part of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; structure. It makes sense that if any of those fields change then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; values should also be updated. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;persona_proc_adopt&lt;/code&gt; is part of the persona subsystem. The persona subsystem provides a mechanism for a process or thread to assume a uid, gid and group memberships all at once. So again this is similar to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setXXX&lt;/code&gt; functions. Since the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; structure stores some of the audit session related identifiers we also have a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_security_token&lt;/code&gt; from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_session_setaia&lt;/code&gt; which is responsible for updating credentials of a process based on new audit info.&lt;/p&gt;

&lt;p&gt;All of these calls just go to ensure that a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&lt;/code&gt; always has it’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token&lt;/code&gt; field populated and updated appropriately throughout it’s lifetime. It is actually possible to retrieve a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&lt;/code&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token&lt;/code&gt; using the Mach &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task_info&lt;/code&gt; API. Here’s a short example:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;audit_token_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;mach_msg_type_number_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TASK_AUDIT_TOKEN_COUNT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;kr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;task_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mach_task_self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TASK_AUDIT_TOKEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task_info_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KERN_SUCCESS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error getting task audit_token&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;        
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There is actually another Mach API call to set a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&lt;/code&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token&lt;/code&gt; called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;host_security_set_task_token&lt;/code&gt;. The first parameter of the function is the host security port which is not accessible from user space at all. So in practice only the kernal can change a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&lt;/code&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;mach-message-trailers&quot;&gt;mach message trailers&lt;/h2&gt;

&lt;p&gt;If we continue searching through the XNU source for usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; we come across the following structure:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mach_msg_trailer_type_t&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;msgh_trailer_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mach_msg_trailer_size_t&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;msgh_trailer_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mach_port_seqno_t&lt;/span&gt;             &lt;span class=&quot;n&quot;&gt;msgh_seqno&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;security_token_t&lt;/span&gt;              &lt;span class=&quot;n&quot;&gt;msgh_sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;audit_token_t&lt;/span&gt;                 &lt;span class=&quot;n&quot;&gt;msgh_audit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mach_msg_audit_trailer_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Mach messages can optionally have message trailers appended to them. Trailers are not settable from user space and can only be set by the kernel. The contents of the trailer are assumed to be trusted since only the kernel can set them. If we further search the code for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msgh_audit&lt;/code&gt; we can find the following call sites:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ipc_kmsg_get&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ipc_kmsg_get_from_kernel&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mach_msg_send&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mach_msg_overwrite&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the core mach messaging functions of the kernel and each one has a section of code similar to the following:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/*
 * reserve for the trailer the largest space (MAX_TRAILER_SIZE)
 * However, the internal size field of the trailer (msgh_trailer_size)
 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize
 * the cases where no implicit data is requested.
 */&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;trailer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mach_msg_max_trailer_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vm_offset_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kmsg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ikm_header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;send_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;trailer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_sender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current_thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sec_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;trailer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_audit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current_thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;trailer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_trailer_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MACH_MSG_TRAILER_FORMAT_0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;trailer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_trailer_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MACH_MSG_TRAILER_MINIMUM_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As part of the mach message routines the kernel will allocate a trailer structure of the maximum size possible. When the message is copied back to user space of the receiving process only the portion of the trailer requested will be delivered.&lt;/p&gt;

&lt;p&gt;This is a really interesting feature because it means as part of every Mach message sent it’s possible to have the sender’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token&lt;/code&gt; value sent along with it. Here’s a short example of how this can be done.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mach_msg_header_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mach_msg_audit_trailer_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trailer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;mach_port_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;server_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;kern_return_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;kr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mach_port_allocate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mach_task_self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MACH_PORT_RIGHT_RECEIVE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;server_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KERN_SUCCESS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error allocating port&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mach_msg_option_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MACH_RCV_MSG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MACH_RCV_TRAILER_TYPE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MACH_RCV_TRAILER_AUDIT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MACH_RCV_TRAILER_ELEMENTS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MACH_RCV_TRAILER_AUDIT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;kr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mach_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;server_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;MACH_MSG_TIMEOUT_NONE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;MACH_PORT_NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KERN_SUCCESS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error receiving mach message 0x%x&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pid  %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;trailer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msgh_audit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;csops_audittoken-system-call&quot;&gt;csops_audittoken system call&lt;/h2&gt;

&lt;p&gt;Continuing our search through the XNU source code there’s one more place worth mentioning making use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; structure. Suprisingly it’s a portion of the code that doesn’t seem to have anything to do with the OpenBSM subsystem. It’s part of the code signing system calls. There’s two system calls implemented in XNU to support code signing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int csops(pid_t pid, unsigned int  ops, void * useraddr, size_t usersize);&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int csops_audittoken(pid_t pid, unsigned int  ops, void * useraddr, size_t usersize, audit_token_t * token);&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These system calls get used by the Security framework to support checking code signing attributes of processes. Both of them will call into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;csops_internal&lt;/code&gt; function. If we look into that code we can see how the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; gets used:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;pt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proc_find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PROC_NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ESRCH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;upid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p_pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;uidversion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p_idversion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uaudittoken&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USER_ADDR_NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copyin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uaudittoken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;audit_token_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/* verify the audit token pid/idversion matches with proc */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uidversion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ESRCH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;csops_audittoken&lt;/code&gt; version of the system call is used the code will perform an additional check to make sure the process looked up by PID actually matches the values on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt;. The key is to make use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_idversion&lt;/code&gt; field in addition to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_pid&lt;/code&gt;. This prevents the PID reuse vulnerability that was mentioned at the start of this write up.&lt;/p&gt;

&lt;h1 id=&quot;xpc-and-audit-tokens&quot;&gt;XPC and audit tokens&lt;/h1&gt;

&lt;p&gt;Now that we know how the kernel implements and stores the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; we can take a closer look at XPC and how it makes use of the functionality. Unfortunately &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libxpc.dylib&lt;/code&gt; is not open source so we’ll have to do some reverse engineering to understand what’s going on. If you’re using the XPC C API instead of the higher level Objective-C API the way to get a connection’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; is to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;void xpc_connection_get_audit_token(xpc_connection_t, audit_token_t *);&lt;/code&gt;. If we disassemble &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_get_audit_token&lt;/code&gt; we see the following:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;__fastcall&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;xpc_connection_get_audit_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_QWORD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_QWORD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rax&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;os_unfair_lock_lock_with_options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;84&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x10000LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os_unfair_lock_unlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;84&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since we don’t have any source for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libxpc.dylib&lt;/code&gt; we’ll do some guess work here but the function is pretty straight forward. It simply accesses internal fields of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_t&lt;/code&gt; structure passed in and copies it to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; pointer. I would guess that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_t&lt;/code&gt; structure actually has an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; field within it. Based on this knowledge we can continue our search looking for where this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_t&lt;/code&gt; field gets set. With a short amount of digging we can find the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_set_creds&lt;/code&gt; function. Disassembled it looks like the mirror opposite of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_get_audit_token&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;__int64 __fastcall _xpc_connection_set_creds(_QWORD *a1, __int64 a2)
{
    __int64 *v2; // r14
    __int64 v3; // rax

    v2 = (__int64 *)_xpc_mach_msg_get_audit_token(a2);
    os_unfair_lock_lock_with_options((char *)a1 + 84, 0x10000LL);
    a1[15] = v2[3];
    a1[14] = v2[2];
    v3 = *v2;
    a1[13] = v2[1];
    a1[12] = v3;
    return os_unfair_lock_unlock((char *)a1 + 84);
}

unsigned __int64 __fastcall _xpc_mach_msg_get_audit_token(__int64 a1)
{
    return a1 + ((*(unsigned int *)(a1 + 4) + 3LL) &amp;amp; 0xFFFFFFFFFFFFFFFCLL) + 20;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From here we can search for all the callers of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_set_creds&lt;/code&gt; and find the following functions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_mach_event&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_unpack_message&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_mach_event&lt;/code&gt; function is called from two other functions: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_create&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_set_event_handler2&lt;/code&gt;. In both cases the functions that use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_mach_event&lt;/code&gt; pass it into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libdispatch&lt;/code&gt; event handler for handling Mach messages. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_unpack_message&lt;/code&gt; itself is called from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_mach_event&lt;/code&gt; as well as two other XPC message sending functions.&lt;/p&gt;

&lt;p&gt;Based on what we know about the kernel implementation and the disassembly and function names above it’s safe to say that XPC is retrieving the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; from the mach message trailer for each message that it receives. It will then call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_xpc_connection_set_creds&lt;/code&gt; passing in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_t&lt;/code&gt; structure as well as the mach message to ensure that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; field of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_t&lt;/code&gt; is up to date.&lt;/p&gt;

&lt;p&gt;We can verify this through an XPC test application by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_get_audit_token&lt;/code&gt; in our server process when the client first connects, then have the client call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setuid&lt;/code&gt; (which will force the kernel to update the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task&lt;/code&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token&lt;/code&gt;) and then send a message to the server. The server can then call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_get_audit_token&lt;/code&gt; again and see that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; values have been updated.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;After diving into all the details of what an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; is, and how it gets used, I think it’s important to take a step back. We started this journey by discussing an XPC service best practice of using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; rather than the PID to verify the code signing of an incoming connection. With the knowledge of all the internals we can now more clearly say why this is more secure. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;audit_token_t&lt;/code&gt; contains not just the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_pid&lt;/code&gt; of the incoming process but also the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_idversion&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_idversion&lt;/code&gt; is what allows the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;csops_audittoken&lt;/code&gt; system call to make sure that the process we’re checking code signing on actually matches what we expect. It prevents the race condition of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_pid&lt;/code&gt; looping back around and the server blindly trusting that it’s the same process.&lt;/p&gt;</content><author><name>Scott Knight</name></author><category term="Reverse Engineering" /><category term="Kernel" /><category term="macOS" /><category term="XPC" /><summary type="html">The recent Objective by the Sea v3.0 conference had a lot of great talks. Two that stood out to me were Abusing and Securing XPC in macOS Apps by Wojciech Reguła and Job(s) Bless Us! Privileged Operations on macOS by Julia Vashchenko. Both talks discussed different aspects of XPC services and the types of security bugs that can occur in them. There were some great best practice recommendations that both speakers shared for securing your own XPC services. One of those recommendations was to use the audit token rather than PID when checking the connecting process. Since the audit token APIs aren’t public I thought it would be interesting to take a closer look at what audit tokens actually are and where they come from.</summary></entry><entry><title type="html">Building XNU 6153.11.26 (almost)</title><link href="https://knight.sc/debugging/2020/02/18/building-xnu.html" rel="alternate" type="text/html" title="Building XNU 6153.11.26 (almost)" /><published>2020-02-18T00:00:00+00:00</published><updated>2020-02-18T00:00:00+00:00</updated><id>https://knight.sc/debugging/2020/02/18/building-xnu</id><content type="html" xml:base="https://knight.sc/debugging/2020/02/18/building-xnu.html">&lt;p&gt;A couple weeks ago Apple finally released the XNU source code for macOS Catalina. It looks like they have now added more of the open source packages needed to build the entire XNU kernel, so it’s time to update my build instructions.&lt;/p&gt;

&lt;p&gt;If you’re interested in looking through what’s new or changed in the latest XNU code, you can look at a diff of the latest source here:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/knightsc/darwin-xnu/commit/21722f3926534b9dab63b1194b0136ddd6d1fc24&quot; target=&quot;_blank&quot;&gt;https://github.com/knightsc/darwin-xnu/commit/21722f3926534b9dab63b1194b0136ddd6d1fc24&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first issue that I ran into was compilation issues with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dtrace-338.0.1&lt;/code&gt;. It looks like Apple is now including a handful of llvm header files as part of dtrace in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include&lt;/code&gt; subfolder. One of those files &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include/llvm-Support/PointerLikeTypeTraits.h&lt;/code&gt; still references a file from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;llvmCore&lt;/code&gt; folder structure. So in order to get the dtrace tools to compile I had to generate the missing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataTypes.h&lt;/code&gt; file and update &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PointerLikeTypeTraits.h&lt;/code&gt; to reference it.&lt;/p&gt;

&lt;p&gt;With this dtrace header fix in place the build script will run through and generate all of the depedencies needed to try to compile the kernel. Unfortunately it looks like there are some errors compiling the kernel itself that I’m still looking into.&lt;/p&gt;

&lt;p&gt;For now if you want to follow along at home, here’s a bash script to automate the entire process of building a DEBUG kernel. (Note: It pulls the fixed dtrace header files from gists I’ve created.):&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/knightsc/abbee4ac48b0a43198f5ae39c0f8843f.js&quot;&gt;&lt;/script&gt;</content><author><name>Scott Knight</name></author><category term="Debugging" /><category term="C" /><category term="Kernel" /><category term="macOS" /><summary type="html">A couple weeks ago Apple finally released the XNU source code for macOS Catalina. It looks like they have now added more of the open source packages needed to build the entire XNU kernel, so it’s time to update my build instructions.</summary></entry><entry><title type="html">CoreServicesUIAgent internals</title><link href="https://knight.sc/reverse%20engineering/2019/12/24/coreservicesuiagent-internals.html" rel="alternate" type="text/html" title="CoreServicesUIAgent internals" /><published>2019-12-24T00:00:00+00:00</published><updated>2019-12-24T00:00:00+00:00</updated><id>https://knight.sc/reverse%20engineering/2019/12/24/coreservicesuiagent-internals</id><content type="html" xml:base="https://knight.sc/reverse%20engineering/2019/12/24/coreservicesuiagent-internals.html">&lt;p&gt;The recent release of macOS 10.15.2 had some additional updates to the Xprotect yara rules within it. After reviewing &lt;a href=&quot;https://github.com/knightsc/XProtect/commit/750e22c1bd870f8ee8f0f5ec9b6d410f0c90a0e3&quot; target=&quot;_blank&quot;&gt;what changed&lt;/a&gt; in the yara rules I decided to dig a little deeper into how Xprotect gets called. Jonathan Levin’s excellent book &lt;a href=&quot;https://www.amazon.com/MacOS-iOS-Internals-III-Insecurity/dp/0991055535/&quot; target=&quot;_blank&quot;&gt;MacOS and iOS Internals, Volume III: Security &amp;amp; Insecurity&lt;/a&gt; briefly talks about Gatekeeper and Xprotect but didn’t have the internals I was looking for. I ended up finding Patrick Wardle’s excellent &lt;a href=&quot;https://www.virusbulletin.com/uploads/pdf/conference_slides/2015/Wardle-VB2015.pdf&quot; target=&quot;_blank&quot;&gt;presentation&lt;/a&gt; from the 2015 Virus Bulletin Conference. His slide deck does a great job of explinaing the communication between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;XprotectService&lt;/code&gt;. It did, however, make me question what all does &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; do? This posts digs into the internals of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; and documents its functionality.&lt;/p&gt;

&lt;h1 id=&quot;coreservicesuiagent&quot;&gt;CoreServicesUIAgent&lt;/h1&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; has the responsibility of providing the occasional GUI to the end user when various other system frameworks need user input. The app bundle can be found in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/System/Library/CoreServices/CoreServicesUIAgent.app&lt;/code&gt; and is installed as a LaunchAgent via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/System/Library/LaunchAgents/com.apple.coreservices.uiagent.plist&lt;/code&gt;. The LaunchAgent plist is short enough that I’ll include the whole thing here:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;plist&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;version=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;Label&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;com.apple.coreservices.uiagent&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;Program&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;/System/Library/CoreServices/CoreServicesUIAgent.app/Contents/MacOS/CoreServicesUIAgent&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;MachServices&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.coreservices.code-evaluation&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.coreservices.quarantine-resolver&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;EnablePressuredExit&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;EnableTransactions&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;POSIXSpawnType&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Interactive&lt;span class=&quot;nt&quot;&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When a user logs into the system, an instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; is started and we can see from the plist that it has two Mach services that it provides. I’ll start the exploration of the binary by looking at what it does at startup and then dive into each of the services.&lt;/p&gt;

&lt;h2 id=&quot;initialization&quot;&gt;Initialization&lt;/h2&gt;

&lt;p&gt;If we look at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; binary the application delegate class is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CSUIController&lt;/code&gt;. Looking at this class we can see what happens when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; starts up.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;com.apple.coreservices.uiagent.active-handler-queue&lt;/code&gt; dispatch queue&lt;/li&gt;
  &lt;li&gt;Register a handful of message handlers (quarantine, launch error, file open, check access, etc)&lt;/li&gt;
  &lt;li&gt;Register to listen for locale changes&lt;/li&gt;
  &lt;li&gt;Create a new instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CSUICodeEvaluationController&lt;/code&gt;, which in turn creates the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSXPCListener&lt;/code&gt; object for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;com.apple.coreservices.code-evaluation&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_create_mach_service&lt;/code&gt; for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;com.apple.coreservices.quarantine-resolver&lt;/code&gt; service&lt;/li&gt;
  &lt;li&gt;Calls the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CSUIController&lt;/code&gt; classes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;beginListeningForWindowChanges&lt;/code&gt; method to listen for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSWindow&lt;/code&gt; lifecycle events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s a bit odd that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;code-evaluation&lt;/code&gt; service makes use of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSXPCListener&lt;/code&gt; object while the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;qaurantine-resolver&lt;/code&gt; makes use of the C based XPC APIs. My guess is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;quarantine-resolver&lt;/code&gt; code has been around for longer.&lt;/p&gt;

&lt;h2 id=&quot;comapplecoreservicesquarantine-resolver&quot;&gt;com.apple.coreservices.quarantine-resolver&lt;/h2&gt;

&lt;p&gt;Searching for callers of this service we find that the primary caller is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt;. Within the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt; there is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__LSAgentGetConnection()&lt;/code&gt; function that gets called in various other functions to retrieve an XPC connection to this service. I’ll start by covering some of the general connection handling of this service.&lt;/p&gt;

&lt;h3 id=&quot;csuicontroller-handleincomingxpcconnection&quot;&gt;CSUIController handleIncomingXPCConnection&lt;/h3&gt;

&lt;p&gt;This handler gets set up during &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; initialization. It’s responsible for accepting or denying incoming XPC connections. In general there are only a few basic checks. Keep in mind that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; is a launch agent so it’s running as the currently logged in user. It starts by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_connection_get_audit_token&lt;/code&gt; to get security information from the calling process. It then proceeds to check the euid and asid to ensure that it’s the same logged in user trying to call the service.&lt;/p&gt;

&lt;p&gt;There is alternatively an entitlement check for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;com.apple.private.coreservicesuiagent.allowedtouseCSUIFromOutsideSession&lt;/code&gt; entitlement to see if a different user is allowed to call the service. As far as I could tell no application on the system has this entitlement.&lt;/p&gt;

&lt;h3 id=&quot;csuicontroller-handleincomingxpcmessage&quot;&gt;CSUIController handleIncomingXPCMessage&lt;/h3&gt;

&lt;p&gt;If the connection is accepted then the next step is to read and handle the XPC message itself. Every valid XPC message sent to this service has an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64&lt;/code&gt; value sent in the dictionary called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd&lt;/code&gt; which lets the service know which message handler to hand off to.&lt;/p&gt;

&lt;p&gt;At this point if an invalid &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd&lt;/code&gt; value is sent then the service calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xpc_dictionary_create_reply&lt;/code&gt; and sets an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int64&lt;/code&gt; value with a name of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;com.apple.coreservices.uiagent.status&lt;/code&gt; and a negative error code.&lt;/p&gt;

&lt;p&gt;Finally this method will call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scheduleHandlerForMessageType&lt;/code&gt; to actually create and run the appropriate handler.&lt;/p&gt;

&lt;h3 id=&quot;csuicontroller-schedulehandlerformessagetype&quot;&gt;CSUIController scheduleHandlerForMessageType&lt;/h3&gt;

&lt;p&gt;This method starts by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CSUIMessageHandler classForMessageType&lt;/code&gt; which will loop through the registered message handlers and attempt to initialize the appropriate one for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd&lt;/code&gt; value sent in the XPC message. It then gets the audit token and checks whether the message handler allows callers that are sandboxed processes. Only some of the registered message handlers allow this. Finally, if permission checks pass, the method schedules a call to the message handlers &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handleMessageWithCompletionHandler&lt;/code&gt; method on a dispatch queue with the name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;com.apple.coreservices.uiagent.background-message-queue&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;message-handlers&quot;&gt;Message Handlers&lt;/h3&gt;

&lt;p&gt;The message handlers make up the majority of the logic for this service. All the various message handlers get registered when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; starts up and based on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd&lt;/code&gt; various handlers get called.&lt;/p&gt;

&lt;h4 id=&quot;csuimessagehandler&quot;&gt;CSUIMessageHandler&lt;/h4&gt;

&lt;p&gt;All message handlers inherit from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CSUIMessageHandler&lt;/code&gt; base class. Most of the class logic is implemented in class methods that allow the registration and lookup of appropriate message handlers. But there are also default implementations of some of the message handler instance methods as well. For example &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canBeUsedBySandboxedApplications&lt;/code&gt; has a default return value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NO&lt;/code&gt; and only the message handlers that need to allow sandbox access override this method.&lt;/p&gt;

&lt;h4 id=&quot;csuiquarantinemessagehandler&quot;&gt;CSUIQuarantineMessageHandler&lt;/h4&gt;

&lt;p&gt;This handler is responsible for Gatekeeper and Xprotect checking. It’s called from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchService.framework&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_LSOpenStuffCallLocal&lt;/code&gt; function. As mentioned in the blog opening Patrick Wardle has a great &lt;a href=&quot;https://www.virusbulletin.com/uploads/pdf/conference_slides/2015/Wardle-VB2015.pdf&quot; target=&quot;_blank&quot;&gt;slide deck&lt;/a&gt; that covers the details fairly well. Ultimately though this message handler delegates most of the checking off to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GKQuarantineResolver&lt;/code&gt; class. This class attempts to check and resolve items that are marked as quarantined. It makes use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Xprotect.framework&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;XProtectAnalysis&lt;/code&gt; class to call into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;XprotectService&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Overall this message handler seems like a weird fit into this service. Most of the other services are really in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; to present the occasional dialog to the end user. While this handler does show dialogs to the user if items are blocked it does also have the quarantine resolver logic. Some of this code almost seems like it should be in it’s own service and then that service calls into this if it needs to present a dialog to the user.&lt;/p&gt;

&lt;p&gt;The XPC message values can be seen below:&lt;/p&gt;

&lt;h5 id=&quot;xpc-values&quot;&gt;XPC Values&lt;/h5&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Key&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;cmd&lt;/td&gt;
      &lt;td&gt;int64&lt;/td&gt;
      &lt;td&gt;0x1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;data&lt;/td&gt;
      &lt;td&gt;data&lt;/td&gt;
      &lt;td&gt;See Data Values below.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;flags&lt;/td&gt;
      &lt;td&gt;uint64&lt;/td&gt;
      &lt;td&gt;?&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;firstLaunchPSN&lt;/td&gt;
      &lt;td&gt;uint64&lt;/td&gt;
      &lt;td&gt;process serial number&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h5 id=&quot;data-values&quot;&gt;Data Values&lt;/h5&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Key&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;LSQAllowUnsigned&lt;/td&gt;
      &lt;td&gt;NSNumber&lt;/td&gt;
      &lt;td&gt;YES or NO&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;LSQAppPSN&lt;/td&gt;
      &lt;td&gt;NSNumber&lt;/td&gt;
      &lt;td&gt;process serial number&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;LSQAppPath&lt;/td&gt;
      &lt;td&gt;NSString&lt;/td&gt;
      &lt;td&gt;Full path to the application to be evaluated&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;LSQAuthorization&lt;/td&gt;
      &lt;td&gt;NSData&lt;/td&gt;
      &lt;td&gt;A serialized AuthorizationRef object&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;LSQItemSandboxExtensions&lt;/td&gt;
      &lt;td&gt;NSDictionary&lt;/td&gt;
      &lt;td&gt;?&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;LSQRiskCategory&lt;/td&gt;
      &lt;td&gt;NSString&lt;/td&gt;
      &lt;td&gt;Various risk categories. For example: “LSRiskCategoryUnsafeExecutable”&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;lslauncherrorhandler&quot;&gt;LSLaunchErrorHandler&lt;/h4&gt;

&lt;p&gt;This message handler gets called from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_LSErrorDictPost&lt;/code&gt; function. This function is called at various spots in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt; when there’s a problem trying to launch an application. The only thing this message handler does is present an error dialog to the user letting them know there was an issue launching the application.&lt;/p&gt;

&lt;p&gt;The XPC message values can be seen below:&lt;/p&gt;

&lt;h5 id=&quot;xpc-values-1&quot;&gt;XPC Values&lt;/h5&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Key&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;cmd&lt;/td&gt;
      &lt;td&gt;int64&lt;/td&gt;
      &lt;td&gt;0x2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;data&lt;/td&gt;
      &lt;td&gt;data&lt;/td&gt;
      &lt;td&gt;See Data Values below.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h5 id=&quot;data-values-1&quot;&gt;Data Values&lt;/h5&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Key&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Action&lt;/td&gt;
      &lt;td&gt;NSString&lt;/td&gt;
      &lt;td&gt;Not sure what this is used for. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GURL&lt;/code&gt; is one possible value&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ErrorCode&lt;/td&gt;
      &lt;td&gt;NSNumber&lt;/td&gt;
      &lt;td&gt;The error code from trying to launch an application&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;AppPath&lt;/td&gt;
      &lt;td&gt;NSString&lt;/td&gt;
      &lt;td&gt;Full path to the application that couldn’t be launched&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;AppMimimumSystemVersion&lt;/td&gt;
      &lt;td&gt;NSString&lt;/td&gt;
      &lt;td&gt;?&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;AppMaximumSystemVersion&lt;/td&gt;
      &lt;td&gt;NSString&lt;/td&gt;
      &lt;td&gt;?&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;csuilsopenhandler&quot;&gt;CSUILSOpenHandler&lt;/h4&gt;

&lt;p&gt;This is an interesting handler because it can actually be called from sandboxed application. It’s called from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchService.framework&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_LSRemoteOpenCall invokeWithError&lt;/code&gt; method. If the caller is sandboxed then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sandbox_check_by_audit_token&lt;/code&gt; method is called checking if the caller was granted &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsopen&lt;/code&gt; privileges. Doing a quick search through sandbox profiles we can see the following applications that are allowed to call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsopen&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;com.apple.AppSSOAgent.sb:(allow lsopen)
com.apple.CommerceKit.TransactionService.sb:(allow lsopen)
com.apple.ServicesUIAgent.sb:(allow lsopen)
com.apple.appstoreagent.sb:(allow lsopen)
com.apple.appstored.sb:(allow lsopen)
com.apple.assistantd.sb:(allow lsopen)
com.apple.commerce.sb:(allow lsopen)
com.apple.commerced.sb:(allow lsopen)
com.apple.iMessage.shared.sb:(allow lsopen)
com.apple.storeassetd.sb:(allow lsopen)
com.apple.storedownloadd.sb:(allow lsopen)
com.apple.storeuid.sb:(allow lsopen)
com.apple.studentd.sb:(allow lsopen)
com.apple.telephonyutilities.callservicesd.sb:(allow lsopen)
com.apple.touristd.sb:(allow lsopen)
fmfd.sb:(allow lsopen)
usernoted.sb:(allow lsopen)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This handler is interesting because normally from a non sandboxed application the caller can just use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt; directly to open another application. This handler seems to really just be here to provide this functionality to sandboxed applications. If the caller has the appropriate sandbox permissions then this message handler simply calls into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_LSOpenCallInvokeXPC&lt;/code&gt; function of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt;. It seems like for sandboxed applications &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServuceisUIAgent&lt;/code&gt; provides a convienant launch agent process to put random code into.&lt;/p&gt;

&lt;p&gt;The XPC message values can be seen below:&lt;/p&gt;

&lt;h5 id=&quot;xpc-values-2&quot;&gt;XPC Values&lt;/h5&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Key&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;cmd&lt;/td&gt;
      &lt;td&gt;int64&lt;/td&gt;
      &lt;td&gt;0x3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;call&lt;/td&gt;
      &lt;td&gt;data&lt;/td&gt;
      &lt;td&gt;A serialized version of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_LSRemoteOpenCall&lt;/code&gt; instance.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;csuicheckaccesshandler&quot;&gt;CSUICheckAccessHandler&lt;/h4&gt;

&lt;p&gt;This is another message handler that is callable from the sandbox and seems to only exist as a way to provide functionality to sandboxed processes. All this message handler does is call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;access&lt;/code&gt; system call. When calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;access&lt;/code&gt; the value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R_OK&lt;/code&gt; is passed in as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mode&lt;/code&gt;. It then returns the value it gets back to the caller in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flags&lt;/code&gt; value. It’s called from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_BindingBlueprint::checkUserAccessFlags&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The XPC message values can be seen below:&lt;/p&gt;

&lt;h5 id=&quot;xpc-values-3&quot;&gt;XPC Values&lt;/h5&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Key&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;cmd&lt;/td&gt;
      &lt;td&gt;int64&lt;/td&gt;
      &lt;td&gt;0x5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;path&lt;/td&gt;
      &lt;td&gt;string&lt;/td&gt;
      &lt;td&gt;The full path to the file to check&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;csuigetdisplaynamehandler&quot;&gt;CSUIGetDisplayNameHandler&lt;/h4&gt;

&lt;p&gt;Another handler that can be called from sandboxed applications. This one seems to be just for retrieving the proper localized name of a given application. It gets called from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_LaunchServices::URLPropertyProvider::prepareLocalizedNameValue&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The XPC message values can be seen below:&lt;/p&gt;

&lt;h5 id=&quot;xpc-values-4&quot;&gt;XPC Values&lt;/h5&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Key&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;cmd&lt;/td&gt;
      &lt;td&gt;int64&lt;/td&gt;
      &lt;td&gt;0x7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;path&lt;/td&gt;
      &lt;td&gt;string&lt;/td&gt;
      &lt;td&gt;The path to an installed application&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;com.apple.coreservices.uiagent.localizations&lt;/td&gt;
      &lt;td&gt;xpc_object_t&lt;/td&gt;
      &lt;td&gt;?&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;csuichangedefaulthandlerhandler&quot;&gt;CSUIChangeDefaultHandlerHandler&lt;/h4&gt;

&lt;p&gt;At first glance this message handler seems like it might be interesting. It’s called from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_LSSetSchemeHandler&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt;. When a message is sent over to this handler it replies right away and then runs a code block. After digging a little deeper into this it really is only displaying a prompt to the end user. This message handler will call back into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt; using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LSDModifyService&lt;/code&gt; class which in turn asks &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsd&lt;/code&gt; to do the real work.&lt;/p&gt;

&lt;p&gt;The XPC message values can be seen below:&lt;/p&gt;

&lt;h5 id=&quot;xpc-values-5&quot;&gt;XPC Values&lt;/h5&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Key&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;cmd&lt;/td&gt;
      &lt;td&gt;int64&lt;/td&gt;
      &lt;td&gt;0x8&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;scheme&lt;/td&gt;
      &lt;td&gt;string&lt;/td&gt;
      &lt;td&gt;The scheme of the document handler that is being changed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;bundleidentifier&lt;/td&gt;
      &lt;td&gt;string&lt;/td&gt;
      &lt;td&gt;The bundle id of the new document handler&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;bundleversion&lt;/td&gt;
      &lt;td&gt;string&lt;/td&gt;
      &lt;td&gt;The version number of the bundle that will be the new document handler&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;remove&lt;/td&gt;
      &lt;td&gt;bool&lt;/td&gt;
      &lt;td&gt;A bool indicating whether the handler is being removed or not.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;csuirecommendsafarihandler&quot;&gt;CSUIRecommendSafariHandler&lt;/h4&gt;

&lt;p&gt;Another handler that can be called from the sandbox. This message handler appears to be what displays the prompt if Safari isn’t the default browser. It’s called from a block in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LSApplicationCheckin&lt;/code&gt; in the case of a process that is a browser.&lt;/p&gt;

&lt;p&gt;The XPC message values can be seen below:&lt;/p&gt;

&lt;h5 id=&quot;xpc-values-6&quot;&gt;XPC Values&lt;/h5&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Key&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;cmd&lt;/td&gt;
      &lt;td&gt;int64&lt;/td&gt;
      &lt;td&gt;0x9&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;comapplecoreservicescode-evaluation&quot;&gt;com.apple.coreservices.code-evaluation&lt;/h2&gt;

&lt;p&gt;This services makes use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSXPC*&lt;/code&gt; classes. It’s only called from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt; has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LSCodeEvaluationClientManager&lt;/code&gt; class that is part of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LSCodeEvaluation&lt;/code&gt; class. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LSCodeEvaluationClientManager&lt;/code&gt; calls into the remote service of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServucesUIAgent&lt;/code&gt; and makes use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LSCodeEvaluationServerProtocol&lt;/code&gt; for the remote interface. In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CSUICodeEvaluationController&lt;/code&gt; implements the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LSCodeEvaluationServerProtocol&lt;/code&gt;. The protocol can be seen below:&lt;/p&gt;

&lt;div class=&quot;language-objc highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;@class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LSCodeEvaluationInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NSString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NSUUID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LSCodeEvaluationServerProtocol&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showSecurityPreferencesAnchor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showOriginForInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LSCodeEvaluationInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ejectVolumeForInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LSCodeEvaluationInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;moveItemToTrashForInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LSCodeEvaluationInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;closeProgressForInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LSCodeEvaluationInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;updateProgressForInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LSCodeEvaluationInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;startProgressForInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LSCodeEvaluationInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;registerWithLaunchServicesForInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LSCodeEvaluationInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;updateQuarantineFlagsForInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LSCodeEvaluationInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg1&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg2&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;clearFlags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg3&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;presentPromptOfType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg1&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg2&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LSCodeEvaluationInfo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg3&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSUUID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;arg4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’m not entirely clear how and when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt; makes use of this remote service but for the most part this service is really just presenting dialogs to the end user. Methods in the protocol above that seem to take an actual action end up calling back into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LaunchServices.framework&lt;/code&gt; to do any of the real work.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;This proved to be an interesting deep dive into the internals of a system launch agent that probably most of us take for granted. Additionally, there really seem to three types of main functionality that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; handles:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Coordinating and running quarantine malware checks&lt;/li&gt;
  &lt;li&gt;Providing random functionality to sandboxed processes&lt;/li&gt;
  &lt;li&gt;Displaying dialogs to the logged in user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Displaying dialogs is clearly the majority of what the launch agent does. Historically I would guess this was also the only thing in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt;. Over time it seems like like the launch agent provided a convienant point to add additional functionality that should be running as the logged in user. All of the above internals comes from macOS 10.15.2. It would be interesting to go back over the last couple major versions of macOS and see how the internal mach services have changed or grown over time. Finally if you want to play around with sending some XPC messages to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreServicesUIAgent&lt;/code&gt; you can find a small command line program I used for testing &lt;a href=&quot;https://gist.github.com/knightsc/a22967814423934ef4e7a3f3c235dd11&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</content><author><name>Scott Knight</name></author><category term="Reverse Engineering" /><category term="Assembly" /><category term="macOS" /><category term="x86" /><summary type="html">The recent release of macOS 10.15.2 had some additional updates to the Xprotect yara rules within it. After reviewing what changed in the yara rules I decided to dig a little deeper into how Xprotect gets called. Jonathan Levin’s excellent book MacOS and iOS Internals, Volume III: Security &amp;amp; Insecurity briefly talks about Gatekeeper and Xprotect but didn’t have the internals I was looking for. I ended up finding Patrick Wardle’s excellent presentation from the 2015 Virus Bulletin Conference. His slide deck does a great job of explinaing the communication between LaunchServices, CoreServicesUIAgent and the XprotectService. It did, however, make me question what all does CoreServicesUIAgent do? This posts digs into the internals of CoreServicesUIAgent and documents its functionality.</summary></entry><entry><title type="html">CVE-2019-8805 - A macOS Catalina privilege escalation</title><link href="https://knight.sc/reverse%20engineering/2019/10/31/macos-catalina-privilege-escalation.html" rel="alternate" type="text/html" title="CVE-2019-8805 - A macOS Catalina privilege escalation" /><published>2019-10-31T00:00:00+00:00</published><updated>2019-10-31T00:00:00+00:00</updated><id>https://knight.sc/reverse%20engineering/2019/10/31/macos-catalina-privilege-escalation</id><content type="html" xml:base="https://knight.sc/reverse%20engineering/2019/10/31/macos-catalina-privilege-escalation.html">&lt;p&gt;With the release of macOS Catalina in October, Apple rolled out a set of interesting new features collectively called &lt;a href=&quot;https://developer.apple.com/system-extensions/&quot; target=&quot;_blank&quot;&gt;System Extensions&lt;/a&gt;. System Extensions are a set of user space frameworks encouraging developers who currently maintain and ship kernel extensions to move their features to user space for increased security and stability. One of these new frameworks is the &lt;a href=&quot;https://developer.apple.com/documentation/endpointsecurity&quot; target=&quot;_blank&quot;&gt;Endpoint Security&lt;/a&gt; framework. As a security researcher this framework is of special interest. It’s intended to provide a public and stable API for implementing security products. During the process of looking into what functionality the Endpoint Security framework provided, a privilege escalation bug was identified that would let an attacker execute any code they wanted with root privileges. The following describes both the vulnerability as well as what Apple did to fix the issue.&lt;/p&gt;

&lt;h1 id=&quot;endpoint-security-architecture&quot;&gt;Endpoint Security Architecture&lt;/h1&gt;

&lt;p&gt;There are a lot of different parts to the Endpoint Security framework and in order to understand the vulnerability it will be useful to briefly cover the architecture of the Endpoint Security framework. The framework spans three different layers. There’s the user layer, the system layer, and then finally the kernel layer.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/macos-catalina-privilege-escalation-1.png&quot; alt=&quot;Endpoint Security Architecture&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In order to use the Endpoint Security framework a developer needs to create at least two applications. One is an application that actually uses the Endpoint Security framework (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libEndpointSecurity.dylib&lt;/code&gt;) and will run in the system layer. The other is an application running in the user layer that makes use of the System Extensions framework to actually prompt the user to approve and install the Endpoint Security extension. Apple takes care of creating and maintaining the components running in the kernel layer.&lt;/p&gt;

&lt;p&gt;As can be seen in the diagram above, normally when loading an Endpoint Security extension the user application uses the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SystemExtensions.framework&lt;/code&gt; and programmatically requests to install/load the specific extension. This sends a message to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysextd&lt;/code&gt; daemon which is then responsible for sending a message to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt; daemon. The task that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt; daemon carries out is installing extensions and starting them up. To start them, the daemon calls into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServiceManagement.framework&lt;/code&gt; calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SMJobSubmit&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SMJobSubmit&lt;/code&gt; is what sends a message to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;launchd&lt;/code&gt; and it will launch the extension as a root daemon. Due to the way &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;launchd&lt;/code&gt; works, even if a user exits the program, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;launchd&lt;/code&gt; will just restart it again.&lt;/p&gt;

&lt;h1 id=&quot;the-vulnerability&quot;&gt;The Vulnerability&lt;/h1&gt;

&lt;p&gt;The privilege escalation vulnerability actually exists within &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SystemExtensions.framework&lt;/code&gt; it depends on. All of the communication above, between daemons, takes place using a low level system IPC mechanism called &lt;a href=&quot;https://developer.apple.com/documentation/xpc&quot; target=&quot;_blank&quot;&gt;XPC&lt;/a&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SystemExtensions.framework&lt;/code&gt; provides a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OSSystemExtensionPointListener&lt;/code&gt; class used by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt; to listen for the XPC activation requests &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysextd&lt;/code&gt; sends. When the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt; daemon starts up it does the following:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/macos-catalina-privilege-escalation-2.png&quot; alt=&quot;ESD Source&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OSSystemExtensionPointListener&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SystemExtensions.framework&lt;/code&gt; is what’s actually responsible for listening to XPC activation requests from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysextd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;XPC is a standard IPC mechanism on macOS that any application utilize and copmmunicate with. So what’s stopping a malicious application from sending a XPC request to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt; asking it to launch a malicious program? Normally the answer is entitlements. Apple’s built a good system in macOS and iOS where critical subsystems of the OS are protected by entitlement checks. A random binary has to have a special entitlement embedded in it and be properly signed to communicate with critical parts of the OS. In this case however the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OSSystemExtensionPointListener&lt;/code&gt; class did not have any entitlement checks.&lt;/p&gt;

&lt;p&gt;This means that in macOS 10.15.0 an attacker can send a specially crafted XPC message directly to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;com.apple.endpointsecurity.system-extensions&quot;&lt;/code&gt; service and request &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;launchd&lt;/code&gt; to start any application the attacker chooses. Compounding the issue, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;launchd&lt;/code&gt; will treat the application it’s starting as a system daemon. It will run it as root and ensure that the process is always running, even if the user tries to kill it.&lt;/p&gt;

&lt;h1 id=&quot;apples-patch&quot;&gt;Apple’s Patch&lt;/h1&gt;

&lt;p&gt;With the release of &lt;a href=&quot;https://support.apple.com/en-us/HT210722&quot; target=&quot;_blank&quot;&gt;macOS 10.15.1&lt;/a&gt;, Apple has patched this vulnerability. If we disassemble and reconstruct the code for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[OSSystemExtensionPointListener listener:shouldAcceptNewConnection:]&lt;/code&gt; we can see the changes that they applied:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/macos-catalina-privilege-escalation-3.png&quot; alt=&quot;OSSystemExtensionPointListere diff&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The first thing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[OSSystemExtensionPointListener listener:shouldAcceptNewConnection:]&lt;/code&gt; method does now is call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueForEntitlement&lt;/code&gt; passing in the string &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;com.apple.private.security.storage.SystemExtensionManagement&quot;&lt;/code&gt;. If the calling program does not have this entitlement then the message “XPC denied because caller lacks entitlement” will be logged and the connection will not be accepted. If you filter the macOS logs for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt; and attempt to send the specially crafted XPC message you can see this error in the system logs:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;default    16:04:04.919496-0400    endpointsecurityd Init ipc server
default    16:04:04.923851-0400    endpointsecurityd ESD init
default    16:04:04.926649-0400    endpointsecurityd XPC denied because caller lacks entitlement
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The only binary that has this special entitlement is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysextd&lt;/code&gt;. This means that now in macOS 10.15.1 only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysextd&lt;/code&gt; can ask &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt; to install and launch extensions.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;The new System Extensions framework in macOS Catalina is a great step forward for even more security and stability in macOS. In this case the vulnerability was fairly straightforward and Apple was able to patch it quickly. As Apple creates more and more system daemons to do specialized jobs however it does create an increased attack surface. In turn this creates more ways for attackers to find their way into the secure parts of the OS. As security researchers, this means we also need to be working to understand these new security mechanisms and testing them to see if they work as expected.&lt;/p&gt;</content><author><name>Scott Knight</name></author><category term="Reverse Engineering" /><category term="Exploits" /><category term="macOS" /><category term="Objective-C" /><summary type="html">With the release of macOS Catalina in October, Apple rolled out a set of interesting new features collectively called System Extensions. System Extensions are a set of user space frameworks encouraging developers who currently maintain and ship kernel extensions to move their features to user space for increased security and stability. One of these new frameworks is the Endpoint Security framework. As a security researcher this framework is of special interest. It’s intended to provide a public and stable API for implementing security products. During the process of looking into what functionality the Endpoint Security framework provided, a privilege escalation bug was identified that would let an attacker execute any code they wanted with root privileges. The following describes both the vulnerability as well as what Apple did to fix the issue.</summary></entry><entry><title type="html">System Extension internals</title><link href="https://knight.sc/reverse%20engineering/2019/08/24/system-extension-internals.html" rel="alternate" type="text/html" title="System Extension internals" /><published>2019-08-24T00:00:00+00:00</published><updated>2019-08-24T00:00:00+00:00</updated><id>https://knight.sc/reverse%20engineering/2019/08/24/system-extension-internals</id><content type="html" xml:base="https://knight.sc/reverse%20engineering/2019/08/24/system-extension-internals.html">&lt;p&gt;One of the most exciting things announced at this years WWDC was &lt;a href=&quot;https://developer.apple.com/system-extensions/&quot; target=&quot;_blank&quot;&gt;System Extensions&lt;/a&gt;. From a security perspective I think this is a really important advancedment for macOS. It means less third party code running in kernel space which should mean more security and stability. From a programmers perspective I think this is even more important. It means that the code developers previously had to write in C++ can now be written in a more modern language like Swift. Apple has been attempting to wrangle in kexts for a while now and this seems to be the final nail in the coffin. They have said macOS 10.15 will be the last release to fully support kexts without compromises and that in future releases of macOS Kernel Extensions with System Extension equivalents will not load at all. I thought it might be interesting to look at the internals of how System Extensions work.&lt;/p&gt;

&lt;p&gt;First a disclaimer: everything that follows is based on the Catalina betas so these details might change by the time of the final release. Additionally my goal with this article is to provide an extremely high level overview. There are a lot of moving parts to System Extensions and it wouldn’t be possible to cover all the internals in one post. With that out of the way let’s take a look at how all the different subsystems communicate with each other.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/system-extension-internals-1.png&quot; alt=&quot;System Extension Internals&quot; class=&quot;align-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Conceptually there’s really two big chunks to this. A user program calling into system services to activate or deactivate an extension and then the system itself running the extensions. The extensions then are what communicate with the kernel. Let’s take a look at some of the different subsystems.&lt;/p&gt;

&lt;h1 id=&quot;systemextensionsframework&quot;&gt;SystemExtensions.framework&lt;/h1&gt;
&lt;hr /&gt;

&lt;p&gt;This is one of the new frameworks in Catalina. It’s written in Objective-C and is pretty small. You can read through the official documentation on it &lt;a href=&quot;https://developer.apple.com/documentation/systemextensions&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. Its sole purpose is to provide end user applications a way to install and uninstall system extensions. Installation is one area that I hope continues to evolve because for critical security extensions it doesn’t make sense that a user application needs to run once before you’re protected. Regardless there are a couple internal classes that are worth calling out.&lt;/p&gt;

&lt;h2 id=&quot;ossystemextensioninfo&quot;&gt;OSSystemExtensionInfo&lt;/h2&gt;

&lt;p&gt;This class represents the full information pertaining to a system extension. This object conforms to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSSecureCoding&lt;/code&gt; and is used when making requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OSSystemExtensionPointListener&lt;/code&gt; instances.&lt;/p&gt;

&lt;h2 id=&quot;ossystemextensionpointlistener&quot;&gt;OSSystemExtensionPointListener&lt;/h2&gt;

&lt;p&gt;The main System Extension daemon has friend daemons that it uses to handle the different types of system extension categories. Both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt;and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nesessionmanager&lt;/code&gt; use this class at start up to create a XPC service that listens for system extension start and stop events.&lt;/p&gt;

&lt;h2 id=&quot;ossystemextensionclient&quot;&gt;OSSystemExtensionClient&lt;/h2&gt;

&lt;p&gt;This class is the main way for the different applications to talk to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysextd&lt;/code&gt;. You can see a list of apps using this class by searching for it with ripgrep&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rg &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-M&lt;/span&gt; 80 OSSystemExtensionClient 2&amp;gt; /dev/null
/sbin/kextload
/usr/bin/kextutil
/usr/bin/systemextensionsctl
/usr/libexec/endpointsecurityd
/usr/libexec/kextd
/usr/libexec/nesessionmanager
/usr/sbin/kextcache
/System/Library/Frameworks/SystemExtensions.framework/Versions/A/Helpers/sysextd
/System/Library/Frameworks/SystemExtensions.framework/Versions/A/SystemExtensions
/System/Library/PreferencePanes/Security.prefPane/Contents/MacOS/Security
/System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv
/System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/Resources/DesktopServicesHelper
/System/Library/PrivateFrameworks/TCC.framework/Versions/A/Resources/tccd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;systemextensionsctl&quot;&gt;systemextensionsctl&lt;/h1&gt;
&lt;hr /&gt;

&lt;p&gt;This is a small command line utility provided by Apple to “list and control System Extensions installed”. It’s also written in Objective-C. It makes direct use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OSSystemExtensionClient&lt;/code&gt; class to call into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysextd&lt;/code&gt;. While this isn’t pictured in the diagram above it’s worth calling out because it’s not well documented and is useful for anyone playing around with System Extensions. In the first Catalina beta it was actually non-functional but now if you run the command you can see some basic help information about it.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;systemextensionctl
systemextensionsctl: usage:
    systemextensionsctl developer &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;on|off]
    systemextensionsctl list &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;category]
    systemextensionsctl reset  - reset all System Extensions state
    systemextensionsctl uninstall &amp;lt;teamId&amp;gt; &amp;lt;bundleId&amp;gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; can also accept &lt;span class=&quot;s1&quot;&gt;'-'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;teamID
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are some other test commands not documented. They all basically allow further testing of calls into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysextd&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    systemextensionsctl disable &amp;lt;teamID&amp;gt; &amp;lt;bundleID&amp;gt;; can also accept '-' or 'plat' for teamID
    systemextensionsctl enable &amp;lt;teamID&amp;gt; &amp;lt;bundleID&amp;gt;; can also accept '-' or 'plat' for teamID
    systemextensionsctl test &amp;lt;test_routine_name&amp;gt;
    systemextensionsctl testauthz &amp;lt;test_routine_name&amp;gt;
    systemextensionsctl testshouldmove &amp;lt;fromPath&amp;gt; &amp;lt;toPath&amp;gt;; n.b. paths not URLs. To test moving to trash, specify \\\&quot;Trash\\\&quot; as toPath.
    systemextensionsctl testwillmove &amp;lt;fromPath&amp;gt; &amp;lt;toPath&amp;gt;; n.b. paths not URLs. To test moving to trash, specify \\\&quot;Trash\\\&quot; as toPath.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally I think it’s useful to see what entitlements applications like these have to get some idea of whether or not the functionality is locked down or not.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;plist&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;version=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.private.system-extensions.modify&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;sysextd&quot;&gt;sysextd&lt;/h1&gt;
&lt;hr /&gt;

&lt;p&gt;This is a new system daemon. It’s mostly written in swift, which is exciting to see. Most of the existing system daemons are written in Objective-C. It’s great to see Apple adopting Swift more and more for internal uses other than just end user applications. This daemon is responsible for installation, approval, and uninstalling of all the system extensions. It has the following entitlements:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;plist&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;version=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.private.security.storage.SystemExtensionManagement&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It delegates out actions to each of the relevant subsystems: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kextd&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nesessionmanager&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt;. There are a couple internal classes that are worth calling out.&lt;/p&gt;

&lt;h2 id=&quot;kextdclient&quot;&gt;KextdClient&lt;/h2&gt;

&lt;p&gt;This class forwards requests off to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kextd&lt;/code&gt; through IOKit for DriverKit loading.&lt;/p&gt;

&lt;h2 id=&quot;standardextensiondelegate&quot;&gt;StandardExtensionDelegate&lt;/h2&gt;

&lt;p&gt;This class provides common actions for forwarding requests off to any friend daemon that implements the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OSSystemExtensionPointListener&lt;/code&gt; class.&lt;/p&gt;

&lt;h2 id=&quot;networkextensioncategorydelegate&quot;&gt;NetworkExtensionCategoryDelegate&lt;/h2&gt;
&lt;h2 id=&quot;endpointsecuritycategorydelegate&quot;&gt;EndpointSecurityCategoryDelegate&lt;/h2&gt;

&lt;p&gt;These two classes leverage the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StandardExtensionDelegate&lt;/code&gt; logic for the most part. They’re both responsible for claiming their respective extension types.&lt;/p&gt;

&lt;h1 id=&quot;driverkit&quot;&gt;DriverKit&lt;/h1&gt;
&lt;hr /&gt;

&lt;p&gt;DriveKit extensions have a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.dext&lt;/code&gt; file type. There’s a lot that goes on to make user space drivers work so again I won’t go into it in great detail. The DriverKit extension binaries are a bit weird. They have no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LC_MAIN&lt;/code&gt; command in the Mach-O binary. This means if you wanted to try to run the extension yourself in user space you couldn’t. In fact if you try to run it in LLDB you’ll get the following error: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error: Bad executable (or shared library)&lt;/code&gt;. Ultimately the binaries do get loaded and run in user space. It would be interesting to dig a little further into the loading process of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.dext&lt;/code&gt; files. Overall, I like the architecture and find it very interesting. The user mode drivers basically set up a connection to IOKit and get forwarded events happening and can send back responses as well.&lt;/p&gt;

&lt;h2 id=&quot;iokitframework&quot;&gt;IOKit.framework&lt;/h2&gt;

&lt;p&gt;There’s a couple new internal functions in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IOKit.framework&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;_kextmanagervalidateextension&quot;&gt;_KextManagerValidateExtension&lt;/h3&gt;
&lt;h3 id=&quot;_kextmanagerupdateextension&quot;&gt;_KextManagerUpdateExtension&lt;/h3&gt;
&lt;h3 id=&quot;_kextmanagerstopextension&quot;&gt;_KextManagerStopExtension&lt;/h3&gt;

&lt;p&gt;These three functions are used by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kextd&lt;/code&gt; to install and uninstall DriverKit extensions.&lt;/p&gt;

&lt;h2 id=&quot;kextd&quot;&gt;kextd&lt;/h2&gt;

&lt;p&gt;There were changes to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kextd&lt;/code&gt; in order for it to understand what drivers have a corresponding user executable. I’m hoping that Apple will release Catalina source shortly after final release in order to be able to look into this more.&lt;/p&gt;

&lt;h2 id=&quot;kernel&quot;&gt;kernel&lt;/h2&gt;

&lt;p&gt;The kernel side of IOKit had changes to support sending events of to user space. It looks like in the kernel &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IOUserServer&lt;/code&gt; corresponds to the user space version of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IOUserServer&lt;/code&gt; class in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DriverKit.framework&lt;/code&gt;&lt;/p&gt;

&lt;h1 id=&quot;endpoint-security&quot;&gt;Endpoint Security&lt;/h1&gt;
&lt;hr /&gt;

&lt;p&gt;This is one of the most interesting  parts of System Extensions in my opinion. From what I can tell Apple took their standard pattern for kext to system daemon communication and attempted to turn it into a framework. That way third parties would only have to worry about writing the system daemon side of things and Apple could control the kernel side. Ideally this should lead to much better stability for third party security tools as they’ll be kicked out of doing nasty things inside of kernel space.&lt;/p&gt;

&lt;h2 id=&quot;endpointsecurityd&quot;&gt;endpointsecurityd&lt;/h2&gt;

&lt;p&gt;This is another new system daemon. Written in Objective-C. It’s responsible for the installing and uninstalling of endpoint security extensions. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libEndpointSecurity.dylib&lt;/code&gt; doesn’t communicate with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpointsecurityd&lt;/code&gt; in any way. There are a handful of entitlements the daemon has:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;plist&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;version=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.private.endpoint-security.manager&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.private.security.storage.SystemExtensionManagement&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.private.system-extensions.extension-point&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.private.tcc.manager&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.private.xpc.protected-services&lt;span class=&quot;nt&quot;&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;libendpointsecuritydylib&quot;&gt;libEndpointSecurity.dylib&lt;/h2&gt;

&lt;p&gt;When you write an Endpoint Security extension this is the main library that you’ll use. It makes use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IOKit.framework&lt;/code&gt; to register itself as a client with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EndpointSecurity.kext&lt;/code&gt;. From there it can opt in or out of listening for certain events from the Kernel Extension and send responses back.&lt;/p&gt;

&lt;h2 id=&quot;endpointsecuritykext&quot;&gt;EndpointSecurity.kext&lt;/h2&gt;

&lt;p&gt;If you’ve ever looked at any third party antivirus kernel extensions this kext looks very similar. It uses the MACF and kauth kernel frameworks to listen to events happening and then sends messages out to any registerd clients. Those registered clients can then make decision on whether to allow or deny the actions happening.&lt;/p&gt;

&lt;h1 id=&quot;network-extensions&quot;&gt;Network Extensions&lt;/h1&gt;
&lt;hr /&gt;

&lt;p&gt;This is probably where I’ve spent the least amount of time looking into things. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NetworkExtension.framework&lt;/code&gt; was something that already existed. As part of Catalina some of the functionality that already existed on iOS is now ported over to macOS. With Network Extensions you can now create things like firewall applications that run completely in user space rather than having to use Network Kernel Extensions&lt;/p&gt;

&lt;h2 id=&quot;nesessionmanager&quot;&gt;nesessionmanager&lt;/h2&gt;

&lt;p&gt;The daemon listens for messages from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysextd&lt;/code&gt; to take care of validating, starting and stopping network extensions&lt;/p&gt;

&lt;h2 id=&quot;networkextensionframework&quot;&gt;NetworkExtension.framework&lt;/h2&gt;

&lt;p&gt;This framework existed but there is a new public function that should be noted.&lt;/p&gt;

&lt;h3 id=&quot;neproviderstartsystemextensionmode&quot;&gt;NEProvider.startSystemExtensionMode()&lt;/h3&gt;

&lt;p&gt;This method is responsible for starting up a listening XPC server. This allows the kernel to send out relevant messages to the user space Network Extensions.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;hr /&gt;

&lt;p&gt;So as you can see there are a lot of different pieces involved in “System Extensions” and I only barely managed to scratch the surface. I’m excited to see how this evolves and the increased security it should bring.&lt;/p&gt;</content><author><name>Scott Knight</name></author><category term="Reverse Engineering" /><category term="Assembly" /><category term="macOS" /><category term="x86" /><summary type="html">One of the most exciting things announced at this years WWDC was System Extensions. From a security perspective I think this is a really important advancedment for macOS. It means less third party code running in kernel space which should mean more security and stability. From a programmers perspective I think this is even more important. It means that the code developers previously had to write in C++ can now be written in a more modern language like Swift. Apple has been attempting to wrangle in kexts for a while now and this seems to be the final nail in the coffin. They have said macOS 10.15 will be the last release to fully support kexts without compromises and that in future releases of macOS Kernel Extensions with System Extension equivalents will not load at all. I thought it might be interesting to look at the internals of how System Extensions work.</summary></entry><entry><title type="html">Swift metadata</title><link href="https://knight.sc/reverse%20engineering/2019/07/17/swift-metadata.html" rel="alternate" type="text/html" title="Swift metadata" /><published>2019-07-17T00:00:00+00:00</published><updated>2019-07-17T00:00:00+00:00</updated><id>https://knight.sc/reverse%20engineering/2019/07/17/swift-metadata</id><content type="html" xml:base="https://knight.sc/reverse%20engineering/2019/07/17/swift-metadata.html">&lt;p&gt;When reverse engineering macOS binaries that are written in Objective-C, &lt;a href=&quot;https://github.com/nygard/class-dump/&quot; target=&quot;_blank&quot;&gt;class-dump&lt;/a&gt; is a common tool used to extract Objective-C declarations from the runtime information stored in the Mach-O files. With Swift binaries, since there is Objective-C compatability, sometimes you can extract declarations using &lt;a href=&quot;https://github.com/nygard/class-dump/&quot; target=&quot;_blank&quot;&gt;class-dump&lt;/a&gt; but not always. Swift has a rich set of type metadata itself but the &lt;a href=&quot;https://github.com/apple/swift/blob/master/docs/ABI/TypeMetadata.rst&quot; target=&quot;_blank&quot;&gt;documentation&lt;/a&gt; is not up to date. With Swift 5 bringing &lt;a href=&quot;https://swift.org/blog/abi-stability-and-more/&quot; target=&quot;_blank&quot;&gt;ABI stability&lt;/a&gt; I thought it would be interesting to take a look at the type of metadata availble in Swift binaries.&lt;/p&gt;

&lt;p&gt;From the &lt;a href=&quot;https://github.com/apple/swift/blob/master/docs/ABI/TypeMetadata.rst&quot; target=&quot;_blank&quot;&gt;documentation&lt;/a&gt; we see the following overview of Swift type metadata:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The Swift runtime keeps a metadata record for every type used in a program, including every instantiation of generic types. These metadata records can be used by (TODO: reflection and) debugger tools to discover information about types.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To start off with lets start with finding out where the Swift metadata is stored in a Mach-O file. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jtool -l&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;otool -l&lt;/code&gt; will work in this case.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;jtool2 &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; /Applications/Stocks.app/Contents/MacOS/Stocks
LC 00: LC_SEGMENT_64              Mem: 0x000000000-0x100000000    __PAGEZERO
LC 01: LC_SEGMENT_64              Mem: 0x100000000-0x100028000    __TEXT
    Mem: 0x100002ca0-0x100020304        __TEXT.__text    &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Normal&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    Mem: 0x100020304-0x100020a90        __TEXT.__stubs    &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Symbol Stubs&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    Mem: 0x100020a90-0x100021734        __TEXT.__stub_helper    &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Normal&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    Mem: 0x100021740-0x100022c28        __TEXT.__const
    Mem: 0x100022c30-0x100024dc5        __TEXT.__cstring    &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;C-String Literals&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    Mem: 0x100024dc5-0x100026630        __TEXT.__objc_methname    &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;C-String Literals&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    Mem: 0x100026630-0x100026d54        __TEXT.__swift5_typeref
    Mem: 0x100026d60-0x100027061        __TEXT.__swift5_reflstr
    Mem: 0x100027064-0x1000274cc        __TEXT.__swift5_fieldmd
    Mem: 0x1000274cc-0x100027608        __TEXT.__swift5_capture
    Mem: 0x100027608-0x100027668        __TEXT.__swift5_assocty
    Mem: 0x100027668-0x1000276f8        __TEXT.__swift5_proto
    Mem: 0x1000276f8-0x10002776c        __TEXT.__swift5_types
    Mem: 0x10002776c-0x100027794        __TEXT.__swift5_builtin
    Mem: 0x100027794-0x1000277ac        __TEXT.__swift5_protos
    Mem: 0x1000277ac-0x100027bb0        __TEXT.__unwind_info
    Mem: 0x100027bb0-0x100027ff8        __TEXT.__eh_frame
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can see that in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__TEXT&lt;/code&gt; segment of the binary there are a handful of sections that start with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__swift5&lt;/code&gt; prefix. With the documentation out of date the best way to determine what goes in these sections is to look directly in the Swift code. Here are some of the most helpful places in code I’ve found:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/apple/swift/blob/master/include/swift/ABI/Metadata.h&quot; target=&quot;_blank&quot;&gt;https://github.com/apple/swift/blob/master/include/swift/ABI/Metadata.h&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/apple/swift/blob/master/include/swift/Reflection/Records.h&quot; target=&quot;_blank&quot;&gt;https://github.com/apple/swift/blob/master/include/swift/Reflection/Records.h&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/apple/swift/blob/master/lib/IRGen/GenDecl.cpp&quot; target=&quot;_blank&quot;&gt;https://github.com/apple/swift/blob/master/lib/IRGen/GenDecl.cpp&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/apple/swift/blob/master/lib/IRGen/GenMeta.cpp&quot; target=&quot;_blank&quot;&gt;https://github.com/apple/swift/blob/master/lib/IRGen/GenMeta.cpp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are just a few of the example files I found useful while looking into Swift metadata. In general the useful code breaks down into ABI code, reflection code and LLVM IR generation code. The metadata in the LLVM IR code is nicely labelled and is the same as what gets emitted in the final compiled binary. If you have a test &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.swift&lt;/code&gt; file you can generate the IR yourself for inspection using the following command:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;swiftc &lt;span class=&quot;nt&quot;&gt;-emit-ir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-Xfrontend&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-disable-llvm-optzns&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; test.swift &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; test.ir
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What follows is a high level description of all the Swift 5 sections that can show up in a Swift binary.&lt;/p&gt;

&lt;h1 id=&quot;__text__swift5_protos&quot;&gt;__TEXT.__swift5_protos&lt;/h1&gt;

&lt;p&gt;This section contains an array of 32-bit signed integers. Each integer is a relative offset that points to a protocol descriptor in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__TEXT.__const&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;A protocol descriptor has the following format:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProtocolDescriptor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt;                      &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Parent&lt;/span&gt;                     &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;                       &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumRequirementsInSignature&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumRequirements&lt;/span&gt;            &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;AssociatedTypeNames&lt;/span&gt;        &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;__text__swift5_proto&quot;&gt;__TEXT.__swift5_proto&lt;/h1&gt;

&lt;p&gt;This section contains an array of 32-bit signed integers. Each integer is a relative offset that points to a protocol conformance descriptor in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__TEXT.__const&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;A protocol conformance descriptor has the following format:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProtocolConformanceDescriptor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ProtocolDescriptor&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;NominalTypeDescriptor&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ProtocolWitnessTable&lt;/span&gt;  &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ConformanceFlags&lt;/span&gt;      &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;__text__swift5_types&quot;&gt;__TEXT.__swift5_types&lt;/h1&gt;

&lt;p&gt;This section contains an array of 32-bit signed integers. Each integer is a relative offset that points to a nominal type descriptor in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__TEXT.__const&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;A nominal type descriptor can take different formats based on what type it represents. There are different structures for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Enum&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Struct&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Class&lt;/code&gt; types. They have the following format:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EnumDescriptor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt;                               &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Parent&lt;/span&gt;                              &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;                                &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;AccessFunction&lt;/span&gt;                      &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FieldDescriptor&lt;/span&gt;                     &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumPayloadCasesAndPayloadSizeOffset&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumEmptyCases&lt;/span&gt;                       &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StructDescriptor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt;                   &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Parent&lt;/span&gt;                  &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;                    &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;AccessFunction&lt;/span&gt;          &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FieldDescriptor&lt;/span&gt;         &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumFields&lt;/span&gt;               &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FieldOffsetVectorOffset&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ClassDescriptor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt;                       &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Parent&lt;/span&gt;                      &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;                        &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;AccessFunction&lt;/span&gt;              &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FieldDescriptor&lt;/span&gt;             &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;SuperclassType&lt;/span&gt;              &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MetadataNegativeSizeInWords&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MetadataPositiveSizeInWords&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumImmediateMembers&lt;/span&gt;         &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumFields&lt;/span&gt;                   &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;__text__const&quot;&gt;__TEXT.__const&lt;/h1&gt;

&lt;p&gt;This section is not Swift specific. It contains descriptors referenced from other sections. Here are some of the various structures you’ll see in this section:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Protocol conformance descriptor&lt;/li&gt;
  &lt;li&gt;Module descriptor&lt;/li&gt;
  &lt;li&gt;Protocol descriptor&lt;/li&gt;
  &lt;li&gt;Nominal type descriptors&lt;/li&gt;
  &lt;li&gt;Direct field offsets&lt;/li&gt;
  &lt;li&gt;Method descriptors&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;__text__swift5_fieldmd&quot;&gt;__TEXT.__swift5_fieldmd&lt;/h1&gt;

&lt;p&gt;This section contains an array of field descriptors. A field descriptor contains a collection of field records for a single class, struct or enum declaration. Each field descriptor can be a different length depending on how many field records the type contains.&lt;/p&gt;

&lt;p&gt;A field descriptor has the following format:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FieldRecord&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt;           &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MangledTypeName&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FieldName&lt;/span&gt;       &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FieldDescriptor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MangledTypeName&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Superclass&lt;/span&gt;      &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Kind&lt;/span&gt;            &lt;span class=&quot;kt&quot;&gt;uint16&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FieldRecordSize&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint16&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumFields&lt;/span&gt;       &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FieldRecords&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FieldRecord&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;__text__swift5_assocty&quot;&gt;__TEXT.__swift5_assocty&lt;/h1&gt;

&lt;p&gt;This section contains an array of associated type descriptors. An associated type descriptor contains a collection of associated type records for a conformance. An associated type records describe the mapping from an associated type to the type witness of a conformance.&lt;/p&gt;

&lt;p&gt;An associated type descriptor has the following format:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AssociatedTypeRecord&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;                &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;SubstitutedTypeName&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AssociatedTypeDescriptor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ConformingTypeName&lt;/span&gt;       &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ProtocolTypeName&lt;/span&gt;         &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumAssociatedTypes&lt;/span&gt;       &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;AssociatedTypeRecordSize&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;AssociatedTypeRecords&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AssociatedTypeRecord&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;__text__swift5_builtin&quot;&gt;__TEXT.__swift5_builtin&lt;/h1&gt;

&lt;p&gt;This section contains an array of builtin type descriptors. A builtin type descriptor describes the basic layout information about any builtin types referenced from other sections.&lt;/p&gt;

&lt;p&gt;A builtin type descriptor has the following format:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BuiltinTypeDescriptor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;TypeName&lt;/span&gt;            &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Size&lt;/span&gt;                &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;AlignmentAndFlags&lt;/span&gt;   &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Stride&lt;/span&gt;              &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumExtraInhabitants&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;__text__swift5_capture&quot;&gt;__TEXT.__swift5_capture&lt;/h1&gt;

&lt;p&gt;Capture descriptors describe the layout of a closure context object. Unlike nominal types, the generic substitutions for a closure context come from the object, and not the metadata.&lt;/p&gt;

&lt;p&gt;A capture descriptor has the following format:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CaptureTypeRecord&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MangledTypeName&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MetadataSourceRecord&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MangledTypeName&lt;/span&gt;       &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MangledMetadataSource&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CaptureDescriptor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumCaptureTypes&lt;/span&gt;       &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumMetadataSources&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumBindings&lt;/span&gt;           &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;CaptureTypeRecords&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CaptureTypeRecord&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MetadataSourceRecords&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MetadataSourceRecord&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;__text__swift5_typeref&quot;&gt;__TEXT.__swift5_typeref&lt;/h1&gt;

&lt;p&gt;This section contains a list of mangled type names that are referenced from other sections. This is essentially all the different types that are used in the application. The Swift docs and code are the best places to find out more information about mangled type names.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/apple/swift/blob/master/docs/ABI/Mangling.rst&quot; target=&quot;_blank&quot;&gt;https://github.com/apple/swift/blob/master/docs/ABI/Mangling.rst&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/apple/swift/blob/master/lib/Demangling/Demangler.cpp&quot; target=&quot;_blank&quot;&gt;https://github.com/apple/swift/blob/master/lib/Demangling/Demangler.cpp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;__text__swift5_reflstr&quot;&gt;__TEXT.__swift5_reflstr&lt;/h1&gt;

&lt;p&gt;This section contains an array of C strings. The strings are field names for the properties of the metadata defined in other sections.&lt;/p&gt;

&lt;h1 id=&quot;__text__swift5_replace&quot;&gt;__TEXT.__swift5_replace&lt;/h1&gt;

&lt;p&gt;This section contains dynamic replacement information. This is essentially the Swift equivalent of Objective-C method swizzling. You can read more about this Swift feature &lt;a href=&quot;https://forums.swift.org/t/dynamic-method-replacement/16619&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The dynamic replacement information has the following format:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Replacement&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ReplacedFunctionKey&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NewFunction&lt;/span&gt;         &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Replacement&lt;/span&gt;         &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt;               &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ReplacementScope&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumReplacements&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AutomaticReplacements&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt;            &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumReplacements&lt;/span&gt;  &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// hard coded to 1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Replacements&lt;/span&gt;     &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;__text__swift5_replac2&quot;&gt;__TEXT.__swift5_replac2&lt;/h1&gt;

&lt;p&gt;This section contains dynamica replacement information for opaque types. It’s not clear why this additional section was created instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__swift5_replace&lt;/code&gt; but you can see the original pull request that implemented it &lt;a href=&quot;https://github.com/apple/swift/pull/24781&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The dynamic replacement information for opaque types has the following format:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Replacement&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Original&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Replacement&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AutomaticReplacementsSome&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Flags&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NumReplacements&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Replacements&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Replacement&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;__data__const&quot;&gt;__DATA.__const&lt;/h1&gt;

&lt;p&gt;This section is not Swift specific. It contains things like value witness tables and full type metadata. Presumably some of the metadata is placed here so it can be modified at runtime.&lt;/p&gt;

&lt;h1 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h1&gt;

&lt;p&gt;My hope is the information above helps make it more clear what type of extra information is stored in Swift binaries. Just like was mentioned in the official metadata documentation this information can be used for writing debug tools. It should be possible to use this information to create a &lt;a href=&quot;https://github.com/nygard/class-dump/&quot; target=&quot;_blank&quot;&gt;class-dump&lt;/a&gt; like tool for Swift binaries.&lt;/p&gt;</content><author><name>Scott Knight</name></author><category term="Reverse Engineering" /><category term="Swift" /><summary type="html">When reverse engineering macOS binaries that are written in Objective-C, class-dump is a common tool used to extract Objective-C declarations from the runtime information stored in the Mach-O files. With Swift binaries, since there is Objective-C compatability, sometimes you can extract declarations using class-dump but not always. Swift has a rich set of type metadata itself but the documentation is not up to date. With Swift 5 bringing ABI stability I thought it would be interesting to take a look at the type of metadata availble in Swift binaries.</summary></entry><entry><title type="html">Debugging Apple binaries that use PT_DENY_ATTACH</title><link href="https://knight.sc/debugging/2019/06/03/debugging-apple-binaries-that-use-pt-deny-attach.html" rel="alternate" type="text/html" title="Debugging Apple binaries that use PT_DENY_ATTACH" /><published>2019-06-03T00:00:00+00:00</published><updated>2019-06-03T00:00:00+00:00</updated><id>https://knight.sc/debugging/2019/06/03/debugging-apple-binaries-that-use-pt-deny-attach</id><content type="html" xml:base="https://knight.sc/debugging/2019/06/03/debugging-apple-binaries-that-use-pt-deny-attach.html">&lt;p&gt;Recently while looking into the Apple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adid&lt;/code&gt; daemon, I noticed that I couldn’t attach to the process with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lldb&lt;/code&gt; even if SIP was completely disabled. After digging into it a little bit I came to the conclusion that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adid&lt;/code&gt; was calling the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; API passing in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PT_DENY_ATTACH&lt;/code&gt;. There are numerous other posts out there (like &lt;a href=&quot;https://alexomara.com/blog/defeating-anti-debug-techniques-macos-ptrace-variants/&quot; target=&quot;_blank&quot;&gt;this one&lt;/a&gt;) that talk about defeating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PT_DENY_ATTACH&lt;/code&gt; if you’re running the application yourself. In my case &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adid&lt;/code&gt; is started as a LaunchDaemon and is already running by the time a user is logged in. I decided to take a look at how you could defeat the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; call even after the application is already running.&lt;/p&gt;

&lt;p&gt;First a quick note on how I determined that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adid&lt;/code&gt; was using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; API. I started off on a virtual machine with SIP disabled. This is my usual setup when inspecting Apple platform binaries. I tried to connect to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adid&lt;/code&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lldb&lt;/code&gt; but it didn’t seem to work.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ps xa | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;adid
  374   ??  Ss     0:00.06 /System/Library/PrivateFrameworks/CoreADI.framework/adid

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;lldb &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;attach 374&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; attach 374
error: attach failed: Error 1

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;lldb &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;attach 374&quot;&lt;/span&gt;
Password:
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; attach 374
error: attach failed: lost connection
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The second attempt running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lldb&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo&lt;/code&gt; resulted in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;debugserver&lt;/code&gt; itself crashing with a segmentation fault. This is what made me think that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; might be in use. Checking the symbols on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adid&lt;/code&gt; confirmed this.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;jtool2 &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; /System/Library/PrivateFrameworks/CoreADI.framework/adid  | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;ptrace
                 U _ptrace
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From there I decided that I should be able to either catch the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; call at boot time by debugging XNU itself or potentially inspect and undo the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; call from the running process. I set up my virtual machine for &lt;a href=&quot;/debugging/2018/08/15/macos-kernel-debugging.html&quot; target=&quot;_blank&quot;&gt;kernel debugging&lt;/a&gt; and then decided to look into what the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; call itself does when called. Looking in the &lt;a href=&quot;https://github.com/knightsc/darwin-xnu/blob/master/bsd/kern/mach_process.c#L149&quot; target=&quot;_blank&quot;&gt;XNU source&lt;/a&gt; we can see that the following happens when calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace(PT_DENY_ATTACH, 0, 0, 0);&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define P_LNOATTACH     0x00001000
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;req&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PT_DENY_ATTACH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;proc_lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ISSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p_lflag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;P_LTRACED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;proc_unlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;KERNEL_DEBUG_CONSTANT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BSDDBG_CODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DBG_BSD_PROC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BSD_PROC_FRCEXIT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DBG_FUNC_NONE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p_pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;W_EXITCODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ENOTSUP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;exit1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;W_EXITCODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ENOTSUP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;thread_exception_return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/* NOTREACHED */&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;SET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p_lflag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;P_LNOATTACH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;proc_unlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; API is called with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PT_DENY_ATTACH&lt;/code&gt; argument what happens is that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proc&lt;/code&gt; structures &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_lflag&lt;/code&gt; field gets updated to have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P_LNOATTACH&lt;/code&gt; flag set. Some of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;proc&lt;/code&gt; fields are &lt;a href=&quot;https://github.com/knightsc/darwin-xnu/blob/master/bsd/kern/proc_info.c#L615&quot; target=&quot;_blank&quot;&gt;exposed to user space&lt;/a&gt; APIs but unfortunately it doesn’t look like the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_lflag&lt;/code&gt; is. At this point I decided to start up &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lldb&lt;/code&gt; and connect to the kernel and inspect the task itself. (The following commands assume you’ve loaded the lldbmacros that come with the Kernel Debug Kit)&lt;/p&gt;

&lt;p&gt;First I got some information about the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adid&lt;/code&gt; task.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; showtask &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt; adid
task                 vm_map               ipc_space            &lt;span class=&quot;c&quot;&gt;#acts flags    pid       process             io_policy  wq_state  command&lt;/span&gt;
0xffffff8017de1188   0xffffff8018d97838   0xffffff801acca980       3 R        374   0xffffff801acecd50            BLT  2  2  0    adid

&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; showprocinfo 0xffffff801acecd50
Process 0xffffff801acecd50
	name adid
	pid:374    task:0xffffff8017de1188   p_stat:2      parent pid: 1
Cred: euid 265 ruid 265 svuid 265
Flags: 0x4004
	0x00000004 - process is 64 bit
	0x00004000 - process has called &lt;span class=&quot;nb&quot;&gt;exec&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that we have an address for the process itself we can inspect the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_lflag&lt;/code&gt; field.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; p/x &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;struct proc &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;0xffffff801acecd50&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;-&amp;gt;p_lflag
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;unsigned int&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0x00801000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can see that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_lflag&lt;/code&gt; field has the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P_LNOATTACH&lt;/code&gt; flag set. All we need to do to effectively negate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; call is to change the value of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p_lflag&lt;/code&gt; field.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;expr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;struct proc &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;0xffffff801acecd50&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;-&amp;gt;p_lflag &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0x00800000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lldb&lt;/code&gt; can happily attach to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adid&lt;/code&gt; process. This effectively solves the original problem I had, which was being able to debug &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adid&lt;/code&gt; after it has already started, but it got me wondering what other processes Apple has that might be doing the same type of thing. I created a short &lt;a href=&quot;https://github.com/knightsc/lldb/blob/master/scripts/kernhelper.py&quot; target=&quot;_blank&quot;&gt;python script&lt;/a&gt; to check all tasks to see if they had the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P_LNOATTACH&lt;/code&gt; flag set.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;command &lt;/span&gt;script import kernhelper.py

&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; script kernhelper.show_ptrace_deny_attach_procs&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
...
...
0xffffff8025cabe20: SecurityAgent
0xffffff802a615b70: authorizationhos
0xffffff802cbd87f0: adid

&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lldb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So you can see there are a couple other processes running after first login that also have called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; passing in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PT_DENY_ATTACH&lt;/code&gt; argument. These correspond to the following binaries:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/System/Library/Frameworks/Security.framework/Versions/A/MachServices/SecurityAgent.bundle/Contents/MacOS/SecurityAgent
/System/Library/Frameworks/Security.framework/Versions/A/MachServices/authorizationhost.bundle/Contents/MacOS/authorizationhost
/System/Library/PrivateFrameworks/CoreADI.framework/adid
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we go even further and try to search for all binaries on a clean macOS 10.14.5 install that reference &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptrace&lt;/code&gt; we see the following list:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /System/Library
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rg &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-M&lt;/span&gt; 80 _ptrace 2&amp;gt; /dev/null
Kernels/kernel
QuickTime/QuickTimeComponents.component/Contents/MacOS/QuickTimeComponents
CoreServices/AppleFileServer.app/Contents/MacOS/AppleFileServer
Frameworks/DVDPlayback.framework/Versions/A/DVDPlayback
PrivateFrameworks/CoreADI.framework/Versions/A/adid
PrivateFrameworks/CoreFP.framework/Versions/A/fpsd
PrivateFrameworks/DiskImages.framework/Versions/A/DiskImages
PrivateFrameworks/AnnotationKit.framework/Versions/A/XPCServices/com.apple.AnnotationKit.MigratorService.xpc/Contents/MacOS/com.apple.AnnotationKit.MigratorService
Frameworks/Security.framework/Versions/A/MachServices/SecurityAgent.bundle/Contents/MacOS/SecurityAgent
Frameworks/Security.framework/Versions/A/MachServices/authorizationhost.bundle/Contents/MacOS/authorizationhost
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’m not sure if all of these are really using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PT_DENY_ATTACH&lt;/code&gt; or if some are just referencing the text &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_ptrace&lt;/code&gt; in some way but they are candidates that could be looked at in the future.&lt;/p&gt;

&lt;p&gt;My hope is this post shows a good example of how you can get started with kernel debugging learning about the internals of XNU itself as well as showing that as long as we still have control of the kernel on macOS there’s ultimately not much Apple can do to prevent us from inspecting their binaries.&lt;/p&gt;</content><author><name>Scott Knight</name></author><category term="Debugging" /><category term="Kernel" /><category term="LLDB" /><category term="macOS" /><category term="Python" /><summary type="html">Recently while looking into the Apple adid daemon, I noticed that I couldn’t attach to the process with lldb even if SIP was completely disabled. After digging into it a little bit I came to the conclusion that adid was calling the ptrace API passing in PT_DENY_ATTACH. There are numerous other posts out there (like this one) that talk about defeating PT_DENY_ATTACH if you’re running the application yourself. In my case adid is started as a LaunchDaemon and is already running by the time a user is logged in. I decided to take a look at how you could defeat the ptrace call even after the application is already running.</summary></entry></feed>